* config/i386/bsd.h (ASM_BYTE): New define.
[official-gcc.git] / gcc / config / i386 / i386.md
blob3d832f11249ed8974abad5f86cad5571568f53f0
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 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; E,e -- likewise, but for compare-and-branch fused insn.
34 ;; F,f -- likewise, but for floating-point.
35 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;;      otherwise nothing
37 ;; R -- print the prefix for register names.
38 ;; z -- print the opcode suffix for the size of the current operand.
39 ;; Z -- likewise, with special suffixes for x87 instructions.
40 ;; * -- print a star (in certain assembler syntax)
41 ;; A -- print an absolute memory reference.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
44 ;;      delimiter.
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;;      %b0 would print %al if operands[0] is reg 0.
47 ;; w --  likewise, print the HImode name of the register.
48 ;; k --  likewise, print the SImode name of the register.
49 ;; q --  likewise, print the DImode name of the register.
50 ;; x --  likewise, print the V4SFmode name of the register.
51 ;; t --  likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for SSE5 com* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
64 ;; UNSPEC usage:
66 (define_constants
67   [; Relocation specifiers
68    (UNSPEC_GOT                  0)
69    (UNSPEC_GOTOFF               1)
70    (UNSPEC_GOTPCREL             2)
71    (UNSPEC_GOTTPOFF             3)
72    (UNSPEC_TPOFF                4)
73    (UNSPEC_NTPOFF               5)
74    (UNSPEC_DTPOFF               6)
75    (UNSPEC_GOTNTPOFF            7)
76    (UNSPEC_INDNTPOFF            8)
77    (UNSPEC_PLTOFF               9)
78    (UNSPEC_MACHOPIC_OFFSET      10)
80    ; Prologue support
81    (UNSPEC_STACK_ALLOC          11)
82    (UNSPEC_SET_GOT              12)
83    (UNSPEC_SSE_PROLOGUE_SAVE    13)
84    (UNSPEC_REG_SAVE             14)
85    (UNSPEC_DEF_CFA              15)
86    (UNSPEC_SET_RIP              16)
87    (UNSPEC_SET_GOT_OFFSET       17)
88    (UNSPEC_MEMORY_BLOCKAGE      18)
90    ; TLS support
91    (UNSPEC_TP                   20)
92    (UNSPEC_TLS_GD               21)
93    (UNSPEC_TLS_LD_BASE          22)
94    (UNSPEC_TLSDESC              23)
96    ; Other random patterns
97    (UNSPEC_SCAS                 30)
98    (UNSPEC_FNSTSW               31)
99    (UNSPEC_SAHF                 32)
100    (UNSPEC_FSTCW                33)
101    (UNSPEC_ADD_CARRY            34)
102    (UNSPEC_FLDCW                35)
103    (UNSPEC_REP                  36)
104    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
105    (UNSPEC_TRUNC_NOOP           39)
107    ; For SSE/MMX support:
108    (UNSPEC_FIX_NOTRUNC          40)
109    (UNSPEC_MASKMOV              41)
110    (UNSPEC_MOVMSK               42)
111    (UNSPEC_MOVNT                43)
112    (UNSPEC_MOVU                 44)
113    (UNSPEC_RCP                  45)
114    (UNSPEC_RSQRT                46)
115    (UNSPEC_SFENCE               47)
116    (UNSPEC_PFRCP                49)
117    (UNSPEC_PFRCPIT1             40)
118    (UNSPEC_PFRCPIT2             41)
119    (UNSPEC_PFRSQRT              42)
120    (UNSPEC_PFRSQIT1             43)
121    (UNSPEC_MFENCE               44)
122    (UNSPEC_LFENCE               45)
123    (UNSPEC_PSADBW               46)
124    (UNSPEC_LDDQU                47)
125    (UNSPEC_MS_TO_SYSV_CALL      48)
127    ; Generic math support
128    (UNSPEC_COPYSIGN             50)
129    (UNSPEC_IEEE_MIN             51)     ; not commutative
130    (UNSPEC_IEEE_MAX             52)     ; not commutative
132    ; x87 Floating point
133    (UNSPEC_SIN                  60)
134    (UNSPEC_COS                  61)
135    (UNSPEC_FPATAN               62)
136    (UNSPEC_FYL2X                63)
137    (UNSPEC_FYL2XP1              64)
138    (UNSPEC_FRNDINT              65)
139    (UNSPEC_FIST                 66)
140    (UNSPEC_F2XM1                67)
141    (UNSPEC_TAN                  68)
142    (UNSPEC_FXAM                 69)
144    ; x87 Rounding
145    (UNSPEC_FRNDINT_FLOOR        70)
146    (UNSPEC_FRNDINT_CEIL         71)
147    (UNSPEC_FRNDINT_TRUNC        72)
148    (UNSPEC_FRNDINT_MASK_PM      73)
149    (UNSPEC_FIST_FLOOR           74)
150    (UNSPEC_FIST_CEIL            75)
152    ; x87 Double output FP
153    (UNSPEC_SINCOS_COS           80)
154    (UNSPEC_SINCOS_SIN           81)
155    (UNSPEC_XTRACT_FRACT         84)
156    (UNSPEC_XTRACT_EXP           85)
157    (UNSPEC_FSCALE_FRACT         86)
158    (UNSPEC_FSCALE_EXP           87)
159    (UNSPEC_FPREM_F              88)
160    (UNSPEC_FPREM_U              89)
161    (UNSPEC_FPREM1_F             90)
162    (UNSPEC_FPREM1_U             91)
164    (UNSPEC_C2_FLAG              95)
165    (UNSPEC_FXAM_MEM             96)
167    ; SSP patterns
168    (UNSPEC_SP_SET               100)
169    (UNSPEC_SP_TEST              101)
170    (UNSPEC_SP_TLS_SET           102)
171    (UNSPEC_SP_TLS_TEST          103)
173    ; SSSE3
174    (UNSPEC_PSHUFB               120)
175    (UNSPEC_PSIGN                121)
176    (UNSPEC_PALIGNR              122)
178    ; For SSE4A support
179    (UNSPEC_EXTRQI               130)
180    (UNSPEC_EXTRQ                131)
181    (UNSPEC_INSERTQI             132)
182    (UNSPEC_INSERTQ              133)
184    ; For SSE4.1 support
185    (UNSPEC_BLENDV               134)
186    (UNSPEC_INSERTPS             135)
187    (UNSPEC_DP                   136)
188    (UNSPEC_MOVNTDQA             137)
189    (UNSPEC_MPSADBW              138)
190    (UNSPEC_PHMINPOSUW           139)
191    (UNSPEC_PTEST                140)
192    (UNSPEC_ROUND                141)
194    ; For SSE4.2 support
195    (UNSPEC_CRC32                143)
196    (UNSPEC_PCMPESTR             144)
197    (UNSPEC_PCMPISTR             145)
199    ;; For SSE5
200    (UNSPEC_SSE5_INTRINSIC       150)
201    (UNSPEC_SSE5_UNSIGNED_CMP    151)
202    (UNSPEC_SSE5_TRUEFALSE       152)
203    (UNSPEC_SSE5_PERMUTE         153)
204    (UNSPEC_FRCZ                 154)
205    (UNSPEC_CVTPH2PS             155)
206    (UNSPEC_CVTPS2PH             156)
208    ; For AES support
209    (UNSPEC_AESENC               159)
210    (UNSPEC_AESENCLAST           160)
211    (UNSPEC_AESDEC               161)
212    (UNSPEC_AESDECLAST           162)
213    (UNSPEC_AESIMC               163)
214    (UNSPEC_AESKEYGENASSIST      164)
216    ; For PCLMUL support
217    (UNSPEC_PCLMUL               165)
219    ; For AVX support
220    (UNSPEC_PCMP                 166)
221    (UNSPEC_VPERMIL              167)
222    (UNSPEC_VPERMIL2F128         168)
223    (UNSPEC_MASKLOAD             169)
224    (UNSPEC_MASKSTORE            170)
225    (UNSPEC_CAST                 171)
226    (UNSPEC_VTESTP               172)
227   ])
229 (define_constants
230   [(UNSPECV_BLOCKAGE            0)
231    (UNSPECV_STACK_PROBE         1)
232    (UNSPECV_EMMS                2)
233    (UNSPECV_LDMXCSR             3)
234    (UNSPECV_STMXCSR             4)
235    (UNSPECV_FEMMS               5)
236    (UNSPECV_CLFLUSH             6)
237    (UNSPECV_ALIGN               7)
238    (UNSPECV_MONITOR             8)
239    (UNSPECV_MWAIT               9)
240    (UNSPECV_CMPXCHG             10)
241    (UNSPECV_XCHG                12)
242    (UNSPECV_LOCK                13)
243    (UNSPECV_PROLOGUE_USE        14)
244    (UNSPECV_CLD                 15)
245    (UNSPECV_VZEROALL            16)
246    (UNSPECV_VZEROUPPER          17)
247    (UNSPECV_RDTSC               18)
248    (UNSPECV_RDTSCP              19)
249    (UNSPECV_RDPMC               20)
250   ])
252 ;; Constants to represent pcomtrue/pcomfalse variants
253 (define_constants
254   [(PCOM_FALSE                  0)
255    (PCOM_TRUE                   1)
256    (COM_FALSE_S                 2)
257    (COM_FALSE_P                 3)
258    (COM_TRUE_S                  4)
259    (COM_TRUE_P                  5)
260   ])
262 ;; Constants used in the SSE5 pperm instruction
263 (define_constants
264   [(PPERM_SRC                   0x00)   /* copy source */
265    (PPERM_INVERT                0x20)   /* invert source */
266    (PPERM_REVERSE               0x40)   /* bit reverse source */
267    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
268    (PPERM_ZERO                  0x80)   /* all 0's */
269    (PPERM_ONES                  0xa0)   /* all 1's */
270    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
271    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
272    (PPERM_SRC1                  0x00)   /* use first source byte */
273    (PPERM_SRC2                  0x10)   /* use second source byte */
274    ])
276 ;; Registers by name.
277 (define_constants
278   [(AX_REG                       0)
279    (DX_REG                       1)
280    (CX_REG                       2)
281    (BX_REG                       3)
282    (SI_REG                       4)
283    (DI_REG                       5)
284    (BP_REG                       6)
285    (SP_REG                       7)
286    (ST0_REG                      8)
287    (ST1_REG                      9)
288    (ST2_REG                     10)
289    (ST3_REG                     11)
290    (ST4_REG                     12)
291    (ST5_REG                     13)
292    (ST6_REG                     14)
293    (ST7_REG                     15)
294    (FLAGS_REG                   17)
295    (FPSR_REG                    18)
296    (FPCR_REG                    19)
297    (XMM0_REG                    21)
298    (XMM1_REG                    22)
299    (XMM2_REG                    23)
300    (XMM3_REG                    24)
301    (XMM4_REG                    25)
302    (XMM5_REG                    26)
303    (XMM6_REG                    27)
304    (XMM7_REG                    28)
305    (MM0_REG                     29)
306    (MM1_REG                     30)
307    (MM2_REG                     31)
308    (MM3_REG                     32)
309    (MM4_REG                     33)
310    (MM5_REG                     34)
311    (MM6_REG                     35)
312    (MM7_REG                     36)
313    (R8_REG                      37)
314    (R9_REG                      38)
315    (R10_REG                     39)
316    (R11_REG                     40)
317    (R12_REG                     41)
318    (R13_REG                     42)
319    (XMM8_REG                    45)
320    (XMM9_REG                    46)
321    (XMM10_REG                   47)
322    (XMM11_REG                   48)
323    (XMM12_REG                   49)
324    (XMM13_REG                   50)
325    (XMM14_REG                   51)
326    (XMM15_REG                   52)
327   ])
329 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
330 ;; from i386.c.
332 ;; In C guard expressions, put expressions which may be compile-time
333 ;; constants first.  This allows for better optimization.  For
334 ;; example, write "TARGET_64BIT && reload_completed", not
335 ;; "reload_completed && TARGET_64BIT".
338 ;; Processor type.
339 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
340                     generic64,amdfam10"
341   (const (symbol_ref "ix86_schedule")))
343 ;; A basic instruction type.  Refinements due to arguments to be
344 ;; provided in other attributes.
345 (define_attr "type"
346   "other,multi,
347    alu,alu1,negnot,imov,imovx,lea,
348    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
349    icmp,test,ibr,setcc,icmov,
350    push,pop,call,callv,leave,
351    str,bitmanip,
352    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
353    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
354    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
355    ssemuladd,sse4arg,
356    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
357   (const_string "other"))
359 ;; Main data type used by the insn
360 (define_attr "mode"
361   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
362   (const_string "unknown"))
364 ;; The CPU unit operations uses.
365 (define_attr "unit" "integer,i387,sse,mmx,unknown"
366   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
367            (const_string "i387")
368          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
369                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
370                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
371            (const_string "sse")
372          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
373            (const_string "mmx")
374          (eq_attr "type" "other")
375            (const_string "unknown")]
376          (const_string "integer")))
378 ;; The (bounding maximum) length of an instruction immediate.
379 (define_attr "length_immediate" ""
380   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
381                           bitmanip")
382            (const_int 0)
383          (eq_attr "unit" "i387,sse,mmx")
384            (const_int 0)
385          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
386                           imul,icmp,push,pop")
387            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
388          (eq_attr "type" "imov,test")
389            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
390          (eq_attr "type" "call")
391            (if_then_else (match_operand 0 "constant_call_address_operand" "")
392              (const_int 4)
393              (const_int 0))
394          (eq_attr "type" "callv")
395            (if_then_else (match_operand 1 "constant_call_address_operand" "")
396              (const_int 4)
397              (const_int 0))
398          ;; We don't know the size before shorten_branches.  Expect
399          ;; the instruction to fit for better scheduling.
400          (eq_attr "type" "ibr")
401            (const_int 1)
402          ]
403          (symbol_ref "/* Update immediate_length and other attributes! */
404                       gcc_unreachable (),1")))
406 ;; The (bounding maximum) length of an instruction address.
407 (define_attr "length_address" ""
408   (cond [(eq_attr "type" "str,other,multi,fxch")
409            (const_int 0)
410          (and (eq_attr "type" "call")
411               (match_operand 0 "constant_call_address_operand" ""))
412              (const_int 0)
413          (and (eq_attr "type" "callv")
414               (match_operand 1 "constant_call_address_operand" ""))
415              (const_int 0)
416          ]
417          (symbol_ref "ix86_attr_length_address_default (insn)")))
419 ;; Set when length prefix is used.
420 (define_attr "prefix_data16" ""
421   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
422            (const_int 0)
423          (eq_attr "mode" "HI")
424            (const_int 1)
425          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
426            (const_int 1)
427         ]
428         (const_int 0)))
430 ;; Set when string REP prefix is used.
431 (define_attr "prefix_rep" ""
432   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
433            (const_int 0)
434          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
435            (const_int 1)
436         ]
437         (const_int 0)))
439 ;; Set when 0f opcode prefix is used.
440 (define_attr "prefix_0f" ""
441   (if_then_else
442     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
443          (eq_attr "unit" "sse,mmx"))
444     (const_int 1)
445     (const_int 0)))
447 ;; Set when REX opcode prefix is used.
448 (define_attr "prefix_rex" ""
449   (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
450            (const_int 0)
451          (and (eq_attr "mode" "DI")
452               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
453                    (eq_attr "unit" "!mmx")))
454            (const_int 1)
455          (and (eq_attr "mode" "QI")
456               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
457                   (const_int 0)))
458            (const_int 1)
459          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
460              (const_int 0))
461            (const_int 1)
462          (and (eq_attr "type" "imovx")
463               (match_operand:QI 1 "ext_QIreg_operand" ""))
464            (const_int 1)
465         ]
466         (const_int 0)))
468 ;; There are also additional prefixes in 3DNOW, SSSE3 or SSE5.
469 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
470 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
471 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
472 (define_attr "prefix_extra" ""
473   (cond [(eq_attr "type" "ssemuladd,sse4arg")
474            (const_int 2)
475          (eq_attr "type" "sseiadd1,ssecvt1")
476            (const_int 1)
477         ]
478         (const_int 0)))
480 ;; Prefix used: original, VEX or maybe VEX.
481 (define_attr "prefix" "orig,vex,maybe_vex"
482   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
483     (const_string "vex")
484     (const_string "orig")))
486 ;; VEX W bit is used.
487 (define_attr "prefix_vex_w" "" (const_int 0))
489 ;; The length of VEX prefix
490 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
491 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
492 ;; still prefix_0f 1, with prefix_extra 1.
493 (define_attr "length_vex" ""
494   (if_then_else (and (eq_attr "prefix_0f" "1")
495                      (eq_attr "prefix_extra" "0"))
496     (if_then_else (eq_attr "prefix_vex_w" "1")
497       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
498       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
499     (if_then_else (eq_attr "prefix_vex_w" "1")
500       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
501       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
503 ;; Set when modrm byte is used.
504 (define_attr "modrm" ""
505   (cond [(eq_attr "type" "str,leave")
506            (const_int 0)
507          (eq_attr "unit" "i387")
508            (const_int 0)
509          (and (eq_attr "type" "incdec")
510               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
511                    (ior (match_operand:SI 1 "register_operand" "")
512                         (match_operand:HI 1 "register_operand" ""))))
513            (const_int 0)
514          (and (eq_attr "type" "push")
515               (not (match_operand 1 "memory_operand" "")))
516            (const_int 0)
517          (and (eq_attr "type" "pop")
518               (not (match_operand 0 "memory_operand" "")))
519            (const_int 0)
520          (and (eq_attr "type" "imov")
521               (and (not (eq_attr "mode" "DI"))
522                    (ior (and (match_operand 0 "register_operand" "")
523                              (match_operand 1 "immediate_operand" ""))
524                         (ior (and (match_operand 0 "ax_reg_operand" "")
525                                   (match_operand 1 "memory_displacement_only_operand" ""))
526                              (and (match_operand 0 "memory_displacement_only_operand" "")
527                                   (match_operand 1 "ax_reg_operand" ""))))))
528            (const_int 0)
529          (and (eq_attr "type" "call")
530               (match_operand 0 "constant_call_address_operand" ""))
531              (const_int 0)
532          (and (eq_attr "type" "callv")
533               (match_operand 1 "constant_call_address_operand" ""))
534              (const_int 0)
535          (and (eq_attr "type" "alu,alu1,icmp,test")
536               (match_operand 0 "ax_reg_operand" ""))
537              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
538          ]
539          (const_int 1)))
541 ;; The (bounding maximum) length of an instruction in bytes.
542 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
543 ;; Later we may want to split them and compute proper length as for
544 ;; other insns.
545 (define_attr "length" ""
546   (cond [(eq_attr "type" "other,multi,fistp,frndint")
547            (const_int 16)
548          (eq_attr "type" "fcmp")
549            (const_int 4)
550          (eq_attr "unit" "i387")
551            (plus (const_int 2)
552                  (plus (attr "prefix_data16")
553                        (attr "length_address")))
554          (ior (eq_attr "prefix" "vex")
555               (and (eq_attr "prefix" "maybe_vex")
556                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
557            (plus (attr "length_vex")
558                  (plus (attr "length_immediate")
559                        (plus (attr "modrm")
560                              (attr "length_address"))))]
561          (plus (plus (attr "modrm")
562                      (plus (attr "prefix_0f")
563                            (plus (attr "prefix_rex")
564                                  (plus (attr "prefix_extra")
565                                        (const_int 1)))))
566                (plus (attr "prefix_rep")
567                      (plus (attr "prefix_data16")
568                            (plus (attr "length_immediate")
569                                  (attr "length_address")))))))
571 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
572 ;; `store' if there is a simple memory reference therein, or `unknown'
573 ;; if the instruction is complex.
575 (define_attr "memory" "none,load,store,both,unknown"
576   (cond [(eq_attr "type" "other,multi,str")
577            (const_string "unknown")
578          (eq_attr "type" "lea,fcmov,fpspc")
579            (const_string "none")
580          (eq_attr "type" "fistp,leave")
581            (const_string "both")
582          (eq_attr "type" "frndint")
583            (const_string "load")
584          (eq_attr "type" "push")
585            (if_then_else (match_operand 1 "memory_operand" "")
586              (const_string "both")
587              (const_string "store"))
588          (eq_attr "type" "pop")
589            (if_then_else (match_operand 0 "memory_operand" "")
590              (const_string "both")
591              (const_string "load"))
592          (eq_attr "type" "setcc")
593            (if_then_else (match_operand 0 "memory_operand" "")
594              (const_string "store")
595              (const_string "none"))
596          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
597            (if_then_else (ior (match_operand 0 "memory_operand" "")
598                               (match_operand 1 "memory_operand" ""))
599              (const_string "load")
600              (const_string "none"))
601          (eq_attr "type" "ibr")
602            (if_then_else (match_operand 0 "memory_operand" "")
603              (const_string "load")
604              (const_string "none"))
605          (eq_attr "type" "call")
606            (if_then_else (match_operand 0 "constant_call_address_operand" "")
607              (const_string "none")
608              (const_string "load"))
609          (eq_attr "type" "callv")
610            (if_then_else (match_operand 1 "constant_call_address_operand" "")
611              (const_string "none")
612              (const_string "load"))
613          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
614               (match_operand 1 "memory_operand" ""))
615            (const_string "both")
616          (and (match_operand 0 "memory_operand" "")
617               (match_operand 1 "memory_operand" ""))
618            (const_string "both")
619          (match_operand 0 "memory_operand" "")
620            (const_string "store")
621          (match_operand 1 "memory_operand" "")
622            (const_string "load")
623          (and (eq_attr "type"
624                  "!alu1,negnot,ishift1,
625                    imov,imovx,icmp,test,bitmanip,
626                    fmov,fcmp,fsgn,
627                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
628                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
629               (match_operand 2 "memory_operand" ""))
630            (const_string "load")
631          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
632               (match_operand 3 "memory_operand" ""))
633            (const_string "load")
634         ]
635         (const_string "none")))
637 ;; Indicates if an instruction has both an immediate and a displacement.
639 (define_attr "imm_disp" "false,true,unknown"
640   (cond [(eq_attr "type" "other,multi")
641            (const_string "unknown")
642          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
643               (and (match_operand 0 "memory_displacement_operand" "")
644                    (match_operand 1 "immediate_operand" "")))
645            (const_string "true")
646          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
647               (and (match_operand 0 "memory_displacement_operand" "")
648                    (match_operand 2 "immediate_operand" "")))
649            (const_string "true")
650         ]
651         (const_string "false")))
653 ;; Indicates if an FP operation has an integer source.
655 (define_attr "fp_int_src" "false,true"
656   (const_string "false"))
658 ;; Defines rounding mode of an FP operation.
660 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
661   (const_string "any"))
663 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
664 (define_attr "use_carry" "0,1" (const_string "0"))
666 ;; Define attribute to indicate unaligned ssemov insns
667 (define_attr "movu" "0,1" (const_string "0"))
669 ;; Describe a user's asm statement.
670 (define_asm_attributes
671   [(set_attr "length" "128")
672    (set_attr "type" "multi")])
674 ;; All integer comparison codes.
675 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
677 ;; All floating-point comparison codes.
678 (define_code_iterator fp_cond [unordered ordered
679                                uneq unge ungt unle unlt ltgt ])
681 (define_code_iterator plusminus [plus minus])
683 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
685 ;; Base name for define_insn
686 (define_code_attr plusminus_insn
687   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
688    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
690 ;; Base name for insn mnemonic.
691 (define_code_attr plusminus_mnemonic
692   [(plus "add") (ss_plus "adds") (us_plus "addus")
693    (minus "sub") (ss_minus "subs") (us_minus "subus")])
695 ;; Mark commutative operators as such in constraints.
696 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
697                         (minus "") (ss_minus "") (us_minus "")])
699 ;; Mapping of signed max and min
700 (define_code_iterator smaxmin [smax smin])
702 ;; Mapping of unsigned max and min
703 (define_code_iterator umaxmin [umax umin])
705 ;; Mapping of signed/unsigned max and min
706 (define_code_iterator maxmin [smax smin umax umin])
708 ;; Base name for integer and FP insn mnemonic
709 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
710                                  (umax "maxu") (umin "minu")])
711 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
713 ;; Mapping of parallel logic operators
714 (define_code_iterator plogic [and ior xor])
716 ;; Base name for insn mnemonic.
717 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
719 ;; Mapping of abs neg operators
720 (define_code_iterator absneg [abs neg])
722 ;; Base name for x87 insn mnemonic.
723 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
725 ;; All single word integer modes.
726 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
728 ;; Single word integer modes without QImode.
729 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
731 ;; Instruction suffix for integer modes.
732 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
734 ;; Register class for integer modes.
735 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
737 ;; Immediate operand constraint for integer modes.
738 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
740 ;; General operand predicate for integer modes.
741 (define_mode_attr general_operand
742         [(QI "general_operand")
743          (HI "general_operand")
744          (SI "general_operand")
745          (DI "x86_64_general_operand")])
747 ;; SSE and x87 SFmode and DFmode floating point modes
748 (define_mode_iterator MODEF [SF DF])
750 ;; All x87 floating point modes
751 (define_mode_iterator X87MODEF [SF DF XF])
753 ;; All integer modes handled by x87 fisttp operator.
754 (define_mode_iterator X87MODEI [HI SI DI])
756 ;; All integer modes handled by integer x87 operators.
757 (define_mode_iterator X87MODEI12 [HI SI])
759 ;; All integer modes handled by SSE cvtts?2si* operators.
760 (define_mode_iterator SSEMODEI24 [SI DI])
762 ;; SSE asm suffix for floating point modes
763 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
765 ;; SSE vector mode corresponding to a scalar mode
766 (define_mode_attr ssevecmode
767   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
769 ;; Instruction suffix for REX 64bit operators.
770 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
772 ;; This mode iterator allows :P to be used for patterns that operate on
773 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
774 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
777 ;; Scheduling descriptions
779 (include "pentium.md")
780 (include "ppro.md")
781 (include "k6.md")
782 (include "athlon.md")
783 (include "geode.md")
784 (include "atom.md")
787 ;; Operand and operator predicates and constraints
789 (include "predicates.md")
790 (include "constraints.md")
793 ;; Compare and branch/compare and store instructions.
795 (define_expand "cbranchti4"
796   [(set (reg:CC FLAGS_REG)
797         (compare:CC (match_operand:TI 1 "nonimmediate_operand" "")
798                     (match_operand:TI 2 "x86_64_general_operand" "")))
799    (set (pc) (if_then_else
800               (match_operator 0 "comparison_operator"
801                [(reg:CC FLAGS_REG)
802                 (const_int 0)])
803               (label_ref (match_operand 3 "" ""))
804               (pc)))]
805   "TARGET_64BIT"
807   if (MEM_P (operands[1]) && MEM_P (operands[2]))
808     operands[1] = force_reg (TImode, operands[1]);
809   ix86_compare_op0 = operands[1];
810   ix86_compare_op1 = operands[2];
811   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
812   DONE;
815 (define_expand "cbranchdi4"
816   [(set (reg:CC FLAGS_REG)
817         (compare:CC (match_operand:DI 1 "nonimmediate_operand" "")
818                     (match_operand:DI 2 "x86_64_general_operand" "")))
819    (set (pc) (if_then_else
820               (match_operator 0 "comparison_operator"
821                [(reg:CC FLAGS_REG)
822                 (const_int 0)])
823               (label_ref (match_operand 3 "" ""))
824               (pc)))]
825   ""
827   if (MEM_P (operands[1]) && MEM_P (operands[2]))
828     operands[1] = force_reg (DImode, operands[1]);
829   ix86_compare_op0 = operands[1];
830   ix86_compare_op1 = operands[2];
831   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
832   DONE;
835 (define_expand "cstoredi4"
836   [(set (reg:CC FLAGS_REG)
837         (compare:CC (match_operand:DI 2 "nonimmediate_operand" "")
838                     (match_operand:DI 3 "x86_64_general_operand" "")))
839    (set (match_operand:QI 0 "register_operand" "")
840               (match_operator 1 "comparison_operator"
841                [(reg:CC FLAGS_REG)
842                 (const_int 0)]))]
843   "TARGET_64BIT"
845   if (MEM_P (operands[2]) && MEM_P (operands[3]))
846     operands[2] = force_reg (DImode, operands[2]);
847   ix86_compare_op0 = operands[2];
848   ix86_compare_op1 = operands[3];
849   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
850   DONE;
853 (define_expand "cbranchsi4"
854   [(set (reg:CC FLAGS_REG)
855         (compare:CC (match_operand:SI 1 "cmpsi_operand" "")
856                     (match_operand:SI 2 "general_operand" "")))
857    (set (pc) (if_then_else
858               (match_operator 0 "comparison_operator"
859                [(reg:CC FLAGS_REG)
860                 (const_int 0)])
861               (label_ref (match_operand 3 "" ""))
862               (pc)))]
863   ""
865   if (MEM_P (operands[1]) && MEM_P (operands[2]))
866     operands[1] = force_reg (SImode, operands[1]);
867   ix86_compare_op0 = operands[1];
868   ix86_compare_op1 = operands[2];
869   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
870   DONE;
873 (define_expand "cstoresi4"
874   [(set (reg:CC FLAGS_REG)
875         (compare:CC (match_operand:SI 2 "cmpsi_operand" "")
876                     (match_operand:SI 3 "general_operand" "")))
877    (set (match_operand:QI 0 "register_operand" "")
878               (match_operator 1 "comparison_operator"
879                [(reg:CC FLAGS_REG)
880                 (const_int 0)]))]
881   ""
883   if (MEM_P (operands[2]) && MEM_P (operands[3]))
884     operands[2] = force_reg (SImode, operands[2]);
885   ix86_compare_op0 = operands[2];
886   ix86_compare_op1 = operands[3];
887   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
888   DONE;
891 (define_expand "cbranchhi4"
892   [(set (reg:CC FLAGS_REG)
893         (compare:CC (match_operand:HI 1 "nonimmediate_operand" "")
894                     (match_operand:HI 2 "general_operand" "")))
895    (set (pc) (if_then_else
896               (match_operator 0 "comparison_operator"
897                [(reg:CC FLAGS_REG)
898                 (const_int 0)])
899               (label_ref (match_operand 3 "" ""))
900               (pc)))]
901   ""
903   if (MEM_P (operands[1]) && MEM_P (operands[2]))
904     operands[1] = force_reg (HImode, operands[1]);
905   ix86_compare_op0 = operands[1];
906   ix86_compare_op1 = operands[2];
907   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
908   DONE;
911 (define_expand "cstorehi4"
912   [(set (reg:CC FLAGS_REG)
913         (compare:CC (match_operand:HI 2 "nonimmediate_operand" "")
914                     (match_operand:HI 3 "general_operand" "")))
915    (set (match_operand:QI 0 "register_operand" "")
916               (match_operator 1 "comparison_operator"
917                [(reg:CC FLAGS_REG)
918                 (const_int 0)]))]
919   ""
921   if (MEM_P (operands[2]) && MEM_P (operands[3]))
922     operands[2] = force_reg (HImode, operands[2]);
923   ix86_compare_op0 = operands[2];
924   ix86_compare_op1 = operands[3];
925   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
926   DONE;
930 (define_expand "cbranchqi4"
931   [(set (reg:CC FLAGS_REG)
932         (compare:CC (match_operand:QI 1 "nonimmediate_operand" "")
933                     (match_operand:QI 2 "general_operand" "")))
934    (set (pc) (if_then_else
935               (match_operator 0 "comparison_operator"
936                [(reg:CC FLAGS_REG)
937                 (const_int 0)])
938               (label_ref (match_operand 3 "" ""))
939               (pc)))]
940   ""
942   if (MEM_P (operands[1]) && MEM_P (operands[2]))
943     operands[1] = force_reg (QImode, operands[1]);
944   ix86_compare_op0 = operands[1];
945   ix86_compare_op1 = operands[2];
946   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
947   DONE;
951 (define_expand "cstoreqi4"
952   [(set (reg:CC FLAGS_REG)
953         (compare:CC (match_operand:QI 2 "nonimmediate_operand" "")
954                     (match_operand:QI 3 "general_operand" "")))
955    (set (match_operand:QI 0 "register_operand" "")
956               (match_operator 1 "comparison_operator"
957                [(reg:CC FLAGS_REG)
958                 (const_int 0)]))]
959   ""
961   if (MEM_P (operands[2]) && MEM_P (operands[3]))
962     operands[2] = force_reg (QImode, operands[2]);
963   ix86_compare_op0 = operands[2];
964   ix86_compare_op1 = operands[3];
965   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
966   DONE;
970 (define_insn "cmpdi_ccno_1_rex64"
971   [(set (reg FLAGS_REG)
972         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
973                  (match_operand:DI 1 "const0_operand" "")))]
974   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
975   "@
976    test{q}\t%0, %0
977    cmp{q}\t{%1, %0|%0, %1}"
978   [(set_attr "type" "test,icmp")
979    (set_attr "length_immediate" "0,1")
980    (set_attr "mode" "DI")])
982 (define_insn "*cmpdi_minus_1_rex64"
983   [(set (reg FLAGS_REG)
984         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
985                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
986                  (const_int 0)))]
987   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
988   "cmp{q}\t{%1, %0|%0, %1}"
989   [(set_attr "type" "icmp")
990    (set_attr "mode" "DI")])
992 (define_expand "cmpdi_1_rex64"
993   [(set (reg:CC FLAGS_REG)
994         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
995                     (match_operand:DI 1 "general_operand" "")))]
996   "TARGET_64BIT"
997   "")
999 (define_insn "cmpdi_1_insn_rex64"
1000   [(set (reg FLAGS_REG)
1001         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
1002                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
1003   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1004   "cmp{q}\t{%1, %0|%0, %1}"
1005   [(set_attr "type" "icmp")
1006    (set_attr "mode" "DI")])
1009 (define_insn "*cmpsi_ccno_1"
1010   [(set (reg FLAGS_REG)
1011         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1012                  (match_operand:SI 1 "const0_operand" "")))]
1013   "ix86_match_ccmode (insn, CCNOmode)"
1014   "@
1015    test{l}\t%0, %0
1016    cmp{l}\t{%1, %0|%0, %1}"
1017   [(set_attr "type" "test,icmp")
1018    (set_attr "length_immediate" "0,1")
1019    (set_attr "mode" "SI")])
1021 (define_insn "*cmpsi_minus_1"
1022   [(set (reg FLAGS_REG)
1023         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1024                            (match_operand:SI 1 "general_operand" "ri,mr"))
1025                  (const_int 0)))]
1026   "ix86_match_ccmode (insn, CCGOCmode)"
1027   "cmp{l}\t{%1, %0|%0, %1}"
1028   [(set_attr "type" "icmp")
1029    (set_attr "mode" "SI")])
1031 (define_expand "cmpsi_1"
1032   [(set (reg:CC FLAGS_REG)
1033         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
1034                     (match_operand:SI 1 "general_operand" "")))]
1035   ""
1036   "")
1038 (define_insn "*cmpsi_1_insn"
1039   [(set (reg FLAGS_REG)
1040         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1041                  (match_operand:SI 1 "general_operand" "ri,mr")))]
1042   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1043     && ix86_match_ccmode (insn, CCmode)"
1044   "cmp{l}\t{%1, %0|%0, %1}"
1045   [(set_attr "type" "icmp")
1046    (set_attr "mode" "SI")])
1048 (define_insn "*cmphi_ccno_1"
1049   [(set (reg FLAGS_REG)
1050         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1051                  (match_operand:HI 1 "const0_operand" "")))]
1052   "ix86_match_ccmode (insn, CCNOmode)"
1053   "@
1054    test{w}\t%0, %0
1055    cmp{w}\t{%1, %0|%0, %1}"
1056   [(set_attr "type" "test,icmp")
1057    (set_attr "length_immediate" "0,1")
1058    (set_attr "mode" "HI")])
1060 (define_insn "*cmphi_minus_1"
1061   [(set (reg FLAGS_REG)
1062         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1063                            (match_operand:HI 1 "general_operand" "rn,mr"))
1064                  (const_int 0)))]
1065   "ix86_match_ccmode (insn, CCGOCmode)"
1066   "cmp{w}\t{%1, %0|%0, %1}"
1067   [(set_attr "type" "icmp")
1068    (set_attr "mode" "HI")])
1070 (define_insn "*cmphi_1"
1071   [(set (reg FLAGS_REG)
1072         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1073                  (match_operand:HI 1 "general_operand" "rn,mr")))]
1074   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1075    && ix86_match_ccmode (insn, CCmode)"
1076   "cmp{w}\t{%1, %0|%0, %1}"
1077   [(set_attr "type" "icmp")
1078    (set_attr "mode" "HI")])
1080 (define_insn "*cmpqi_ccno_1"
1081   [(set (reg FLAGS_REG)
1082         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1083                  (match_operand:QI 1 "const0_operand" "")))]
1084   "ix86_match_ccmode (insn, CCNOmode)"
1085   "@
1086    test{b}\t%0, %0
1087    cmp{b}\t{$0, %0|%0, 0}"
1088   [(set_attr "type" "test,icmp")
1089    (set_attr "length_immediate" "0,1")
1090    (set_attr "mode" "QI")])
1092 (define_insn "*cmpqi_1"
1093   [(set (reg FLAGS_REG)
1094         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1095                  (match_operand:QI 1 "general_operand" "qn,mq")))]
1096   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1097     && ix86_match_ccmode (insn, CCmode)"
1098   "cmp{b}\t{%1, %0|%0, %1}"
1099   [(set_attr "type" "icmp")
1100    (set_attr "mode" "QI")])
1102 (define_insn "*cmpqi_minus_1"
1103   [(set (reg FLAGS_REG)
1104         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1105                            (match_operand:QI 1 "general_operand" "qn,mq"))
1106                  (const_int 0)))]
1107   "ix86_match_ccmode (insn, CCGOCmode)"
1108   "cmp{b}\t{%1, %0|%0, %1}"
1109   [(set_attr "type" "icmp")
1110    (set_attr "mode" "QI")])
1112 (define_insn "*cmpqi_ext_1"
1113   [(set (reg FLAGS_REG)
1114         (compare
1115           (match_operand:QI 0 "general_operand" "Qm")
1116           (subreg:QI
1117             (zero_extract:SI
1118               (match_operand 1 "ext_register_operand" "Q")
1119               (const_int 8)
1120               (const_int 8)) 0)))]
1121   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1122   "cmp{b}\t{%h1, %0|%0, %h1}"
1123   [(set_attr "type" "icmp")
1124    (set_attr "mode" "QI")])
1126 (define_insn "*cmpqi_ext_1_rex64"
1127   [(set (reg FLAGS_REG)
1128         (compare
1129           (match_operand:QI 0 "register_operand" "Q")
1130           (subreg:QI
1131             (zero_extract:SI
1132               (match_operand 1 "ext_register_operand" "Q")
1133               (const_int 8)
1134               (const_int 8)) 0)))]
1135   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1136   "cmp{b}\t{%h1, %0|%0, %h1}"
1137   [(set_attr "type" "icmp")
1138    (set_attr "mode" "QI")])
1140 (define_insn "*cmpqi_ext_2"
1141   [(set (reg FLAGS_REG)
1142         (compare
1143           (subreg:QI
1144             (zero_extract:SI
1145               (match_operand 0 "ext_register_operand" "Q")
1146               (const_int 8)
1147               (const_int 8)) 0)
1148           (match_operand:QI 1 "const0_operand" "")))]
1149   "ix86_match_ccmode (insn, CCNOmode)"
1150   "test{b}\t%h0, %h0"
1151   [(set_attr "type" "test")
1152    (set_attr "length_immediate" "0")
1153    (set_attr "mode" "QI")])
1155 (define_expand "cmpqi_ext_3"
1156   [(set (reg:CC FLAGS_REG)
1157         (compare:CC
1158           (subreg:QI
1159             (zero_extract:SI
1160               (match_operand 0 "ext_register_operand" "")
1161               (const_int 8)
1162               (const_int 8)) 0)
1163           (match_operand:QI 1 "general_operand" "")))]
1164   ""
1165   "")
1167 (define_insn "cmpqi_ext_3_insn"
1168   [(set (reg FLAGS_REG)
1169         (compare
1170           (subreg:QI
1171             (zero_extract:SI
1172               (match_operand 0 "ext_register_operand" "Q")
1173               (const_int 8)
1174               (const_int 8)) 0)
1175           (match_operand:QI 1 "general_operand" "Qmn")))]
1176   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1177   "cmp{b}\t{%1, %h0|%h0, %1}"
1178   [(set_attr "type" "icmp")
1179    (set_attr "modrm" "1")
1180    (set_attr "mode" "QI")])
1182 (define_insn "cmpqi_ext_3_insn_rex64"
1183   [(set (reg FLAGS_REG)
1184         (compare
1185           (subreg:QI
1186             (zero_extract:SI
1187               (match_operand 0 "ext_register_operand" "Q")
1188               (const_int 8)
1189               (const_int 8)) 0)
1190           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1191   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1192   "cmp{b}\t{%1, %h0|%h0, %1}"
1193   [(set_attr "type" "icmp")
1194    (set_attr "modrm" "1")
1195    (set_attr "mode" "QI")])
1197 (define_insn "*cmpqi_ext_4"
1198   [(set (reg FLAGS_REG)
1199         (compare
1200           (subreg:QI
1201             (zero_extract:SI
1202               (match_operand 0 "ext_register_operand" "Q")
1203               (const_int 8)
1204               (const_int 8)) 0)
1205           (subreg:QI
1206             (zero_extract:SI
1207               (match_operand 1 "ext_register_operand" "Q")
1208               (const_int 8)
1209               (const_int 8)) 0)))]
1210   "ix86_match_ccmode (insn, CCmode)"
1211   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1212   [(set_attr "type" "icmp")
1213    (set_attr "mode" "QI")])
1215 ;; These implement float point compares.
1216 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1217 ;; which would allow mix and match FP modes on the compares.  Which is what
1218 ;; the old patterns did, but with many more of them.
1220 (define_expand "cbranchxf4"
1221   [(set (reg:CC FLAGS_REG)
1222         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1223                     (match_operand:XF 2 "nonmemory_operand" "")))
1224    (set (pc) (if_then_else
1225               (match_operator 0 "ix86_fp_comparison_operator"
1226                [(reg:CC FLAGS_REG)
1227                 (const_int 0)])
1228               (label_ref (match_operand 3 "" ""))
1229               (pc)))]
1230   "TARGET_80387"
1232   ix86_compare_op0 = operands[1];
1233   ix86_compare_op1 = operands[2];
1234   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1235   DONE;
1238 (define_expand "cstorexf4"
1239   [(set (reg:CC FLAGS_REG)
1240         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1241                     (match_operand:XF 3 "nonmemory_operand" "")))
1242    (set (match_operand:QI 0 "register_operand" "")
1243               (match_operator 1 "ix86_fp_comparison_operator"
1244                [(reg:CC FLAGS_REG)
1245                 (const_int 0)]))]
1246   "TARGET_80387"
1248   ix86_compare_op0 = operands[2];
1249   ix86_compare_op1 = operands[3];
1250   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1251   DONE;
1254 (define_expand "cbranch<mode>4"
1255   [(set (reg:CC FLAGS_REG)
1256         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1257                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1258    (set (pc) (if_then_else
1259               (match_operator 0 "ix86_fp_comparison_operator"
1260                [(reg:CC FLAGS_REG)
1261                 (const_int 0)])
1262               (label_ref (match_operand 3 "" ""))
1263               (pc)))]
1264   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1266   ix86_compare_op0 = operands[1];
1267   ix86_compare_op1 = operands[2];
1268   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1269   DONE;
1272 (define_expand "cstore<mode>4"
1273   [(set (reg:CC FLAGS_REG)
1274         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1275                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1276    (set (match_operand:QI 0 "register_operand" "")
1277               (match_operator 1 "ix86_fp_comparison_operator"
1278                [(reg:CC FLAGS_REG)
1279                 (const_int 0)]))]
1280   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1282   ix86_compare_op0 = operands[2];
1283   ix86_compare_op1 = operands[3];
1284   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1285   DONE;
1288 (define_expand "cbranchcc4"
1289   [(set (pc) (if_then_else
1290               (match_operator 0 "comparison_operator"
1291                [(match_operand 1 "flags_reg_operand" "")
1292                 (match_operand 2 "const0_operand" "")])
1293               (label_ref (match_operand 3 "" ""))
1294               (pc)))]
1295   ""
1297   ix86_compare_op0 = operands[1];
1298   ix86_compare_op1 = operands[2];
1299   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1300   DONE;
1303 (define_expand "cstorecc4"
1304   [(set (match_operand:QI 0 "register_operand" "")
1305               (match_operator 1 "comparison_operator"
1306                [(match_operand 2 "flags_reg_operand" "")
1307                 (match_operand 3 "const0_operand" "")]))]
1308   ""
1310   ix86_compare_op0 = operands[2];
1311   ix86_compare_op1 = operands[3];
1312   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1313   DONE;
1317 ;; FP compares, step 1:
1318 ;; Set the FP condition codes.
1320 ;; CCFPmode     compare with exceptions
1321 ;; CCFPUmode    compare with no exceptions
1323 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1324 ;; used to manage the reg stack popping would not be preserved.
1326 (define_insn "*cmpfp_0"
1327   [(set (match_operand:HI 0 "register_operand" "=a")
1328         (unspec:HI
1329           [(compare:CCFP
1330              (match_operand 1 "register_operand" "f")
1331              (match_operand 2 "const0_operand" ""))]
1332         UNSPEC_FNSTSW))]
1333   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1334    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1335   "* return output_fp_compare (insn, operands, 0, 0);"
1336   [(set_attr "type" "multi")
1337    (set_attr "unit" "i387")
1338    (set (attr "mode")
1339      (cond [(match_operand:SF 1 "" "")
1340               (const_string "SF")
1341             (match_operand:DF 1 "" "")
1342               (const_string "DF")
1343            ]
1344            (const_string "XF")))])
1346 (define_insn_and_split "*cmpfp_0_cc"
1347   [(set (reg:CCFP FLAGS_REG)
1348         (compare:CCFP
1349           (match_operand 1 "register_operand" "f")
1350           (match_operand 2 "const0_operand" "")))
1351    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1352   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1353    && TARGET_SAHF && !TARGET_CMOVE
1354    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1355   "#"
1356   "&& reload_completed"
1357   [(set (match_dup 0)
1358         (unspec:HI
1359           [(compare:CCFP (match_dup 1)(match_dup 2))]
1360         UNSPEC_FNSTSW))
1361    (set (reg:CC FLAGS_REG)
1362         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1363   ""
1364   [(set_attr "type" "multi")
1365    (set_attr "unit" "i387")
1366    (set (attr "mode")
1367      (cond [(match_operand:SF 1 "" "")
1368               (const_string "SF")
1369             (match_operand:DF 1 "" "")
1370               (const_string "DF")
1371            ]
1372            (const_string "XF")))])
1374 (define_insn "*cmpfp_xf"
1375   [(set (match_operand:HI 0 "register_operand" "=a")
1376         (unspec:HI
1377           [(compare:CCFP
1378              (match_operand:XF 1 "register_operand" "f")
1379              (match_operand:XF 2 "register_operand" "f"))]
1380           UNSPEC_FNSTSW))]
1381   "TARGET_80387"
1382   "* return output_fp_compare (insn, operands, 0, 0);"
1383   [(set_attr "type" "multi")
1384    (set_attr "unit" "i387")
1385    (set_attr "mode" "XF")])
1387 (define_insn_and_split "*cmpfp_xf_cc"
1388   [(set (reg:CCFP FLAGS_REG)
1389         (compare:CCFP
1390           (match_operand:XF 1 "register_operand" "f")
1391           (match_operand:XF 2 "register_operand" "f")))
1392    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1393   "TARGET_80387
1394    && TARGET_SAHF && !TARGET_CMOVE"
1395   "#"
1396   "&& reload_completed"
1397   [(set (match_dup 0)
1398         (unspec:HI
1399           [(compare:CCFP (match_dup 1)(match_dup 2))]
1400         UNSPEC_FNSTSW))
1401    (set (reg:CC FLAGS_REG)
1402         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1403   ""
1404   [(set_attr "type" "multi")
1405    (set_attr "unit" "i387")
1406    (set_attr "mode" "XF")])
1408 (define_insn "*cmpfp_<mode>"
1409   [(set (match_operand:HI 0 "register_operand" "=a")
1410         (unspec:HI
1411           [(compare:CCFP
1412              (match_operand:MODEF 1 "register_operand" "f")
1413              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1414           UNSPEC_FNSTSW))]
1415   "TARGET_80387"
1416   "* return output_fp_compare (insn, operands, 0, 0);"
1417   [(set_attr "type" "multi")
1418    (set_attr "unit" "i387")
1419    (set_attr "mode" "<MODE>")])
1421 (define_insn_and_split "*cmpfp_<mode>_cc"
1422   [(set (reg:CCFP FLAGS_REG)
1423         (compare:CCFP
1424           (match_operand:MODEF 1 "register_operand" "f")
1425           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1426    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1427   "TARGET_80387
1428    && TARGET_SAHF && !TARGET_CMOVE"
1429   "#"
1430   "&& reload_completed"
1431   [(set (match_dup 0)
1432         (unspec:HI
1433           [(compare:CCFP (match_dup 1)(match_dup 2))]
1434         UNSPEC_FNSTSW))
1435    (set (reg:CC FLAGS_REG)
1436         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1437   ""
1438   [(set_attr "type" "multi")
1439    (set_attr "unit" "i387")
1440    (set_attr "mode" "<MODE>")])
1442 (define_insn "*cmpfp_u"
1443   [(set (match_operand:HI 0 "register_operand" "=a")
1444         (unspec:HI
1445           [(compare:CCFPU
1446              (match_operand 1 "register_operand" "f")
1447              (match_operand 2 "register_operand" "f"))]
1448           UNSPEC_FNSTSW))]
1449   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1450    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1451   "* return output_fp_compare (insn, operands, 0, 1);"
1452   [(set_attr "type" "multi")
1453    (set_attr "unit" "i387")
1454    (set (attr "mode")
1455      (cond [(match_operand:SF 1 "" "")
1456               (const_string "SF")
1457             (match_operand:DF 1 "" "")
1458               (const_string "DF")
1459            ]
1460            (const_string "XF")))])
1462 (define_insn_and_split "*cmpfp_u_cc"
1463   [(set (reg:CCFPU FLAGS_REG)
1464         (compare:CCFPU
1465           (match_operand 1 "register_operand" "f")
1466           (match_operand 2 "register_operand" "f")))
1467    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1468   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1469    && TARGET_SAHF && !TARGET_CMOVE
1470    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1471   "#"
1472   "&& reload_completed"
1473   [(set (match_dup 0)
1474         (unspec:HI
1475           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1476         UNSPEC_FNSTSW))
1477    (set (reg:CC FLAGS_REG)
1478         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1479   ""
1480   [(set_attr "type" "multi")
1481    (set_attr "unit" "i387")
1482    (set (attr "mode")
1483      (cond [(match_operand:SF 1 "" "")
1484               (const_string "SF")
1485             (match_operand:DF 1 "" "")
1486               (const_string "DF")
1487            ]
1488            (const_string "XF")))])
1490 (define_insn "*cmpfp_<mode>"
1491   [(set (match_operand:HI 0 "register_operand" "=a")
1492         (unspec:HI
1493           [(compare:CCFP
1494              (match_operand 1 "register_operand" "f")
1495              (match_operator 3 "float_operator"
1496                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1497           UNSPEC_FNSTSW))]
1498   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1499    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1500    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1501   "* return output_fp_compare (insn, operands, 0, 0);"
1502   [(set_attr "type" "multi")
1503    (set_attr "unit" "i387")
1504    (set_attr "fp_int_src" "true")
1505    (set_attr "mode" "<MODE>")])
1507 (define_insn_and_split "*cmpfp_<mode>_cc"
1508   [(set (reg:CCFP FLAGS_REG)
1509         (compare:CCFP
1510           (match_operand 1 "register_operand" "f")
1511           (match_operator 3 "float_operator"
1512             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1513    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1514   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1515    && TARGET_SAHF && !TARGET_CMOVE
1516    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1517    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1518   "#"
1519   "&& reload_completed"
1520   [(set (match_dup 0)
1521         (unspec:HI
1522           [(compare:CCFP
1523              (match_dup 1)
1524              (match_op_dup 3 [(match_dup 2)]))]
1525         UNSPEC_FNSTSW))
1526    (set (reg:CC FLAGS_REG)
1527         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1528   ""
1529   [(set_attr "type" "multi")
1530    (set_attr "unit" "i387")
1531    (set_attr "fp_int_src" "true")
1532    (set_attr "mode" "<MODE>")])
1534 ;; FP compares, step 2
1535 ;; Move the fpsw to ax.
1537 (define_insn "x86_fnstsw_1"
1538   [(set (match_operand:HI 0 "register_operand" "=a")
1539         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1540   "TARGET_80387"
1541   "fnstsw\t%0"
1542   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1543    (set_attr "mode" "SI")
1544    (set_attr "unit" "i387")])
1546 ;; FP compares, step 3
1547 ;; Get ax into flags, general case.
1549 (define_insn "x86_sahf_1"
1550   [(set (reg:CC FLAGS_REG)
1551         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1552                    UNSPEC_SAHF))]
1553   "TARGET_SAHF"
1555 #ifdef HAVE_AS_IX86_SAHF
1556   return "sahf";
1557 #else
1558   return ASM_BYTE "0x9e";
1559 #endif
1561   [(set_attr "length" "1")
1562    (set_attr "athlon_decode" "vector")
1563    (set_attr "amdfam10_decode" "direct")
1564    (set_attr "mode" "SI")])
1566 ;; Pentium Pro can do steps 1 through 3 in one go.
1567 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1568 (define_insn "*cmpfp_i_mixed"
1569   [(set (reg:CCFP FLAGS_REG)
1570         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1571                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1572   "TARGET_MIX_SSE_I387
1573    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1574    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1575   "* return output_fp_compare (insn, operands, 1, 0);"
1576   [(set_attr "type" "fcmp,ssecomi")
1577    (set_attr "prefix" "orig,maybe_vex")
1578    (set (attr "mode")
1579      (if_then_else (match_operand:SF 1 "" "")
1580         (const_string "SF")
1581         (const_string "DF")))
1582    (set (attr "prefix_rep")
1583         (if_then_else (eq_attr "type" "ssecomi")
1584                       (const_string "0")
1585                       (const_string "*")))
1586    (set (attr "prefix_data16")
1587         (cond [(eq_attr "type" "fcmp")
1588                  (const_string "*")
1589                (eq_attr "mode" "DF")
1590                  (const_string "1")
1591               ]
1592               (const_string "0")))
1593    (set_attr "athlon_decode" "vector")
1594    (set_attr "amdfam10_decode" "direct")])
1596 (define_insn "*cmpfp_i_sse"
1597   [(set (reg:CCFP FLAGS_REG)
1598         (compare:CCFP (match_operand 0 "register_operand" "x")
1599                       (match_operand 1 "nonimmediate_operand" "xm")))]
1600   "TARGET_SSE_MATH
1601    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1602    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1603   "* return output_fp_compare (insn, operands, 1, 0);"
1604   [(set_attr "type" "ssecomi")
1605    (set_attr "prefix" "maybe_vex")
1606    (set (attr "mode")
1607      (if_then_else (match_operand:SF 1 "" "")
1608         (const_string "SF")
1609         (const_string "DF")))
1610    (set_attr "prefix_rep" "0")
1611    (set (attr "prefix_data16")
1612         (if_then_else (eq_attr "mode" "DF")
1613                       (const_string "1")
1614                       (const_string "0")))
1615    (set_attr "athlon_decode" "vector")
1616    (set_attr "amdfam10_decode" "direct")])
1618 (define_insn "*cmpfp_i_i387"
1619   [(set (reg:CCFP FLAGS_REG)
1620         (compare:CCFP (match_operand 0 "register_operand" "f")
1621                       (match_operand 1 "register_operand" "f")))]
1622   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1623    && TARGET_CMOVE
1624    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1625    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1626   "* return output_fp_compare (insn, operands, 1, 0);"
1627   [(set_attr "type" "fcmp")
1628    (set (attr "mode")
1629      (cond [(match_operand:SF 1 "" "")
1630               (const_string "SF")
1631             (match_operand:DF 1 "" "")
1632               (const_string "DF")
1633            ]
1634            (const_string "XF")))
1635    (set_attr "athlon_decode" "vector")
1636    (set_attr "amdfam10_decode" "direct")])
1638 (define_insn "*cmpfp_iu_mixed"
1639   [(set (reg:CCFPU FLAGS_REG)
1640         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1641                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1642   "TARGET_MIX_SSE_I387
1643    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1644    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1645   "* return output_fp_compare (insn, operands, 1, 1);"
1646   [(set_attr "type" "fcmp,ssecomi")
1647    (set_attr "prefix" "orig,maybe_vex")
1648    (set (attr "mode")
1649      (if_then_else (match_operand:SF 1 "" "")
1650         (const_string "SF")
1651         (const_string "DF")))
1652    (set (attr "prefix_rep")
1653         (if_then_else (eq_attr "type" "ssecomi")
1654                       (const_string "0")
1655                       (const_string "*")))
1656    (set (attr "prefix_data16")
1657         (cond [(eq_attr "type" "fcmp")
1658                  (const_string "*")
1659                (eq_attr "mode" "DF")
1660                  (const_string "1")
1661               ]
1662               (const_string "0")))
1663    (set_attr "athlon_decode" "vector")
1664    (set_attr "amdfam10_decode" "direct")])
1666 (define_insn "*cmpfp_iu_sse"
1667   [(set (reg:CCFPU FLAGS_REG)
1668         (compare:CCFPU (match_operand 0 "register_operand" "x")
1669                        (match_operand 1 "nonimmediate_operand" "xm")))]
1670   "TARGET_SSE_MATH
1671    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1672    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1673   "* return output_fp_compare (insn, operands, 1, 1);"
1674   [(set_attr "type" "ssecomi")
1675    (set_attr "prefix" "maybe_vex")
1676    (set (attr "mode")
1677      (if_then_else (match_operand:SF 1 "" "")
1678         (const_string "SF")
1679         (const_string "DF")))
1680    (set_attr "prefix_rep" "0")
1681    (set (attr "prefix_data16")
1682         (if_then_else (eq_attr "mode" "DF")
1683                       (const_string "1")
1684                       (const_string "0")))
1685    (set_attr "athlon_decode" "vector")
1686    (set_attr "amdfam10_decode" "direct")])
1688 (define_insn "*cmpfp_iu_387"
1689   [(set (reg:CCFPU FLAGS_REG)
1690         (compare:CCFPU (match_operand 0 "register_operand" "f")
1691                        (match_operand 1 "register_operand" "f")))]
1692   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1693    && TARGET_CMOVE
1694    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1695    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1696   "* return output_fp_compare (insn, operands, 1, 1);"
1697   [(set_attr "type" "fcmp")
1698    (set (attr "mode")
1699      (cond [(match_operand:SF 1 "" "")
1700               (const_string "SF")
1701             (match_operand:DF 1 "" "")
1702               (const_string "DF")
1703            ]
1704            (const_string "XF")))
1705    (set_attr "athlon_decode" "vector")
1706    (set_attr "amdfam10_decode" "direct")])
1708 ;; Move instructions.
1710 ;; General case of fullword move.
1712 (define_expand "movsi"
1713   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1714         (match_operand:SI 1 "general_operand" ""))]
1715   ""
1716   "ix86_expand_move (SImode, operands); DONE;")
1718 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1719 ;; general_operand.
1721 ;; %%% We don't use a post-inc memory reference because x86 is not a
1722 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1723 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1724 ;; targets without our curiosities, and it is just as easy to represent
1725 ;; this differently.
1727 (define_insn "*pushsi2"
1728   [(set (match_operand:SI 0 "push_operand" "=<")
1729         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1730   "!TARGET_64BIT"
1731   "push{l}\t%1"
1732   [(set_attr "type" "push")
1733    (set_attr "mode" "SI")])
1735 ;; For 64BIT abi we always round up to 8 bytes.
1736 (define_insn "*pushsi2_rex64"
1737   [(set (match_operand:SI 0 "push_operand" "=X")
1738         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1739   "TARGET_64BIT"
1740   "push{q}\t%q1"
1741   [(set_attr "type" "push")
1742    (set_attr "mode" "SI")])
1744 (define_insn "*pushsi2_prologue"
1745   [(set (match_operand:SI 0 "push_operand" "=<")
1746         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1747    (clobber (mem:BLK (scratch)))]
1748   "!TARGET_64BIT"
1749   "push{l}\t%1"
1750   [(set_attr "type" "push")
1751    (set_attr "mode" "SI")])
1753 (define_insn "*popsi1_epilogue"
1754   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1755         (mem:SI (reg:SI SP_REG)))
1756    (set (reg:SI SP_REG)
1757         (plus:SI (reg:SI SP_REG) (const_int 4)))
1758    (clobber (mem:BLK (scratch)))]
1759   "!TARGET_64BIT"
1760   "pop{l}\t%0"
1761   [(set_attr "type" "pop")
1762    (set_attr "mode" "SI")])
1764 (define_insn "popsi1"
1765   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1766         (mem:SI (reg:SI SP_REG)))
1767    (set (reg:SI SP_REG)
1768         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1769   "!TARGET_64BIT"
1770   "pop{l}\t%0"
1771   [(set_attr "type" "pop")
1772    (set_attr "mode" "SI")])
1774 (define_insn "*movsi_xor"
1775   [(set (match_operand:SI 0 "register_operand" "=r")
1776         (match_operand:SI 1 "const0_operand" ""))
1777    (clobber (reg:CC FLAGS_REG))]
1778   "reload_completed"
1779   "xor{l}\t%0, %0"
1780   [(set_attr "type" "alu1")
1781    (set_attr "mode" "SI")
1782    (set_attr "length_immediate" "0")])
1784 (define_insn "*movsi_or"
1785   [(set (match_operand:SI 0 "register_operand" "=r")
1786         (match_operand:SI 1 "immediate_operand" "i"))
1787    (clobber (reg:CC FLAGS_REG))]
1788   "reload_completed
1789    && operands[1] == constm1_rtx"
1791   operands[1] = constm1_rtx;
1792   return "or{l}\t{%1, %0|%0, %1}";
1794   [(set_attr "type" "alu1")
1795    (set_attr "mode" "SI")
1796    (set_attr "length_immediate" "1")])
1798 (define_insn "*movsi_1"
1799   [(set (match_operand:SI 0 "nonimmediate_operand"
1800                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1801         (match_operand:SI 1 "general_operand"
1802                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1803   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1805   switch (get_attr_type (insn))
1806     {
1807     case TYPE_SSELOG1:
1808       if (get_attr_mode (insn) == MODE_TI)
1809         return "%vpxor\t%0, %d0";
1810       return "%vxorps\t%0, %d0";
1812     case TYPE_SSEMOV:
1813       switch (get_attr_mode (insn))
1814         {
1815         case MODE_TI:
1816           return "%vmovdqa\t{%1, %0|%0, %1}";
1817         case MODE_V4SF:
1818           return "%vmovaps\t{%1, %0|%0, %1}";
1819         case MODE_SI:
1820           return "%vmovd\t{%1, %0|%0, %1}";
1821         case MODE_SF:
1822           return "%vmovss\t{%1, %0|%0, %1}";
1823         default:
1824           gcc_unreachable ();
1825         }
1827     case TYPE_MMX:
1828       return "pxor\t%0, %0";
1830     case TYPE_MMXMOV:
1831       if (get_attr_mode (insn) == MODE_DI)
1832         return "movq\t{%1, %0|%0, %1}";
1833       return "movd\t{%1, %0|%0, %1}";
1835     case TYPE_LEA:
1836       return "lea{l}\t{%1, %0|%0, %1}";
1838     default:
1839       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1840       return "mov{l}\t{%1, %0|%0, %1}";
1841     }
1843   [(set (attr "type")
1844      (cond [(eq_attr "alternative" "2")
1845               (const_string "mmx")
1846             (eq_attr "alternative" "3,4,5")
1847               (const_string "mmxmov")
1848             (eq_attr "alternative" "6")
1849               (const_string "sselog1")
1850             (eq_attr "alternative" "7,8,9,10,11")
1851               (const_string "ssemov")
1852             (match_operand:DI 1 "pic_32bit_operand" "")
1853               (const_string "lea")
1854            ]
1855            (const_string "imov")))
1856    (set (attr "prefix")
1857      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1858        (const_string "orig")
1859        (const_string "maybe_vex")))
1860    (set (attr "prefix_data16")
1861      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1862        (const_string "1")
1863        (const_string "*")))
1864    (set (attr "mode")
1865      (cond [(eq_attr "alternative" "2,3")
1866               (const_string "DI")
1867             (eq_attr "alternative" "6,7")
1868               (if_then_else
1869                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1870                 (const_string "V4SF")
1871                 (const_string "TI"))
1872             (and (eq_attr "alternative" "8,9,10,11")
1873                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1874               (const_string "SF")
1875            ]
1876            (const_string "SI")))])
1878 ;; Stores and loads of ax to arbitrary constant address.
1879 ;; We fake an second form of instruction to force reload to load address
1880 ;; into register when rax is not available
1881 (define_insn "*movabssi_1_rex64"
1882   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1883         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1884   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1885   "@
1886    movabs{l}\t{%1, %P0|%P0, %1}
1887    mov{l}\t{%1, %a0|%a0, %1}"
1888   [(set_attr "type" "imov")
1889    (set_attr "modrm" "0,*")
1890    (set_attr "length_address" "8,0")
1891    (set_attr "length_immediate" "0,*")
1892    (set_attr "memory" "store")
1893    (set_attr "mode" "SI")])
1895 (define_insn "*movabssi_2_rex64"
1896   [(set (match_operand:SI 0 "register_operand" "=a,r")
1897         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1898   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1899   "@
1900    movabs{l}\t{%P1, %0|%0, %P1}
1901    mov{l}\t{%a1, %0|%0, %a1}"
1902   [(set_attr "type" "imov")
1903    (set_attr "modrm" "0,*")
1904    (set_attr "length_address" "8,0")
1905    (set_attr "length_immediate" "0")
1906    (set_attr "memory" "load")
1907    (set_attr "mode" "SI")])
1909 (define_insn "*swapsi"
1910   [(set (match_operand:SI 0 "register_operand" "+r")
1911         (match_operand:SI 1 "register_operand" "+r"))
1912    (set (match_dup 1)
1913         (match_dup 0))]
1914   ""
1915   "xchg{l}\t%1, %0"
1916   [(set_attr "type" "imov")
1917    (set_attr "mode" "SI")
1918    (set_attr "pent_pair" "np")
1919    (set_attr "athlon_decode" "vector")
1920    (set_attr "amdfam10_decode" "double")])
1922 (define_expand "movhi"
1923   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1924         (match_operand:HI 1 "general_operand" ""))]
1925   ""
1926   "ix86_expand_move (HImode, operands); DONE;")
1928 (define_insn "*pushhi2"
1929   [(set (match_operand:HI 0 "push_operand" "=X")
1930         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1931   "!TARGET_64BIT"
1932   "push{l}\t%k1"
1933   [(set_attr "type" "push")
1934    (set_attr "mode" "SI")])
1936 ;; For 64BIT abi we always round up to 8 bytes.
1937 (define_insn "*pushhi2_rex64"
1938   [(set (match_operand:HI 0 "push_operand" "=X")
1939         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1940   "TARGET_64BIT"
1941   "push{q}\t%q1"
1942   [(set_attr "type" "push")
1943    (set_attr "mode" "DI")])
1945 (define_insn "*movhi_1"
1946   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1947         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1948   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1950   switch (get_attr_type (insn))
1951     {
1952     case TYPE_IMOVX:
1953       /* movzwl is faster than movw on p2 due to partial word stalls,
1954          though not as fast as an aligned movl.  */
1955       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1956     default:
1957       if (get_attr_mode (insn) == MODE_SI)
1958         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1959       else
1960         return "mov{w}\t{%1, %0|%0, %1}";
1961     }
1963   [(set (attr "type")
1964      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1965               (const_string "imov")
1966             (and (eq_attr "alternative" "0")
1967                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1968                           (const_int 0))
1969                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1970                           (const_int 0))))
1971               (const_string "imov")
1972             (and (eq_attr "alternative" "1,2")
1973                  (match_operand:HI 1 "aligned_operand" ""))
1974               (const_string "imov")
1975             (and (ne (symbol_ref "TARGET_MOVX")
1976                      (const_int 0))
1977                  (eq_attr "alternative" "0,2"))
1978               (const_string "imovx")
1979            ]
1980            (const_string "imov")))
1981     (set (attr "mode")
1982       (cond [(eq_attr "type" "imovx")
1983                (const_string "SI")
1984              (and (eq_attr "alternative" "1,2")
1985                   (match_operand:HI 1 "aligned_operand" ""))
1986                (const_string "SI")
1987              (and (eq_attr "alternative" "0")
1988                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1989                            (const_int 0))
1990                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1991                            (const_int 0))))
1992                (const_string "SI")
1993             ]
1994             (const_string "HI")))])
1996 ;; Stores and loads of ax to arbitrary constant address.
1997 ;; We fake an second form of instruction to force reload to load address
1998 ;; into register when rax is not available
1999 (define_insn "*movabshi_1_rex64"
2000   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2001         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
2002   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2003   "@
2004    movabs{w}\t{%1, %P0|%P0, %1}
2005    mov{w}\t{%1, %a0|%a0, %1}"
2006   [(set_attr "type" "imov")
2007    (set_attr "modrm" "0,*")
2008    (set_attr "length_address" "8,0")
2009    (set_attr "length_immediate" "0,*")
2010    (set_attr "memory" "store")
2011    (set_attr "mode" "HI")])
2013 (define_insn "*movabshi_2_rex64"
2014   [(set (match_operand:HI 0 "register_operand" "=a,r")
2015         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2016   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2017   "@
2018    movabs{w}\t{%P1, %0|%0, %P1}
2019    mov{w}\t{%a1, %0|%0, %a1}"
2020   [(set_attr "type" "imov")
2021    (set_attr "modrm" "0,*")
2022    (set_attr "length_address" "8,0")
2023    (set_attr "length_immediate" "0")
2024    (set_attr "memory" "load")
2025    (set_attr "mode" "HI")])
2027 (define_insn "*swaphi_1"
2028   [(set (match_operand:HI 0 "register_operand" "+r")
2029         (match_operand:HI 1 "register_operand" "+r"))
2030    (set (match_dup 1)
2031         (match_dup 0))]
2032   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2033   "xchg{l}\t%k1, %k0"
2034   [(set_attr "type" "imov")
2035    (set_attr "mode" "SI")
2036    (set_attr "pent_pair" "np")
2037    (set_attr "athlon_decode" "vector")
2038    (set_attr "amdfam10_decode" "double")])
2040 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2041 (define_insn "*swaphi_2"
2042   [(set (match_operand:HI 0 "register_operand" "+r")
2043         (match_operand:HI 1 "register_operand" "+r"))
2044    (set (match_dup 1)
2045         (match_dup 0))]
2046   "TARGET_PARTIAL_REG_STALL"
2047   "xchg{w}\t%1, %0"
2048   [(set_attr "type" "imov")
2049    (set_attr "mode" "HI")
2050    (set_attr "pent_pair" "np")
2051    (set_attr "athlon_decode" "vector")])
2053 (define_expand "movstricthi"
2054   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
2055         (match_operand:HI 1 "general_operand" ""))]
2056   ""
2058   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2059     FAIL;
2060   /* Don't generate memory->memory moves, go through a register */
2061   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2062     operands[1] = force_reg (HImode, operands[1]);
2065 (define_insn "*movstricthi_1"
2066   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
2067         (match_operand:HI 1 "general_operand" "rn,m"))]
2068   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2069    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2070   "mov{w}\t{%1, %0|%0, %1}"
2071   [(set_attr "type" "imov")
2072    (set_attr "mode" "HI")])
2074 (define_insn "*movstricthi_xor"
2075   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
2076         (match_operand:HI 1 "const0_operand" ""))
2077    (clobber (reg:CC FLAGS_REG))]
2078   "reload_completed"
2079   "xor{w}\t%0, %0"
2080   [(set_attr "type" "alu1")
2081    (set_attr "mode" "HI")
2082    (set_attr "length_immediate" "0")])
2084 (define_expand "movqi"
2085   [(set (match_operand:QI 0 "nonimmediate_operand" "")
2086         (match_operand:QI 1 "general_operand" ""))]
2087   ""
2088   "ix86_expand_move (QImode, operands); DONE;")
2090 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2091 ;; "push a byte".  But actually we use pushl, which has the effect
2092 ;; of rounding the amount pushed up to a word.
2094 (define_insn "*pushqi2"
2095   [(set (match_operand:QI 0 "push_operand" "=X")
2096         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
2097   "!TARGET_64BIT"
2098   "push{l}\t%k1"
2099   [(set_attr "type" "push")
2100    (set_attr "mode" "SI")])
2102 ;; For 64BIT abi we always round up to 8 bytes.
2103 (define_insn "*pushqi2_rex64"
2104   [(set (match_operand:QI 0 "push_operand" "=X")
2105         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
2106   "TARGET_64BIT"
2107   "push{q}\t%q1"
2108   [(set_attr "type" "push")
2109    (set_attr "mode" "DI")])
2111 ;; Situation is quite tricky about when to choose full sized (SImode) move
2112 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2113 ;; partial register dependency machines (such as AMD Athlon), where QImode
2114 ;; moves issue extra dependency and for partial register stalls machines
2115 ;; that don't use QImode patterns (and QImode move cause stall on the next
2116 ;; instruction).
2118 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2119 ;; register stall machines with, where we use QImode instructions, since
2120 ;; partial register stall can be caused there.  Then we use movzx.
2121 (define_insn "*movqi_1"
2122   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2123         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
2124   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2126   switch (get_attr_type (insn))
2127     {
2128     case TYPE_IMOVX:
2129       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2130       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2131     default:
2132       if (get_attr_mode (insn) == MODE_SI)
2133         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2134       else
2135         return "mov{b}\t{%1, %0|%0, %1}";
2136     }
2138   [(set (attr "type")
2139      (cond [(and (eq_attr "alternative" "5")
2140                  (not (match_operand:QI 1 "aligned_operand" "")))
2141               (const_string "imovx")
2142             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2143               (const_string "imov")
2144             (and (eq_attr "alternative" "3")
2145                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2146                           (const_int 0))
2147                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2148                           (const_int 0))))
2149               (const_string "imov")
2150             (eq_attr "alternative" "3,5")
2151               (const_string "imovx")
2152             (and (ne (symbol_ref "TARGET_MOVX")
2153                      (const_int 0))
2154                  (eq_attr "alternative" "2"))
2155               (const_string "imovx")
2156            ]
2157            (const_string "imov")))
2158    (set (attr "mode")
2159       (cond [(eq_attr "alternative" "3,4,5")
2160                (const_string "SI")
2161              (eq_attr "alternative" "6")
2162                (const_string "QI")
2163              (eq_attr "type" "imovx")
2164                (const_string "SI")
2165              (and (eq_attr "type" "imov")
2166                   (and (eq_attr "alternative" "0,1")
2167                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2168                                 (const_int 0))
2169                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2170                                      (const_int 0))
2171                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2172                                      (const_int 0))))))
2173                (const_string "SI")
2174              ;; Avoid partial register stalls when not using QImode arithmetic
2175              (and (eq_attr "type" "imov")
2176                   (and (eq_attr "alternative" "0,1")
2177                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2178                                 (const_int 0))
2179                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2180                                 (const_int 0)))))
2181                (const_string "SI")
2182            ]
2183            (const_string "QI")))])
2185 (define_insn "*swapqi_1"
2186   [(set (match_operand:QI 0 "register_operand" "+r")
2187         (match_operand:QI 1 "register_operand" "+r"))
2188    (set (match_dup 1)
2189         (match_dup 0))]
2190   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2191   "xchg{l}\t%k1, %k0"
2192   [(set_attr "type" "imov")
2193    (set_attr "mode" "SI")
2194    (set_attr "pent_pair" "np")
2195    (set_attr "athlon_decode" "vector")
2196    (set_attr "amdfam10_decode" "vector")])
2198 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2199 (define_insn "*swapqi_2"
2200   [(set (match_operand:QI 0 "register_operand" "+q")
2201         (match_operand:QI 1 "register_operand" "+q"))
2202    (set (match_dup 1)
2203         (match_dup 0))]
2204   "TARGET_PARTIAL_REG_STALL"
2205   "xchg{b}\t%1, %0"
2206   [(set_attr "type" "imov")
2207    (set_attr "mode" "QI")
2208    (set_attr "pent_pair" "np")
2209    (set_attr "athlon_decode" "vector")])
2211 (define_expand "movstrictqi"
2212   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2213         (match_operand:QI 1 "general_operand" ""))]
2214   ""
2216   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2217     FAIL;
2218   /* Don't generate memory->memory moves, go through a register.  */
2219   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2220     operands[1] = force_reg (QImode, operands[1]);
2223 (define_insn "*movstrictqi_1"
2224   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2225         (match_operand:QI 1 "general_operand" "*qn,m"))]
2226   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2227    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2228   "mov{b}\t{%1, %0|%0, %1}"
2229   [(set_attr "type" "imov")
2230    (set_attr "mode" "QI")])
2232 (define_insn "*movstrictqi_xor"
2233   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2234         (match_operand:QI 1 "const0_operand" ""))
2235    (clobber (reg:CC FLAGS_REG))]
2236   "reload_completed"
2237   "xor{b}\t%0, %0"
2238   [(set_attr "type" "alu1")
2239    (set_attr "mode" "QI")
2240    (set_attr "length_immediate" "0")])
2242 (define_insn "*movsi_extv_1"
2243   [(set (match_operand:SI 0 "register_operand" "=R")
2244         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2245                          (const_int 8)
2246                          (const_int 8)))]
2247   ""
2248   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2249   [(set_attr "type" "imovx")
2250    (set_attr "mode" "SI")])
2252 (define_insn "*movhi_extv_1"
2253   [(set (match_operand:HI 0 "register_operand" "=R")
2254         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2255                          (const_int 8)
2256                          (const_int 8)))]
2257   ""
2258   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2259   [(set_attr "type" "imovx")
2260    (set_attr "mode" "SI")])
2262 (define_insn "*movqi_extv_1"
2263   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2264         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2265                          (const_int 8)
2266                          (const_int 8)))]
2267   "!TARGET_64BIT"
2269   switch (get_attr_type (insn))
2270     {
2271     case TYPE_IMOVX:
2272       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2273     default:
2274       return "mov{b}\t{%h1, %0|%0, %h1}";
2275     }
2277   [(set (attr "type")
2278      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2279                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2280                              (ne (symbol_ref "TARGET_MOVX")
2281                                  (const_int 0))))
2282         (const_string "imovx")
2283         (const_string "imov")))
2284    (set (attr "mode")
2285      (if_then_else (eq_attr "type" "imovx")
2286         (const_string "SI")
2287         (const_string "QI")))])
2289 (define_insn "*movqi_extv_1_rex64"
2290   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2291         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2292                          (const_int 8)
2293                          (const_int 8)))]
2294   "TARGET_64BIT"
2296   switch (get_attr_type (insn))
2297     {
2298     case TYPE_IMOVX:
2299       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2300     default:
2301       return "mov{b}\t{%h1, %0|%0, %h1}";
2302     }
2304   [(set (attr "type")
2305      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2306                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2307                              (ne (symbol_ref "TARGET_MOVX")
2308                                  (const_int 0))))
2309         (const_string "imovx")
2310         (const_string "imov")))
2311    (set (attr "mode")
2312      (if_then_else (eq_attr "type" "imovx")
2313         (const_string "SI")
2314         (const_string "QI")))])
2316 ;; Stores and loads of ax to arbitrary constant address.
2317 ;; We fake an second form of instruction to force reload to load address
2318 ;; into register when rax is not available
2319 (define_insn "*movabsqi_1_rex64"
2320   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2321         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2322   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2323   "@
2324    movabs{b}\t{%1, %P0|%P0, %1}
2325    mov{b}\t{%1, %a0|%a0, %1}"
2326   [(set_attr "type" "imov")
2327    (set_attr "modrm" "0,*")
2328    (set_attr "length_address" "8,0")
2329    (set_attr "length_immediate" "0,*")
2330    (set_attr "memory" "store")
2331    (set_attr "mode" "QI")])
2333 (define_insn "*movabsqi_2_rex64"
2334   [(set (match_operand:QI 0 "register_operand" "=a,r")
2335         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2336   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2337   "@
2338    movabs{b}\t{%P1, %0|%0, %P1}
2339    mov{b}\t{%a1, %0|%0, %a1}"
2340   [(set_attr "type" "imov")
2341    (set_attr "modrm" "0,*")
2342    (set_attr "length_address" "8,0")
2343    (set_attr "length_immediate" "0")
2344    (set_attr "memory" "load")
2345    (set_attr "mode" "QI")])
2347 (define_insn "*movdi_extzv_1"
2348   [(set (match_operand:DI 0 "register_operand" "=R")
2349         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2350                          (const_int 8)
2351                          (const_int 8)))]
2352   "TARGET_64BIT"
2353   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2354   [(set_attr "type" "imovx")
2355    (set_attr "mode" "SI")])
2357 (define_insn "*movsi_extzv_1"
2358   [(set (match_operand:SI 0 "register_operand" "=R")
2359         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2360                          (const_int 8)
2361                          (const_int 8)))]
2362   ""
2363   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2364   [(set_attr "type" "imovx")
2365    (set_attr "mode" "SI")])
2367 (define_insn "*movqi_extzv_2"
2368   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2369         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2370                                     (const_int 8)
2371                                     (const_int 8)) 0))]
2372   "!TARGET_64BIT"
2374   switch (get_attr_type (insn))
2375     {
2376     case TYPE_IMOVX:
2377       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2378     default:
2379       return "mov{b}\t{%h1, %0|%0, %h1}";
2380     }
2382   [(set (attr "type")
2383      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2384                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2385                              (ne (symbol_ref "TARGET_MOVX")
2386                                  (const_int 0))))
2387         (const_string "imovx")
2388         (const_string "imov")))
2389    (set (attr "mode")
2390      (if_then_else (eq_attr "type" "imovx")
2391         (const_string "SI")
2392         (const_string "QI")))])
2394 (define_insn "*movqi_extzv_2_rex64"
2395   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2396         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2397                                     (const_int 8)
2398                                     (const_int 8)) 0))]
2399   "TARGET_64BIT"
2401   switch (get_attr_type (insn))
2402     {
2403     case TYPE_IMOVX:
2404       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2405     default:
2406       return "mov{b}\t{%h1, %0|%0, %h1}";
2407     }
2409   [(set (attr "type")
2410      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2411                         (ne (symbol_ref "TARGET_MOVX")
2412                             (const_int 0)))
2413         (const_string "imovx")
2414         (const_string "imov")))
2415    (set (attr "mode")
2416      (if_then_else (eq_attr "type" "imovx")
2417         (const_string "SI")
2418         (const_string "QI")))])
2420 (define_insn "movsi_insv_1"
2421   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2422                          (const_int 8)
2423                          (const_int 8))
2424         (match_operand:SI 1 "general_operand" "Qmn"))]
2425   "!TARGET_64BIT"
2426   "mov{b}\t{%b1, %h0|%h0, %b1}"
2427   [(set_attr "type" "imov")
2428    (set_attr "mode" "QI")])
2430 (define_insn "*movsi_insv_1_rex64"
2431   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2432                          (const_int 8)
2433                          (const_int 8))
2434         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2435   "TARGET_64BIT"
2436   "mov{b}\t{%b1, %h0|%h0, %b1}"
2437   [(set_attr "type" "imov")
2438    (set_attr "mode" "QI")])
2440 (define_insn "movdi_insv_1_rex64"
2441   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2442                          (const_int 8)
2443                          (const_int 8))
2444         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2445   "TARGET_64BIT"
2446   "mov{b}\t{%b1, %h0|%h0, %b1}"
2447   [(set_attr "type" "imov")
2448    (set_attr "mode" "QI")])
2450 (define_insn "*movqi_insv_2"
2451   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2452                          (const_int 8)
2453                          (const_int 8))
2454         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2455                      (const_int 8)))]
2456   ""
2457   "mov{b}\t{%h1, %h0|%h0, %h1}"
2458   [(set_attr "type" "imov")
2459    (set_attr "mode" "QI")])
2461 (define_expand "movdi"
2462   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2463         (match_operand:DI 1 "general_operand" ""))]
2464   ""
2465   "ix86_expand_move (DImode, operands); DONE;")
2467 (define_insn "*pushdi"
2468   [(set (match_operand:DI 0 "push_operand" "=<")
2469         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2470   "!TARGET_64BIT"
2471   "#")
2473 (define_insn "*pushdi2_rex64"
2474   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2475         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2476   "TARGET_64BIT"
2477   "@
2478    push{q}\t%1
2479    #"
2480   [(set_attr "type" "push,multi")
2481    (set_attr "mode" "DI")])
2483 ;; Convert impossible pushes of immediate to existing instructions.
2484 ;; First try to get scratch register and go through it.  In case this
2485 ;; fails, push sign extended lower part first and then overwrite
2486 ;; upper part by 32bit move.
2487 (define_peephole2
2488   [(match_scratch:DI 2 "r")
2489    (set (match_operand:DI 0 "push_operand" "")
2490         (match_operand:DI 1 "immediate_operand" ""))]
2491   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2492    && !x86_64_immediate_operand (operands[1], DImode)"
2493   [(set (match_dup 2) (match_dup 1))
2494    (set (match_dup 0) (match_dup 2))]
2495   "")
2497 ;; We need to define this as both peepholer and splitter for case
2498 ;; peephole2 pass is not run.
2499 ;; "&& 1" is needed to keep it from matching the previous pattern.
2500 (define_peephole2
2501   [(set (match_operand:DI 0 "push_operand" "")
2502         (match_operand:DI 1 "immediate_operand" ""))]
2503   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2504    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2505   [(set (match_dup 0) (match_dup 1))
2506    (set (match_dup 2) (match_dup 3))]
2507   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2508    operands[1] = gen_lowpart (DImode, operands[2]);
2509    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2510                                                     GEN_INT (4)));
2511   ")
2513 (define_split
2514   [(set (match_operand:DI 0 "push_operand" "")
2515         (match_operand:DI 1 "immediate_operand" ""))]
2516   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2517                     ? epilogue_completed : reload_completed)
2518    && !symbolic_operand (operands[1], DImode)
2519    && !x86_64_immediate_operand (operands[1], DImode)"
2520   [(set (match_dup 0) (match_dup 1))
2521    (set (match_dup 2) (match_dup 3))]
2522   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2523    operands[1] = gen_lowpart (DImode, operands[2]);
2524    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2525                                                     GEN_INT (4)));
2526   ")
2528 (define_insn "*pushdi2_prologue_rex64"
2529   [(set (match_operand:DI 0 "push_operand" "=<")
2530         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2531    (clobber (mem:BLK (scratch)))]
2532   "TARGET_64BIT"
2533   "push{q}\t%1"
2534   [(set_attr "type" "push")
2535    (set_attr "mode" "DI")])
2537 (define_insn "*popdi1_epilogue_rex64"
2538   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2539         (mem:DI (reg:DI SP_REG)))
2540    (set (reg:DI SP_REG)
2541         (plus:DI (reg:DI SP_REG) (const_int 8)))
2542    (clobber (mem:BLK (scratch)))]
2543   "TARGET_64BIT"
2544   "pop{q}\t%0"
2545   [(set_attr "type" "pop")
2546    (set_attr "mode" "DI")])
2548 (define_insn "popdi1"
2549   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2550         (mem:DI (reg:DI SP_REG)))
2551    (set (reg:DI SP_REG)
2552         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2553   "TARGET_64BIT"
2554   "pop{q}\t%0"
2555   [(set_attr "type" "pop")
2556    (set_attr "mode" "DI")])
2558 (define_insn "*movdi_xor_rex64"
2559   [(set (match_operand:DI 0 "register_operand" "=r")
2560         (match_operand:DI 1 "const0_operand" ""))
2561    (clobber (reg:CC FLAGS_REG))]
2562   "TARGET_64BIT
2563    && reload_completed"
2564   "xor{l}\t%k0, %k0";
2565   [(set_attr "type" "alu1")
2566    (set_attr "mode" "SI")
2567    (set_attr "length_immediate" "0")])
2569 (define_insn "*movdi_or_rex64"
2570   [(set (match_operand:DI 0 "register_operand" "=r")
2571         (match_operand:DI 1 "const_int_operand" "i"))
2572    (clobber (reg:CC FLAGS_REG))]
2573   "TARGET_64BIT
2574    && reload_completed
2575    && operands[1] == constm1_rtx"
2577   operands[1] = constm1_rtx;
2578   return "or{q}\t{%1, %0|%0, %1}";
2580   [(set_attr "type" "alu1")
2581    (set_attr "mode" "DI")
2582    (set_attr "length_immediate" "1")])
2584 (define_insn "*movdi_2"
2585   [(set (match_operand:DI 0 "nonimmediate_operand"
2586                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2587         (match_operand:DI 1 "general_operand"
2588                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2589   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2590   "@
2591    #
2592    #
2593    pxor\t%0, %0
2594    movq\t{%1, %0|%0, %1}
2595    movq\t{%1, %0|%0, %1}
2596    %vpxor\t%0, %d0
2597    %vmovq\t{%1, %0|%0, %1}
2598    %vmovdqa\t{%1, %0|%0, %1}
2599    %vmovq\t{%1, %0|%0, %1}
2600    xorps\t%0, %0
2601    movlps\t{%1, %0|%0, %1}
2602    movaps\t{%1, %0|%0, %1}
2603    movlps\t{%1, %0|%0, %1}"
2604   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2605    (set (attr "prefix")
2606      (if_then_else (eq_attr "alternative" "5,6,7,8")
2607        (const_string "vex")
2608        (const_string "orig")))
2609    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2611 (define_split
2612   [(set (match_operand:DI 0 "push_operand" "")
2613         (match_operand:DI 1 "general_operand" ""))]
2614   "!TARGET_64BIT && reload_completed
2615    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2616   [(const_int 0)]
2617   "ix86_split_long_move (operands); DONE;")
2619 ;; %%% This multiword shite has got to go.
2620 (define_split
2621   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2622         (match_operand:DI 1 "general_operand" ""))]
2623   "!TARGET_64BIT && reload_completed
2624    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2625    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2626   [(const_int 0)]
2627   "ix86_split_long_move (operands); DONE;")
2629 (define_insn "*movdi_1_rex64"
2630   [(set (match_operand:DI 0 "nonimmediate_operand"
2631           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2632         (match_operand:DI 1 "general_operand"
2633           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2634   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2636   switch (get_attr_type (insn))
2637     {
2638     case TYPE_SSECVT:
2639       if (SSE_REG_P (operands[0]))
2640         return "movq2dq\t{%1, %0|%0, %1}";
2641       else
2642         return "movdq2q\t{%1, %0|%0, %1}";
2644     case TYPE_SSEMOV:
2645       if (TARGET_AVX)
2646         {
2647           if (get_attr_mode (insn) == MODE_TI)
2648             return "vmovdqa\t{%1, %0|%0, %1}";
2649           else
2650             return "vmovq\t{%1, %0|%0, %1}";
2651         }
2653       if (get_attr_mode (insn) == MODE_TI)
2654         return "movdqa\t{%1, %0|%0, %1}";
2655       /* FALLTHRU */
2657     case TYPE_MMXMOV:
2658       /* Moves from and into integer register is done using movd
2659          opcode with REX prefix.  */
2660       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2661         return "movd\t{%1, %0|%0, %1}";
2662       return "movq\t{%1, %0|%0, %1}";
2664     case TYPE_SSELOG1:
2665       return "%vpxor\t%0, %d0";
2667     case TYPE_MMX:
2668       return "pxor\t%0, %0";
2670     case TYPE_MULTI:
2671       return "#";
2673     case TYPE_LEA:
2674       return "lea{q}\t{%a1, %0|%0, %a1}";
2676     default:
2677       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2678       if (get_attr_mode (insn) == MODE_SI)
2679         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2680       else if (which_alternative == 2)
2681         return "movabs{q}\t{%1, %0|%0, %1}";
2682       else
2683         return "mov{q}\t{%1, %0|%0, %1}";
2684     }
2686   [(set (attr "type")
2687      (cond [(eq_attr "alternative" "5")
2688               (const_string "mmx")
2689             (eq_attr "alternative" "6,7,8,9,10")
2690               (const_string "mmxmov")
2691             (eq_attr "alternative" "11")
2692               (const_string "sselog1")
2693             (eq_attr "alternative" "12,13,14,15,16")
2694               (const_string "ssemov")
2695             (eq_attr "alternative" "17,18")
2696               (const_string "ssecvt")
2697             (eq_attr "alternative" "4")
2698               (const_string "multi")
2699             (match_operand:DI 1 "pic_32bit_operand" "")
2700               (const_string "lea")
2701            ]
2702            (const_string "imov")))
2703    (set (attr "modrm")
2704      (if_then_else
2705        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2706          (const_string "0")
2707          (const_string "*")))
2708    (set (attr "length_immediate")
2709      (if_then_else
2710        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2711          (const_string "8")
2712          (const_string "*")))
2713    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2714    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2715    (set (attr "prefix")
2716      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2717        (const_string "maybe_vex")
2718        (const_string "orig")))
2719    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2721 ;; Stores and loads of ax to arbitrary constant address.
2722 ;; We fake an second form of instruction to force reload to load address
2723 ;; into register when rax is not available
2724 (define_insn "*movabsdi_1_rex64"
2725   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2726         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2727   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2728   "@
2729    movabs{q}\t{%1, %P0|%P0, %1}
2730    mov{q}\t{%1, %a0|%a0, %1}"
2731   [(set_attr "type" "imov")
2732    (set_attr "modrm" "0,*")
2733    (set_attr "length_address" "8,0")
2734    (set_attr "length_immediate" "0,*")
2735    (set_attr "memory" "store")
2736    (set_attr "mode" "DI")])
2738 (define_insn "*movabsdi_2_rex64"
2739   [(set (match_operand:DI 0 "register_operand" "=a,r")
2740         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2741   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2742   "@
2743    movabs{q}\t{%P1, %0|%0, %P1}
2744    mov{q}\t{%a1, %0|%0, %a1}"
2745   [(set_attr "type" "imov")
2746    (set_attr "modrm" "0,*")
2747    (set_attr "length_address" "8,0")
2748    (set_attr "length_immediate" "0")
2749    (set_attr "memory" "load")
2750    (set_attr "mode" "DI")])
2752 ;; Convert impossible stores of immediate to existing instructions.
2753 ;; First try to get scratch register and go through it.  In case this
2754 ;; fails, move by 32bit parts.
2755 (define_peephole2
2756   [(match_scratch:DI 2 "r")
2757    (set (match_operand:DI 0 "memory_operand" "")
2758         (match_operand:DI 1 "immediate_operand" ""))]
2759   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2760    && !x86_64_immediate_operand (operands[1], DImode)"
2761   [(set (match_dup 2) (match_dup 1))
2762    (set (match_dup 0) (match_dup 2))]
2763   "")
2765 ;; We need to define this as both peepholer and splitter for case
2766 ;; peephole2 pass is not run.
2767 ;; "&& 1" is needed to keep it from matching the previous pattern.
2768 (define_peephole2
2769   [(set (match_operand:DI 0 "memory_operand" "")
2770         (match_operand:DI 1 "immediate_operand" ""))]
2771   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2772    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2773   [(set (match_dup 2) (match_dup 3))
2774    (set (match_dup 4) (match_dup 5))]
2775   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2777 (define_split
2778   [(set (match_operand:DI 0 "memory_operand" "")
2779         (match_operand:DI 1 "immediate_operand" ""))]
2780   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2781                     ? epilogue_completed : reload_completed)
2782    && !symbolic_operand (operands[1], DImode)
2783    && !x86_64_immediate_operand (operands[1], DImode)"
2784   [(set (match_dup 2) (match_dup 3))
2785    (set (match_dup 4) (match_dup 5))]
2786   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2788 (define_insn "*swapdi_rex64"
2789   [(set (match_operand:DI 0 "register_operand" "+r")
2790         (match_operand:DI 1 "register_operand" "+r"))
2791    (set (match_dup 1)
2792         (match_dup 0))]
2793   "TARGET_64BIT"
2794   "xchg{q}\t%1, %0"
2795   [(set_attr "type" "imov")
2796    (set_attr "mode" "DI")
2797    (set_attr "pent_pair" "np")
2798    (set_attr "athlon_decode" "vector")
2799    (set_attr "amdfam10_decode" "double")])
2801 (define_expand "movoi"
2802   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2803         (match_operand:OI 1 "general_operand" ""))]
2804   "TARGET_AVX"
2805   "ix86_expand_move (OImode, operands); DONE;")
2807 (define_insn "*movoi_internal"
2808   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2809         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2810   "TARGET_AVX
2811    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2813   switch (which_alternative)
2814     {
2815     case 0:
2816       return "vxorps\t%0, %0, %0";
2817     case 1:
2818     case 2:
2819       if (misaligned_operand (operands[0], OImode)
2820           || misaligned_operand (operands[1], OImode))
2821         return "vmovdqu\t{%1, %0|%0, %1}";
2822       else
2823         return "vmovdqa\t{%1, %0|%0, %1}";
2824     default:
2825       gcc_unreachable ();
2826     }
2828   [(set_attr "type" "sselog1,ssemov,ssemov")
2829    (set_attr "prefix" "vex")
2830    (set_attr "mode" "OI")])
2832 (define_expand "movti"
2833   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2834         (match_operand:TI 1 "nonimmediate_operand" ""))]
2835   "TARGET_SSE || TARGET_64BIT"
2837   if (TARGET_64BIT)
2838     ix86_expand_move (TImode, operands);
2839   else if (push_operand (operands[0], TImode))
2840     ix86_expand_push (TImode, operands[1]);
2841   else
2842     ix86_expand_vector_move (TImode, operands);
2843   DONE;
2846 (define_insn "*movti_internal"
2847   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2848         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2849   "TARGET_SSE && !TARGET_64BIT
2850    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2852   switch (which_alternative)
2853     {
2854     case 0:
2855       if (get_attr_mode (insn) == MODE_V4SF)
2856         return "%vxorps\t%0, %d0";
2857       else
2858         return "%vpxor\t%0, %d0";
2859     case 1:
2860     case 2:
2861       /* TDmode values are passed as TImode on the stack.  Moving them
2862          to stack may result in unaligned memory access.  */
2863       if (misaligned_operand (operands[0], TImode)
2864           || misaligned_operand (operands[1], TImode))
2865         {
2866           if (get_attr_mode (insn) == MODE_V4SF)
2867             return "%vmovups\t{%1, %0|%0, %1}";
2868          else
2869            return "%vmovdqu\t{%1, %0|%0, %1}";
2870         }
2871       else
2872         {
2873           if (get_attr_mode (insn) == MODE_V4SF)
2874             return "%vmovaps\t{%1, %0|%0, %1}";
2875          else
2876            return "%vmovdqa\t{%1, %0|%0, %1}";
2877         }
2878     default:
2879       gcc_unreachable ();
2880     }
2882   [(set_attr "type" "sselog1,ssemov,ssemov")
2883    (set_attr "prefix" "maybe_vex")
2884    (set (attr "mode")
2885         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2886                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2887                  (const_string "V4SF")
2888                (and (eq_attr "alternative" "2")
2889                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2890                         (const_int 0)))
2891                  (const_string "V4SF")]
2892               (const_string "TI")))])
2894 (define_insn "*movti_rex64"
2895   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2896         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2897   "TARGET_64BIT
2898    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2900   switch (which_alternative)
2901     {
2902     case 0:
2903     case 1:
2904       return "#";
2905     case 2:
2906       if (get_attr_mode (insn) == MODE_V4SF)
2907         return "%vxorps\t%0, %d0";
2908       else
2909         return "%vpxor\t%0, %d0";
2910     case 3:
2911     case 4:
2912       /* TDmode values are passed as TImode on the stack.  Moving them
2913          to stack may result in unaligned memory access.  */
2914       if (misaligned_operand (operands[0], TImode)
2915           || misaligned_operand (operands[1], TImode))
2916         {
2917           if (get_attr_mode (insn) == MODE_V4SF)
2918             return "%vmovups\t{%1, %0|%0, %1}";
2919          else
2920            return "%vmovdqu\t{%1, %0|%0, %1}";
2921         }
2922       else
2923         {
2924           if (get_attr_mode (insn) == MODE_V4SF)
2925             return "%vmovaps\t{%1, %0|%0, %1}";
2926          else
2927            return "%vmovdqa\t{%1, %0|%0, %1}";
2928         }
2929     default:
2930       gcc_unreachable ();
2931     }
2933   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2934    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2935    (set (attr "mode")
2936         (cond [(eq_attr "alternative" "2,3")
2937                  (if_then_else
2938                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2939                        (const_int 0))
2940                    (const_string "V4SF")
2941                    (const_string "TI"))
2942                (eq_attr "alternative" "4")
2943                  (if_then_else
2944                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2945                             (const_int 0))
2946                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2947                             (const_int 0)))
2948                    (const_string "V4SF")
2949                    (const_string "TI"))]
2950                (const_string "DI")))])
2952 (define_split
2953   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2954         (match_operand:TI 1 "general_operand" ""))]
2955   "reload_completed && !SSE_REG_P (operands[0])
2956    && !SSE_REG_P (operands[1])"
2957   [(const_int 0)]
2958   "ix86_split_long_move (operands); DONE;")
2960 ;; This expands to what emit_move_complex would generate if we didn't
2961 ;; have a movti pattern.  Having this avoids problems with reload on
2962 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2963 ;; to have around all the time.
2964 (define_expand "movcdi"
2965   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2966         (match_operand:CDI 1 "general_operand" ""))]
2967   ""
2969   if (push_operand (operands[0], CDImode))
2970     emit_move_complex_push (CDImode, operands[0], operands[1]);
2971   else
2972     emit_move_complex_parts (operands[0], operands[1]);
2973   DONE;
2976 (define_expand "movsf"
2977   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2978         (match_operand:SF 1 "general_operand" ""))]
2979   ""
2980   "ix86_expand_move (SFmode, operands); DONE;")
2982 (define_insn "*pushsf"
2983   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2984         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2985   "!TARGET_64BIT"
2987   /* Anything else should be already split before reg-stack.  */
2988   gcc_assert (which_alternative == 1);
2989   return "push{l}\t%1";
2991   [(set_attr "type" "multi,push,multi")
2992    (set_attr "unit" "i387,*,*")
2993    (set_attr "mode" "SF,SI,SF")])
2995 (define_insn "*pushsf_rex64"
2996   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2997         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2998   "TARGET_64BIT"
3000   /* Anything else should be already split before reg-stack.  */
3001   gcc_assert (which_alternative == 1);
3002   return "push{q}\t%q1";
3004   [(set_attr "type" "multi,push,multi")
3005    (set_attr "unit" "i387,*,*")
3006    (set_attr "mode" "SF,DI,SF")])
3008 (define_split
3009   [(set (match_operand:SF 0 "push_operand" "")
3010         (match_operand:SF 1 "memory_operand" ""))]
3011   "reload_completed
3012    && MEM_P (operands[1])
3013    && (operands[2] = find_constant_src (insn))"
3014   [(set (match_dup 0)
3015         (match_dup 2))])
3018 ;; %%% Kill this when call knows how to work this out.
3019 (define_split
3020   [(set (match_operand:SF 0 "push_operand" "")
3021         (match_operand:SF 1 "any_fp_register_operand" ""))]
3022   "!TARGET_64BIT"
3023   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
3024    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
3026 (define_split
3027   [(set (match_operand:SF 0 "push_operand" "")
3028         (match_operand:SF 1 "any_fp_register_operand" ""))]
3029   "TARGET_64BIT"
3030   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3031    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
3033 (define_insn "*movsf_1"
3034   [(set (match_operand:SF 0 "nonimmediate_operand"
3035           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3036         (match_operand:SF 1 "general_operand"
3037           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
3038   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3039    && (reload_in_progress || reload_completed
3040        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3041        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3042            && standard_80387_constant_p (operands[1]))
3043        || GET_CODE (operands[1]) != CONST_DOUBLE
3044        || memory_operand (operands[0], SFmode))"
3046   switch (which_alternative)
3047     {
3048     case 0:
3049     case 1:
3050       return output_387_reg_move (insn, operands);
3052     case 2:
3053       return standard_80387_constant_opcode (operands[1]);
3055     case 3:
3056     case 4:
3057       return "mov{l}\t{%1, %0|%0, %1}";
3058     case 5:
3059       if (get_attr_mode (insn) == MODE_TI)
3060         return "%vpxor\t%0, %d0";
3061       else
3062         return "%vxorps\t%0, %d0";
3063     case 6:
3064       if (get_attr_mode (insn) == MODE_V4SF)
3065         return "%vmovaps\t{%1, %0|%0, %1}";
3066       else
3067         return "%vmovss\t{%1, %d0|%d0, %1}";
3068     case 7:
3069       if (TARGET_AVX)
3070         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3071                                    : "vmovss\t{%1, %0|%0, %1}";
3072       else
3073         return "movss\t{%1, %0|%0, %1}";
3074     case 8:
3075       return "%vmovss\t{%1, %0|%0, %1}";
3077     case 9: case 10: case 14: case 15:
3078       return "movd\t{%1, %0|%0, %1}";
3079     case 12: case 13:
3080       return "%vmovd\t{%1, %0|%0, %1}";
3082     case 11:
3083       return "movq\t{%1, %0|%0, %1}";
3085     default:
3086       gcc_unreachable ();
3087     }
3089   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3090    (set (attr "prefix")
3091      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3092        (const_string "maybe_vex")
3093        (const_string "orig")))
3094    (set (attr "mode")
3095         (cond [(eq_attr "alternative" "3,4,9,10")
3096                  (const_string "SI")
3097                (eq_attr "alternative" "5")
3098                  (if_then_else
3099                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3100                                  (const_int 0))
3101                              (ne (symbol_ref "TARGET_SSE2")
3102                                  (const_int 0)))
3103                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3104                             (const_int 0)))
3105                    (const_string "TI")
3106                    (const_string "V4SF"))
3107                /* For architectures resolving dependencies on
3108                   whole SSE registers use APS move to break dependency
3109                   chains, otherwise use short move to avoid extra work.
3111                   Do the same for architectures resolving dependencies on
3112                   the parts.  While in DF mode it is better to always handle
3113                   just register parts, the SF mode is different due to lack
3114                   of instructions to load just part of the register.  It is
3115                   better to maintain the whole registers in single format
3116                   to avoid problems on using packed logical operations.  */
3117                (eq_attr "alternative" "6")
3118                  (if_then_else
3119                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3120                             (const_int 0))
3121                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3122                             (const_int 0)))
3123                    (const_string "V4SF")
3124                    (const_string "SF"))
3125                (eq_attr "alternative" "11")
3126                  (const_string "DI")]
3127                (const_string "SF")))])
3129 (define_insn "*swapsf"
3130   [(set (match_operand:SF 0 "fp_register_operand" "+f")
3131         (match_operand:SF 1 "fp_register_operand" "+f"))
3132    (set (match_dup 1)
3133         (match_dup 0))]
3134   "reload_completed || TARGET_80387"
3136   if (STACK_TOP_P (operands[0]))
3137     return "fxch\t%1";
3138   else
3139     return "fxch\t%0";
3141   [(set_attr "type" "fxch")
3142    (set_attr "mode" "SF")])
3144 (define_expand "movdf"
3145   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3146         (match_operand:DF 1 "general_operand" ""))]
3147   ""
3148   "ix86_expand_move (DFmode, operands); DONE;")
3150 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3151 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3152 ;; On the average, pushdf using integers can be still shorter.  Allow this
3153 ;; pattern for optimize_size too.
3155 (define_insn "*pushdf_nointeger"
3156   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3157         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3158   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3160   /* This insn should be already split before reg-stack.  */
3161   gcc_unreachable ();
3163   [(set_attr "type" "multi")
3164    (set_attr "unit" "i387,*,*,*")
3165    (set_attr "mode" "DF,SI,SI,DF")])
3167 (define_insn "*pushdf_integer"
3168   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3169         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3170   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3172   /* This insn should be already split before reg-stack.  */
3173   gcc_unreachable ();
3175   [(set_attr "type" "multi")
3176    (set_attr "unit" "i387,*,*")
3177    (set_attr "mode" "DF,SI,DF")])
3179 ;; %%% Kill this when call knows how to work this out.
3180 (define_split
3181   [(set (match_operand:DF 0 "push_operand" "")
3182         (match_operand:DF 1 "any_fp_register_operand" ""))]
3183   "reload_completed"
3184   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3185    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3186   "")
3188 (define_split
3189   [(set (match_operand:DF 0 "push_operand" "")
3190         (match_operand:DF 1 "general_operand" ""))]
3191   "reload_completed"
3192   [(const_int 0)]
3193   "ix86_split_long_move (operands); DONE;")
3195 ;; Moving is usually shorter when only FP registers are used. This separate
3196 ;; movdf pattern avoids the use of integer registers for FP operations
3197 ;; when optimizing for size.
3199 (define_insn "*movdf_nointeger"
3200   [(set (match_operand:DF 0 "nonimmediate_operand"
3201                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3202         (match_operand:DF 1 "general_operand"
3203                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3204   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3205    && ((optimize_function_for_size_p (cfun)
3206        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3207    && (reload_in_progress || reload_completed
3208        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3209        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3210            && optimize_function_for_size_p (cfun)
3211            && !memory_operand (operands[0], DFmode)
3212            && standard_80387_constant_p (operands[1]))
3213        || GET_CODE (operands[1]) != CONST_DOUBLE
3214        || ((optimize_function_for_size_p (cfun)
3215             || !TARGET_MEMORY_MISMATCH_STALL
3216             || reload_in_progress || reload_completed)
3217            && memory_operand (operands[0], DFmode)))"
3219   switch (which_alternative)
3220     {
3221     case 0:
3222     case 1:
3223       return output_387_reg_move (insn, operands);
3225     case 2:
3226       return standard_80387_constant_opcode (operands[1]);
3228     case 3:
3229     case 4:
3230       return "#";
3231     case 5:
3232       switch (get_attr_mode (insn))
3233         {
3234         case MODE_V4SF:
3235           return "%vxorps\t%0, %d0";
3236         case MODE_V2DF:
3237           return "%vxorpd\t%0, %d0";
3238         case MODE_TI:
3239           return "%vpxor\t%0, %d0";
3240         default:
3241           gcc_unreachable ();
3242         }
3243     case 6:
3244     case 7:
3245     case 8:
3246       switch (get_attr_mode (insn))
3247         {
3248         case MODE_V4SF:
3249           return "%vmovaps\t{%1, %0|%0, %1}";
3250         case MODE_V2DF:
3251           return "%vmovapd\t{%1, %0|%0, %1}";
3252         case MODE_TI:
3253           return "%vmovdqa\t{%1, %0|%0, %1}";
3254         case MODE_DI:
3255           return "%vmovq\t{%1, %0|%0, %1}";
3256         case MODE_DF:
3257           if (TARGET_AVX)
3258             {
3259               if (REG_P (operands[0]) && REG_P (operands[1]))
3260                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3261               else
3262                 return "vmovsd\t{%1, %0|%0, %1}";
3263             }
3264           else
3265             return "movsd\t{%1, %0|%0, %1}";
3266         case MODE_V1DF:
3267           if (TARGET_AVX)
3268             {
3269               if (REG_P (operands[0]))
3270                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3271               else
3272                 return "vmovlpd\t{%1, %0|%0, %1}";
3273             }
3274           else
3275             return "movlpd\t{%1, %0|%0, %1}";
3276         case MODE_V2SF:
3277           if (TARGET_AVX)
3278             {
3279               if (REG_P (operands[0]))
3280                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3281               else
3282                 return "vmovlps\t{%1, %0|%0, %1}";
3283             }
3284           else
3285             return "movlps\t{%1, %0|%0, %1}";
3286         default:
3287           gcc_unreachable ();
3288         }
3290     default:
3291       gcc_unreachable ();
3292     }
3294   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3295    (set (attr "prefix")
3296      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3297        (const_string "orig")
3298        (const_string "maybe_vex")))
3299    (set (attr "prefix_data16")
3300      (if_then_else (eq_attr "mode" "V1DF")
3301        (const_string "1")
3302        (const_string "*")))
3303    (set (attr "mode")
3304         (cond [(eq_attr "alternative" "0,1,2")
3305                  (const_string "DF")
3306                (eq_attr "alternative" "3,4")
3307                  (const_string "SI")
3309                /* For SSE1, we have many fewer alternatives.  */
3310                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3311                  (cond [(eq_attr "alternative" "5,6")
3312                           (const_string "V4SF")
3313                        ]
3314                    (const_string "V2SF"))
3316                /* xorps is one byte shorter.  */
3317                (eq_attr "alternative" "5")
3318                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3319                             (const_int 0))
3320                           (const_string "V4SF")
3321                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3322                             (const_int 0))
3323                           (const_string "TI")
3324                        ]
3325                        (const_string "V2DF"))
3327                /* For architectures resolving dependencies on
3328                   whole SSE registers use APD move to break dependency
3329                   chains, otherwise use short move to avoid extra work.
3331                   movaps encodes one byte shorter.  */
3332                (eq_attr "alternative" "6")
3333                  (cond
3334                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3335                         (const_int 0))
3336                       (const_string "V4SF")
3337                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3338                         (const_int 0))
3339                       (const_string "V2DF")
3340                    ]
3341                    (const_string "DF"))
3342                /* For architectures resolving dependencies on register
3343                   parts we may avoid extra work to zero out upper part
3344                   of register.  */
3345                (eq_attr "alternative" "7")
3346                  (if_then_else
3347                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3348                        (const_int 0))
3349                    (const_string "V1DF")
3350                    (const_string "DF"))
3351               ]
3352               (const_string "DF")))])
3354 (define_insn "*movdf_integer_rex64"
3355   [(set (match_operand:DF 0 "nonimmediate_operand"
3356                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3357         (match_operand:DF 1 "general_operand"
3358                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3359   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3360    && (reload_in_progress || reload_completed
3361        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3362        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3363            && optimize_function_for_size_p (cfun)
3364            && standard_80387_constant_p (operands[1]))
3365        || GET_CODE (operands[1]) != CONST_DOUBLE
3366        || memory_operand (operands[0], DFmode))"
3368   switch (which_alternative)
3369     {
3370     case 0:
3371     case 1:
3372       return output_387_reg_move (insn, operands);
3374     case 2:
3375       return standard_80387_constant_opcode (operands[1]);
3377     case 3:
3378     case 4:
3379       return "#";
3381     case 5:
3382       switch (get_attr_mode (insn))
3383         {
3384         case MODE_V4SF:
3385           return "%vxorps\t%0, %d0";
3386         case MODE_V2DF:
3387           return "%vxorpd\t%0, %d0";
3388         case MODE_TI:
3389           return "%vpxor\t%0, %d0";
3390         default:
3391           gcc_unreachable ();
3392         }
3393     case 6:
3394     case 7:
3395     case 8:
3396       switch (get_attr_mode (insn))
3397         {
3398         case MODE_V4SF:
3399           return "%vmovaps\t{%1, %0|%0, %1}";
3400         case MODE_V2DF:
3401           return "%vmovapd\t{%1, %0|%0, %1}";
3402         case MODE_TI:
3403           return "%vmovdqa\t{%1, %0|%0, %1}";
3404         case MODE_DI:
3405           return "%vmovq\t{%1, %0|%0, %1}";
3406         case MODE_DF:
3407           if (TARGET_AVX)
3408             {
3409               if (REG_P (operands[0]) && REG_P (operands[1]))
3410                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3411               else
3412                 return "vmovsd\t{%1, %0|%0, %1}";
3413             }
3414           else
3415             return "movsd\t{%1, %0|%0, %1}";
3416         case MODE_V1DF:
3417           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3418         case MODE_V2SF:
3419           return "%vmovlps\t{%1, %d0|%d0, %1}";
3420         default:
3421           gcc_unreachable ();
3422         }
3424     case 9:
3425     case 10:
3426     return "%vmovd\t{%1, %0|%0, %1}";
3428     default:
3429       gcc_unreachable();
3430     }
3432   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3433    (set (attr "prefix")
3434      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3435        (const_string "orig")
3436        (const_string "maybe_vex")))
3437    (set (attr "prefix_data16")
3438      (if_then_else (eq_attr "mode" "V1DF")
3439        (const_string "1")
3440        (const_string "*")))
3441    (set (attr "mode")
3442         (cond [(eq_attr "alternative" "0,1,2")
3443                  (const_string "DF")
3444                (eq_attr "alternative" "3,4,9,10")
3445                  (const_string "DI")
3447                /* For SSE1, we have many fewer alternatives.  */
3448                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3449                  (cond [(eq_attr "alternative" "5,6")
3450                           (const_string "V4SF")
3451                        ]
3452                    (const_string "V2SF"))
3454                /* xorps is one byte shorter.  */
3455                (eq_attr "alternative" "5")
3456                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3457                             (const_int 0))
3458                           (const_string "V4SF")
3459                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3460                             (const_int 0))
3461                           (const_string "TI")
3462                        ]
3463                        (const_string "V2DF"))
3465                /* For architectures resolving dependencies on
3466                   whole SSE registers use APD move to break dependency
3467                   chains, otherwise use short move to avoid extra work.
3469                   movaps encodes one byte shorter.  */
3470                (eq_attr "alternative" "6")
3471                  (cond
3472                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3473                         (const_int 0))
3474                       (const_string "V4SF")
3475                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3476                         (const_int 0))
3477                       (const_string "V2DF")
3478                    ]
3479                    (const_string "DF"))
3480                /* For architectures resolving dependencies on register
3481                   parts we may avoid extra work to zero out upper part
3482                   of register.  */
3483                (eq_attr "alternative" "7")
3484                  (if_then_else
3485                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3486                        (const_int 0))
3487                    (const_string "V1DF")
3488                    (const_string "DF"))
3489               ]
3490               (const_string "DF")))])
3492 (define_insn "*movdf_integer"
3493   [(set (match_operand:DF 0 "nonimmediate_operand"
3494                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3495         (match_operand:DF 1 "general_operand"
3496                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3497   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3498    && optimize_function_for_speed_p (cfun)
3499    && TARGET_INTEGER_DFMODE_MOVES
3500    && (reload_in_progress || reload_completed
3501        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3502        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3503            && optimize_function_for_size_p (cfun)
3504            && standard_80387_constant_p (operands[1]))
3505        || GET_CODE (operands[1]) != CONST_DOUBLE
3506        || memory_operand (operands[0], DFmode))"
3508   switch (which_alternative)
3509     {
3510     case 0:
3511     case 1:
3512       return output_387_reg_move (insn, operands);
3514     case 2:
3515       return standard_80387_constant_opcode (operands[1]);
3517     case 3:
3518     case 4:
3519       return "#";
3521     case 5:
3522       switch (get_attr_mode (insn))
3523         {
3524         case MODE_V4SF:
3525           return "xorps\t%0, %0";
3526         case MODE_V2DF:
3527           return "xorpd\t%0, %0";
3528         case MODE_TI:
3529           return "pxor\t%0, %0";
3530         default:
3531           gcc_unreachable ();
3532         }
3533     case 6:
3534     case 7:
3535     case 8:
3536       switch (get_attr_mode (insn))
3537         {
3538         case MODE_V4SF:
3539           return "movaps\t{%1, %0|%0, %1}";
3540         case MODE_V2DF:
3541           return "movapd\t{%1, %0|%0, %1}";
3542         case MODE_TI:
3543           return "movdqa\t{%1, %0|%0, %1}";
3544         case MODE_DI:
3545           return "movq\t{%1, %0|%0, %1}";
3546         case MODE_DF:
3547           return "movsd\t{%1, %0|%0, %1}";
3548         case MODE_V1DF:
3549           return "movlpd\t{%1, %0|%0, %1}";
3550         case MODE_V2SF:
3551           return "movlps\t{%1, %0|%0, %1}";
3552         default:
3553           gcc_unreachable ();
3554         }
3556     default:
3557       gcc_unreachable();
3558     }
3560   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3561    (set (attr "prefix_data16")
3562      (if_then_else (eq_attr "mode" "V1DF")
3563        (const_string "1")
3564        (const_string "*")))
3565    (set (attr "mode")
3566         (cond [(eq_attr "alternative" "0,1,2")
3567                  (const_string "DF")
3568                (eq_attr "alternative" "3,4")
3569                  (const_string "SI")
3571                /* For SSE1, we have many fewer alternatives.  */
3572                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3573                  (cond [(eq_attr "alternative" "5,6")
3574                           (const_string "V4SF")
3575                        ]
3576                    (const_string "V2SF"))
3578                /* xorps is one byte shorter.  */
3579                (eq_attr "alternative" "5")
3580                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3581                             (const_int 0))
3582                           (const_string "V4SF")
3583                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3584                             (const_int 0))
3585                           (const_string "TI")
3586                        ]
3587                        (const_string "V2DF"))
3589                /* For architectures resolving dependencies on
3590                   whole SSE registers use APD move to break dependency
3591                   chains, otherwise use short move to avoid extra work.
3593                   movaps encodes one byte shorter.  */
3594                (eq_attr "alternative" "6")
3595                  (cond
3596                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3597                         (const_int 0))
3598                       (const_string "V4SF")
3599                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3600                         (const_int 0))
3601                       (const_string "V2DF")
3602                    ]
3603                    (const_string "DF"))
3604                /* For architectures resolving dependencies on register
3605                   parts we may avoid extra work to zero out upper part
3606                   of register.  */
3607                (eq_attr "alternative" "7")
3608                  (if_then_else
3609                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3610                        (const_int 0))
3611                    (const_string "V1DF")
3612                    (const_string "DF"))
3613               ]
3614               (const_string "DF")))])
3616 (define_split
3617   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3618         (match_operand:DF 1 "general_operand" ""))]
3619   "reload_completed
3620    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3621    && ! (ANY_FP_REG_P (operands[0]) ||
3622          (GET_CODE (operands[0]) == SUBREG
3623           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3624    && ! (ANY_FP_REG_P (operands[1]) ||
3625          (GET_CODE (operands[1]) == SUBREG
3626           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3627   [(const_int 0)]
3628   "ix86_split_long_move (operands); DONE;")
3630 (define_insn "*swapdf"
3631   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3632         (match_operand:DF 1 "fp_register_operand" "+f"))
3633    (set (match_dup 1)
3634         (match_dup 0))]
3635   "reload_completed || TARGET_80387"
3637   if (STACK_TOP_P (operands[0]))
3638     return "fxch\t%1";
3639   else
3640     return "fxch\t%0";
3642   [(set_attr "type" "fxch")
3643    (set_attr "mode" "DF")])
3645 (define_expand "movxf"
3646   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3647         (match_operand:XF 1 "general_operand" ""))]
3648   ""
3649   "ix86_expand_move (XFmode, operands); DONE;")
3651 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3652 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3653 ;; Pushing using integer instructions is longer except for constants
3654 ;; and direct memory references.
3655 ;; (assuming that any given constant is pushed only once, but this ought to be
3656 ;;  handled elsewhere).
3658 (define_insn "*pushxf_nointeger"
3659   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3660         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3661   "optimize_function_for_size_p (cfun)"
3663   /* This insn should be already split before reg-stack.  */
3664   gcc_unreachable ();
3666   [(set_attr "type" "multi")
3667    (set_attr "unit" "i387,*,*")
3668    (set_attr "mode" "XF,SI,SI")])
3670 (define_insn "*pushxf_integer"
3671   [(set (match_operand:XF 0 "push_operand" "=<,<")
3672         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3673   "optimize_function_for_speed_p (cfun)"
3675   /* This insn should be already split before reg-stack.  */
3676   gcc_unreachable ();
3678   [(set_attr "type" "multi")
3679    (set_attr "unit" "i387,*")
3680    (set_attr "mode" "XF,SI")])
3682 (define_split
3683   [(set (match_operand 0 "push_operand" "")
3684         (match_operand 1 "general_operand" ""))]
3685   "reload_completed
3686    && (GET_MODE (operands[0]) == XFmode
3687        || GET_MODE (operands[0]) == DFmode)
3688    && !ANY_FP_REG_P (operands[1])"
3689   [(const_int 0)]
3690   "ix86_split_long_move (operands); DONE;")
3692 (define_split
3693   [(set (match_operand:XF 0 "push_operand" "")
3694         (match_operand:XF 1 "any_fp_register_operand" ""))]
3695   ""
3696   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3697    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3698   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3700 ;; Do not use integer registers when optimizing for size
3701 (define_insn "*movxf_nointeger"
3702   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3703         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3704   "optimize_function_for_size_p (cfun)
3705    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3706    && (reload_in_progress || reload_completed
3707        || standard_80387_constant_p (operands[1])
3708        || GET_CODE (operands[1]) != CONST_DOUBLE
3709        || memory_operand (operands[0], XFmode))"
3711   switch (which_alternative)
3712     {
3713     case 0:
3714     case 1:
3715       return output_387_reg_move (insn, operands);
3717     case 2:
3718       return standard_80387_constant_opcode (operands[1]);
3720     case 3: case 4:
3721       return "#";
3722     default:
3723       gcc_unreachable ();
3724     }
3726   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3727    (set_attr "mode" "XF,XF,XF,SI,SI")])
3729 (define_insn "*movxf_integer"
3730   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3731         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3732   "optimize_function_for_speed_p (cfun)
3733    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3734    && (reload_in_progress || reload_completed
3735        || GET_CODE (operands[1]) != CONST_DOUBLE
3736        || memory_operand (operands[0], XFmode))"
3738   switch (which_alternative)
3739     {
3740     case 0:
3741     case 1:
3742       return output_387_reg_move (insn, operands);
3744     case 2:
3745       return standard_80387_constant_opcode (operands[1]);
3747     case 3: case 4:
3748       return "#";
3750     default:
3751       gcc_unreachable ();
3752     }
3754   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3755    (set_attr "mode" "XF,XF,XF,SI,SI")])
3757 (define_expand "movtf"
3758   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3759         (match_operand:TF 1 "nonimmediate_operand" ""))]
3760   "TARGET_SSE2"
3762   ix86_expand_move (TFmode, operands);
3763   DONE;
3766 (define_insn "*movtf_internal"
3767   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3768         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3769   "TARGET_SSE2
3770    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3772   switch (which_alternative)
3773     {
3774     case 0:
3775     case 1:
3776       if (get_attr_mode (insn) == MODE_V4SF)
3777         return "%vmovaps\t{%1, %0|%0, %1}";
3778       else
3779         return "%vmovdqa\t{%1, %0|%0, %1}";
3780     case 2:
3781       if (get_attr_mode (insn) == MODE_V4SF)
3782         return "%vxorps\t%0, %d0";
3783       else
3784         return "%vpxor\t%0, %d0";
3785     case 3:
3786     case 4:
3787         return "#";
3788     default:
3789       gcc_unreachable ();
3790     }
3792   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3793    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3794    (set (attr "mode")
3795         (cond [(eq_attr "alternative" "0,2")
3796                  (if_then_else
3797                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3798                        (const_int 0))
3799                    (const_string "V4SF")
3800                    (const_string "TI"))
3801                (eq_attr "alternative" "1")
3802                  (if_then_else
3803                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3804                             (const_int 0))
3805                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3806                             (const_int 0)))
3807                    (const_string "V4SF")
3808                    (const_string "TI"))]
3809                (const_string "DI")))])
3811 (define_insn "*pushtf_sse"
3812   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3813         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3814   "TARGET_SSE2"
3816   /* This insn should be already split before reg-stack.  */
3817   gcc_unreachable ();
3819   [(set_attr "type" "multi")
3820    (set_attr "unit" "sse,*,*")
3821    (set_attr "mode" "TF,SI,SI")])
3823 (define_split
3824   [(set (match_operand:TF 0 "push_operand" "")
3825         (match_operand:TF 1 "general_operand" ""))]
3826   "TARGET_SSE2 && reload_completed
3827    && !SSE_REG_P (operands[1])"
3828   [(const_int 0)]
3829   "ix86_split_long_move (operands); DONE;")
3831 (define_split
3832   [(set (match_operand:TF 0 "push_operand" "")
3833         (match_operand:TF 1 "any_fp_register_operand" ""))]
3834   "TARGET_SSE2"
3835   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3836    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3837   "")
3839 (define_split
3840   [(set (match_operand 0 "nonimmediate_operand" "")
3841         (match_operand 1 "general_operand" ""))]
3842   "reload_completed
3843    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3844    && GET_MODE (operands[0]) == XFmode
3845    && ! (ANY_FP_REG_P (operands[0]) ||
3846          (GET_CODE (operands[0]) == SUBREG
3847           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3848    && ! (ANY_FP_REG_P (operands[1]) ||
3849          (GET_CODE (operands[1]) == SUBREG
3850           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3851   [(const_int 0)]
3852   "ix86_split_long_move (operands); DONE;")
3854 (define_split
3855   [(set (match_operand 0 "register_operand" "")
3856         (match_operand 1 "memory_operand" ""))]
3857   "reload_completed
3858    && MEM_P (operands[1])
3859    && (GET_MODE (operands[0]) == TFmode
3860        || GET_MODE (operands[0]) == XFmode
3861        || GET_MODE (operands[0]) == SFmode
3862        || GET_MODE (operands[0]) == DFmode)
3863    && (operands[2] = find_constant_src (insn))"
3864   [(set (match_dup 0) (match_dup 2))]
3866   rtx c = operands[2];
3867   rtx r = operands[0];
3869   if (GET_CODE (r) == SUBREG)
3870     r = SUBREG_REG (r);
3872   if (SSE_REG_P (r))
3873     {
3874       if (!standard_sse_constant_p (c))
3875         FAIL;
3876     }
3877   else if (FP_REG_P (r))
3878     {
3879       if (!standard_80387_constant_p (c))
3880         FAIL;
3881     }
3882   else if (MMX_REG_P (r))
3883     FAIL;
3886 (define_split
3887   [(set (match_operand 0 "register_operand" "")
3888         (float_extend (match_operand 1 "memory_operand" "")))]
3889   "reload_completed
3890    && MEM_P (operands[1])
3891    && (GET_MODE (operands[0]) == TFmode
3892        || GET_MODE (operands[0]) == XFmode
3893        || GET_MODE (operands[0]) == SFmode
3894        || GET_MODE (operands[0]) == DFmode)
3895    && (operands[2] = find_constant_src (insn))"
3896   [(set (match_dup 0) (match_dup 2))]
3898   rtx c = operands[2];
3899   rtx r = operands[0];
3901   if (GET_CODE (r) == SUBREG)
3902     r = SUBREG_REG (r);
3904   if (SSE_REG_P (r))
3905     {
3906       if (!standard_sse_constant_p (c))
3907         FAIL;
3908     }
3909   else if (FP_REG_P (r))
3910     {
3911       if (!standard_80387_constant_p (c))
3912         FAIL;
3913     }
3914   else if (MMX_REG_P (r))
3915     FAIL;
3918 (define_insn "swapxf"
3919   [(set (match_operand:XF 0 "register_operand" "+f")
3920         (match_operand:XF 1 "register_operand" "+f"))
3921    (set (match_dup 1)
3922         (match_dup 0))]
3923   "TARGET_80387"
3925   if (STACK_TOP_P (operands[0]))
3926     return "fxch\t%1";
3927   else
3928     return "fxch\t%0";
3930   [(set_attr "type" "fxch")
3931    (set_attr "mode" "XF")])
3933 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3934 (define_split
3935   [(set (match_operand:X87MODEF 0 "register_operand" "")
3936         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3937   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3938    && (standard_80387_constant_p (operands[1]) == 8
3939        || standard_80387_constant_p (operands[1]) == 9)"
3940   [(set (match_dup 0)(match_dup 1))
3941    (set (match_dup 0)
3942         (neg:X87MODEF (match_dup 0)))]
3944   REAL_VALUE_TYPE r;
3946   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3947   if (real_isnegzero (&r))
3948     operands[1] = CONST0_RTX (<MODE>mode);
3949   else
3950     operands[1] = CONST1_RTX (<MODE>mode);
3953 (define_split
3954   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3955         (match_operand:TF 1 "general_operand" ""))]
3956   "reload_completed
3957    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3958   [(const_int 0)]
3959   "ix86_split_long_move (operands); DONE;")
3961 ;; Zero extension instructions
3963 (define_expand "zero_extendhisi2"
3964   [(set (match_operand:SI 0 "register_operand" "")
3965      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3966   ""
3968   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3969     {
3970       operands[1] = force_reg (HImode, operands[1]);
3971       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3972       DONE;
3973     }
3976 (define_insn "zero_extendhisi2_and"
3977   [(set (match_operand:SI 0 "register_operand" "=r")
3978      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3979    (clobber (reg:CC FLAGS_REG))]
3980   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3981   "#"
3982   [(set_attr "type" "alu1")
3983    (set_attr "mode" "SI")])
3985 (define_split
3986   [(set (match_operand:SI 0 "register_operand" "")
3987         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3988    (clobber (reg:CC FLAGS_REG))]
3989   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3990    && optimize_function_for_speed_p (cfun)"
3991   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3992               (clobber (reg:CC FLAGS_REG))])]
3993   "")
3995 (define_insn "*zero_extendhisi2_movzwl"
3996   [(set (match_operand:SI 0 "register_operand" "=r")
3997      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3998   "!TARGET_ZERO_EXTEND_WITH_AND
3999    || optimize_function_for_size_p (cfun)"
4000   "movz{wl|x}\t{%1, %0|%0, %1}"
4001   [(set_attr "type" "imovx")
4002    (set_attr "mode" "SI")])
4004 (define_expand "zero_extendqihi2"
4005   [(parallel
4006     [(set (match_operand:HI 0 "register_operand" "")
4007        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4008      (clobber (reg:CC FLAGS_REG))])]
4009   ""
4010   "")
4012 (define_insn "*zero_extendqihi2_and"
4013   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4014      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4015    (clobber (reg:CC FLAGS_REG))]
4016   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4017   "#"
4018   [(set_attr "type" "alu1")
4019    (set_attr "mode" "HI")])
4021 (define_insn "*zero_extendqihi2_movzbw_and"
4022   [(set (match_operand:HI 0 "register_operand" "=r,r")
4023      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4024    (clobber (reg:CC FLAGS_REG))]
4025   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4026   "#"
4027   [(set_attr "type" "imovx,alu1")
4028    (set_attr "mode" "HI")])
4030 ; zero extend to SImode here to avoid partial register stalls
4031 (define_insn "*zero_extendqihi2_movzbl"
4032   [(set (match_operand:HI 0 "register_operand" "=r")
4033      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4034   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4035    && reload_completed"
4036   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4037   [(set_attr "type" "imovx")
4038    (set_attr "mode" "SI")])
4040 ;; For the movzbw case strip only the clobber
4041 (define_split
4042   [(set (match_operand:HI 0 "register_operand" "")
4043         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4044    (clobber (reg:CC FLAGS_REG))]
4045   "reload_completed
4046    && (!TARGET_ZERO_EXTEND_WITH_AND
4047        || optimize_function_for_size_p (cfun))
4048    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4049   [(set (match_operand:HI 0 "register_operand" "")
4050         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
4052 ;; When source and destination does not overlap, clear destination
4053 ;; first and then do the movb
4054 (define_split
4055   [(set (match_operand:HI 0 "register_operand" "")
4056         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4057    (clobber (reg:CC FLAGS_REG))]
4058   "reload_completed
4059    && ANY_QI_REG_P (operands[0])
4060    && (TARGET_ZERO_EXTEND_WITH_AND
4061        && optimize_function_for_speed_p (cfun))
4062    && !reg_overlap_mentioned_p (operands[0], operands[1])"
4063   [(set (match_dup 0) (const_int 0))
4064    (set (strict_low_part (match_dup 2)) (match_dup 1))]
4065   "operands[2] = gen_lowpart (QImode, operands[0]);")
4067 ;; Rest is handled by single and.
4068 (define_split
4069   [(set (match_operand:HI 0 "register_operand" "")
4070         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
4071    (clobber (reg:CC FLAGS_REG))]
4072   "reload_completed
4073    && true_regnum (operands[0]) == true_regnum (operands[1])"
4074   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
4075               (clobber (reg:CC FLAGS_REG))])]
4076   "")
4078 (define_expand "zero_extendqisi2"
4079   [(parallel
4080     [(set (match_operand:SI 0 "register_operand" "")
4081        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4082      (clobber (reg:CC FLAGS_REG))])]
4083   ""
4084   "")
4086 (define_insn "*zero_extendqisi2_and"
4087   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
4088      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4089    (clobber (reg:CC FLAGS_REG))]
4090   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4091   "#"
4092   [(set_attr "type" "alu1")
4093    (set_attr "mode" "SI")])
4095 (define_insn "*zero_extendqisi2_movzbw_and"
4096   [(set (match_operand:SI 0 "register_operand" "=r,r")
4097      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4098    (clobber (reg:CC FLAGS_REG))]
4099   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4100   "#"
4101   [(set_attr "type" "imovx,alu1")
4102    (set_attr "mode" "SI")])
4104 (define_insn "*zero_extendqisi2_movzbw"
4105   [(set (match_operand:SI 0 "register_operand" "=r")
4106      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4107   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4108    && reload_completed"
4109   "movz{bl|x}\t{%1, %0|%0, %1}"
4110   [(set_attr "type" "imovx")
4111    (set_attr "mode" "SI")])
4113 ;; For the movzbl case strip only the clobber
4114 (define_split
4115   [(set (match_operand:SI 0 "register_operand" "")
4116         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4117    (clobber (reg:CC FLAGS_REG))]
4118   "reload_completed
4119    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4120    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4121   [(set (match_dup 0)
4122         (zero_extend:SI (match_dup 1)))])
4124 ;; When source and destination does not overlap, clear destination
4125 ;; first and then do the movb
4126 (define_split
4127   [(set (match_operand:SI 0 "register_operand" "")
4128         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4129    (clobber (reg:CC FLAGS_REG))]
4130   "reload_completed
4131    && ANY_QI_REG_P (operands[0])
4132    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4133    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4134    && !reg_overlap_mentioned_p (operands[0], operands[1])"
4135   [(set (match_dup 0) (const_int 0))
4136    (set (strict_low_part (match_dup 2)) (match_dup 1))]
4137   "operands[2] = gen_lowpart (QImode, operands[0]);")
4139 ;; Rest is handled by single and.
4140 (define_split
4141   [(set (match_operand:SI 0 "register_operand" "")
4142         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4143    (clobber (reg:CC FLAGS_REG))]
4144   "reload_completed
4145    && true_regnum (operands[0]) == true_regnum (operands[1])"
4146   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4147               (clobber (reg:CC FLAGS_REG))])]
4148   "")
4150 ;; %%% Kill me once multi-word ops are sane.
4151 (define_expand "zero_extendsidi2"
4152   [(set (match_operand:DI 0 "register_operand" "")
4153      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4154   ""
4156   if (!TARGET_64BIT)
4157     {
4158       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4159       DONE;
4160     }
4163 (define_insn "zero_extendsidi2_32"
4164   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4165         (zero_extend:DI
4166          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
4167    (clobber (reg:CC FLAGS_REG))]
4168   "!TARGET_64BIT"
4169   "@
4170    #
4171    #
4172    #
4173    movd\t{%1, %0|%0, %1}
4174    movd\t{%1, %0|%0, %1}
4175    %vmovd\t{%1, %0|%0, %1}
4176    %vmovd\t{%1, %0|%0, %1}"
4177   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4178    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4179    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4181 (define_insn "zero_extendsidi2_rex64"
4182   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4183      (zero_extend:DI
4184        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4185   "TARGET_64BIT"
4186   "@
4187    mov\t{%k1, %k0|%k0, %k1}
4188    #
4189    movd\t{%1, %0|%0, %1}
4190    movd\t{%1, %0|%0, %1}
4191    %vmovd\t{%1, %0|%0, %1}
4192    %vmovd\t{%1, %0|%0, %1}"
4193   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4194    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4195    (set_attr "prefix_0f" "0,*,*,*,*,*")
4196    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4198 (define_split
4199   [(set (match_operand:DI 0 "memory_operand" "")
4200      (zero_extend:DI (match_dup 0)))]
4201   "TARGET_64BIT"
4202   [(set (match_dup 4) (const_int 0))]
4203   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4205 (define_split
4206   [(set (match_operand:DI 0 "register_operand" "")
4207         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4208    (clobber (reg:CC FLAGS_REG))]
4209   "!TARGET_64BIT && reload_completed
4210    && true_regnum (operands[0]) == true_regnum (operands[1])"
4211   [(set (match_dup 4) (const_int 0))]
4212   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4214 (define_split
4215   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4216         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4217    (clobber (reg:CC FLAGS_REG))]
4218   "!TARGET_64BIT && reload_completed
4219    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4220   [(set (match_dup 3) (match_dup 1))
4221    (set (match_dup 4) (const_int 0))]
4222   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4224 (define_insn "zero_extendhidi2"
4225   [(set (match_operand:DI 0 "register_operand" "=r")
4226      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4227   "TARGET_64BIT"
4228   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4229   [(set_attr "type" "imovx")
4230    (set_attr "mode" "SI")])
4232 (define_insn "zero_extendqidi2"
4233   [(set (match_operand:DI 0 "register_operand" "=r")
4234      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4235   "TARGET_64BIT"
4236   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4237   [(set_attr "type" "imovx")
4238    (set_attr "mode" "SI")])
4240 ;; Sign extension instructions
4242 (define_expand "extendsidi2"
4243   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4244                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4245               (clobber (reg:CC FLAGS_REG))
4246               (clobber (match_scratch:SI 2 ""))])]
4247   ""
4249   if (TARGET_64BIT)
4250     {
4251       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4252       DONE;
4253     }
4256 (define_insn "*extendsidi2_1"
4257   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4258         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4259    (clobber (reg:CC FLAGS_REG))
4260    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4261   "!TARGET_64BIT"
4262   "#")
4264 (define_insn "extendsidi2_rex64"
4265   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4266         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4267   "TARGET_64BIT"
4268   "@
4269    {cltq|cdqe}
4270    movs{lq|x}\t{%1, %0|%0, %1}"
4271   [(set_attr "type" "imovx")
4272    (set_attr "mode" "DI")
4273    (set_attr "prefix_0f" "0")
4274    (set_attr "modrm" "0,1")])
4276 (define_insn "extendhidi2"
4277   [(set (match_operand:DI 0 "register_operand" "=r")
4278         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4279   "TARGET_64BIT"
4280   "movs{wq|x}\t{%1, %0|%0, %1}"
4281   [(set_attr "type" "imovx")
4282    (set_attr "mode" "DI")])
4284 (define_insn "extendqidi2"
4285   [(set (match_operand:DI 0 "register_operand" "=r")
4286         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4287   "TARGET_64BIT"
4288   "movs{bq|x}\t{%1, %0|%0, %1}"
4289    [(set_attr "type" "imovx")
4290     (set_attr "mode" "DI")])
4292 ;; Extend to memory case when source register does die.
4293 (define_split
4294   [(set (match_operand:DI 0 "memory_operand" "")
4295         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4296    (clobber (reg:CC FLAGS_REG))
4297    (clobber (match_operand:SI 2 "register_operand" ""))]
4298   "(reload_completed
4299     && dead_or_set_p (insn, operands[1])
4300     && !reg_mentioned_p (operands[1], operands[0]))"
4301   [(set (match_dup 3) (match_dup 1))
4302    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4303               (clobber (reg:CC FLAGS_REG))])
4304    (set (match_dup 4) (match_dup 1))]
4305   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4307 ;; Extend to memory case when source register does not die.
4308 (define_split
4309   [(set (match_operand:DI 0 "memory_operand" "")
4310         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4311    (clobber (reg:CC FLAGS_REG))
4312    (clobber (match_operand:SI 2 "register_operand" ""))]
4313   "reload_completed"
4314   [(const_int 0)]
4316   split_di (&operands[0], 1, &operands[3], &operands[4]);
4318   emit_move_insn (operands[3], operands[1]);
4320   /* Generate a cltd if possible and doing so it profitable.  */
4321   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4322       && true_regnum (operands[1]) == AX_REG
4323       && true_regnum (operands[2]) == DX_REG)
4324     {
4325       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4326     }
4327   else
4328     {
4329       emit_move_insn (operands[2], operands[1]);
4330       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4331     }
4332   emit_move_insn (operands[4], operands[2]);
4333   DONE;
4336 ;; Extend to register case.  Optimize case where source and destination
4337 ;; registers match and cases where we can use cltd.
4338 (define_split
4339   [(set (match_operand:DI 0 "register_operand" "")
4340         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4341    (clobber (reg:CC FLAGS_REG))
4342    (clobber (match_scratch:SI 2 ""))]
4343   "reload_completed"
4344   [(const_int 0)]
4346   split_di (&operands[0], 1, &operands[3], &operands[4]);
4348   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4349     emit_move_insn (operands[3], operands[1]);
4351   /* Generate a cltd if possible and doing so it profitable.  */
4352   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4353       && true_regnum (operands[3]) == AX_REG)
4354     {
4355       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4356       DONE;
4357     }
4359   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4360     emit_move_insn (operands[4], operands[1]);
4362   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4363   DONE;
4366 (define_insn "extendhisi2"
4367   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4368         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4369   ""
4371   switch (get_attr_prefix_0f (insn))
4372     {
4373     case 0:
4374       return "{cwtl|cwde}";
4375     default:
4376       return "movs{wl|x}\t{%1, %0|%0, %1}";
4377     }
4379   [(set_attr "type" "imovx")
4380    (set_attr "mode" "SI")
4381    (set (attr "prefix_0f")
4382      ;; movsx is short decodable while cwtl is vector decoded.
4383      (if_then_else (and (eq_attr "cpu" "!k6")
4384                         (eq_attr "alternative" "0"))
4385         (const_string "0")
4386         (const_string "1")))
4387    (set (attr "modrm")
4388      (if_then_else (eq_attr "prefix_0f" "0")
4389         (const_string "0")
4390         (const_string "1")))])
4392 (define_insn "*extendhisi2_zext"
4393   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4394         (zero_extend:DI
4395           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4396   "TARGET_64BIT"
4398   switch (get_attr_prefix_0f (insn))
4399     {
4400     case 0:
4401       return "{cwtl|cwde}";
4402     default:
4403       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4404     }
4406   [(set_attr "type" "imovx")
4407    (set_attr "mode" "SI")
4408    (set (attr "prefix_0f")
4409      ;; movsx is short decodable while cwtl is vector decoded.
4410      (if_then_else (and (eq_attr "cpu" "!k6")
4411                         (eq_attr "alternative" "0"))
4412         (const_string "0")
4413         (const_string "1")))
4414    (set (attr "modrm")
4415      (if_then_else (eq_attr "prefix_0f" "0")
4416         (const_string "0")
4417         (const_string "1")))])
4419 (define_insn "extendqihi2"
4420   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4421         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4422   ""
4424   switch (get_attr_prefix_0f (insn))
4425     {
4426     case 0:
4427       return "{cbtw|cbw}";
4428     default:
4429       return "movs{bw|x}\t{%1, %0|%0, %1}";
4430     }
4432   [(set_attr "type" "imovx")
4433    (set_attr "mode" "HI")
4434    (set (attr "prefix_0f")
4435      ;; movsx is short decodable while cwtl is vector decoded.
4436      (if_then_else (and (eq_attr "cpu" "!k6")
4437                         (eq_attr "alternative" "0"))
4438         (const_string "0")
4439         (const_string "1")))
4440    (set (attr "modrm")
4441      (if_then_else (eq_attr "prefix_0f" "0")
4442         (const_string "0")
4443         (const_string "1")))])
4445 (define_insn "extendqisi2"
4446   [(set (match_operand:SI 0 "register_operand" "=r")
4447         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4448   ""
4449   "movs{bl|x}\t{%1, %0|%0, %1}"
4450    [(set_attr "type" "imovx")
4451     (set_attr "mode" "SI")])
4453 (define_insn "*extendqisi2_zext"
4454   [(set (match_operand:DI 0 "register_operand" "=r")
4455         (zero_extend:DI
4456           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4457   "TARGET_64BIT"
4458   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4459    [(set_attr "type" "imovx")
4460     (set_attr "mode" "SI")])
4462 ;; Conversions between float and double.
4464 ;; These are all no-ops in the model used for the 80387.  So just
4465 ;; emit moves.
4467 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4468 (define_insn "*dummy_extendsfdf2"
4469   [(set (match_operand:DF 0 "push_operand" "=<")
4470         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4471   "0"
4472   "#")
4474 (define_split
4475   [(set (match_operand:DF 0 "push_operand" "")
4476         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4477   ""
4478   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4479    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4481 (define_insn "*dummy_extendsfxf2"
4482   [(set (match_operand:XF 0 "push_operand" "=<")
4483         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4484   "0"
4485   "#")
4487 (define_split
4488   [(set (match_operand:XF 0 "push_operand" "")
4489         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4490   ""
4491   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4492    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4493   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4495 (define_split
4496   [(set (match_operand:XF 0 "push_operand" "")
4497         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4498   ""
4499   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4500    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4501   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4503 (define_expand "extendsfdf2"
4504   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4505         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4506   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4508   /* ??? Needed for compress_float_constant since all fp constants
4509      are LEGITIMATE_CONSTANT_P.  */
4510   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4511     {
4512       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4513           && standard_80387_constant_p (operands[1]) > 0)
4514         {
4515           operands[1] = simplify_const_unary_operation
4516             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4517           emit_move_insn_1 (operands[0], operands[1]);
4518           DONE;
4519         }
4520       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4521     }
4524 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4525    cvtss2sd:
4526       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4527       cvtps2pd xmm2,xmm1
4528    We do the conversion post reload to avoid producing of 128bit spills
4529    that might lead to ICE on 32bit target.  The sequence unlikely combine
4530    anyway.  */
4531 (define_split
4532   [(set (match_operand:DF 0 "register_operand" "")
4533         (float_extend:DF
4534           (match_operand:SF 1 "nonimmediate_operand" "")))]
4535   "TARGET_USE_VECTOR_FP_CONVERTS
4536    && optimize_insn_for_speed_p ()
4537    && reload_completed && SSE_REG_P (operands[0])"
4538    [(set (match_dup 2)
4539          (float_extend:V2DF
4540            (vec_select:V2SF
4541              (match_dup 3)
4542              (parallel [(const_int 0) (const_int 1)]))))]
4544   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4545   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4546   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4547      Try to avoid move when unpacking can be done in source.  */
4548   if (REG_P (operands[1]))
4549     {
4550       /* If it is unsafe to overwrite upper half of source, we need
4551          to move to destination and unpack there.  */
4552       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4553            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4554           && true_regnum (operands[0]) != true_regnum (operands[1]))
4555         {
4556           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4557           emit_move_insn (tmp, operands[1]);
4558         }
4559       else
4560         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4561       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4562     }
4563   else
4564     emit_insn (gen_vec_setv4sf_0 (operands[3],
4565                                   CONST0_RTX (V4SFmode), operands[1]));
4568 (define_insn "*extendsfdf2_mixed"
4569   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4570         (float_extend:DF
4571           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4572   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4574   switch (which_alternative)
4575     {
4576     case 0:
4577     case 1:
4578       return output_387_reg_move (insn, operands);
4580     case 2:
4581       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4583     default:
4584       gcc_unreachable ();
4585     }
4587   [(set_attr "type" "fmov,fmov,ssecvt")
4588    (set_attr "prefix" "orig,orig,maybe_vex")
4589    (set_attr "mode" "SF,XF,DF")])
4591 (define_insn "*extendsfdf2_sse"
4592   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4593         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4594   "TARGET_SSE2 && TARGET_SSE_MATH"
4595   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4596   [(set_attr "type" "ssecvt")
4597    (set_attr "prefix" "maybe_vex")
4598    (set_attr "mode" "DF")])
4600 (define_insn "*extendsfdf2_i387"
4601   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4602         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4603   "TARGET_80387"
4604   "* return output_387_reg_move (insn, operands);"
4605   [(set_attr "type" "fmov")
4606    (set_attr "mode" "SF,XF")])
4608 (define_expand "extend<mode>xf2"
4609   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4610         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4611   "TARGET_80387"
4613   /* ??? Needed for compress_float_constant since all fp constants
4614      are LEGITIMATE_CONSTANT_P.  */
4615   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4616     {
4617       if (standard_80387_constant_p (operands[1]) > 0)
4618         {
4619           operands[1] = simplify_const_unary_operation
4620             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4621           emit_move_insn_1 (operands[0], operands[1]);
4622           DONE;
4623         }
4624       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4625     }
4628 (define_insn "*extend<mode>xf2_i387"
4629   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4630         (float_extend:XF
4631           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4632   "TARGET_80387"
4633   "* return output_387_reg_move (insn, operands);"
4634   [(set_attr "type" "fmov")
4635    (set_attr "mode" "<MODE>,XF")])
4637 ;; %%% This seems bad bad news.
4638 ;; This cannot output into an f-reg because there is no way to be sure
4639 ;; of truncating in that case.  Otherwise this is just like a simple move
4640 ;; insn.  So we pretend we can output to a reg in order to get better
4641 ;; register preferencing, but we really use a stack slot.
4643 ;; Conversion from DFmode to SFmode.
4645 (define_expand "truncdfsf2"
4646   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4647         (float_truncate:SF
4648           (match_operand:DF 1 "nonimmediate_operand" "")))]
4649   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4651   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4652     ;
4653   else if (flag_unsafe_math_optimizations)
4654     ;
4655   else
4656     {
4657       enum ix86_stack_slot slot = (virtuals_instantiated
4658                                    ? SLOT_TEMP
4659                                    : SLOT_VIRTUAL);
4660       rtx temp = assign_386_stack_local (SFmode, slot);
4661       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4662       DONE;
4663     }
4666 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4667    cvtsd2ss:
4668       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4669       cvtpd2ps xmm2,xmm1
4670    We do the conversion post reload to avoid producing of 128bit spills
4671    that might lead to ICE on 32bit target.  The sequence unlikely combine
4672    anyway.  */
4673 (define_split
4674   [(set (match_operand:SF 0 "register_operand" "")
4675         (float_truncate:SF
4676           (match_operand:DF 1 "nonimmediate_operand" "")))]
4677   "TARGET_USE_VECTOR_FP_CONVERTS
4678    && optimize_insn_for_speed_p ()
4679    && reload_completed && SSE_REG_P (operands[0])"
4680    [(set (match_dup 2)
4681          (vec_concat:V4SF
4682            (float_truncate:V2SF
4683              (match_dup 4))
4684            (match_dup 3)))]
4686   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4687   operands[3] = CONST0_RTX (V2SFmode);
4688   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4689   /* Use movsd for loading from memory, unpcklpd for registers.
4690      Try to avoid move when unpacking can be done in source, or SSE3
4691      movddup is available.  */
4692   if (REG_P (operands[1]))
4693     {
4694       if (!TARGET_SSE3
4695           && true_regnum (operands[0]) != true_regnum (operands[1])
4696           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4697               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4698         {
4699           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4700           emit_move_insn (tmp, operands[1]);
4701           operands[1] = tmp;
4702         }
4703       else if (!TARGET_SSE3)
4704         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4705       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4706     }
4707   else
4708     emit_insn (gen_sse2_loadlpd (operands[4],
4709                                  CONST0_RTX (V2DFmode), operands[1]));
4712 (define_expand "truncdfsf2_with_temp"
4713   [(parallel [(set (match_operand:SF 0 "" "")
4714                    (float_truncate:SF (match_operand:DF 1 "" "")))
4715               (clobber (match_operand:SF 2 "" ""))])]
4716   "")
4718 (define_insn "*truncdfsf_fast_mixed"
4719   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4720         (float_truncate:SF
4721           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4722   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4724   switch (which_alternative)
4725     {
4726     case 0:
4727       return output_387_reg_move (insn, operands);
4728     case 1:
4729       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4730     default:
4731       gcc_unreachable ();
4732     }
4734   [(set_attr "type" "fmov,ssecvt")
4735    (set_attr "prefix" "orig,maybe_vex")
4736    (set_attr "mode" "SF")])
4738 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4739 ;; because nothing we do here is unsafe.
4740 (define_insn "*truncdfsf_fast_sse"
4741   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4742         (float_truncate:SF
4743           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4744   "TARGET_SSE2 && TARGET_SSE_MATH"
4745   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4746   [(set_attr "type" "ssecvt")
4747    (set_attr "prefix" "maybe_vex")
4748    (set_attr "mode" "SF")])
4750 (define_insn "*truncdfsf_fast_i387"
4751   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4752         (float_truncate:SF
4753           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4754   "TARGET_80387 && flag_unsafe_math_optimizations"
4755   "* return output_387_reg_move (insn, operands);"
4756   [(set_attr "type" "fmov")
4757    (set_attr "mode" "SF")])
4759 (define_insn "*truncdfsf_mixed"
4760   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4761         (float_truncate:SF
4762           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4763    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4764   "TARGET_MIX_SSE_I387"
4766   switch (which_alternative)
4767     {
4768     case 0:
4769       return output_387_reg_move (insn, operands);
4770     case 1:
4771       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4773     default:
4774       return "#";
4775     }
4777   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4778    (set_attr "unit" "*,*,i387,i387,i387")
4779    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4780    (set_attr "mode" "SF")])
4782 (define_insn "*truncdfsf_i387"
4783   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4784         (float_truncate:SF
4785           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4786    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4787   "TARGET_80387"
4789   switch (which_alternative)
4790     {
4791     case 0:
4792       return output_387_reg_move (insn, operands);
4794     default:
4795       return "#";
4796     }
4798   [(set_attr "type" "fmov,multi,multi,multi")
4799    (set_attr "unit" "*,i387,i387,i387")
4800    (set_attr "mode" "SF")])
4802 (define_insn "*truncdfsf2_i387_1"
4803   [(set (match_operand:SF 0 "memory_operand" "=m")
4804         (float_truncate:SF
4805           (match_operand:DF 1 "register_operand" "f")))]
4806   "TARGET_80387
4807    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4808    && !TARGET_MIX_SSE_I387"
4809   "* return output_387_reg_move (insn, operands);"
4810   [(set_attr "type" "fmov")
4811    (set_attr "mode" "SF")])
4813 (define_split
4814   [(set (match_operand:SF 0 "register_operand" "")
4815         (float_truncate:SF
4816          (match_operand:DF 1 "fp_register_operand" "")))
4817    (clobber (match_operand 2 "" ""))]
4818   "reload_completed"
4819   [(set (match_dup 2) (match_dup 1))
4820    (set (match_dup 0) (match_dup 2))]
4822   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4825 ;; Conversion from XFmode to {SF,DF}mode
4827 (define_expand "truncxf<mode>2"
4828   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4829                    (float_truncate:MODEF
4830                      (match_operand:XF 1 "register_operand" "")))
4831               (clobber (match_dup 2))])]
4832   "TARGET_80387"
4834   if (flag_unsafe_math_optimizations)
4835     {
4836       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4837       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4838       if (reg != operands[0])
4839         emit_move_insn (operands[0], reg);
4840       DONE;
4841     }
4842   else
4843     {
4844      enum ix86_stack_slot slot = (virtuals_instantiated
4845                                   ? SLOT_TEMP
4846                                   : SLOT_VIRTUAL);
4847       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4848     }
4851 (define_insn "*truncxfsf2_mixed"
4852   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4853         (float_truncate:SF
4854           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4855    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4856   "TARGET_80387"
4858   gcc_assert (!which_alternative);
4859   return output_387_reg_move (insn, operands);
4861   [(set_attr "type" "fmov,multi,multi,multi")
4862    (set_attr "unit" "*,i387,i387,i387")
4863    (set_attr "mode" "SF")])
4865 (define_insn "*truncxfdf2_mixed"
4866   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4867         (float_truncate:DF
4868           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4869    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4870   "TARGET_80387"
4872   gcc_assert (!which_alternative);
4873   return output_387_reg_move (insn, operands);
4875   [(set_attr "type" "fmov,multi,multi,multi")
4876    (set_attr "unit" "*,i387,i387,i387")
4877    (set_attr "mode" "DF")])
4879 (define_insn "truncxf<mode>2_i387_noop"
4880   [(set (match_operand:MODEF 0 "register_operand" "=f")
4881         (float_truncate:MODEF
4882           (match_operand:XF 1 "register_operand" "f")))]
4883   "TARGET_80387 && flag_unsafe_math_optimizations"
4884   "* return output_387_reg_move (insn, operands);"
4885   [(set_attr "type" "fmov")
4886    (set_attr "mode" "<MODE>")])
4888 (define_insn "*truncxf<mode>2_i387"
4889   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4890         (float_truncate:MODEF
4891           (match_operand:XF 1 "register_operand" "f")))]
4892   "TARGET_80387"
4893   "* return output_387_reg_move (insn, operands);"
4894   [(set_attr "type" "fmov")
4895    (set_attr "mode" "<MODE>")])
4897 (define_split
4898   [(set (match_operand:MODEF 0 "register_operand" "")
4899         (float_truncate:MODEF
4900           (match_operand:XF 1 "register_operand" "")))
4901    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4902   "TARGET_80387 && reload_completed"
4903   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4904    (set (match_dup 0) (match_dup 2))]
4905   "")
4907 (define_split
4908   [(set (match_operand:MODEF 0 "memory_operand" "")
4909         (float_truncate:MODEF
4910           (match_operand:XF 1 "register_operand" "")))
4911    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4912   "TARGET_80387"
4913   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4914   "")
4916 ;; Signed conversion to DImode.
4918 (define_expand "fix_truncxfdi2"
4919   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4920                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4921               (clobber (reg:CC FLAGS_REG))])]
4922   "TARGET_80387"
4924   if (TARGET_FISTTP)
4925    {
4926      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4927      DONE;
4928    }
4931 (define_expand "fix_trunc<mode>di2"
4932   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4933                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4934               (clobber (reg:CC FLAGS_REG))])]
4935   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4937   if (TARGET_FISTTP
4938       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4939    {
4940      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4941      DONE;
4942    }
4943   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4944    {
4945      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4946      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4947      if (out != operands[0])
4948         emit_move_insn (operands[0], out);
4949      DONE;
4950    }
4953 ;; Signed conversion to SImode.
4955 (define_expand "fix_truncxfsi2"
4956   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4957                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4958               (clobber (reg:CC FLAGS_REG))])]
4959   "TARGET_80387"
4961   if (TARGET_FISTTP)
4962    {
4963      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4964      DONE;
4965    }
4968 (define_expand "fix_trunc<mode>si2"
4969   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4970                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4971               (clobber (reg:CC FLAGS_REG))])]
4972   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4974   if (TARGET_FISTTP
4975       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4976    {
4977      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4978      DONE;
4979    }
4980   if (SSE_FLOAT_MODE_P (<MODE>mode))
4981    {
4982      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4983      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4984      if (out != operands[0])
4985         emit_move_insn (operands[0], out);
4986      DONE;
4987    }
4990 ;; Signed conversion to HImode.
4992 (define_expand "fix_trunc<mode>hi2"
4993   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4994                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4995               (clobber (reg:CC FLAGS_REG))])]
4996   "TARGET_80387
4997    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4999   if (TARGET_FISTTP)
5000    {
5001      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
5002      DONE;
5003    }
5006 ;; Unsigned conversion to SImode.
5008 (define_expand "fixuns_trunc<mode>si2"
5009   [(parallel
5010     [(set (match_operand:SI 0 "register_operand" "")
5011           (unsigned_fix:SI
5012             (match_operand:MODEF 1 "nonimmediate_operand" "")))
5013      (use (match_dup 2))
5014      (clobber (match_scratch:<ssevecmode> 3 ""))
5015      (clobber (match_scratch:<ssevecmode> 4 ""))])]
5016   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
5018   enum machine_mode mode = <MODE>mode;
5019   enum machine_mode vecmode = <ssevecmode>mode;
5020   REAL_VALUE_TYPE TWO31r;
5021   rtx two31;
5023   if (optimize_insn_for_size_p ())
5024     FAIL;
5026   real_ldexp (&TWO31r, &dconst1, 31);
5027   two31 = const_double_from_real_value (TWO31r, mode);
5028   two31 = ix86_build_const_vector (mode, true, two31);
5029   operands[2] = force_reg (vecmode, two31);
5032 (define_insn_and_split "*fixuns_trunc<mode>_1"
5033   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5034         (unsigned_fix:SI
5035           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5036    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
5037    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5038    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5039   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5040    && optimize_function_for_speed_p (cfun)"
5041   "#"
5042   "&& reload_completed"
5043   [(const_int 0)]
5045   ix86_split_convert_uns_si_sse (operands);
5046   DONE;
5049 ;; Unsigned conversion to HImode.
5050 ;; Without these patterns, we'll try the unsigned SI conversion which
5051 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5053 (define_expand "fixuns_trunc<mode>hi2"
5054   [(set (match_dup 2)
5055         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
5056    (set (match_operand:HI 0 "nonimmediate_operand" "")
5057         (subreg:HI (match_dup 2) 0))]
5058   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5059   "operands[2] = gen_reg_rtx (SImode);")
5061 ;; When SSE is available, it is always faster to use it!
5062 (define_insn "fix_trunc<mode>di_sse"
5063   [(set (match_operand:DI 0 "register_operand" "=r,r")
5064         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5065   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
5066    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5067   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
5068   [(set_attr "type" "sseicvt")
5069    (set_attr "prefix" "maybe_vex")
5070    (set_attr "prefix_rex" "1")
5071    (set_attr "mode" "<MODE>")
5072    (set_attr "athlon_decode" "double,vector")
5073    (set_attr "amdfam10_decode" "double,double")])
5075 (define_insn "fix_trunc<mode>si_sse"
5076   [(set (match_operand:SI 0 "register_operand" "=r,r")
5077         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5078   "SSE_FLOAT_MODE_P (<MODE>mode)
5079    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5080   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
5081   [(set_attr "type" "sseicvt")
5082    (set_attr "prefix" "maybe_vex")
5083    (set_attr "mode" "<MODE>")
5084    (set_attr "athlon_decode" "double,vector")
5085    (set_attr "amdfam10_decode" "double,double")])
5087 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
5088 (define_peephole2
5089   [(set (match_operand:MODEF 0 "register_operand" "")
5090         (match_operand:MODEF 1 "memory_operand" ""))
5091    (set (match_operand:SSEMODEI24 2 "register_operand" "")
5092         (fix:SSEMODEI24 (match_dup 0)))]
5093   "TARGET_SHORTEN_X87_SSE
5094    && peep2_reg_dead_p (2, operands[0])"
5095   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
5096   "")
5098 ;; Avoid vector decoded forms of the instruction.
5099 (define_peephole2
5100   [(match_scratch:DF 2 "Y2")
5101    (set (match_operand:SSEMODEI24 0 "register_operand" "")
5102         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
5103   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5104   [(set (match_dup 2) (match_dup 1))
5105    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5106   "")
5108 (define_peephole2
5109   [(match_scratch:SF 2 "x")
5110    (set (match_operand:SSEMODEI24 0 "register_operand" "")
5111         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
5112   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5113   [(set (match_dup 2) (match_dup 1))
5114    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5115   "")
5117 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5118   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5119         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5120   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5121    && TARGET_FISTTP
5122    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5123          && (TARGET_64BIT || <MODE>mode != DImode))
5124         && TARGET_SSE_MATH)
5125    && can_create_pseudo_p ()"
5126   "#"
5127   "&& 1"
5128   [(const_int 0)]
5130   if (memory_operand (operands[0], VOIDmode))
5131     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5132   else
5133     {
5134       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5135       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5136                                                             operands[1],
5137                                                             operands[2]));
5138     }
5139   DONE;
5141   [(set_attr "type" "fisttp")
5142    (set_attr "mode" "<MODE>")])
5144 (define_insn "fix_trunc<mode>_i387_fisttp"
5145   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5146         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5147    (clobber (match_scratch:XF 2 "=&1f"))]
5148   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5149    && TARGET_FISTTP
5150    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5151          && (TARGET_64BIT || <MODE>mode != DImode))
5152         && TARGET_SSE_MATH)"
5153   "* return output_fix_trunc (insn, operands, 1);"
5154   [(set_attr "type" "fisttp")
5155    (set_attr "mode" "<MODE>")])
5157 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5158   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5159         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5160    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5161    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5162   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5163    && TARGET_FISTTP
5164    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5165         && (TARGET_64BIT || <MODE>mode != DImode))
5166         && TARGET_SSE_MATH)"
5167   "#"
5168   [(set_attr "type" "fisttp")
5169    (set_attr "mode" "<MODE>")])
5171 (define_split
5172   [(set (match_operand:X87MODEI 0 "register_operand" "")
5173         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5174    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5175    (clobber (match_scratch 3 ""))]
5176   "reload_completed"
5177   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5178               (clobber (match_dup 3))])
5179    (set (match_dup 0) (match_dup 2))]
5180   "")
5182 (define_split
5183   [(set (match_operand:X87MODEI 0 "memory_operand" "")
5184         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5185    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5186    (clobber (match_scratch 3 ""))]
5187   "reload_completed"
5188   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5189               (clobber (match_dup 3))])]
5190   "")
5192 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5193 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5194 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5195 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5196 ;; function in i386.c.
5197 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5198   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5199         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5200    (clobber (reg:CC FLAGS_REG))]
5201   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5202    && !TARGET_FISTTP
5203    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5204          && (TARGET_64BIT || <MODE>mode != DImode))
5205    && can_create_pseudo_p ()"
5206   "#"
5207   "&& 1"
5208   [(const_int 0)]
5210   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5212   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5213   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5214   if (memory_operand (operands[0], VOIDmode))
5215     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5216                                          operands[2], operands[3]));
5217   else
5218     {
5219       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5220       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5221                                                      operands[2], operands[3],
5222                                                      operands[4]));
5223     }
5224   DONE;
5226   [(set_attr "type" "fistp")
5227    (set_attr "i387_cw" "trunc")
5228    (set_attr "mode" "<MODE>")])
5230 (define_insn "fix_truncdi_i387"
5231   [(set (match_operand:DI 0 "memory_operand" "=m")
5232         (fix:DI (match_operand 1 "register_operand" "f")))
5233    (use (match_operand:HI 2 "memory_operand" "m"))
5234    (use (match_operand:HI 3 "memory_operand" "m"))
5235    (clobber (match_scratch:XF 4 "=&1f"))]
5236   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5237    && !TARGET_FISTTP
5238    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5239   "* return output_fix_trunc (insn, operands, 0);"
5240   [(set_attr "type" "fistp")
5241    (set_attr "i387_cw" "trunc")
5242    (set_attr "mode" "DI")])
5244 (define_insn "fix_truncdi_i387_with_temp"
5245   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5246         (fix:DI (match_operand 1 "register_operand" "f,f")))
5247    (use (match_operand:HI 2 "memory_operand" "m,m"))
5248    (use (match_operand:HI 3 "memory_operand" "m,m"))
5249    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5250    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5251   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5252    && !TARGET_FISTTP
5253    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5254   "#"
5255   [(set_attr "type" "fistp")
5256    (set_attr "i387_cw" "trunc")
5257    (set_attr "mode" "DI")])
5259 (define_split
5260   [(set (match_operand:DI 0 "register_operand" "")
5261         (fix:DI (match_operand 1 "register_operand" "")))
5262    (use (match_operand:HI 2 "memory_operand" ""))
5263    (use (match_operand:HI 3 "memory_operand" ""))
5264    (clobber (match_operand:DI 4 "memory_operand" ""))
5265    (clobber (match_scratch 5 ""))]
5266   "reload_completed"
5267   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5268               (use (match_dup 2))
5269               (use (match_dup 3))
5270               (clobber (match_dup 5))])
5271    (set (match_dup 0) (match_dup 4))]
5272   "")
5274 (define_split
5275   [(set (match_operand:DI 0 "memory_operand" "")
5276         (fix:DI (match_operand 1 "register_operand" "")))
5277    (use (match_operand:HI 2 "memory_operand" ""))
5278    (use (match_operand:HI 3 "memory_operand" ""))
5279    (clobber (match_operand:DI 4 "memory_operand" ""))
5280    (clobber (match_scratch 5 ""))]
5281   "reload_completed"
5282   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5283               (use (match_dup 2))
5284               (use (match_dup 3))
5285               (clobber (match_dup 5))])]
5286   "")
5288 (define_insn "fix_trunc<mode>_i387"
5289   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5290         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5291    (use (match_operand:HI 2 "memory_operand" "m"))
5292    (use (match_operand:HI 3 "memory_operand" "m"))]
5293   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5294    && !TARGET_FISTTP
5295    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5296   "* return output_fix_trunc (insn, operands, 0);"
5297   [(set_attr "type" "fistp")
5298    (set_attr "i387_cw" "trunc")
5299    (set_attr "mode" "<MODE>")])
5301 (define_insn "fix_trunc<mode>_i387_with_temp"
5302   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5303         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5304    (use (match_operand:HI 2 "memory_operand" "m,m"))
5305    (use (match_operand:HI 3 "memory_operand" "m,m"))
5306    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5307   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5308    && !TARGET_FISTTP
5309    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5310   "#"
5311   [(set_attr "type" "fistp")
5312    (set_attr "i387_cw" "trunc")
5313    (set_attr "mode" "<MODE>")])
5315 (define_split
5316   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5317         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5318    (use (match_operand:HI 2 "memory_operand" ""))
5319    (use (match_operand:HI 3 "memory_operand" ""))
5320    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5321   "reload_completed"
5322   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5323               (use (match_dup 2))
5324               (use (match_dup 3))])
5325    (set (match_dup 0) (match_dup 4))]
5326   "")
5328 (define_split
5329   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5330         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5331    (use (match_operand:HI 2 "memory_operand" ""))
5332    (use (match_operand:HI 3 "memory_operand" ""))
5333    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5334   "reload_completed"
5335   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5336               (use (match_dup 2))
5337               (use (match_dup 3))])]
5338   "")
5340 (define_insn "x86_fnstcw_1"
5341   [(set (match_operand:HI 0 "memory_operand" "=m")
5342         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5343   "TARGET_80387"
5344   "fnstcw\t%0"
5345   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5346    (set_attr "mode" "HI")
5347    (set_attr "unit" "i387")])
5349 (define_insn "x86_fldcw_1"
5350   [(set (reg:HI FPCR_REG)
5351         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5352   "TARGET_80387"
5353   "fldcw\t%0"
5354   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5355    (set_attr "mode" "HI")
5356    (set_attr "unit" "i387")
5357    (set_attr "athlon_decode" "vector")
5358    (set_attr "amdfam10_decode" "vector")])
5360 ;; Conversion between fixed point and floating point.
5362 ;; Even though we only accept memory inputs, the backend _really_
5363 ;; wants to be able to do this between registers.
5365 (define_expand "floathi<mode>2"
5366   [(set (match_operand:X87MODEF 0 "register_operand" "")
5367         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5368   "TARGET_80387
5369    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5370        || TARGET_MIX_SSE_I387)"
5371   "")
5373 ;; Pre-reload splitter to add memory clobber to the pattern.
5374 (define_insn_and_split "*floathi<mode>2_1"
5375   [(set (match_operand:X87MODEF 0 "register_operand" "")
5376         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5377   "TARGET_80387
5378    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5379        || TARGET_MIX_SSE_I387)
5380    && can_create_pseudo_p ()"
5381   "#"
5382   "&& 1"
5383   [(parallel [(set (match_dup 0)
5384               (float:X87MODEF (match_dup 1)))
5385    (clobber (match_dup 2))])]
5386   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5388 (define_insn "*floathi<mode>2_i387_with_temp"
5389   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5390         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5391   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5392   "TARGET_80387
5393    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5394        || TARGET_MIX_SSE_I387)"
5395   "#"
5396   [(set_attr "type" "fmov,multi")
5397    (set_attr "mode" "<MODE>")
5398    (set_attr "unit" "*,i387")
5399    (set_attr "fp_int_src" "true")])
5401 (define_insn "*floathi<mode>2_i387"
5402   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5403         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5404   "TARGET_80387
5405    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5406        || TARGET_MIX_SSE_I387)"
5407   "fild%Z1\t%1"
5408   [(set_attr "type" "fmov")
5409    (set_attr "mode" "<MODE>")
5410    (set_attr "fp_int_src" "true")])
5412 (define_split
5413   [(set (match_operand:X87MODEF 0 "register_operand" "")
5414         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5415    (clobber (match_operand:HI 2 "memory_operand" ""))]
5416   "TARGET_80387
5417    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5418        || TARGET_MIX_SSE_I387)
5419    && reload_completed"
5420   [(set (match_dup 2) (match_dup 1))
5421    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5422   "")
5424 (define_split
5425   [(set (match_operand:X87MODEF 0 "register_operand" "")
5426         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5427    (clobber (match_operand:HI 2 "memory_operand" ""))]
5428    "TARGET_80387
5429     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5430         || TARGET_MIX_SSE_I387)
5431     && reload_completed"
5432   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5433   "")
5435 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5436   [(set (match_operand:X87MODEF 0 "register_operand" "")
5437         (float:X87MODEF
5438           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5439   "TARGET_80387
5440    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5441        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5442   "
5444   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5445         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5446       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5447     {
5448       rtx reg = gen_reg_rtx (XFmode);
5449       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5450 /* Avoid references to nonexistent function in dead code in XFmode case.  */
5451 #define gen_truncxfxf2 gen_truncxfdf2
5452       emit_insn (gen_truncxf<X87MODEF:mode>2 (operands[0], reg));
5453 #undef gen_truncxfxf2
5454       DONE;
5455     }
5458 ;; Pre-reload splitter to add memory clobber to the pattern.
5459 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5460   [(set (match_operand:X87MODEF 0 "register_operand" "")
5461         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5462   "((TARGET_80387
5463      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5464      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5465            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5466          || TARGET_MIX_SSE_I387))
5467     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5468         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5469         && ((<SSEMODEI24:MODE>mode == SImode
5470              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5471              && optimize_function_for_speed_p (cfun)
5472              && flag_trapping_math)
5473             || !(TARGET_INTER_UNIT_CONVERSIONS
5474                  || optimize_function_for_size_p (cfun)))))
5475    && can_create_pseudo_p ()"
5476   "#"
5477   "&& 1"
5478   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5479               (clobber (match_dup 2))])]
5481   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5483   /* Avoid store forwarding (partial memory) stall penalty
5484      by passing DImode value through XMM registers.  */
5485   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5486       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5487       && optimize_function_for_speed_p (cfun))
5488     {
5489       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5490                                                             operands[1],
5491                                                             operands[2]));
5492       DONE;
5493     }
5496 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5497   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5498         (float:MODEF
5499           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5500    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5501   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5502    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5503   "#"
5504   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5505    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5506    (set_attr "unit" "*,i387,*,*,*")
5507    (set_attr "athlon_decode" "*,*,double,direct,double")
5508    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5509    (set_attr "fp_int_src" "true")])
5511 (define_insn "*floatsi<mode>2_vector_mixed"
5512   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5513         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5514   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5515    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5516   "@
5517    fild%Z1\t%1
5518    #"
5519   [(set_attr "type" "fmov,sseicvt")
5520    (set_attr "mode" "<MODE>,<ssevecmode>")
5521    (set_attr "unit" "i387,*")
5522    (set_attr "athlon_decode" "*,direct")
5523    (set_attr "amdfam10_decode" "*,double")
5524    (set_attr "fp_int_src" "true")])
5526 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5527   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5528         (float:MODEF
5529           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5530   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5531   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5532    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5533   "#"
5534   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5535    (set_attr "mode" "<MODEF:MODE>")
5536    (set_attr "unit" "*,i387,*,*")
5537    (set_attr "athlon_decode" "*,*,double,direct")
5538    (set_attr "amdfam10_decode" "*,*,vector,double")
5539    (set_attr "fp_int_src" "true")])
5541 (define_split
5542   [(set (match_operand:MODEF 0 "register_operand" "")
5543         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5544    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5545   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5546    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5547    && TARGET_INTER_UNIT_CONVERSIONS
5548    && reload_completed
5549    && (SSE_REG_P (operands[0])
5550        || (GET_CODE (operands[0]) == SUBREG
5551            && SSE_REG_P (operands[0])))"
5552   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5553   "")
5555 (define_split
5556   [(set (match_operand:MODEF 0 "register_operand" "")
5557         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5558    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5559   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5560    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5561    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5562    && reload_completed
5563    && (SSE_REG_P (operands[0])
5564        || (GET_CODE (operands[0]) == SUBREG
5565            && SSE_REG_P (operands[0])))"
5566   [(set (match_dup 2) (match_dup 1))
5567    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5568   "")
5570 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5571   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5572         (float:MODEF
5573           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5574   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5575    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5576    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5577   "@
5578    fild%Z1\t%1
5579    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5580    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5581   [(set_attr "type" "fmov,sseicvt,sseicvt")
5582    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5583    (set_attr "mode" "<MODEF:MODE>")
5584    (set (attr "prefix_rex")
5585      (if_then_else
5586        (and (eq_attr "prefix" "maybe_vex")
5587             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5588        (const_string "1")
5589        (const_string "*")))
5590    (set_attr "unit" "i387,*,*")
5591    (set_attr "athlon_decode" "*,double,direct")
5592    (set_attr "amdfam10_decode" "*,vector,double")
5593    (set_attr "fp_int_src" "true")])
5595 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5596   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5597         (float:MODEF
5598           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5599   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5600    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5601    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5602   "@
5603    fild%Z1\t%1
5604    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5605   [(set_attr "type" "fmov,sseicvt")
5606    (set_attr "prefix" "orig,maybe_vex")
5607    (set_attr "mode" "<MODEF:MODE>")
5608    (set (attr "prefix_rex")
5609      (if_then_else
5610        (and (eq_attr "prefix" "maybe_vex")
5611             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5612        (const_string "1")
5613        (const_string "*")))
5614    (set_attr "athlon_decode" "*,direct")
5615    (set_attr "amdfam10_decode" "*,double")
5616    (set_attr "fp_int_src" "true")])
5618 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5619   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5620         (float:MODEF
5621           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5622    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5623   "TARGET_SSE2 && TARGET_SSE_MATH
5624    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5625   "#"
5626   [(set_attr "type" "sseicvt")
5627    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5628    (set_attr "athlon_decode" "double,direct,double")
5629    (set_attr "amdfam10_decode" "vector,double,double")
5630    (set_attr "fp_int_src" "true")])
5632 (define_insn "*floatsi<mode>2_vector_sse"
5633   [(set (match_operand:MODEF 0 "register_operand" "=x")
5634         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5635   "TARGET_SSE2 && TARGET_SSE_MATH
5636    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5637   "#"
5638   [(set_attr "type" "sseicvt")
5639    (set_attr "mode" "<MODE>")
5640    (set_attr "athlon_decode" "direct")
5641    (set_attr "amdfam10_decode" "double")
5642    (set_attr "fp_int_src" "true")])
5644 (define_split
5645   [(set (match_operand:MODEF 0 "register_operand" "")
5646         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5647    (clobber (match_operand:SI 2 "memory_operand" ""))]
5648   "TARGET_SSE2 && TARGET_SSE_MATH
5649    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5650    && reload_completed
5651    && (SSE_REG_P (operands[0])
5652        || (GET_CODE (operands[0]) == SUBREG
5653            && SSE_REG_P (operands[0])))"
5654   [(const_int 0)]
5656   rtx op1 = operands[1];
5658   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5659                                      <MODE>mode, 0);
5660   if (GET_CODE (op1) == SUBREG)
5661     op1 = SUBREG_REG (op1);
5663   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5664     {
5665       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5666       emit_insn (gen_sse2_loadld (operands[4],
5667                                   CONST0_RTX (V4SImode), operands[1]));
5668     }
5669   /* We can ignore possible trapping value in the
5670      high part of SSE register for non-trapping math. */
5671   else if (SSE_REG_P (op1) && !flag_trapping_math)
5672     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5673   else
5674     {
5675       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5676       emit_move_insn (operands[2], operands[1]);
5677       emit_insn (gen_sse2_loadld (operands[4],
5678                                   CONST0_RTX (V4SImode), operands[2]));
5679     }
5680   emit_insn
5681     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5682   DONE;
5685 (define_split
5686   [(set (match_operand:MODEF 0 "register_operand" "")
5687         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5688    (clobber (match_operand:SI 2 "memory_operand" ""))]
5689   "TARGET_SSE2 && TARGET_SSE_MATH
5690    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5691    && reload_completed
5692    && (SSE_REG_P (operands[0])
5693        || (GET_CODE (operands[0]) == SUBREG
5694            && SSE_REG_P (operands[0])))"
5695   [(const_int 0)]
5697   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5698                                      <MODE>mode, 0);
5699   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5701   emit_insn (gen_sse2_loadld (operands[4],
5702                               CONST0_RTX (V4SImode), operands[1]));
5703   emit_insn
5704     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5705   DONE;
5708 (define_split
5709   [(set (match_operand:MODEF 0 "register_operand" "")
5710         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5711   "TARGET_SSE2 && TARGET_SSE_MATH
5712    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5713    && reload_completed
5714    && (SSE_REG_P (operands[0])
5715        || (GET_CODE (operands[0]) == SUBREG
5716            && SSE_REG_P (operands[0])))"
5717   [(const_int 0)]
5719   rtx op1 = operands[1];
5721   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5722                                      <MODE>mode, 0);
5723   if (GET_CODE (op1) == SUBREG)
5724     op1 = SUBREG_REG (op1);
5726   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5727     {
5728       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5729       emit_insn (gen_sse2_loadld (operands[4],
5730                                   CONST0_RTX (V4SImode), operands[1]));
5731     }
5732   /* We can ignore possible trapping value in the
5733      high part of SSE register for non-trapping math. */
5734   else if (SSE_REG_P (op1) && !flag_trapping_math)
5735     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5736   else
5737     gcc_unreachable ();
5738   emit_insn
5739     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5740   DONE;
5743 (define_split
5744   [(set (match_operand:MODEF 0 "register_operand" "")
5745         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5746   "TARGET_SSE2 && TARGET_SSE_MATH
5747    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5748    && reload_completed
5749    && (SSE_REG_P (operands[0])
5750        || (GET_CODE (operands[0]) == SUBREG
5751            && SSE_REG_P (operands[0])))"
5752   [(const_int 0)]
5754   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5755                                      <MODE>mode, 0);
5756   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5758   emit_insn (gen_sse2_loadld (operands[4],
5759                               CONST0_RTX (V4SImode), operands[1]));
5760   emit_insn
5761     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5762   DONE;
5765 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5766   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5767         (float:MODEF
5768           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5769   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5770   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5771    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5772   "#"
5773   [(set_attr "type" "sseicvt")
5774    (set_attr "mode" "<MODEF:MODE>")
5775    (set_attr "athlon_decode" "double,direct")
5776    (set_attr "amdfam10_decode" "vector,double")
5777    (set_attr "fp_int_src" "true")])
5779 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5780   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5781         (float:MODEF
5782           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5783   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5784    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5785    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5786   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5787   [(set_attr "type" "sseicvt")
5788    (set_attr "prefix" "maybe_vex")
5789    (set_attr "mode" "<MODEF:MODE>")
5790    (set (attr "prefix_rex")
5791      (if_then_else
5792        (and (eq_attr "prefix" "maybe_vex")
5793             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5794        (const_string "1")
5795        (const_string "*")))
5796    (set_attr "athlon_decode" "double,direct")
5797    (set_attr "amdfam10_decode" "vector,double")
5798    (set_attr "fp_int_src" "true")])
5800 (define_split
5801   [(set (match_operand:MODEF 0 "register_operand" "")
5802         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5803    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5804   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5805    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5806    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5807    && reload_completed
5808    && (SSE_REG_P (operands[0])
5809        || (GET_CODE (operands[0]) == SUBREG
5810            && SSE_REG_P (operands[0])))"
5811   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5812   "")
5814 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5815   [(set (match_operand:MODEF 0 "register_operand" "=x")
5816         (float:MODEF
5817           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5818   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5819    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5820    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5821   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5822   [(set_attr "type" "sseicvt")
5823    (set_attr "prefix" "maybe_vex")
5824    (set_attr "mode" "<MODEF:MODE>")
5825    (set (attr "prefix_rex")
5826      (if_then_else
5827        (and (eq_attr "prefix" "maybe_vex")
5828             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5829        (const_string "1")
5830        (const_string "*")))
5831    (set_attr "athlon_decode" "direct")
5832    (set_attr "amdfam10_decode" "double")
5833    (set_attr "fp_int_src" "true")])
5835 (define_split
5836   [(set (match_operand:MODEF 0 "register_operand" "")
5837         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5838    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5839   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5840    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5841    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5842    && reload_completed
5843    && (SSE_REG_P (operands[0])
5844        || (GET_CODE (operands[0]) == SUBREG
5845            && SSE_REG_P (operands[0])))"
5846   [(set (match_dup 2) (match_dup 1))
5847    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5848   "")
5850 (define_split
5851   [(set (match_operand:MODEF 0 "register_operand" "")
5852         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5853    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5854   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5855    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5856    && reload_completed
5857    && (SSE_REG_P (operands[0])
5858        || (GET_CODE (operands[0]) == SUBREG
5859            && SSE_REG_P (operands[0])))"
5860   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5861   "")
5863 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5864   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5865         (float:X87MODEF
5866           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5867   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5868   "TARGET_80387
5869    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5870   "@
5871    fild%Z1\t%1
5872    #"
5873   [(set_attr "type" "fmov,multi")
5874    (set_attr "mode" "<X87MODEF:MODE>")
5875    (set_attr "unit" "*,i387")
5876    (set_attr "fp_int_src" "true")])
5878 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5879   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5880         (float:X87MODEF
5881           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5882   "TARGET_80387
5883    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5884   "fild%Z1\t%1"
5885   [(set_attr "type" "fmov")
5886    (set_attr "mode" "<X87MODEF:MODE>")
5887    (set_attr "fp_int_src" "true")])
5889 (define_split
5890   [(set (match_operand:X87MODEF 0 "register_operand" "")
5891         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5892    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5893   "TARGET_80387
5894    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5895    && reload_completed
5896    && FP_REG_P (operands[0])"
5897   [(set (match_dup 2) (match_dup 1))
5898    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5899   "")
5901 (define_split
5902   [(set (match_operand:X87MODEF 0 "register_operand" "")
5903         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5904    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5905   "TARGET_80387
5906    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5907    && reload_completed
5908    && FP_REG_P (operands[0])"
5909   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5910   "")
5912 ;; Avoid store forwarding (partial memory) stall penalty
5913 ;; by passing DImode value through XMM registers.  */
5915 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5916   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5917         (float:X87MODEF
5918           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5919    (clobber (match_scratch:V4SI 3 "=X,x"))
5920    (clobber (match_scratch:V4SI 4 "=X,x"))
5921    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5922   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5923    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5924    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5925   "#"
5926   [(set_attr "type" "multi")
5927    (set_attr "mode" "<X87MODEF:MODE>")
5928    (set_attr "unit" "i387")
5929    (set_attr "fp_int_src" "true")])
5931 (define_split
5932   [(set (match_operand:X87MODEF 0 "register_operand" "")
5933         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5934    (clobber (match_scratch:V4SI 3 ""))
5935    (clobber (match_scratch:V4SI 4 ""))
5936    (clobber (match_operand:DI 2 "memory_operand" ""))]
5937   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5938    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5939    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5940    && reload_completed
5941    && FP_REG_P (operands[0])"
5942   [(set (match_dup 2) (match_dup 3))
5943    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5945   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5946      Assemble the 64-bit DImode value in an xmm register.  */
5947   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5948                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5949   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5950                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5951   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5953   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5956 (define_split
5957   [(set (match_operand:X87MODEF 0 "register_operand" "")
5958         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5959    (clobber (match_scratch:V4SI 3 ""))
5960    (clobber (match_scratch:V4SI 4 ""))
5961    (clobber (match_operand:DI 2 "memory_operand" ""))]
5962   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5963    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5964    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5965    && reload_completed
5966    && FP_REG_P (operands[0])"
5967   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5968   "")
5970 ;; Avoid store forwarding (partial memory) stall penalty by extending
5971 ;; SImode value to DImode through XMM register instead of pushing two
5972 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5973 ;; targets benefit from this optimization. Also note that fild
5974 ;; loads from memory only.
5976 (define_insn "*floatunssi<mode>2_1"
5977   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5978         (unsigned_float:X87MODEF
5979           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5980    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5981    (clobber (match_scratch:SI 3 "=X,x"))]
5982   "!TARGET_64BIT
5983    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5984    && TARGET_SSE"
5985   "#"
5986   [(set_attr "type" "multi")
5987    (set_attr "mode" "<MODE>")])
5989 (define_split
5990   [(set (match_operand:X87MODEF 0 "register_operand" "")
5991         (unsigned_float:X87MODEF
5992           (match_operand:SI 1 "register_operand" "")))
5993    (clobber (match_operand:DI 2 "memory_operand" ""))
5994    (clobber (match_scratch:SI 3 ""))]
5995   "!TARGET_64BIT
5996    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5997    && TARGET_SSE
5998    && reload_completed"
5999   [(set (match_dup 2) (match_dup 1))
6000    (set (match_dup 0)
6001         (float:X87MODEF (match_dup 2)))]
6002   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
6004 (define_split
6005   [(set (match_operand:X87MODEF 0 "register_operand" "")
6006         (unsigned_float:X87MODEF
6007           (match_operand:SI 1 "memory_operand" "")))
6008    (clobber (match_operand:DI 2 "memory_operand" ""))
6009    (clobber (match_scratch:SI 3 ""))]
6010   "!TARGET_64BIT
6011    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6012    && TARGET_SSE
6013    && reload_completed"
6014   [(set (match_dup 2) (match_dup 3))
6015    (set (match_dup 0)
6016         (float:X87MODEF (match_dup 2)))]
6018   emit_move_insn (operands[3], operands[1]);
6019   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
6022 (define_expand "floatunssi<mode>2"
6023   [(parallel
6024      [(set (match_operand:X87MODEF 0 "register_operand" "")
6025            (unsigned_float:X87MODEF
6026              (match_operand:SI 1 "nonimmediate_operand" "")))
6027       (clobber (match_dup 2))
6028       (clobber (match_scratch:SI 3 ""))])]
6029   "!TARGET_64BIT
6030    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6031         && TARGET_SSE)
6032        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
6034   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
6035     {
6036       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6037       DONE;
6038     }
6039   else
6040     {
6041       enum ix86_stack_slot slot = (virtuals_instantiated
6042                                    ? SLOT_TEMP
6043                                    : SLOT_VIRTUAL);
6044       operands[2] = assign_386_stack_local (DImode, slot);
6045     }
6048 (define_expand "floatunsdisf2"
6049   [(use (match_operand:SF 0 "register_operand" ""))
6050    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
6051   "TARGET_64BIT && TARGET_SSE_MATH"
6052   "x86_emit_floatuns (operands); DONE;")
6054 (define_expand "floatunsdidf2"
6055   [(use (match_operand:DF 0 "register_operand" ""))
6056    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
6057   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6058    && TARGET_SSE2 && TARGET_SSE_MATH"
6060   if (TARGET_64BIT)
6061     x86_emit_floatuns (operands);
6062   else
6063     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6064   DONE;
6067 ;; Add instructions
6069 ;; %%% splits for addditi3
6071 (define_expand "addti3"
6072   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6073         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6074                  (match_operand:TI 2 "x86_64_general_operand" "")))]
6075   "TARGET_64BIT"
6076   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
6078 (define_insn "*addti3_1"
6079   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6080         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
6081                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6082    (clobber (reg:CC FLAGS_REG))]
6083   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
6084   "#")
6086 (define_split
6087   [(set (match_operand:TI 0 "nonimmediate_operand" "")
6088         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6089                  (match_operand:TI 2 "x86_64_general_operand" "")))
6090    (clobber (reg:CC FLAGS_REG))]
6091   "TARGET_64BIT && reload_completed"
6092   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
6093                                           UNSPEC_ADD_CARRY))
6094               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
6095    (parallel [(set (match_dup 3)
6096                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6097                                      (match_dup 4))
6098                             (match_dup 5)))
6099               (clobber (reg:CC FLAGS_REG))])]
6100   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
6102 ;; %%% splits for addsidi3
6103 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
6104 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
6105 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
6107 (define_expand "adddi3"
6108   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6109         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6110                  (match_operand:DI 2 "x86_64_general_operand" "")))]
6111   ""
6112   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
6114 (define_insn "*adddi3_1"
6115   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6116         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6117                  (match_operand:DI 2 "general_operand" "roiF,riF")))
6118    (clobber (reg:CC FLAGS_REG))]
6119   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6120   "#")
6122 (define_split
6123   [(set (match_operand:DI 0 "nonimmediate_operand" "")
6124         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6125                  (match_operand:DI 2 "general_operand" "")))
6126    (clobber (reg:CC FLAGS_REG))]
6127   "!TARGET_64BIT && reload_completed"
6128   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
6129                                           UNSPEC_ADD_CARRY))
6130               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
6131    (parallel [(set (match_dup 3)
6132                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6133                                      (match_dup 4))
6134                             (match_dup 5)))
6135               (clobber (reg:CC FLAGS_REG))])]
6136   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
6138 (define_insn "adddi3_carry_rex64"
6139   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6140           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6141                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
6142                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6143    (clobber (reg:CC FLAGS_REG))]
6144   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6145   "adc{q}\t{%2, %0|%0, %2}"
6146   [(set_attr "type" "alu")
6147    (set_attr "use_carry" "1")
6148    (set_attr "pent_pair" "pu")
6149    (set_attr "mode" "DI")])
6151 (define_insn "*adddi3_cc_rex64"
6152   [(set (reg:CC FLAGS_REG)
6153         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
6154                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
6155                    UNSPEC_ADD_CARRY))
6156    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6157         (plus:DI (match_dup 1) (match_dup 2)))]
6158   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6159   "add{q}\t{%2, %0|%0, %2}"
6160   [(set_attr "type" "alu")
6161    (set_attr "mode" "DI")])
6163 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6164   [(set (reg:CCC FLAGS_REG)
6165         (compare:CCC
6166             (plusminus:SWI
6167                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6168                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6169             (match_dup 1)))
6170    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6171         (plusminus:SWI (match_dup 1) (match_dup 2)))]
6172   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6173   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6174   [(set_attr "type" "alu")
6175    (set_attr "mode" "<MODE>")])
6177 (define_insn "*add<mode>3_cconly_overflow"
6178   [(set (reg:CCC FLAGS_REG)
6179         (compare:CCC
6180                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
6181                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
6182                 (match_dup 1)))
6183    (clobber (match_scratch:SWI 0 "=<r>"))]
6184   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6185   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6186   [(set_attr "type" "alu")
6187    (set_attr "mode" "<MODE>")])
6189 (define_insn "*sub<mode>3_cconly_overflow"
6190   [(set (reg:CCC FLAGS_REG)
6191         (compare:CCC
6192              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6193                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6194              (match_dup 0)))]
6195   ""
6196   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6197   [(set_attr "type" "icmp")
6198    (set_attr "mode" "<MODE>")])
6200 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6201   [(set (reg:CCC FLAGS_REG)
6202         (compare:CCC
6203             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6204                           (match_operand:SI 2 "general_operand" "g"))
6205             (match_dup 1)))
6206    (set (match_operand:DI 0 "register_operand" "=r")
6207         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6208   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6209   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6210   [(set_attr "type" "alu")
6211    (set_attr "mode" "SI")])
6213 (define_insn "addqi3_carry"
6214   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6215           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6216                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
6217                    (match_operand:QI 2 "general_operand" "qn,qm")))
6218    (clobber (reg:CC FLAGS_REG))]
6219   "ix86_binary_operator_ok (PLUS, QImode, operands)"
6220   "adc{b}\t{%2, %0|%0, %2}"
6221   [(set_attr "type" "alu")
6222    (set_attr "use_carry" "1")
6223    (set_attr "pent_pair" "pu")
6224    (set_attr "mode" "QI")])
6226 (define_insn "addhi3_carry"
6227   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6228           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6229                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
6230                    (match_operand:HI 2 "general_operand" "rn,rm")))
6231    (clobber (reg:CC FLAGS_REG))]
6232   "ix86_binary_operator_ok (PLUS, HImode, operands)"
6233   "adc{w}\t{%2, %0|%0, %2}"
6234   [(set_attr "type" "alu")
6235    (set_attr "use_carry" "1")
6236    (set_attr "pent_pair" "pu")
6237    (set_attr "mode" "HI")])
6239 (define_insn "addsi3_carry"
6240   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6241           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6242                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
6243                    (match_operand:SI 2 "general_operand" "ri,rm")))
6244    (clobber (reg:CC FLAGS_REG))]
6245   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6246   "adc{l}\t{%2, %0|%0, %2}"
6247   [(set_attr "type" "alu")
6248    (set_attr "use_carry" "1")
6249    (set_attr "pent_pair" "pu")
6250    (set_attr "mode" "SI")])
6252 (define_insn "*addsi3_carry_zext"
6253   [(set (match_operand:DI 0 "register_operand" "=r")
6254           (zero_extend:DI
6255             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6256                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
6257                      (match_operand:SI 2 "general_operand" "g"))))
6258    (clobber (reg:CC FLAGS_REG))]
6259   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6260   "adc{l}\t{%2, %k0|%k0, %2}"
6261   [(set_attr "type" "alu")
6262    (set_attr "use_carry" "1")
6263    (set_attr "pent_pair" "pu")
6264    (set_attr "mode" "SI")])
6266 (define_insn "*addsi3_cc"
6267   [(set (reg:CC FLAGS_REG)
6268         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
6269                     (match_operand:SI 2 "general_operand" "ri,rm")]
6270                    UNSPEC_ADD_CARRY))
6271    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6272         (plus:SI (match_dup 1) (match_dup 2)))]
6273   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6274   "add{l}\t{%2, %0|%0, %2}"
6275   [(set_attr "type" "alu")
6276    (set_attr "mode" "SI")])
6278 (define_insn "addqi3_cc"
6279   [(set (reg:CC FLAGS_REG)
6280         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6281                     (match_operand:QI 2 "general_operand" "qn,qm")]
6282                    UNSPEC_ADD_CARRY))
6283    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6284         (plus:QI (match_dup 1) (match_dup 2)))]
6285   "ix86_binary_operator_ok (PLUS, QImode, operands)"
6286   "add{b}\t{%2, %0|%0, %2}"
6287   [(set_attr "type" "alu")
6288    (set_attr "mode" "QI")])
6290 (define_expand "addsi3"
6291   [(set (match_operand:SI 0 "nonimmediate_operand" "")
6292         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6293                  (match_operand:SI 2 "general_operand" "")))]
6294   ""
6295   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
6297 (define_insn "*lea_1"
6298   [(set (match_operand:SI 0 "register_operand" "=r")
6299         (match_operand:SI 1 "no_seg_address_operand" "p"))]
6300   "!TARGET_64BIT"
6301   "lea{l}\t{%a1, %0|%0, %a1}"
6302   [(set_attr "type" "lea")
6303    (set_attr "mode" "SI")])
6305 (define_insn "*lea_1_rex64"
6306   [(set (match_operand:SI 0 "register_operand" "=r")
6307         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6308   "TARGET_64BIT"
6309   "lea{l}\t{%a1, %0|%0, %a1}"
6310   [(set_attr "type" "lea")
6311    (set_attr "mode" "SI")])
6313 (define_insn "*lea_1_zext"
6314   [(set (match_operand:DI 0 "register_operand" "=r")
6315         (zero_extend:DI
6316          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6317   "TARGET_64BIT"
6318   "lea{l}\t{%a1, %k0|%k0, %a1}"
6319   [(set_attr "type" "lea")
6320    (set_attr "mode" "SI")])
6322 (define_insn "*lea_2_rex64"
6323   [(set (match_operand:DI 0 "register_operand" "=r")
6324         (match_operand:DI 1 "no_seg_address_operand" "p"))]
6325   "TARGET_64BIT"
6326   "lea{q}\t{%a1, %0|%0, %a1}"
6327   [(set_attr "type" "lea")
6328    (set_attr "mode" "DI")])
6330 ;; The lea patterns for non-Pmodes needs to be matched by several
6331 ;; insns converted to real lea by splitters.
6333 (define_insn_and_split "*lea_general_1"
6334   [(set (match_operand 0 "register_operand" "=r")
6335         (plus (plus (match_operand 1 "index_register_operand" "l")
6336                     (match_operand 2 "register_operand" "r"))
6337               (match_operand 3 "immediate_operand" "i")))]
6338   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6339     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6340    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6341    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6342    && GET_MODE (operands[0]) == GET_MODE (operands[2])
6343    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6344        || GET_MODE (operands[3]) == VOIDmode)"
6345   "#"
6346   "&& reload_completed"
6347   [(const_int 0)]
6349   rtx pat;
6350   operands[0] = gen_lowpart (SImode, operands[0]);
6351   operands[1] = gen_lowpart (Pmode, operands[1]);
6352   operands[2] = gen_lowpart (Pmode, operands[2]);
6353   operands[3] = gen_lowpart (Pmode, operands[3]);
6354   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6355                       operands[3]);
6356   if (Pmode != SImode)
6357     pat = gen_rtx_SUBREG (SImode, pat, 0);
6358   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6359   DONE;
6361   [(set_attr "type" "lea")
6362    (set_attr "mode" "SI")])
6364 (define_insn_and_split "*lea_general_1_zext"
6365   [(set (match_operand:DI 0 "register_operand" "=r")
6366         (zero_extend:DI
6367           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
6368                             (match_operand:SI 2 "register_operand" "r"))
6369                    (match_operand:SI 3 "immediate_operand" "i"))))]
6370   "TARGET_64BIT"
6371   "#"
6372   "&& reload_completed"
6373   [(set (match_dup 0)
6374         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6375                                                      (match_dup 2))
6376                                             (match_dup 3)) 0)))]
6378   operands[1] = gen_lowpart (Pmode, operands[1]);
6379   operands[2] = gen_lowpart (Pmode, operands[2]);
6380   operands[3] = gen_lowpart (Pmode, operands[3]);
6382   [(set_attr "type" "lea")
6383    (set_attr "mode" "SI")])
6385 (define_insn_and_split "*lea_general_2"
6386   [(set (match_operand 0 "register_operand" "=r")
6387         (plus (mult (match_operand 1 "index_register_operand" "l")
6388                     (match_operand 2 "const248_operand" "i"))
6389               (match_operand 3 "nonmemory_operand" "ri")))]
6390   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6391     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6392    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6393    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6394    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6395        || GET_MODE (operands[3]) == VOIDmode)"
6396   "#"
6397   "&& reload_completed"
6398   [(const_int 0)]
6400   rtx pat;
6401   operands[0] = gen_lowpart (SImode, operands[0]);
6402   operands[1] = gen_lowpart (Pmode, operands[1]);
6403   operands[3] = gen_lowpart (Pmode, operands[3]);
6404   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6405                       operands[3]);
6406   if (Pmode != SImode)
6407     pat = gen_rtx_SUBREG (SImode, pat, 0);
6408   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6409   DONE;
6411   [(set_attr "type" "lea")
6412    (set_attr "mode" "SI")])
6414 (define_insn_and_split "*lea_general_2_zext"
6415   [(set (match_operand:DI 0 "register_operand" "=r")
6416         (zero_extend:DI
6417           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6418                             (match_operand:SI 2 "const248_operand" "n"))
6419                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6420   "TARGET_64BIT"
6421   "#"
6422   "&& reload_completed"
6423   [(set (match_dup 0)
6424         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6425                                                      (match_dup 2))
6426                                             (match_dup 3)) 0)))]
6428   operands[1] = gen_lowpart (Pmode, operands[1]);
6429   operands[3] = gen_lowpart (Pmode, operands[3]);
6431   [(set_attr "type" "lea")
6432    (set_attr "mode" "SI")])
6434 (define_insn_and_split "*lea_general_3"
6435   [(set (match_operand 0 "register_operand" "=r")
6436         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6437                           (match_operand 2 "const248_operand" "i"))
6438                     (match_operand 3 "register_operand" "r"))
6439               (match_operand 4 "immediate_operand" "i")))]
6440   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6441     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6442    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6443    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6444    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6445   "#"
6446   "&& reload_completed"
6447   [(const_int 0)]
6449   rtx pat;
6450   operands[0] = gen_lowpart (SImode, operands[0]);
6451   operands[1] = gen_lowpart (Pmode, operands[1]);
6452   operands[3] = gen_lowpart (Pmode, operands[3]);
6453   operands[4] = gen_lowpart (Pmode, operands[4]);
6454   pat = gen_rtx_PLUS (Pmode,
6455                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6456                                                          operands[2]),
6457                                     operands[3]),
6458                       operands[4]);
6459   if (Pmode != SImode)
6460     pat = gen_rtx_SUBREG (SImode, pat, 0);
6461   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6462   DONE;
6464   [(set_attr "type" "lea")
6465    (set_attr "mode" "SI")])
6467 (define_insn_and_split "*lea_general_3_zext"
6468   [(set (match_operand:DI 0 "register_operand" "=r")
6469         (zero_extend:DI
6470           (plus:SI (plus:SI (mult:SI
6471                               (match_operand:SI 1 "index_register_operand" "l")
6472                               (match_operand:SI 2 "const248_operand" "n"))
6473                             (match_operand:SI 3 "register_operand" "r"))
6474                    (match_operand:SI 4 "immediate_operand" "i"))))]
6475   "TARGET_64BIT"
6476   "#"
6477   "&& reload_completed"
6478   [(set (match_dup 0)
6479         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6480                                                               (match_dup 2))
6481                                                      (match_dup 3))
6482                                             (match_dup 4)) 0)))]
6484   operands[1] = gen_lowpart (Pmode, operands[1]);
6485   operands[3] = gen_lowpart (Pmode, operands[3]);
6486   operands[4] = gen_lowpart (Pmode, operands[4]);
6488   [(set_attr "type" "lea")
6489    (set_attr "mode" "SI")])
6491 (define_insn "*adddi_1_rex64"
6492   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
6493         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r,r")
6494                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,0,le")))
6495    (clobber (reg:CC FLAGS_REG))]
6496   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6498   switch (get_attr_type (insn))
6499     {
6500     case TYPE_LEA:
6501       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6502       return "lea{q}\t{%a2, %0|%0, %a2}";
6504     case TYPE_INCDEC:
6505       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6506       if (operands[2] == const1_rtx)
6507         return "inc{q}\t%0";
6508       else
6509         {
6510           gcc_assert (operands[2] == constm1_rtx);
6511           return "dec{q}\t%0";
6512         }
6514     default:
6515       /* Use add as much as possible to replace lea for AGU optimization. */
6516       if (which_alternative == 2 && TARGET_OPT_AGU)
6517         return "add{q}\t{%1, %0|%0, %1}";
6518         
6519       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6521       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6522          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6523       if (CONST_INT_P (operands[2])
6524           /* Avoid overflows.  */
6525           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6526           && (INTVAL (operands[2]) == 128
6527               || (INTVAL (operands[2]) < 0
6528                   && INTVAL (operands[2]) != -128)))
6529         {
6530           operands[2] = GEN_INT (-INTVAL (operands[2]));
6531           return "sub{q}\t{%2, %0|%0, %2}";
6532         }
6533       return "add{q}\t{%2, %0|%0, %2}";
6534     }
6536   [(set (attr "type")
6537      (cond [(and (eq_attr "alternative" "2") 
6538                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6539               (const_string "lea")
6540             (eq_attr "alternative" "3")
6541               (const_string "lea")
6542             ; Current assemblers are broken and do not allow @GOTOFF in
6543             ; ought but a memory context.
6544             (match_operand:DI 2 "pic_symbolic_operand" "")
6545               (const_string "lea")
6546             (match_operand:DI 2 "incdec_operand" "")
6547               (const_string "incdec")
6548            ]
6549            (const_string "alu")))
6550    (set (attr "length_immediate")
6551       (if_then_else
6552         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6553         (const_string "1")
6554         (const_string "*")))
6555    (set_attr "mode" "DI")])
6557 ;; Convert lea to the lea pattern to avoid flags dependency.
6558 (define_split
6559   [(set (match_operand:DI 0 "register_operand" "")
6560         (plus:DI (match_operand:DI 1 "register_operand" "")
6561                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6562    (clobber (reg:CC FLAGS_REG))]
6563   "TARGET_64BIT && reload_completed 
6564    && ix86_lea_for_add_ok (PLUS, insn, operands)"
6565   [(set (match_dup 0)
6566         (plus:DI (match_dup 1)
6567                  (match_dup 2)))]
6568   "")
6570 (define_insn "*adddi_2_rex64"
6571   [(set (reg FLAGS_REG)
6572         (compare
6573           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6574                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6575           (const_int 0)))
6576    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6577         (plus:DI (match_dup 1) (match_dup 2)))]
6578   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6579    && ix86_binary_operator_ok (PLUS, DImode, operands)
6580    /* Current assemblers are broken and do not allow @GOTOFF in
6581       ought but a memory context.  */
6582    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6584   switch (get_attr_type (insn))
6585     {
6586     case TYPE_INCDEC:
6587       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6588       if (operands[2] == const1_rtx)
6589         return "inc{q}\t%0";
6590       else
6591         {
6592           gcc_assert (operands[2] == constm1_rtx);
6593           return "dec{q}\t%0";
6594         }
6596     default:
6597       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6598       /* ???? We ought to handle there the 32bit case too
6599          - do we need new constraint?  */
6600       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6601          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6602       if (CONST_INT_P (operands[2])
6603           /* Avoid overflows.  */
6604           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6605           && (INTVAL (operands[2]) == 128
6606               || (INTVAL (operands[2]) < 0
6607                   && INTVAL (operands[2]) != -128)))
6608         {
6609           operands[2] = GEN_INT (-INTVAL (operands[2]));
6610           return "sub{q}\t{%2, %0|%0, %2}";
6611         }
6612       return "add{q}\t{%2, %0|%0, %2}";
6613     }
6615   [(set (attr "type")
6616      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6617         (const_string "incdec")
6618         (const_string "alu")))
6619    (set (attr "length_immediate")
6620       (if_then_else
6621         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6622         (const_string "1")
6623         (const_string "*")))
6624    (set_attr "mode" "DI")])
6626 (define_insn "*adddi_3_rex64"
6627   [(set (reg FLAGS_REG)
6628         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6629                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6630    (clobber (match_scratch:DI 0 "=r"))]
6631   "TARGET_64BIT
6632    && ix86_match_ccmode (insn, CCZmode)
6633    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6634    /* Current assemblers are broken and do not allow @GOTOFF in
6635       ought but a memory context.  */
6636    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6638   switch (get_attr_type (insn))
6639     {
6640     case TYPE_INCDEC:
6641       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6642       if (operands[2] == const1_rtx)
6643         return "inc{q}\t%0";
6644       else
6645         {
6646           gcc_assert (operands[2] == constm1_rtx);
6647           return "dec{q}\t%0";
6648         }
6650     default:
6651       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6652       /* ???? We ought to handle there the 32bit case too
6653          - do we need new constraint?  */
6654       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6655          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6656       if (CONST_INT_P (operands[2])
6657           /* Avoid overflows.  */
6658           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6659           && (INTVAL (operands[2]) == 128
6660               || (INTVAL (operands[2]) < 0
6661                   && INTVAL (operands[2]) != -128)))
6662         {
6663           operands[2] = GEN_INT (-INTVAL (operands[2]));
6664           return "sub{q}\t{%2, %0|%0, %2}";
6665         }
6666       return "add{q}\t{%2, %0|%0, %2}";
6667     }
6669   [(set (attr "type")
6670      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6671         (const_string "incdec")
6672         (const_string "alu")))
6673    (set (attr "length_immediate")
6674       (if_then_else
6675         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6676         (const_string "1")
6677         (const_string "*")))
6678    (set_attr "mode" "DI")])
6680 ; For comparisons against 1, -1 and 128, we may generate better code
6681 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6682 ; is matched then.  We can't accept general immediate, because for
6683 ; case of overflows,  the result is messed up.
6684 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6685 ; when negated.
6686 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6687 ; only for comparisons not depending on it.
6688 (define_insn "*adddi_4_rex64"
6689   [(set (reg FLAGS_REG)
6690         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6691                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6692    (clobber (match_scratch:DI 0 "=rm"))]
6693   "TARGET_64BIT
6694    &&  ix86_match_ccmode (insn, CCGCmode)"
6696   switch (get_attr_type (insn))
6697     {
6698     case TYPE_INCDEC:
6699       if (operands[2] == constm1_rtx)
6700         return "inc{q}\t%0";
6701       else
6702         {
6703           gcc_assert (operands[2] == const1_rtx);
6704           return "dec{q}\t%0";
6705         }
6707     default:
6708       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6709       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6710          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6711       if ((INTVAL (operands[2]) == -128
6712            || (INTVAL (operands[2]) > 0
6713                && INTVAL (operands[2]) != 128))
6714           /* Avoid overflows.  */
6715           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6716         return "sub{q}\t{%2, %0|%0, %2}";
6717       operands[2] = GEN_INT (-INTVAL (operands[2]));
6718       return "add{q}\t{%2, %0|%0, %2}";
6719     }
6721   [(set (attr "type")
6722      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6723         (const_string "incdec")
6724         (const_string "alu")))
6725    (set (attr "length_immediate")
6726       (if_then_else
6727         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6728         (const_string "1")
6729         (const_string "*")))
6730    (set_attr "mode" "DI")])
6732 (define_insn "*adddi_5_rex64"
6733   [(set (reg FLAGS_REG)
6734         (compare
6735           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6736                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6737           (const_int 0)))
6738    (clobber (match_scratch:DI 0 "=r"))]
6739   "TARGET_64BIT
6740    && ix86_match_ccmode (insn, CCGOCmode)
6741    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6742    /* Current assemblers are broken and do not allow @GOTOFF in
6743       ought but a memory context.  */
6744    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6746   switch (get_attr_type (insn))
6747     {
6748     case TYPE_INCDEC:
6749       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6750       if (operands[2] == const1_rtx)
6751         return "inc{q}\t%0";
6752       else
6753         {
6754           gcc_assert (operands[2] == constm1_rtx);
6755           return "dec{q}\t%0";
6756         }
6758     default:
6759       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6760       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6761          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6762       if (CONST_INT_P (operands[2])
6763           /* Avoid overflows.  */
6764           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6765           && (INTVAL (operands[2]) == 128
6766               || (INTVAL (operands[2]) < 0
6767                   && INTVAL (operands[2]) != -128)))
6768         {
6769           operands[2] = GEN_INT (-INTVAL (operands[2]));
6770           return "sub{q}\t{%2, %0|%0, %2}";
6771         }
6772       return "add{q}\t{%2, %0|%0, %2}";
6773     }
6775   [(set (attr "type")
6776      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6777         (const_string "incdec")
6778         (const_string "alu")))
6779    (set (attr "length_immediate")
6780       (if_then_else
6781         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6782         (const_string "1")
6783         (const_string "*")))
6784    (set_attr "mode" "DI")])
6787 (define_insn "*addsi_1"
6788   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r,r")
6789         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r,r")
6790                  (match_operand:SI 2 "general_operand" "g,ri,0,li")))
6791    (clobber (reg:CC FLAGS_REG))]
6792   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6794   switch (get_attr_type (insn))
6795     {
6796     case TYPE_LEA:
6797       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6798       return "lea{l}\t{%a2, %0|%0, %a2}";
6800     case TYPE_INCDEC:
6801       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6802       if (operands[2] == const1_rtx)
6803         return "inc{l}\t%0";
6804       else
6805         {
6806           gcc_assert (operands[2] == constm1_rtx);
6807           return "dec{l}\t%0";
6808         }
6810     default:
6811       /* Use add as much as possible to replace lea for AGU optimization. */
6812       if (which_alternative == 2 && TARGET_OPT_AGU)
6813         return "add{l}\t{%1, %0|%0, %1}";
6815       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6817       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6818          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6819       if (CONST_INT_P (operands[2])
6820           && (INTVAL (operands[2]) == 128
6821               || (INTVAL (operands[2]) < 0
6822                   && INTVAL (operands[2]) != -128)))
6823         {
6824           operands[2] = GEN_INT (-INTVAL (operands[2]));
6825           return "sub{l}\t{%2, %0|%0, %2}";
6826         }
6827       return "add{l}\t{%2, %0|%0, %2}";
6828     }
6830   [(set (attr "type")
6831      (cond [(and (eq_attr "alternative" "2") 
6832                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6833                (const_string "lea")
6834             (eq_attr "alternative" "3")
6835               (const_string "lea")
6836             ; Current assemblers are broken and do not allow @GOTOFF in
6837             ; ought but a memory context.
6838             (match_operand:SI 2 "pic_symbolic_operand" "")
6839               (const_string "lea")
6840             (match_operand:SI 2 "incdec_operand" "")
6841               (const_string "incdec")
6842            ]
6843            (const_string "alu")))
6844    (set (attr "length_immediate")
6845       (if_then_else
6846         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6847         (const_string "1")
6848         (const_string "*")))
6849    (set_attr "mode" "SI")])
6851 ;; Convert lea to the lea pattern to avoid flags dependency.
6852 (define_split
6853   [(set (match_operand 0 "register_operand" "")
6854         (plus (match_operand 1 "register_operand" "")
6855               (match_operand 2 "nonmemory_operand" "")))
6856    (clobber (reg:CC FLAGS_REG))]
6857   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
6858   [(const_int 0)]
6860   rtx pat;
6861   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6862      may confuse gen_lowpart.  */
6863   if (GET_MODE (operands[0]) != Pmode)
6864     {
6865       operands[1] = gen_lowpart (Pmode, operands[1]);
6866       operands[2] = gen_lowpart (Pmode, operands[2]);
6867     }
6868   operands[0] = gen_lowpart (SImode, operands[0]);
6869   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6870   if (Pmode != SImode)
6871     pat = gen_rtx_SUBREG (SImode, pat, 0);
6872   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6873   DONE;
6876 ;; It may seem that nonimmediate operand is proper one for operand 1.
6877 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6878 ;; we take care in ix86_binary_operator_ok to not allow two memory
6879 ;; operands so proper swapping will be done in reload.  This allow
6880 ;; patterns constructed from addsi_1 to match.
6881 (define_insn "addsi_1_zext"
6882   [(set (match_operand:DI 0 "register_operand" "=r,r")
6883         (zero_extend:DI
6884           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6885                    (match_operand:SI 2 "general_operand" "g,li"))))
6886    (clobber (reg:CC FLAGS_REG))]
6887   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6889   switch (get_attr_type (insn))
6890     {
6891     case TYPE_LEA:
6892       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6893       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6895     case TYPE_INCDEC:
6896       if (operands[2] == const1_rtx)
6897         return "inc{l}\t%k0";
6898       else
6899         {
6900           gcc_assert (operands[2] == constm1_rtx);
6901           return "dec{l}\t%k0";
6902         }
6904     default:
6905       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6906          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6907       if (CONST_INT_P (operands[2])
6908           && (INTVAL (operands[2]) == 128
6909               || (INTVAL (operands[2]) < 0
6910                   && INTVAL (operands[2]) != -128)))
6911         {
6912           operands[2] = GEN_INT (-INTVAL (operands[2]));
6913           return "sub{l}\t{%2, %k0|%k0, %2}";
6914         }
6915       return "add{l}\t{%2, %k0|%k0, %2}";
6916     }
6918   [(set (attr "type")
6919      (cond [(eq_attr "alternative" "1")
6920               (const_string "lea")
6921             ; Current assemblers are broken and do not allow @GOTOFF in
6922             ; ought but a memory context.
6923             (match_operand:SI 2 "pic_symbolic_operand" "")
6924               (const_string "lea")
6925             (match_operand:SI 2 "incdec_operand" "")
6926               (const_string "incdec")
6927            ]
6928            (const_string "alu")))
6929    (set (attr "length_immediate")
6930       (if_then_else
6931         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6932         (const_string "1")
6933         (const_string "*")))
6934    (set_attr "mode" "SI")])
6936 ;; Convert lea to the lea pattern to avoid flags dependency.
6937 (define_split
6938   [(set (match_operand:DI 0 "register_operand" "")
6939         (zero_extend:DI
6940           (plus:SI (match_operand:SI 1 "register_operand" "")
6941                    (match_operand:SI 2 "nonmemory_operand" ""))))
6942    (clobber (reg:CC FLAGS_REG))]
6943   "TARGET_64BIT && reload_completed
6944    && true_regnum (operands[0]) != true_regnum (operands[1])"
6945   [(set (match_dup 0)
6946         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6948   operands[1] = gen_lowpart (Pmode, operands[1]);
6949   operands[2] = gen_lowpart (Pmode, operands[2]);
6952 (define_insn "*addsi_2"
6953   [(set (reg FLAGS_REG)
6954         (compare
6955           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6956                    (match_operand:SI 2 "general_operand" "g,ri"))
6957           (const_int 0)))
6958    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6959         (plus:SI (match_dup 1) (match_dup 2)))]
6960   "ix86_match_ccmode (insn, CCGOCmode)
6961    && ix86_binary_operator_ok (PLUS, SImode, operands)
6962    /* Current assemblers are broken and do not allow @GOTOFF in
6963       ought but a memory context.  */
6964    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6966   switch (get_attr_type (insn))
6967     {
6968     case TYPE_INCDEC:
6969       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6970       if (operands[2] == const1_rtx)
6971         return "inc{l}\t%0";
6972       else
6973         {
6974           gcc_assert (operands[2] == constm1_rtx);
6975           return "dec{l}\t%0";
6976         }
6978     default:
6979       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6980       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6981          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6982       if (CONST_INT_P (operands[2])
6983           && (INTVAL (operands[2]) == 128
6984               || (INTVAL (operands[2]) < 0
6985                   && INTVAL (operands[2]) != -128)))
6986         {
6987           operands[2] = GEN_INT (-INTVAL (operands[2]));
6988           return "sub{l}\t{%2, %0|%0, %2}";
6989         }
6990       return "add{l}\t{%2, %0|%0, %2}";
6991     }
6993   [(set (attr "type")
6994      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6995         (const_string "incdec")
6996         (const_string "alu")))
6997    (set (attr "length_immediate")
6998       (if_then_else
6999         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7000         (const_string "1")
7001         (const_string "*")))
7002    (set_attr "mode" "SI")])
7004 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7005 (define_insn "*addsi_2_zext"
7006   [(set (reg FLAGS_REG)
7007         (compare
7008           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7009                    (match_operand:SI 2 "general_operand" "g"))
7010           (const_int 0)))
7011    (set (match_operand:DI 0 "register_operand" "=r")
7012         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7013   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7014    && ix86_binary_operator_ok (PLUS, SImode, operands)
7015    /* Current assemblers are broken and do not allow @GOTOFF in
7016       ought but a memory context.  */
7017    && ! pic_symbolic_operand (operands[2], VOIDmode)"
7019   switch (get_attr_type (insn))
7020     {
7021     case TYPE_INCDEC:
7022       if (operands[2] == const1_rtx)
7023         return "inc{l}\t%k0";
7024       else
7025         {
7026           gcc_assert (operands[2] == constm1_rtx);
7027           return "dec{l}\t%k0";
7028         }
7030     default:
7031       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7032          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7033       if (CONST_INT_P (operands[2])
7034           && (INTVAL (operands[2]) == 128
7035               || (INTVAL (operands[2]) < 0
7036                   && INTVAL (operands[2]) != -128)))
7037         {
7038           operands[2] = GEN_INT (-INTVAL (operands[2]));
7039           return "sub{l}\t{%2, %k0|%k0, %2}";
7040         }
7041       return "add{l}\t{%2, %k0|%k0, %2}";
7042     }
7044   [(set (attr "type")
7045      (if_then_else (match_operand:SI 2 "incdec_operand" "")
7046         (const_string "incdec")
7047         (const_string "alu")))
7048    (set (attr "length_immediate")
7049       (if_then_else
7050         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7051         (const_string "1")
7052         (const_string "*")))
7053    (set_attr "mode" "SI")])
7055 (define_insn "*addsi_3"
7056   [(set (reg FLAGS_REG)
7057         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
7058                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
7059    (clobber (match_scratch:SI 0 "=r"))]
7060   "ix86_match_ccmode (insn, CCZmode)
7061    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
7062    /* Current assemblers are broken and do not allow @GOTOFF in
7063       ought but a memory context.  */
7064    && ! pic_symbolic_operand (operands[2], VOIDmode)"
7066   switch (get_attr_type (insn))
7067     {
7068     case TYPE_INCDEC:
7069       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7070       if (operands[2] == const1_rtx)
7071         return "inc{l}\t%0";
7072       else
7073         {
7074           gcc_assert (operands[2] == constm1_rtx);
7075           return "dec{l}\t%0";
7076         }
7078     default:
7079       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7080       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7081          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7082       if (CONST_INT_P (operands[2])
7083           && (INTVAL (operands[2]) == 128
7084               || (INTVAL (operands[2]) < 0
7085                   && INTVAL (operands[2]) != -128)))
7086         {
7087           operands[2] = GEN_INT (-INTVAL (operands[2]));
7088           return "sub{l}\t{%2, %0|%0, %2}";
7089         }
7090       return "add{l}\t{%2, %0|%0, %2}";
7091     }
7093   [(set (attr "type")
7094      (if_then_else (match_operand:SI 2 "incdec_operand" "")
7095         (const_string "incdec")
7096         (const_string "alu")))
7097    (set (attr "length_immediate")
7098       (if_then_else
7099         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7100         (const_string "1")
7101         (const_string "*")))
7102    (set_attr "mode" "SI")])
7104 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7105 (define_insn "*addsi_3_zext"
7106   [(set (reg FLAGS_REG)
7107         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
7108                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
7109    (set (match_operand:DI 0 "register_operand" "=r")
7110         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7111   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
7112    && ix86_binary_operator_ok (PLUS, SImode, operands)
7113    /* Current assemblers are broken and do not allow @GOTOFF in
7114       ought but a memory context.  */
7115    && ! pic_symbolic_operand (operands[2], VOIDmode)"
7117   switch (get_attr_type (insn))
7118     {
7119     case TYPE_INCDEC:
7120       if (operands[2] == const1_rtx)
7121         return "inc{l}\t%k0";
7122       else
7123         {
7124           gcc_assert (operands[2] == constm1_rtx);
7125           return "dec{l}\t%k0";
7126         }
7128     default:
7129       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7130          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7131       if (CONST_INT_P (operands[2])
7132           && (INTVAL (operands[2]) == 128
7133               || (INTVAL (operands[2]) < 0
7134                   && INTVAL (operands[2]) != -128)))
7135         {
7136           operands[2] = GEN_INT (-INTVAL (operands[2]));
7137           return "sub{l}\t{%2, %k0|%k0, %2}";
7138         }
7139       return "add{l}\t{%2, %k0|%k0, %2}";
7140     }
7142   [(set (attr "type")
7143      (if_then_else (match_operand:SI 2 "incdec_operand" "")
7144         (const_string "incdec")
7145         (const_string "alu")))
7146    (set (attr "length_immediate")
7147       (if_then_else
7148         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7149         (const_string "1")
7150         (const_string "*")))
7151    (set_attr "mode" "SI")])
7153 ; For comparisons against 1, -1 and 128, we may generate better code
7154 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
7155 ; is matched then.  We can't accept general immediate, because for
7156 ; case of overflows,  the result is messed up.
7157 ; This pattern also don't hold of 0x80000000, since the value overflows
7158 ; when negated.
7159 ; Also carry flag is reversed compared to cmp, so this conversion is valid
7160 ; only for comparisons not depending on it.
7161 (define_insn "*addsi_4"
7162   [(set (reg FLAGS_REG)
7163         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
7164                  (match_operand:SI 2 "const_int_operand" "n")))
7165    (clobber (match_scratch:SI 0 "=rm"))]
7166   "ix86_match_ccmode (insn, CCGCmode)
7167    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
7169   switch (get_attr_type (insn))
7170     {
7171     case TYPE_INCDEC:
7172       if (operands[2] == constm1_rtx)
7173         return "inc{l}\t%0";
7174       else
7175         {
7176           gcc_assert (operands[2] == const1_rtx);
7177           return "dec{l}\t%0";
7178         }
7180     default:
7181       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7182       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7183          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7184       if ((INTVAL (operands[2]) == -128
7185            || (INTVAL (operands[2]) > 0
7186                && INTVAL (operands[2]) != 128)))
7187         return "sub{l}\t{%2, %0|%0, %2}";
7188       operands[2] = GEN_INT (-INTVAL (operands[2]));
7189       return "add{l}\t{%2, %0|%0, %2}";
7190     }
7192   [(set (attr "type")
7193      (if_then_else (match_operand:SI 2 "incdec_operand" "")
7194         (const_string "incdec")
7195         (const_string "alu")))
7196    (set (attr "length_immediate")
7197       (if_then_else
7198         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7199         (const_string "1")
7200         (const_string "*")))
7201    (set_attr "mode" "SI")])
7203 (define_insn "*addsi_5"
7204   [(set (reg FLAGS_REG)
7205         (compare
7206           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7207                    (match_operand:SI 2 "general_operand" "g"))
7208           (const_int 0)))
7209    (clobber (match_scratch:SI 0 "=r"))]
7210   "ix86_match_ccmode (insn, CCGOCmode)
7211    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
7212    /* Current assemblers are broken and do not allow @GOTOFF in
7213       ought but a memory context.  */
7214    && ! pic_symbolic_operand (operands[2], VOIDmode)"
7216   switch (get_attr_type (insn))
7217     {
7218     case TYPE_INCDEC:
7219       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7220       if (operands[2] == const1_rtx)
7221         return "inc{l}\t%0";
7222       else
7223         {
7224           gcc_assert (operands[2] == constm1_rtx);
7225           return "dec{l}\t%0";
7226         }
7228     default:
7229       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7230       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7231          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7232       if (CONST_INT_P (operands[2])
7233           && (INTVAL (operands[2]) == 128
7234               || (INTVAL (operands[2]) < 0
7235                   && INTVAL (operands[2]) != -128)))
7236         {
7237           operands[2] = GEN_INT (-INTVAL (operands[2]));
7238           return "sub{l}\t{%2, %0|%0, %2}";
7239         }
7240       return "add{l}\t{%2, %0|%0, %2}";
7241     }
7243   [(set (attr "type")
7244      (if_then_else (match_operand:SI 2 "incdec_operand" "")
7245         (const_string "incdec")
7246         (const_string "alu")))
7247    (set (attr "length_immediate")
7248       (if_then_else
7249         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7250         (const_string "1")
7251         (const_string "*")))
7252    (set_attr "mode" "SI")])
7254 (define_expand "addhi3"
7255   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7256         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7257                  (match_operand:HI 2 "general_operand" "")))]
7258   "TARGET_HIMODE_MATH"
7259   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
7261 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
7262 ;; type optimizations enabled by define-splits.  This is not important
7263 ;; for PII, and in fact harmful because of partial register stalls.
7265 (define_insn "*addhi_1_lea"
7266   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7267         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
7268                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
7269    (clobber (reg:CC FLAGS_REG))]
7270   "!TARGET_PARTIAL_REG_STALL
7271    && ix86_binary_operator_ok (PLUS, HImode, operands)"
7273   switch (get_attr_type (insn))
7274     {
7275     case TYPE_LEA:
7276       return "#";
7277     case TYPE_INCDEC:
7278       if (operands[2] == const1_rtx)
7279         return "inc{w}\t%0";
7280       else
7281         {
7282           gcc_assert (operands[2] == constm1_rtx);
7283           return "dec{w}\t%0";
7284         }
7286     default:
7287       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7288          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7289       if (CONST_INT_P (operands[2])
7290           && (INTVAL (operands[2]) == 128
7291               || (INTVAL (operands[2]) < 0
7292                   && INTVAL (operands[2]) != -128)))
7293         {
7294           operands[2] = GEN_INT (-INTVAL (operands[2]));
7295           return "sub{w}\t{%2, %0|%0, %2}";
7296         }
7297       return "add{w}\t{%2, %0|%0, %2}";
7298     }
7300   [(set (attr "type")
7301      (if_then_else (eq_attr "alternative" "2")
7302         (const_string "lea")
7303         (if_then_else (match_operand:HI 2 "incdec_operand" "")
7304            (const_string "incdec")
7305            (const_string "alu"))))
7306    (set (attr "length_immediate")
7307       (if_then_else
7308         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7309         (const_string "1")
7310         (const_string "*")))
7311    (set_attr "mode" "HI,HI,SI")])
7313 (define_insn "*addhi_1"
7314   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7315         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
7316                  (match_operand:HI 2 "general_operand" "rn,rm")))
7317    (clobber (reg:CC FLAGS_REG))]
7318   "TARGET_PARTIAL_REG_STALL
7319    && ix86_binary_operator_ok (PLUS, HImode, operands)"
7321   switch (get_attr_type (insn))
7322     {
7323     case TYPE_INCDEC:
7324       if (operands[2] == const1_rtx)
7325         return "inc{w}\t%0";
7326       else
7327         {
7328           gcc_assert (operands[2] == constm1_rtx);
7329           return "dec{w}\t%0";
7330         }
7332     default:
7333       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7334          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7335       if (CONST_INT_P (operands[2])
7336           && (INTVAL (operands[2]) == 128
7337               || (INTVAL (operands[2]) < 0
7338                   && INTVAL (operands[2]) != -128)))
7339         {
7340           operands[2] = GEN_INT (-INTVAL (operands[2]));
7341           return "sub{w}\t{%2, %0|%0, %2}";
7342         }
7343       return "add{w}\t{%2, %0|%0, %2}";
7344     }
7346   [(set (attr "type")
7347      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7348         (const_string "incdec")
7349         (const_string "alu")))
7350    (set (attr "length_immediate")
7351       (if_then_else
7352         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7353         (const_string "1")
7354         (const_string "*")))
7355    (set_attr "mode" "HI")])
7357 (define_insn "*addhi_2"
7358   [(set (reg FLAGS_REG)
7359         (compare
7360           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
7361                    (match_operand:HI 2 "general_operand" "rmn,rn"))
7362           (const_int 0)))
7363    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
7364         (plus:HI (match_dup 1) (match_dup 2)))]
7365   "ix86_match_ccmode (insn, CCGOCmode)
7366    && ix86_binary_operator_ok (PLUS, HImode, operands)"
7368   switch (get_attr_type (insn))
7369     {
7370     case TYPE_INCDEC:
7371       if (operands[2] == const1_rtx)
7372         return "inc{w}\t%0";
7373       else
7374         {
7375           gcc_assert (operands[2] == constm1_rtx);
7376           return "dec{w}\t%0";
7377         }
7379     default:
7380       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7381          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7382       if (CONST_INT_P (operands[2])
7383           && (INTVAL (operands[2]) == 128
7384               || (INTVAL (operands[2]) < 0
7385                   && INTVAL (operands[2]) != -128)))
7386         {
7387           operands[2] = GEN_INT (-INTVAL (operands[2]));
7388           return "sub{w}\t{%2, %0|%0, %2}";
7389         }
7390       return "add{w}\t{%2, %0|%0, %2}";
7391     }
7393   [(set (attr "type")
7394      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7395         (const_string "incdec")
7396         (const_string "alu")))
7397    (set (attr "length_immediate")
7398       (if_then_else
7399         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7400         (const_string "1")
7401         (const_string "*")))
7402    (set_attr "mode" "HI")])
7404 (define_insn "*addhi_3"
7405   [(set (reg FLAGS_REG)
7406         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
7407                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
7408    (clobber (match_scratch:HI 0 "=r"))]
7409   "ix86_match_ccmode (insn, CCZmode)
7410    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7412   switch (get_attr_type (insn))
7413     {
7414     case TYPE_INCDEC:
7415       if (operands[2] == const1_rtx)
7416         return "inc{w}\t%0";
7417       else
7418         {
7419           gcc_assert (operands[2] == constm1_rtx);
7420           return "dec{w}\t%0";
7421         }
7423     default:
7424       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7425          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7426       if (CONST_INT_P (operands[2])
7427           && (INTVAL (operands[2]) == 128
7428               || (INTVAL (operands[2]) < 0
7429                   && INTVAL (operands[2]) != -128)))
7430         {
7431           operands[2] = GEN_INT (-INTVAL (operands[2]));
7432           return "sub{w}\t{%2, %0|%0, %2}";
7433         }
7434       return "add{w}\t{%2, %0|%0, %2}";
7435     }
7437   [(set (attr "type")
7438      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7439         (const_string "incdec")
7440         (const_string "alu")))
7441    (set (attr "length_immediate")
7442       (if_then_else
7443         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7444         (const_string "1")
7445         (const_string "*")))
7446    (set_attr "mode" "HI")])
7448 ; See comments above addsi_4 for details.
7449 (define_insn "*addhi_4"
7450   [(set (reg FLAGS_REG)
7451         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
7452                  (match_operand:HI 2 "const_int_operand" "n")))
7453    (clobber (match_scratch:HI 0 "=rm"))]
7454   "ix86_match_ccmode (insn, CCGCmode)
7455    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7457   switch (get_attr_type (insn))
7458     {
7459     case TYPE_INCDEC:
7460       if (operands[2] == constm1_rtx)
7461         return "inc{w}\t%0";
7462       else
7463         {
7464           gcc_assert (operands[2] == const1_rtx);
7465           return "dec{w}\t%0";
7466         }
7468     default:
7469       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7470       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7471          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7472       if ((INTVAL (operands[2]) == -128
7473            || (INTVAL (operands[2]) > 0
7474                && INTVAL (operands[2]) != 128)))
7475         return "sub{w}\t{%2, %0|%0, %2}";
7476       operands[2] = GEN_INT (-INTVAL (operands[2]));
7477       return "add{w}\t{%2, %0|%0, %2}";
7478     }
7480   [(set (attr "type")
7481      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7482         (const_string "incdec")
7483         (const_string "alu")))
7484    (set (attr "length_immediate")
7485       (if_then_else
7486         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7487         (const_string "1")
7488         (const_string "*")))
7489    (set_attr "mode" "HI")])
7492 (define_insn "*addhi_5"
7493   [(set (reg FLAGS_REG)
7494         (compare
7495           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7496                    (match_operand:HI 2 "general_operand" "rmn"))
7497           (const_int 0)))
7498    (clobber (match_scratch:HI 0 "=r"))]
7499   "ix86_match_ccmode (insn, CCGOCmode)
7500    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7502   switch (get_attr_type (insn))
7503     {
7504     case TYPE_INCDEC:
7505       if (operands[2] == const1_rtx)
7506         return "inc{w}\t%0";
7507       else
7508         {
7509           gcc_assert (operands[2] == constm1_rtx);
7510           return "dec{w}\t%0";
7511         }
7513     default:
7514       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7515          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7516       if (CONST_INT_P (operands[2])
7517           && (INTVAL (operands[2]) == 128
7518               || (INTVAL (operands[2]) < 0
7519                   && INTVAL (operands[2]) != -128)))
7520         {
7521           operands[2] = GEN_INT (-INTVAL (operands[2]));
7522           return "sub{w}\t{%2, %0|%0, %2}";
7523         }
7524       return "add{w}\t{%2, %0|%0, %2}";
7525     }
7527   [(set (attr "type")
7528      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7529         (const_string "incdec")
7530         (const_string "alu")))
7531    (set (attr "length_immediate")
7532       (if_then_else
7533         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7534         (const_string "1")
7535         (const_string "*")))
7536    (set_attr "mode" "HI")])
7538 (define_expand "addqi3"
7539   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7540         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7541                  (match_operand:QI 2 "general_operand" "")))]
7542   "TARGET_QIMODE_MATH"
7543   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7545 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7546 (define_insn "*addqi_1_lea"
7547   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7548         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7549                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7550    (clobber (reg:CC FLAGS_REG))]
7551   "!TARGET_PARTIAL_REG_STALL
7552    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7554   int widen = (which_alternative == 2);
7555   switch (get_attr_type (insn))
7556     {
7557     case TYPE_LEA:
7558       return "#";
7559     case TYPE_INCDEC:
7560       if (operands[2] == const1_rtx)
7561         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7562       else
7563         {
7564           gcc_assert (operands[2] == constm1_rtx);
7565           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7566         }
7568     default:
7569       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7570          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7571       if (CONST_INT_P (operands[2])
7572           && (INTVAL (operands[2]) == 128
7573               || (INTVAL (operands[2]) < 0
7574                   && INTVAL (operands[2]) != -128)))
7575         {
7576           operands[2] = GEN_INT (-INTVAL (operands[2]));
7577           if (widen)
7578             return "sub{l}\t{%2, %k0|%k0, %2}";
7579           else
7580             return "sub{b}\t{%2, %0|%0, %2}";
7581         }
7582       if (widen)
7583         return "add{l}\t{%k2, %k0|%k0, %k2}";
7584       else
7585         return "add{b}\t{%2, %0|%0, %2}";
7586     }
7588   [(set (attr "type")
7589      (if_then_else (eq_attr "alternative" "3")
7590         (const_string "lea")
7591         (if_then_else (match_operand:QI 2 "incdec_operand" "")
7592            (const_string "incdec")
7593            (const_string "alu"))))
7594    (set (attr "length_immediate")
7595       (if_then_else
7596         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7597         (const_string "1")
7598         (const_string "*")))
7599    (set_attr "mode" "QI,QI,SI,SI")])
7601 (define_insn "*addqi_1"
7602   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7603         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7604                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7605    (clobber (reg:CC FLAGS_REG))]
7606   "TARGET_PARTIAL_REG_STALL
7607    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7609   int widen = (which_alternative == 2);
7610   switch (get_attr_type (insn))
7611     {
7612     case TYPE_INCDEC:
7613       if (operands[2] == const1_rtx)
7614         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7615       else
7616         {
7617           gcc_assert (operands[2] == constm1_rtx);
7618           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7619         }
7621     default:
7622       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7623          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7624       if (CONST_INT_P (operands[2])
7625           && (INTVAL (operands[2]) == 128
7626               || (INTVAL (operands[2]) < 0
7627                   && INTVAL (operands[2]) != -128)))
7628         {
7629           operands[2] = GEN_INT (-INTVAL (operands[2]));
7630           if (widen)
7631             return "sub{l}\t{%2, %k0|%k0, %2}";
7632           else
7633             return "sub{b}\t{%2, %0|%0, %2}";
7634         }
7635       if (widen)
7636         return "add{l}\t{%k2, %k0|%k0, %k2}";
7637       else
7638         return "add{b}\t{%2, %0|%0, %2}";
7639     }
7641   [(set (attr "type")
7642      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7643         (const_string "incdec")
7644         (const_string "alu")))
7645    (set (attr "length_immediate")
7646       (if_then_else
7647         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7648         (const_string "1")
7649         (const_string "*")))
7650    (set_attr "mode" "QI,QI,SI")])
7652 (define_insn "*addqi_1_slp"
7653   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7654         (plus:QI (match_dup 0)
7655                  (match_operand:QI 1 "general_operand" "qn,qnm")))
7656    (clobber (reg:CC FLAGS_REG))]
7657   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7658    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7660   switch (get_attr_type (insn))
7661     {
7662     case TYPE_INCDEC:
7663       if (operands[1] == const1_rtx)
7664         return "inc{b}\t%0";
7665       else
7666         {
7667           gcc_assert (operands[1] == constm1_rtx);
7668           return "dec{b}\t%0";
7669         }
7671     default:
7672       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
7673       if (CONST_INT_P (operands[1])
7674           && INTVAL (operands[1]) < 0)
7675         {
7676           operands[1] = GEN_INT (-INTVAL (operands[1]));
7677           return "sub{b}\t{%1, %0|%0, %1}";
7678         }
7679       return "add{b}\t{%1, %0|%0, %1}";
7680     }
7682   [(set (attr "type")
7683      (if_then_else (match_operand:QI 1 "incdec_operand" "")
7684         (const_string "incdec")
7685         (const_string "alu1")))
7686    (set (attr "memory")
7687      (if_then_else (match_operand 1 "memory_operand" "")
7688         (const_string "load")
7689         (const_string "none")))
7690    (set_attr "mode" "QI")])
7692 (define_insn "*addqi_2"
7693   [(set (reg FLAGS_REG)
7694         (compare
7695           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7696                    (match_operand:QI 2 "general_operand" "qmn,qn"))
7697           (const_int 0)))
7698    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7699         (plus:QI (match_dup 1) (match_dup 2)))]
7700   "ix86_match_ccmode (insn, CCGOCmode)
7701    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7703   switch (get_attr_type (insn))
7704     {
7705     case TYPE_INCDEC:
7706       if (operands[2] == const1_rtx)
7707         return "inc{b}\t%0";
7708       else
7709         {
7710           gcc_assert (operands[2] == constm1_rtx
7711                       || (CONST_INT_P (operands[2])
7712                           && INTVAL (operands[2]) == 255));
7713           return "dec{b}\t%0";
7714         }
7716     default:
7717       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7718       if (CONST_INT_P (operands[2])
7719           && INTVAL (operands[2]) < 0)
7720         {
7721           operands[2] = GEN_INT (-INTVAL (operands[2]));
7722           return "sub{b}\t{%2, %0|%0, %2}";
7723         }
7724       return "add{b}\t{%2, %0|%0, %2}";
7725     }
7727   [(set (attr "type")
7728      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7729         (const_string "incdec")
7730         (const_string "alu")))
7731    (set_attr "mode" "QI")])
7733 (define_insn "*addqi_3"
7734   [(set (reg FLAGS_REG)
7735         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7736                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7737    (clobber (match_scratch:QI 0 "=q"))]
7738   "ix86_match_ccmode (insn, CCZmode)
7739    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7741   switch (get_attr_type (insn))
7742     {
7743     case TYPE_INCDEC:
7744       if (operands[2] == const1_rtx)
7745         return "inc{b}\t%0";
7746       else
7747         {
7748           gcc_assert (operands[2] == constm1_rtx
7749                       || (CONST_INT_P (operands[2])
7750                           && INTVAL (operands[2]) == 255));
7751           return "dec{b}\t%0";
7752         }
7754     default:
7755       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7756       if (CONST_INT_P (operands[2])
7757           && INTVAL (operands[2]) < 0)
7758         {
7759           operands[2] = GEN_INT (-INTVAL (operands[2]));
7760           return "sub{b}\t{%2, %0|%0, %2}";
7761         }
7762       return "add{b}\t{%2, %0|%0, %2}";
7763     }
7765   [(set (attr "type")
7766      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7767         (const_string "incdec")
7768         (const_string "alu")))
7769    (set_attr "mode" "QI")])
7771 ; See comments above addsi_4 for details.
7772 (define_insn "*addqi_4"
7773   [(set (reg FLAGS_REG)
7774         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7775                  (match_operand:QI 2 "const_int_operand" "n")))
7776    (clobber (match_scratch:QI 0 "=qm"))]
7777   "ix86_match_ccmode (insn, CCGCmode)
7778    && (INTVAL (operands[2]) & 0xff) != 0x80"
7780   switch (get_attr_type (insn))
7781     {
7782     case TYPE_INCDEC:
7783       if (operands[2] == constm1_rtx
7784           || (CONST_INT_P (operands[2])
7785               && INTVAL (operands[2]) == 255))
7786         return "inc{b}\t%0";
7787       else
7788         {
7789           gcc_assert (operands[2] == const1_rtx);
7790           return "dec{b}\t%0";
7791         }
7793     default:
7794       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7795       if (INTVAL (operands[2]) < 0)
7796         {
7797           operands[2] = GEN_INT (-INTVAL (operands[2]));
7798           return "add{b}\t{%2, %0|%0, %2}";
7799         }
7800       return "sub{b}\t{%2, %0|%0, %2}";
7801     }
7803   [(set (attr "type")
7804      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7805         (const_string "incdec")
7806         (const_string "alu")))
7807    (set_attr "mode" "QI")])
7810 (define_insn "*addqi_5"
7811   [(set (reg FLAGS_REG)
7812         (compare
7813           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7814                    (match_operand:QI 2 "general_operand" "qmn"))
7815           (const_int 0)))
7816    (clobber (match_scratch:QI 0 "=q"))]
7817   "ix86_match_ccmode (insn, CCGOCmode)
7818    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7820   switch (get_attr_type (insn))
7821     {
7822     case TYPE_INCDEC:
7823       if (operands[2] == const1_rtx)
7824         return "inc{b}\t%0";
7825       else
7826         {
7827           gcc_assert (operands[2] == constm1_rtx
7828                       || (CONST_INT_P (operands[2])
7829                           && INTVAL (operands[2]) == 255));
7830           return "dec{b}\t%0";
7831         }
7833     default:
7834       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7835       if (CONST_INT_P (operands[2])
7836           && INTVAL (operands[2]) < 0)
7837         {
7838           operands[2] = GEN_INT (-INTVAL (operands[2]));
7839           return "sub{b}\t{%2, %0|%0, %2}";
7840         }
7841       return "add{b}\t{%2, %0|%0, %2}";
7842     }
7844   [(set (attr "type")
7845      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7846         (const_string "incdec")
7847         (const_string "alu")))
7848    (set_attr "mode" "QI")])
7851 (define_insn "addqi_ext_1"
7852   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7853                          (const_int 8)
7854                          (const_int 8))
7855         (plus:SI
7856           (zero_extract:SI
7857             (match_operand 1 "ext_register_operand" "0")
7858             (const_int 8)
7859             (const_int 8))
7860           (match_operand:QI 2 "general_operand" "Qmn")))
7861    (clobber (reg:CC FLAGS_REG))]
7862   "!TARGET_64BIT"
7864   switch (get_attr_type (insn))
7865     {
7866     case TYPE_INCDEC:
7867       if (operands[2] == const1_rtx)
7868         return "inc{b}\t%h0";
7869       else
7870         {
7871           gcc_assert (operands[2] == constm1_rtx
7872                       || (CONST_INT_P (operands[2])
7873                           && INTVAL (operands[2]) == 255));
7874           return "dec{b}\t%h0";
7875         }
7877     default:
7878       return "add{b}\t{%2, %h0|%h0, %2}";
7879     }
7881   [(set (attr "type")
7882      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7883         (const_string "incdec")
7884         (const_string "alu")))
7885    (set_attr "modrm" "1")
7886    (set_attr "mode" "QI")])
7888 (define_insn "*addqi_ext_1_rex64"
7889   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7890                          (const_int 8)
7891                          (const_int 8))
7892         (plus:SI
7893           (zero_extract:SI
7894             (match_operand 1 "ext_register_operand" "0")
7895             (const_int 8)
7896             (const_int 8))
7897           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7898    (clobber (reg:CC FLAGS_REG))]
7899   "TARGET_64BIT"
7901   switch (get_attr_type (insn))
7902     {
7903     case TYPE_INCDEC:
7904       if (operands[2] == const1_rtx)
7905         return "inc{b}\t%h0";
7906       else
7907         {
7908           gcc_assert (operands[2] == constm1_rtx
7909                       || (CONST_INT_P (operands[2])
7910                           && INTVAL (operands[2]) == 255));
7911           return "dec{b}\t%h0";
7912         }
7914     default:
7915       return "add{b}\t{%2, %h0|%h0, %2}";
7916     }
7918   [(set (attr "type")
7919      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7920         (const_string "incdec")
7921         (const_string "alu")))
7922    (set_attr "modrm" "1")
7923    (set_attr "mode" "QI")])
7925 (define_insn "*addqi_ext_2"
7926   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7927                          (const_int 8)
7928                          (const_int 8))
7929         (plus:SI
7930           (zero_extract:SI
7931             (match_operand 1 "ext_register_operand" "%0")
7932             (const_int 8)
7933             (const_int 8))
7934           (zero_extract:SI
7935             (match_operand 2 "ext_register_operand" "Q")
7936             (const_int 8)
7937             (const_int 8))))
7938    (clobber (reg:CC FLAGS_REG))]
7939   ""
7940   "add{b}\t{%h2, %h0|%h0, %h2}"
7941   [(set_attr "type" "alu")
7942    (set_attr "mode" "QI")])
7944 ;; The patterns that match these are at the end of this file.
7946 (define_expand "addxf3"
7947   [(set (match_operand:XF 0 "register_operand" "")
7948         (plus:XF (match_operand:XF 1 "register_operand" "")
7949                  (match_operand:XF 2 "register_operand" "")))]
7950   "TARGET_80387"
7951   "")
7953 (define_expand "add<mode>3"
7954   [(set (match_operand:MODEF 0 "register_operand" "")
7955         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7956                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7957   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7958     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7959   "")
7961 ;; Subtract instructions
7963 ;; %%% splits for subditi3
7965 (define_expand "subti3"
7966   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7967         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7968                   (match_operand:TI 2 "x86_64_general_operand" "")))]
7969   "TARGET_64BIT"
7970   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7972 (define_insn "*subti3_1"
7973   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7974         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7975                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7976    (clobber (reg:CC FLAGS_REG))]
7977   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7978   "#")
7980 (define_split
7981   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7982         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7983                   (match_operand:TI 2 "x86_64_general_operand" "")))
7984    (clobber (reg:CC FLAGS_REG))]
7985   "TARGET_64BIT && reload_completed"
7986   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7987               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7988    (parallel [(set (match_dup 3)
7989                    (minus:DI (match_dup 4)
7990                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7991                                       (match_dup 5))))
7992               (clobber (reg:CC FLAGS_REG))])]
7993   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7995 ;; %%% splits for subsidi3
7997 (define_expand "subdi3"
7998   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7999         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
8000                   (match_operand:DI 2 "x86_64_general_operand" "")))]
8001   ""
8002   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
8004 (define_insn "*subdi3_1"
8005   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
8006         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8007                   (match_operand:DI 2 "general_operand" "roiF,riF")))
8008    (clobber (reg:CC FLAGS_REG))]
8009   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
8010   "#")
8012 (define_split
8013   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8014         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
8015                   (match_operand:DI 2 "general_operand" "")))
8016    (clobber (reg:CC FLAGS_REG))]
8017   "!TARGET_64BIT && reload_completed"
8018   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
8019               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8020    (parallel [(set (match_dup 3)
8021                    (minus:SI (match_dup 4)
8022                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
8023                                       (match_dup 5))))
8024               (clobber (reg:CC FLAGS_REG))])]
8025   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
8027 (define_insn "subdi3_carry_rex64"
8028   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8029           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8030             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
8031                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
8032    (clobber (reg:CC FLAGS_REG))]
8033   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
8034   "sbb{q}\t{%2, %0|%0, %2}"
8035   [(set_attr "type" "alu")
8036    (set_attr "use_carry" "1")
8037    (set_attr "pent_pair" "pu")
8038    (set_attr "mode" "DI")])
8040 (define_insn "*subdi_1_rex64"
8041   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8042         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8043                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8044    (clobber (reg:CC FLAGS_REG))]
8045   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
8046   "sub{q}\t{%2, %0|%0, %2}"
8047   [(set_attr "type" "alu")
8048    (set_attr "mode" "DI")])
8050 (define_insn "*subdi_2_rex64"
8051   [(set (reg FLAGS_REG)
8052         (compare
8053           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8054                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
8055           (const_int 0)))
8056    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8057         (minus:DI (match_dup 1) (match_dup 2)))]
8058   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
8059    && ix86_binary_operator_ok (MINUS, DImode, operands)"
8060   "sub{q}\t{%2, %0|%0, %2}"
8061   [(set_attr "type" "alu")
8062    (set_attr "mode" "DI")])
8064 (define_insn "*subdi_3_rex63"
8065   [(set (reg FLAGS_REG)
8066         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
8067                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8068    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8069         (minus:DI (match_dup 1) (match_dup 2)))]
8070   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8071    && ix86_binary_operator_ok (MINUS, SImode, operands)"
8072   "sub{q}\t{%2, %0|%0, %2}"
8073   [(set_attr "type" "alu")
8074    (set_attr "mode" "DI")])
8076 (define_insn "subqi3_carry"
8077   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8078           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8079             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
8080                (match_operand:QI 2 "general_operand" "qn,qm"))))
8081    (clobber (reg:CC FLAGS_REG))]
8082   "ix86_binary_operator_ok (MINUS, QImode, operands)"
8083   "sbb{b}\t{%2, %0|%0, %2}"
8084   [(set_attr "type" "alu")
8085    (set_attr "use_carry" "1")
8086    (set_attr "pent_pair" "pu")
8087    (set_attr "mode" "QI")])
8089 (define_insn "subhi3_carry"
8090   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8091           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8092             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
8093                (match_operand:HI 2 "general_operand" "rn,rm"))))
8094    (clobber (reg:CC FLAGS_REG))]
8095   "ix86_binary_operator_ok (MINUS, HImode, operands)"
8096   "sbb{w}\t{%2, %0|%0, %2}"
8097   [(set_attr "type" "alu")
8098    (set_attr "use_carry" "1")
8099    (set_attr "pent_pair" "pu")
8100    (set_attr "mode" "HI")])
8102 (define_insn "subsi3_carry"
8103   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8104           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8105             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
8106                (match_operand:SI 2 "general_operand" "ri,rm"))))
8107    (clobber (reg:CC FLAGS_REG))]
8108   "ix86_binary_operator_ok (MINUS, SImode, operands)"
8109   "sbb{l}\t{%2, %0|%0, %2}"
8110   [(set_attr "type" "alu")
8111    (set_attr "use_carry" "1")
8112    (set_attr "pent_pair" "pu")
8113    (set_attr "mode" "SI")])
8115 (define_insn "subsi3_carry_zext"
8116   [(set (match_operand:DI 0 "register_operand" "=r")
8117           (zero_extend:DI
8118             (minus:SI (match_operand:SI 1 "register_operand" "0")
8119               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
8120                  (match_operand:SI 2 "general_operand" "g")))))
8121    (clobber (reg:CC FLAGS_REG))]
8122   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8123   "sbb{l}\t{%2, %k0|%k0, %2}"
8124   [(set_attr "type" "alu")
8125    (set_attr "pent_pair" "pu")
8126    (set_attr "mode" "SI")])
8128 (define_expand "subsi3"
8129   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8130         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
8131                   (match_operand:SI 2 "general_operand" "")))]
8132   ""
8133   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
8135 (define_insn "*subsi_1"
8136   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8137         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8138                   (match_operand:SI 2 "general_operand" "ri,rm")))
8139    (clobber (reg:CC FLAGS_REG))]
8140   "ix86_binary_operator_ok (MINUS, SImode, operands)"
8141   "sub{l}\t{%2, %0|%0, %2}"
8142   [(set_attr "type" "alu")
8143    (set_attr "mode" "SI")])
8145 (define_insn "*subsi_1_zext"
8146   [(set (match_operand:DI 0 "register_operand" "=r")
8147         (zero_extend:DI
8148           (minus:SI (match_operand:SI 1 "register_operand" "0")
8149                     (match_operand:SI 2 "general_operand" "g"))))
8150    (clobber (reg:CC FLAGS_REG))]
8151   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8152   "sub{l}\t{%2, %k0|%k0, %2}"
8153   [(set_attr "type" "alu")
8154    (set_attr "mode" "SI")])
8156 (define_insn "*subsi_2"
8157   [(set (reg FLAGS_REG)
8158         (compare
8159           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8160                     (match_operand:SI 2 "general_operand" "ri,rm"))
8161           (const_int 0)))
8162    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8163         (minus:SI (match_dup 1) (match_dup 2)))]
8164   "ix86_match_ccmode (insn, CCGOCmode)
8165    && ix86_binary_operator_ok (MINUS, SImode, operands)"
8166   "sub{l}\t{%2, %0|%0, %2}"
8167   [(set_attr "type" "alu")
8168    (set_attr "mode" "SI")])
8170 (define_insn "*subsi_2_zext"
8171   [(set (reg FLAGS_REG)
8172         (compare
8173           (minus:SI (match_operand:SI 1 "register_operand" "0")
8174                     (match_operand:SI 2 "general_operand" "g"))
8175           (const_int 0)))
8176    (set (match_operand:DI 0 "register_operand" "=r")
8177         (zero_extend:DI
8178           (minus:SI (match_dup 1)
8179                     (match_dup 2))))]
8180   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
8181    && ix86_binary_operator_ok (MINUS, SImode, operands)"
8182   "sub{l}\t{%2, %k0|%k0, %2}"
8183   [(set_attr "type" "alu")
8184    (set_attr "mode" "SI")])
8186 (define_insn "*subsi_3"
8187   [(set (reg FLAGS_REG)
8188         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
8189                  (match_operand:SI 2 "general_operand" "ri,rm")))
8190    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8191         (minus:SI (match_dup 1) (match_dup 2)))]
8192   "ix86_match_ccmode (insn, CCmode)
8193    && ix86_binary_operator_ok (MINUS, SImode, operands)"
8194   "sub{l}\t{%2, %0|%0, %2}"
8195   [(set_attr "type" "alu")
8196    (set_attr "mode" "SI")])
8198 (define_insn "*subsi_3_zext"
8199   [(set (reg FLAGS_REG)
8200         (compare (match_operand:SI 1 "register_operand" "0")
8201                  (match_operand:SI 2 "general_operand" "g")))
8202    (set (match_operand:DI 0 "register_operand" "=r")
8203         (zero_extend:DI
8204           (minus:SI (match_dup 1)
8205                     (match_dup 2))))]
8206   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8207    && ix86_binary_operator_ok (MINUS, SImode, operands)"
8208   "sub{l}\t{%2, %1|%1, %2}"
8209   [(set_attr "type" "alu")
8210    (set_attr "mode" "DI")])
8212 (define_expand "subhi3"
8213   [(set (match_operand:HI 0 "nonimmediate_operand" "")
8214         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
8215                   (match_operand:HI 2 "general_operand" "")))]
8216   "TARGET_HIMODE_MATH"
8217   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
8219 (define_insn "*subhi_1"
8220   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8221         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8222                   (match_operand:HI 2 "general_operand" "rn,rm")))
8223    (clobber (reg:CC FLAGS_REG))]
8224   "ix86_binary_operator_ok (MINUS, HImode, operands)"
8225   "sub{w}\t{%2, %0|%0, %2}"
8226   [(set_attr "type" "alu")
8227    (set_attr "mode" "HI")])
8229 (define_insn "*subhi_2"
8230   [(set (reg FLAGS_REG)
8231         (compare
8232           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8233                     (match_operand:HI 2 "general_operand" "rn,rm"))
8234           (const_int 0)))
8235    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8236         (minus:HI (match_dup 1) (match_dup 2)))]
8237   "ix86_match_ccmode (insn, CCGOCmode)
8238    && ix86_binary_operator_ok (MINUS, HImode, operands)"
8239   "sub{w}\t{%2, %0|%0, %2}"
8240   [(set_attr "type" "alu")
8241    (set_attr "mode" "HI")])
8243 (define_insn "*subhi_3"
8244   [(set (reg FLAGS_REG)
8245         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
8246                  (match_operand:HI 2 "general_operand" "rn,rm")))
8247    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8248         (minus:HI (match_dup 1) (match_dup 2)))]
8249   "ix86_match_ccmode (insn, CCmode)
8250    && ix86_binary_operator_ok (MINUS, HImode, operands)"
8251   "sub{w}\t{%2, %0|%0, %2}"
8252   [(set_attr "type" "alu")
8253    (set_attr "mode" "HI")])
8255 (define_expand "subqi3"
8256   [(set (match_operand:QI 0 "nonimmediate_operand" "")
8257         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
8258                   (match_operand:QI 2 "general_operand" "")))]
8259   "TARGET_QIMODE_MATH"
8260   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
8262 (define_insn "*subqi_1"
8263   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8264         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8265                   (match_operand:QI 2 "general_operand" "qn,qm")))
8266    (clobber (reg:CC FLAGS_REG))]
8267   "ix86_binary_operator_ok (MINUS, QImode, operands)"
8268   "sub{b}\t{%2, %0|%0, %2}"
8269   [(set_attr "type" "alu")
8270    (set_attr "mode" "QI")])
8272 (define_insn "*subqi_1_slp"
8273   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8274         (minus:QI (match_dup 0)
8275                   (match_operand:QI 1 "general_operand" "qn,qm")))
8276    (clobber (reg:CC FLAGS_REG))]
8277   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8278    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8279   "sub{b}\t{%1, %0|%0, %1}"
8280   [(set_attr "type" "alu1")
8281    (set_attr "mode" "QI")])
8283 (define_insn "*subqi_2"
8284   [(set (reg FLAGS_REG)
8285         (compare
8286           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8287                     (match_operand:QI 2 "general_operand" "qn,qm"))
8288           (const_int 0)))
8289    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8290         (minus:QI (match_dup 1) (match_dup 2)))]
8291   "ix86_match_ccmode (insn, CCGOCmode)
8292    && ix86_binary_operator_ok (MINUS, QImode, operands)"
8293   "sub{b}\t{%2, %0|%0, %2}"
8294   [(set_attr "type" "alu")
8295    (set_attr "mode" "QI")])
8297 (define_insn "*subqi_3"
8298   [(set (reg FLAGS_REG)
8299         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
8300                  (match_operand:QI 2 "general_operand" "qn,qm")))
8301    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8302         (minus:QI (match_dup 1) (match_dup 2)))]
8303   "ix86_match_ccmode (insn, CCmode)
8304    && ix86_binary_operator_ok (MINUS, QImode, operands)"
8305   "sub{b}\t{%2, %0|%0, %2}"
8306   [(set_attr "type" "alu")
8307    (set_attr "mode" "QI")])
8309 ;; The patterns that match these are at the end of this file.
8311 (define_expand "subxf3"
8312   [(set (match_operand:XF 0 "register_operand" "")
8313         (minus:XF (match_operand:XF 1 "register_operand" "")
8314                   (match_operand:XF 2 "register_operand" "")))]
8315   "TARGET_80387"
8316   "")
8318 (define_expand "sub<mode>3"
8319   [(set (match_operand:MODEF 0 "register_operand" "")
8320         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
8321                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8322   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8323     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8324   "")
8326 ;; Multiply instructions
8328 (define_expand "muldi3"
8329   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8330                    (mult:DI (match_operand:DI 1 "register_operand" "")
8331                             (match_operand:DI 2 "x86_64_general_operand" "")))
8332               (clobber (reg:CC FLAGS_REG))])]
8333   "TARGET_64BIT"
8334   "")
8336 ;; On AMDFAM10
8337 ;; IMUL reg64, reg64, imm8      Direct
8338 ;; IMUL reg64, mem64, imm8      VectorPath
8339 ;; IMUL reg64, reg64, imm32     Direct
8340 ;; IMUL reg64, mem64, imm32     VectorPath
8341 ;; IMUL reg64, reg64            Direct
8342 ;; IMUL reg64, mem64            Direct
8344 (define_insn "*muldi3_1_rex64"
8345   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8346         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
8347                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
8348    (clobber (reg:CC FLAGS_REG))]
8349   "TARGET_64BIT
8350    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8351   "@
8352    imul{q}\t{%2, %1, %0|%0, %1, %2}
8353    imul{q}\t{%2, %1, %0|%0, %1, %2}
8354    imul{q}\t{%2, %0|%0, %2}"
8355   [(set_attr "type" "imul")
8356    (set_attr "prefix_0f" "0,0,1")
8357    (set (attr "athlon_decode")
8358         (cond [(eq_attr "cpu" "athlon")
8359                   (const_string "vector")
8360                (eq_attr "alternative" "1")
8361                   (const_string "vector")
8362                (and (eq_attr "alternative" "2")
8363                     (match_operand 1 "memory_operand" ""))
8364                   (const_string "vector")]
8365               (const_string "direct")))
8366    (set (attr "amdfam10_decode")
8367         (cond [(and (eq_attr "alternative" "0,1")
8368                     (match_operand 1 "memory_operand" ""))
8369                   (const_string "vector")]
8370               (const_string "direct")))
8371    (set_attr "mode" "DI")])
8373 (define_expand "mulsi3"
8374   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8375                    (mult:SI (match_operand:SI 1 "register_operand" "")
8376                             (match_operand:SI 2 "general_operand" "")))
8377               (clobber (reg:CC FLAGS_REG))])]
8378   ""
8379   "")
8381 ;; On AMDFAM10
8382 ;; IMUL reg32, reg32, imm8      Direct
8383 ;; IMUL reg32, mem32, imm8      VectorPath
8384 ;; IMUL reg32, reg32, imm32     Direct
8385 ;; IMUL reg32, mem32, imm32     VectorPath
8386 ;; IMUL reg32, reg32            Direct
8387 ;; IMUL reg32, mem32            Direct
8389 (define_insn "*mulsi3_1"
8390   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
8391         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
8392                  (match_operand:SI 2 "general_operand" "K,i,mr")))
8393    (clobber (reg:CC FLAGS_REG))]
8394   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8395   "@
8396    imul{l}\t{%2, %1, %0|%0, %1, %2}
8397    imul{l}\t{%2, %1, %0|%0, %1, %2}
8398    imul{l}\t{%2, %0|%0, %2}"
8399   [(set_attr "type" "imul")
8400    (set_attr "prefix_0f" "0,0,1")
8401    (set (attr "athlon_decode")
8402         (cond [(eq_attr "cpu" "athlon")
8403                   (const_string "vector")
8404                (eq_attr "alternative" "1")
8405                   (const_string "vector")
8406                (and (eq_attr "alternative" "2")
8407                     (match_operand 1 "memory_operand" ""))
8408                   (const_string "vector")]
8409               (const_string "direct")))
8410    (set (attr "amdfam10_decode")
8411         (cond [(and (eq_attr "alternative" "0,1")
8412                     (match_operand 1 "memory_operand" ""))
8413                   (const_string "vector")]
8414               (const_string "direct")))
8415    (set_attr "mode" "SI")])
8417 (define_insn "*mulsi3_1_zext"
8418   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8419         (zero_extend:DI
8420           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
8421                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
8422    (clobber (reg:CC FLAGS_REG))]
8423   "TARGET_64BIT
8424    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8425   "@
8426    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8427    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8428    imul{l}\t{%2, %k0|%k0, %2}"
8429   [(set_attr "type" "imul")
8430    (set_attr "prefix_0f" "0,0,1")
8431    (set (attr "athlon_decode")
8432         (cond [(eq_attr "cpu" "athlon")
8433                   (const_string "vector")
8434                (eq_attr "alternative" "1")
8435                   (const_string "vector")
8436                (and (eq_attr "alternative" "2")
8437                     (match_operand 1 "memory_operand" ""))
8438                   (const_string "vector")]
8439               (const_string "direct")))
8440    (set (attr "amdfam10_decode")
8441         (cond [(and (eq_attr "alternative" "0,1")
8442                     (match_operand 1 "memory_operand" ""))
8443                   (const_string "vector")]
8444               (const_string "direct")))
8445    (set_attr "mode" "SI")])
8447 (define_expand "mulhi3"
8448   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8449                    (mult:HI (match_operand:HI 1 "register_operand" "")
8450                             (match_operand:HI 2 "general_operand" "")))
8451               (clobber (reg:CC FLAGS_REG))])]
8452   "TARGET_HIMODE_MATH"
8453   "")
8455 ;; On AMDFAM10
8456 ;; IMUL reg16, reg16, imm8      VectorPath
8457 ;; IMUL reg16, mem16, imm8      VectorPath
8458 ;; IMUL reg16, reg16, imm16     VectorPath
8459 ;; IMUL reg16, mem16, imm16     VectorPath
8460 ;; IMUL reg16, reg16            Direct
8461 ;; IMUL reg16, mem16            Direct
8462 (define_insn "*mulhi3_1"
8463   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
8464         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
8465                  (match_operand:HI 2 "general_operand" "K,n,mr")))
8466    (clobber (reg:CC FLAGS_REG))]
8467   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8468   "@
8469    imul{w}\t{%2, %1, %0|%0, %1, %2}
8470    imul{w}\t{%2, %1, %0|%0, %1, %2}
8471    imul{w}\t{%2, %0|%0, %2}"
8472   [(set_attr "type" "imul")
8473    (set_attr "prefix_0f" "0,0,1")
8474    (set (attr "athlon_decode")
8475         (cond [(eq_attr "cpu" "athlon")
8476                   (const_string "vector")
8477                (eq_attr "alternative" "1,2")
8478                   (const_string "vector")]
8479               (const_string "direct")))
8480    (set (attr "amdfam10_decode")
8481         (cond [(eq_attr "alternative" "0,1")
8482                   (const_string "vector")]
8483               (const_string "direct")))
8484    (set_attr "mode" "HI")])
8486 (define_expand "mulqi3"
8487   [(parallel [(set (match_operand:QI 0 "register_operand" "")
8488                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8489                             (match_operand:QI 2 "register_operand" "")))
8490               (clobber (reg:CC FLAGS_REG))])]
8491   "TARGET_QIMODE_MATH"
8492   "")
8494 ;;On AMDFAM10
8495 ;; MUL reg8     Direct
8496 ;; MUL mem8     Direct
8498 (define_insn "*mulqi3_1"
8499   [(set (match_operand:QI 0 "register_operand" "=a")
8500         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8501                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8502    (clobber (reg:CC FLAGS_REG))]
8503   "TARGET_QIMODE_MATH
8504    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8505   "mul{b}\t%2"
8506   [(set_attr "type" "imul")
8507    (set_attr "length_immediate" "0")
8508    (set (attr "athlon_decode")
8509      (if_then_else (eq_attr "cpu" "athlon")
8510         (const_string "vector")
8511         (const_string "direct")))
8512    (set_attr "amdfam10_decode" "direct")
8513    (set_attr "mode" "QI")])
8515 (define_expand "umulqihi3"
8516   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8517                    (mult:HI (zero_extend:HI
8518                               (match_operand:QI 1 "nonimmediate_operand" ""))
8519                             (zero_extend:HI
8520                               (match_operand:QI 2 "register_operand" ""))))
8521               (clobber (reg:CC FLAGS_REG))])]
8522   "TARGET_QIMODE_MATH"
8523   "")
8525 (define_insn "*umulqihi3_1"
8526   [(set (match_operand:HI 0 "register_operand" "=a")
8527         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8528                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8529    (clobber (reg:CC FLAGS_REG))]
8530   "TARGET_QIMODE_MATH
8531    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8532   "mul{b}\t%2"
8533   [(set_attr "type" "imul")
8534    (set_attr "length_immediate" "0")
8535    (set (attr "athlon_decode")
8536      (if_then_else (eq_attr "cpu" "athlon")
8537         (const_string "vector")
8538         (const_string "direct")))
8539    (set_attr "amdfam10_decode" "direct")
8540    (set_attr "mode" "QI")])
8542 (define_expand "mulqihi3"
8543   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8544                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8545                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8546               (clobber (reg:CC FLAGS_REG))])]
8547   "TARGET_QIMODE_MATH"
8548   "")
8550 (define_insn "*mulqihi3_insn"
8551   [(set (match_operand:HI 0 "register_operand" "=a")
8552         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8553                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8554    (clobber (reg:CC FLAGS_REG))]
8555   "TARGET_QIMODE_MATH
8556    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8557   "imul{b}\t%2"
8558   [(set_attr "type" "imul")
8559    (set_attr "length_immediate" "0")
8560    (set (attr "athlon_decode")
8561      (if_then_else (eq_attr "cpu" "athlon")
8562         (const_string "vector")
8563         (const_string "direct")))
8564    (set_attr "amdfam10_decode" "direct")
8565    (set_attr "mode" "QI")])
8567 (define_expand "umulditi3"
8568   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8569                    (mult:TI (zero_extend:TI
8570                               (match_operand:DI 1 "nonimmediate_operand" ""))
8571                             (zero_extend:TI
8572                               (match_operand:DI 2 "register_operand" ""))))
8573               (clobber (reg:CC FLAGS_REG))])]
8574   "TARGET_64BIT"
8575   "")
8577 (define_insn "*umulditi3_insn"
8578   [(set (match_operand:TI 0 "register_operand" "=A")
8579         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8580                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8581    (clobber (reg:CC FLAGS_REG))]
8582   "TARGET_64BIT
8583    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8584   "mul{q}\t%2"
8585   [(set_attr "type" "imul")
8586    (set_attr "length_immediate" "0")
8587    (set (attr "athlon_decode")
8588      (if_then_else (eq_attr "cpu" "athlon")
8589         (const_string "vector")
8590         (const_string "double")))
8591    (set_attr "amdfam10_decode" "double")
8592    (set_attr "mode" "DI")])
8594 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8595 (define_expand "umulsidi3"
8596   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8597                    (mult:DI (zero_extend:DI
8598                               (match_operand:SI 1 "nonimmediate_operand" ""))
8599                             (zero_extend:DI
8600                               (match_operand:SI 2 "register_operand" ""))))
8601               (clobber (reg:CC FLAGS_REG))])]
8602   "!TARGET_64BIT"
8603   "")
8605 (define_insn "*umulsidi3_insn"
8606   [(set (match_operand:DI 0 "register_operand" "=A")
8607         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8608                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8609    (clobber (reg:CC FLAGS_REG))]
8610   "!TARGET_64BIT
8611    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8612   "mul{l}\t%2"
8613   [(set_attr "type" "imul")
8614    (set_attr "length_immediate" "0")
8615    (set (attr "athlon_decode")
8616      (if_then_else (eq_attr "cpu" "athlon")
8617         (const_string "vector")
8618         (const_string "double")))
8619    (set_attr "amdfam10_decode" "double")
8620    (set_attr "mode" "SI")])
8622 (define_expand "mulditi3"
8623   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8624                    (mult:TI (sign_extend:TI
8625                               (match_operand:DI 1 "nonimmediate_operand" ""))
8626                             (sign_extend:TI
8627                               (match_operand:DI 2 "register_operand" ""))))
8628               (clobber (reg:CC FLAGS_REG))])]
8629   "TARGET_64BIT"
8630   "")
8632 (define_insn "*mulditi3_insn"
8633   [(set (match_operand:TI 0 "register_operand" "=A")
8634         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8635                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8636    (clobber (reg:CC FLAGS_REG))]
8637   "TARGET_64BIT
8638    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8639   "imul{q}\t%2"
8640   [(set_attr "type" "imul")
8641    (set_attr "length_immediate" "0")
8642    (set (attr "athlon_decode")
8643      (if_then_else (eq_attr "cpu" "athlon")
8644         (const_string "vector")
8645         (const_string "double")))
8646    (set_attr "amdfam10_decode" "double")
8647    (set_attr "mode" "DI")])
8649 (define_expand "mulsidi3"
8650   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8651                    (mult:DI (sign_extend:DI
8652                               (match_operand:SI 1 "nonimmediate_operand" ""))
8653                             (sign_extend:DI
8654                               (match_operand:SI 2 "register_operand" ""))))
8655               (clobber (reg:CC FLAGS_REG))])]
8656   "!TARGET_64BIT"
8657   "")
8659 (define_insn "*mulsidi3_insn"
8660   [(set (match_operand:DI 0 "register_operand" "=A")
8661         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8662                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8663    (clobber (reg:CC FLAGS_REG))]
8664   "!TARGET_64BIT
8665    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8666   "imul{l}\t%2"
8667   [(set_attr "type" "imul")
8668    (set_attr "length_immediate" "0")
8669    (set (attr "athlon_decode")
8670      (if_then_else (eq_attr "cpu" "athlon")
8671         (const_string "vector")
8672         (const_string "double")))
8673    (set_attr "amdfam10_decode" "double")
8674    (set_attr "mode" "SI")])
8676 (define_expand "umuldi3_highpart"
8677   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8678                    (truncate:DI
8679                      (lshiftrt:TI
8680                        (mult:TI (zero_extend:TI
8681                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8682                                 (zero_extend:TI
8683                                   (match_operand:DI 2 "register_operand" "")))
8684                        (const_int 64))))
8685               (clobber (match_scratch:DI 3 ""))
8686               (clobber (reg:CC FLAGS_REG))])]
8687   "TARGET_64BIT"
8688   "")
8690 (define_insn "*umuldi3_highpart_rex64"
8691   [(set (match_operand:DI 0 "register_operand" "=d")
8692         (truncate:DI
8693           (lshiftrt:TI
8694             (mult:TI (zero_extend:TI
8695                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8696                      (zero_extend:TI
8697                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8698             (const_int 64))))
8699    (clobber (match_scratch:DI 3 "=1"))
8700    (clobber (reg:CC FLAGS_REG))]
8701   "TARGET_64BIT
8702    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8703   "mul{q}\t%2"
8704   [(set_attr "type" "imul")
8705    (set_attr "length_immediate" "0")
8706    (set (attr "athlon_decode")
8707      (if_then_else (eq_attr "cpu" "athlon")
8708         (const_string "vector")
8709         (const_string "double")))
8710    (set_attr "amdfam10_decode" "double")
8711    (set_attr "mode" "DI")])
8713 (define_expand "umulsi3_highpart"
8714   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8715                    (truncate:SI
8716                      (lshiftrt:DI
8717                        (mult:DI (zero_extend:DI
8718                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8719                                 (zero_extend:DI
8720                                   (match_operand:SI 2 "register_operand" "")))
8721                        (const_int 32))))
8722               (clobber (match_scratch:SI 3 ""))
8723               (clobber (reg:CC FLAGS_REG))])]
8724   ""
8725   "")
8727 (define_insn "*umulsi3_highpart_insn"
8728   [(set (match_operand:SI 0 "register_operand" "=d")
8729         (truncate:SI
8730           (lshiftrt:DI
8731             (mult:DI (zero_extend:DI
8732                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8733                      (zero_extend:DI
8734                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8735             (const_int 32))))
8736    (clobber (match_scratch:SI 3 "=1"))
8737    (clobber (reg:CC FLAGS_REG))]
8738   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8739   "mul{l}\t%2"
8740   [(set_attr "type" "imul")
8741    (set_attr "length_immediate" "0")
8742    (set (attr "athlon_decode")
8743      (if_then_else (eq_attr "cpu" "athlon")
8744         (const_string "vector")
8745         (const_string "double")))
8746    (set_attr "amdfam10_decode" "double")
8747    (set_attr "mode" "SI")])
8749 (define_insn "*umulsi3_highpart_zext"
8750   [(set (match_operand:DI 0 "register_operand" "=d")
8751         (zero_extend:DI (truncate:SI
8752           (lshiftrt:DI
8753             (mult:DI (zero_extend:DI
8754                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8755                      (zero_extend:DI
8756                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8757             (const_int 32)))))
8758    (clobber (match_scratch:SI 3 "=1"))
8759    (clobber (reg:CC FLAGS_REG))]
8760   "TARGET_64BIT
8761    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8762   "mul{l}\t%2"
8763   [(set_attr "type" "imul")
8764    (set_attr "length_immediate" "0")
8765    (set (attr "athlon_decode")
8766      (if_then_else (eq_attr "cpu" "athlon")
8767         (const_string "vector")
8768         (const_string "double")))
8769    (set_attr "amdfam10_decode" "double")
8770    (set_attr "mode" "SI")])
8772 (define_expand "smuldi3_highpart"
8773   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8774                    (truncate:DI
8775                      (lshiftrt:TI
8776                        (mult:TI (sign_extend:TI
8777                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8778                                 (sign_extend:TI
8779                                   (match_operand:DI 2 "register_operand" "")))
8780                        (const_int 64))))
8781               (clobber (match_scratch:DI 3 ""))
8782               (clobber (reg:CC FLAGS_REG))])]
8783   "TARGET_64BIT"
8784   "")
8786 (define_insn "*smuldi3_highpart_rex64"
8787   [(set (match_operand:DI 0 "register_operand" "=d")
8788         (truncate:DI
8789           (lshiftrt:TI
8790             (mult:TI (sign_extend:TI
8791                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8792                      (sign_extend:TI
8793                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8794             (const_int 64))))
8795    (clobber (match_scratch:DI 3 "=1"))
8796    (clobber (reg:CC FLAGS_REG))]
8797   "TARGET_64BIT
8798    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8799   "imul{q}\t%2"
8800   [(set_attr "type" "imul")
8801    (set (attr "athlon_decode")
8802      (if_then_else (eq_attr "cpu" "athlon")
8803         (const_string "vector")
8804         (const_string "double")))
8805    (set_attr "amdfam10_decode" "double")
8806    (set_attr "mode" "DI")])
8808 (define_expand "smulsi3_highpart"
8809   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8810                    (truncate:SI
8811                      (lshiftrt:DI
8812                        (mult:DI (sign_extend:DI
8813                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8814                                 (sign_extend:DI
8815                                   (match_operand:SI 2 "register_operand" "")))
8816                        (const_int 32))))
8817               (clobber (match_scratch:SI 3 ""))
8818               (clobber (reg:CC FLAGS_REG))])]
8819   ""
8820   "")
8822 (define_insn "*smulsi3_highpart_insn"
8823   [(set (match_operand:SI 0 "register_operand" "=d")
8824         (truncate:SI
8825           (lshiftrt:DI
8826             (mult:DI (sign_extend:DI
8827                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8828                      (sign_extend:DI
8829                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8830             (const_int 32))))
8831    (clobber (match_scratch:SI 3 "=1"))
8832    (clobber (reg:CC FLAGS_REG))]
8833   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8834   "imul{l}\t%2"
8835   [(set_attr "type" "imul")
8836    (set (attr "athlon_decode")
8837      (if_then_else (eq_attr "cpu" "athlon")
8838         (const_string "vector")
8839         (const_string "double")))
8840    (set_attr "amdfam10_decode" "double")
8841    (set_attr "mode" "SI")])
8843 (define_insn "*smulsi3_highpart_zext"
8844   [(set (match_operand:DI 0 "register_operand" "=d")
8845         (zero_extend:DI (truncate:SI
8846           (lshiftrt:DI
8847             (mult:DI (sign_extend:DI
8848                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8849                      (sign_extend:DI
8850                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8851             (const_int 32)))))
8852    (clobber (match_scratch:SI 3 "=1"))
8853    (clobber (reg:CC FLAGS_REG))]
8854   "TARGET_64BIT
8855    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8856   "imul{l}\t%2"
8857   [(set_attr "type" "imul")
8858    (set (attr "athlon_decode")
8859      (if_then_else (eq_attr "cpu" "athlon")
8860         (const_string "vector")
8861         (const_string "double")))
8862    (set_attr "amdfam10_decode" "double")
8863    (set_attr "mode" "SI")])
8865 ;; The patterns that match these are at the end of this file.
8867 (define_expand "mulxf3"
8868   [(set (match_operand:XF 0 "register_operand" "")
8869         (mult:XF (match_operand:XF 1 "register_operand" "")
8870                  (match_operand:XF 2 "register_operand" "")))]
8871   "TARGET_80387"
8872   "")
8874 (define_expand "mul<mode>3"
8875   [(set (match_operand:MODEF 0 "register_operand" "")
8876         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8877                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8878   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8879     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8880   "")
8882 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8885 ;; Divide instructions
8887 (define_insn "divqi3"
8888   [(set (match_operand:QI 0 "register_operand" "=a")
8889         (div:QI (match_operand:HI 1 "register_operand" "0")
8890                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8891    (clobber (reg:CC FLAGS_REG))]
8892   "TARGET_QIMODE_MATH"
8893   "idiv{b}\t%2"
8894   [(set_attr "type" "idiv")
8895    (set_attr "mode" "QI")])
8897 (define_insn "udivqi3"
8898   [(set (match_operand:QI 0 "register_operand" "=a")
8899         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8900                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8901    (clobber (reg:CC FLAGS_REG))]
8902   "TARGET_QIMODE_MATH"
8903   "div{b}\t%2"
8904   [(set_attr "type" "idiv")
8905    (set_attr "mode" "QI")])
8907 ;; The patterns that match these are at the end of this file.
8909 (define_expand "divxf3"
8910   [(set (match_operand:XF 0 "register_operand" "")
8911         (div:XF (match_operand:XF 1 "register_operand" "")
8912                 (match_operand:XF 2 "register_operand" "")))]
8913   "TARGET_80387"
8914   "")
8916 (define_expand "divdf3"
8917   [(set (match_operand:DF 0 "register_operand" "")
8918         (div:DF (match_operand:DF 1 "register_operand" "")
8919                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8920    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
8921     || (TARGET_SSE2 && TARGET_SSE_MATH)"
8922    "")
8924 (define_expand "divsf3"
8925   [(set (match_operand:SF 0 "register_operand" "")
8926         (div:SF (match_operand:SF 1 "register_operand" "")
8927                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8928   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
8929     || TARGET_SSE_MATH"
8931   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8932       && flag_finite_math_only && !flag_trapping_math
8933       && flag_unsafe_math_optimizations)
8934     {
8935       ix86_emit_swdivsf (operands[0], operands[1],
8936                          operands[2], SFmode);
8937       DONE;
8938     }
8941 ;; Remainder instructions.
8943 (define_expand "divmoddi4"
8944   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8945                    (div:DI (match_operand:DI 1 "register_operand" "")
8946                            (match_operand:DI 2 "nonimmediate_operand" "")))
8947               (set (match_operand:DI 3 "register_operand" "")
8948                    (mod:DI (match_dup 1) (match_dup 2)))
8949               (clobber (reg:CC FLAGS_REG))])]
8950   "TARGET_64BIT"
8951   "")
8953 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8954 ;; Penalize eax case slightly because it results in worse scheduling
8955 ;; of code.
8956 (define_insn "*divmoddi4_nocltd_rex64"
8957   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8958         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8959                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8960    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8961         (mod:DI (match_dup 2) (match_dup 3)))
8962    (clobber (reg:CC FLAGS_REG))]
8963   "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8964   "#"
8965   [(set_attr "type" "multi")])
8967 (define_insn "*divmoddi4_cltd_rex64"
8968   [(set (match_operand:DI 0 "register_operand" "=a")
8969         (div:DI (match_operand:DI 2 "register_operand" "a")
8970                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8971    (set (match_operand:DI 1 "register_operand" "=&d")
8972         (mod:DI (match_dup 2) (match_dup 3)))
8973    (clobber (reg:CC FLAGS_REG))]
8974   "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8975   "#"
8976   [(set_attr "type" "multi")])
8978 (define_insn "*divmoddi_noext_rex64"
8979   [(set (match_operand:DI 0 "register_operand" "=a")
8980         (div:DI (match_operand:DI 1 "register_operand" "0")
8981                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8982    (set (match_operand:DI 3 "register_operand" "=d")
8983         (mod:DI (match_dup 1) (match_dup 2)))
8984    (use (match_operand:DI 4 "register_operand" "3"))
8985    (clobber (reg:CC FLAGS_REG))]
8986   "TARGET_64BIT"
8987   "idiv{q}\t%2"
8988   [(set_attr "type" "idiv")
8989    (set_attr "mode" "DI")])
8991 (define_split
8992   [(set (match_operand:DI 0 "register_operand" "")
8993         (div:DI (match_operand:DI 1 "register_operand" "")
8994                 (match_operand:DI 2 "nonimmediate_operand" "")))
8995    (set (match_operand:DI 3 "register_operand" "")
8996         (mod:DI (match_dup 1) (match_dup 2)))
8997    (clobber (reg:CC FLAGS_REG))]
8998   "TARGET_64BIT && reload_completed"
8999   [(parallel [(set (match_dup 3)
9000                    (ashiftrt:DI (match_dup 4) (const_int 63)))
9001               (clobber (reg:CC FLAGS_REG))])
9002    (parallel [(set (match_dup 0)
9003                    (div:DI (reg:DI 0) (match_dup 2)))
9004               (set (match_dup 3)
9005                    (mod:DI (reg:DI 0) (match_dup 2)))
9006               (use (match_dup 3))
9007               (clobber (reg:CC FLAGS_REG))])]
9009   /* Avoid use of cltd in favor of a mov+shift.  */
9010   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
9011     {
9012       if (true_regnum (operands[1]))
9013         emit_move_insn (operands[0], operands[1]);
9014       else
9015         emit_move_insn (operands[3], operands[1]);
9016       operands[4] = operands[3];
9017     }
9018   else
9019     {
9020       gcc_assert (!true_regnum (operands[1]));
9021       operands[4] = operands[1];
9022     }
9026 (define_expand "divmodsi4"
9027   [(parallel [(set (match_operand:SI 0 "register_operand" "")
9028                    (div:SI (match_operand:SI 1 "register_operand" "")
9029                            (match_operand:SI 2 "nonimmediate_operand" "")))
9030               (set (match_operand:SI 3 "register_operand" "")
9031                    (mod:SI (match_dup 1) (match_dup 2)))
9032               (clobber (reg:CC FLAGS_REG))])]
9033   ""
9034   "")
9036 ;; Allow to come the parameter in eax or edx to avoid extra moves.
9037 ;; Penalize eax case slightly because it results in worse scheduling
9038 ;; of code.
9039 (define_insn "*divmodsi4_nocltd"
9040   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
9041         (div:SI (match_operand:SI 2 "register_operand" "1,0")
9042                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
9043    (set (match_operand:SI 1 "register_operand" "=&d,&d")
9044         (mod:SI (match_dup 2) (match_dup 3)))
9045    (clobber (reg:CC FLAGS_REG))]
9046   "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
9047   "#"
9048   [(set_attr "type" "multi")])
9050 (define_insn "*divmodsi4_cltd"
9051   [(set (match_operand:SI 0 "register_operand" "=a")
9052         (div:SI (match_operand:SI 2 "register_operand" "a")
9053                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
9054    (set (match_operand:SI 1 "register_operand" "=&d")
9055         (mod:SI (match_dup 2) (match_dup 3)))
9056    (clobber (reg:CC FLAGS_REG))]
9057   "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
9058   "#"
9059   [(set_attr "type" "multi")])
9061 (define_insn "*divmodsi_noext"
9062   [(set (match_operand:SI 0 "register_operand" "=a")
9063         (div:SI (match_operand:SI 1 "register_operand" "0")
9064                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9065    (set (match_operand:SI 3 "register_operand" "=d")
9066         (mod:SI (match_dup 1) (match_dup 2)))
9067    (use (match_operand:SI 4 "register_operand" "3"))
9068    (clobber (reg:CC FLAGS_REG))]
9069   ""
9070   "idiv{l}\t%2"
9071   [(set_attr "type" "idiv")
9072    (set_attr "mode" "SI")])
9074 (define_split
9075   [(set (match_operand:SI 0 "register_operand" "")
9076         (div:SI (match_operand:SI 1 "register_operand" "")
9077                 (match_operand:SI 2 "nonimmediate_operand" "")))
9078    (set (match_operand:SI 3 "register_operand" "")
9079         (mod:SI (match_dup 1) (match_dup 2)))
9080    (clobber (reg:CC FLAGS_REG))]
9081   "reload_completed"
9082   [(parallel [(set (match_dup 3)
9083                    (ashiftrt:SI (match_dup 4) (const_int 31)))
9084               (clobber (reg:CC FLAGS_REG))])
9085    (parallel [(set (match_dup 0)
9086                    (div:SI (reg:SI 0) (match_dup 2)))
9087               (set (match_dup 3)
9088                    (mod:SI (reg:SI 0) (match_dup 2)))
9089               (use (match_dup 3))
9090               (clobber (reg:CC FLAGS_REG))])]
9092   /* Avoid use of cltd in favor of a mov+shift.  */
9093   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
9094     {
9095       if (true_regnum (operands[1]))
9096         emit_move_insn (operands[0], operands[1]);
9097       else
9098         emit_move_insn (operands[3], operands[1]);
9099       operands[4] = operands[3];
9100     }
9101   else
9102     {
9103       gcc_assert (!true_regnum (operands[1]));
9104       operands[4] = operands[1];
9105     }
9107 ;; %%% Split me.
9108 (define_insn "divmodhi4"
9109   [(set (match_operand:HI 0 "register_operand" "=a")
9110         (div:HI (match_operand:HI 1 "register_operand" "0")
9111                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
9112    (set (match_operand:HI 3 "register_operand" "=&d")
9113         (mod:HI (match_dup 1) (match_dup 2)))
9114    (clobber (reg:CC FLAGS_REG))]
9115   "TARGET_HIMODE_MATH"
9116   "cwtd\;idiv{w}\t%2"
9117   [(set_attr "type" "multi")
9118    (set_attr "length_immediate" "0")
9119    (set_attr "mode" "SI")])
9121 (define_insn "udivmoddi4"
9122   [(set (match_operand:DI 0 "register_operand" "=a")
9123         (udiv:DI (match_operand:DI 1 "register_operand" "0")
9124                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
9125    (set (match_operand:DI 3 "register_operand" "=&d")
9126         (umod:DI (match_dup 1) (match_dup 2)))
9127    (clobber (reg:CC FLAGS_REG))]
9128   "TARGET_64BIT"
9129   "xor{q}\t%3, %3\;div{q}\t%2"
9130   [(set_attr "type" "multi")
9131    (set_attr "length_immediate" "0")
9132    (set_attr "mode" "DI")])
9134 (define_insn "*udivmoddi4_noext"
9135   [(set (match_operand:DI 0 "register_operand" "=a")
9136         (udiv:DI (match_operand:DI 1 "register_operand" "0")
9137                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
9138    (set (match_operand:DI 3 "register_operand" "=d")
9139         (umod:DI (match_dup 1) (match_dup 2)))
9140    (use (match_dup 3))
9141    (clobber (reg:CC FLAGS_REG))]
9142   "TARGET_64BIT"
9143   "div{q}\t%2"
9144   [(set_attr "type" "idiv")
9145    (set_attr "mode" "DI")])
9147 (define_split
9148   [(set (match_operand:DI 0 "register_operand" "")
9149         (udiv:DI (match_operand:DI 1 "register_operand" "")
9150                  (match_operand:DI 2 "nonimmediate_operand" "")))
9151    (set (match_operand:DI 3 "register_operand" "")
9152         (umod:DI (match_dup 1) (match_dup 2)))
9153    (clobber (reg:CC FLAGS_REG))]
9154   "TARGET_64BIT && reload_completed"
9155   [(set (match_dup 3) (const_int 0))
9156    (parallel [(set (match_dup 0)
9157                    (udiv:DI (match_dup 1) (match_dup 2)))
9158               (set (match_dup 3)
9159                    (umod:DI (match_dup 1) (match_dup 2)))
9160               (use (match_dup 3))
9161               (clobber (reg:CC FLAGS_REG))])]
9162   "")
9164 (define_insn "udivmodsi4"
9165   [(set (match_operand:SI 0 "register_operand" "=a")
9166         (udiv:SI (match_operand:SI 1 "register_operand" "0")
9167                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
9168    (set (match_operand:SI 3 "register_operand" "=&d")
9169         (umod:SI (match_dup 1) (match_dup 2)))
9170    (clobber (reg:CC FLAGS_REG))]
9171   ""
9172   "xor{l}\t%3, %3\;div{l}\t%2"
9173   [(set_attr "type" "multi")
9174    (set_attr "length_immediate" "0")
9175    (set_attr "mode" "SI")])
9177 (define_insn "*udivmodsi4_noext"
9178   [(set (match_operand:SI 0 "register_operand" "=a")
9179         (udiv:SI (match_operand:SI 1 "register_operand" "0")
9180                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
9181    (set (match_operand:SI 3 "register_operand" "=d")
9182         (umod:SI (match_dup 1) (match_dup 2)))
9183    (use (match_dup 3))
9184    (clobber (reg:CC FLAGS_REG))]
9185   ""
9186   "div{l}\t%2"
9187   [(set_attr "type" "idiv")
9188    (set_attr "mode" "SI")])
9190 (define_split
9191   [(set (match_operand:SI 0 "register_operand" "")
9192         (udiv:SI (match_operand:SI 1 "register_operand" "")
9193                  (match_operand:SI 2 "nonimmediate_operand" "")))
9194    (set (match_operand:SI 3 "register_operand" "")
9195         (umod:SI (match_dup 1) (match_dup 2)))
9196    (clobber (reg:CC FLAGS_REG))]
9197   "reload_completed"
9198   [(set (match_dup 3) (const_int 0))
9199    (parallel [(set (match_dup 0)
9200                    (udiv:SI (match_dup 1) (match_dup 2)))
9201               (set (match_dup 3)
9202                    (umod:SI (match_dup 1) (match_dup 2)))
9203               (use (match_dup 3))
9204               (clobber (reg:CC FLAGS_REG))])]
9205   "")
9207 (define_expand "udivmodhi4"
9208   [(set (match_dup 4) (const_int 0))
9209    (parallel [(set (match_operand:HI 0 "register_operand" "")
9210                    (udiv:HI (match_operand:HI 1 "register_operand" "")
9211                             (match_operand:HI 2 "nonimmediate_operand" "")))
9212               (set (match_operand:HI 3 "register_operand" "")
9213                    (umod:HI (match_dup 1) (match_dup 2)))
9214               (use (match_dup 4))
9215               (clobber (reg:CC FLAGS_REG))])]
9216   "TARGET_HIMODE_MATH"
9217   "operands[4] = gen_reg_rtx (HImode);")
9219 (define_insn "*udivmodhi_noext"
9220   [(set (match_operand:HI 0 "register_operand" "=a")
9221         (udiv:HI (match_operand:HI 1 "register_operand" "0")
9222                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
9223    (set (match_operand:HI 3 "register_operand" "=d")
9224         (umod:HI (match_dup 1) (match_dup 2)))
9225    (use (match_operand:HI 4 "register_operand" "3"))
9226    (clobber (reg:CC FLAGS_REG))]
9227   ""
9228   "div{w}\t%2"
9229   [(set_attr "type" "idiv")
9230    (set_attr "mode" "HI")])
9232 ;; We cannot use div/idiv for double division, because it causes
9233 ;; "division by zero" on the overflow and that's not what we expect
9234 ;; from truncate.  Because true (non truncating) double division is
9235 ;; never generated, we can't create this insn anyway.
9237 ;(define_insn ""
9238 ;  [(set (match_operand:SI 0 "register_operand" "=a")
9239 ;       (truncate:SI
9240 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
9241 ;                  (zero_extend:DI
9242 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
9243 ;   (set (match_operand:SI 3 "register_operand" "=d")
9244 ;       (truncate:SI
9245 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
9246 ;   (clobber (reg:CC FLAGS_REG))]
9247 ;  ""
9248 ;  "div{l}\t{%2, %0|%0, %2}"
9249 ;  [(set_attr "type" "idiv")])
9251 ;;- Logical AND instructions
9253 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
9254 ;; Note that this excludes ah.
9256 (define_insn "*testdi_1_rex64"
9257   [(set (reg FLAGS_REG)
9258         (compare
9259           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
9260                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
9261           (const_int 0)))]
9262   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9263    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9264   "@
9265    test{l}\t{%k1, %k0|%k0, %k1}
9266    test{l}\t{%k1, %k0|%k0, %k1}
9267    test{q}\t{%1, %0|%0, %1}
9268    test{q}\t{%1, %0|%0, %1}
9269    test{q}\t{%1, %0|%0, %1}"
9270   [(set_attr "type" "test")
9271    (set_attr "modrm" "0,1,0,1,1")
9272    (set_attr "mode" "SI,SI,DI,DI,DI")
9273    (set_attr "pent_pair" "uv,np,uv,np,uv")])
9275 (define_insn "testsi_1"
9276   [(set (reg FLAGS_REG)
9277         (compare
9278           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
9279                   (match_operand:SI 1 "general_operand" "i,i,ri"))
9280           (const_int 0)))]
9281   "ix86_match_ccmode (insn, CCNOmode)
9282    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9283   "test{l}\t{%1, %0|%0, %1}"
9284   [(set_attr "type" "test")
9285    (set_attr "modrm" "0,1,1")
9286    (set_attr "mode" "SI")
9287    (set_attr "pent_pair" "uv,np,uv")])
9289 (define_expand "testsi_ccno_1"
9290   [(set (reg:CCNO FLAGS_REG)
9291         (compare:CCNO
9292           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
9293                   (match_operand:SI 1 "nonmemory_operand" ""))
9294           (const_int 0)))]
9295   ""
9296   "")
9298 (define_insn "*testhi_1"
9299   [(set (reg FLAGS_REG)
9300         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
9301                          (match_operand:HI 1 "general_operand" "n,n,rn"))
9302                  (const_int 0)))]
9303   "ix86_match_ccmode (insn, CCNOmode)
9304    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9305   "test{w}\t{%1, %0|%0, %1}"
9306   [(set_attr "type" "test")
9307    (set_attr "modrm" "0,1,1")
9308    (set_attr "mode" "HI")
9309    (set_attr "pent_pair" "uv,np,uv")])
9311 (define_expand "testqi_ccz_1"
9312   [(set (reg:CCZ FLAGS_REG)
9313         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
9314                              (match_operand:QI 1 "nonmemory_operand" ""))
9315                  (const_int 0)))]
9316   ""
9317   "")
9319 (define_insn "*testqi_1_maybe_si"
9320   [(set (reg FLAGS_REG)
9321         (compare
9322           (and:QI
9323             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
9324             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
9325           (const_int 0)))]
9326    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
9327     && ix86_match_ccmode (insn,
9328                          CONST_INT_P (operands[1])
9329                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
9331   if (which_alternative == 3)
9332     {
9333       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
9334         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
9335       return "test{l}\t{%1, %k0|%k0, %1}";
9336     }
9337   return "test{b}\t{%1, %0|%0, %1}";
9339   [(set_attr "type" "test")
9340    (set_attr "modrm" "0,1,1,1")
9341    (set_attr "mode" "QI,QI,QI,SI")
9342    (set_attr "pent_pair" "uv,np,uv,np")])
9344 (define_insn "*testqi_1"
9345   [(set (reg FLAGS_REG)
9346         (compare
9347           (and:QI
9348             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
9349             (match_operand:QI 1 "general_operand" "n,n,qn"))
9350           (const_int 0)))]
9351   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
9352    && ix86_match_ccmode (insn, CCNOmode)"
9353   "test{b}\t{%1, %0|%0, %1}"
9354   [(set_attr "type" "test")
9355    (set_attr "modrm" "0,1,1")
9356    (set_attr "mode" "QI")
9357    (set_attr "pent_pair" "uv,np,uv")])
9359 (define_expand "testqi_ext_ccno_0"
9360   [(set (reg:CCNO FLAGS_REG)
9361         (compare:CCNO
9362           (and:SI
9363             (zero_extract:SI
9364               (match_operand 0 "ext_register_operand" "")
9365               (const_int 8)
9366               (const_int 8))
9367             (match_operand 1 "const_int_operand" ""))
9368           (const_int 0)))]
9369   ""
9370   "")
9372 (define_insn "*testqi_ext_0"
9373   [(set (reg FLAGS_REG)
9374         (compare
9375           (and:SI
9376             (zero_extract:SI
9377               (match_operand 0 "ext_register_operand" "Q")
9378               (const_int 8)
9379               (const_int 8))
9380             (match_operand 1 "const_int_operand" "n"))
9381           (const_int 0)))]
9382   "ix86_match_ccmode (insn, CCNOmode)"
9383   "test{b}\t{%1, %h0|%h0, %1}"
9384   [(set_attr "type" "test")
9385    (set_attr "mode" "QI")
9386    (set_attr "length_immediate" "1")
9387    (set_attr "modrm" "1")
9388    (set_attr "pent_pair" "np")])
9390 (define_insn "*testqi_ext_1"
9391   [(set (reg FLAGS_REG)
9392         (compare
9393           (and:SI
9394             (zero_extract:SI
9395               (match_operand 0 "ext_register_operand" "Q")
9396               (const_int 8)
9397               (const_int 8))
9398             (zero_extend:SI
9399               (match_operand:QI 1 "general_operand" "Qm")))
9400           (const_int 0)))]
9401   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9402    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9403   "test{b}\t{%1, %h0|%h0, %1}"
9404   [(set_attr "type" "test")
9405    (set_attr "mode" "QI")])
9407 (define_insn "*testqi_ext_1_rex64"
9408   [(set (reg FLAGS_REG)
9409         (compare
9410           (and:SI
9411             (zero_extract:SI
9412               (match_operand 0 "ext_register_operand" "Q")
9413               (const_int 8)
9414               (const_int 8))
9415             (zero_extend:SI
9416               (match_operand:QI 1 "register_operand" "Q")))
9417           (const_int 0)))]
9418   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9419   "test{b}\t{%1, %h0|%h0, %1}"
9420   [(set_attr "type" "test")
9421    (set_attr "mode" "QI")])
9423 (define_insn "*testqi_ext_2"
9424   [(set (reg FLAGS_REG)
9425         (compare
9426           (and:SI
9427             (zero_extract:SI
9428               (match_operand 0 "ext_register_operand" "Q")
9429               (const_int 8)
9430               (const_int 8))
9431             (zero_extract:SI
9432               (match_operand 1 "ext_register_operand" "Q")
9433               (const_int 8)
9434               (const_int 8)))
9435           (const_int 0)))]
9436   "ix86_match_ccmode (insn, CCNOmode)"
9437   "test{b}\t{%h1, %h0|%h0, %h1}"
9438   [(set_attr "type" "test")
9439    (set_attr "mode" "QI")])
9441 ;; Combine likes to form bit extractions for some tests.  Humor it.
9442 (define_insn "*testqi_ext_3"
9443   [(set (reg FLAGS_REG)
9444         (compare (zero_extract:SI
9445                    (match_operand 0 "nonimmediate_operand" "rm")
9446                    (match_operand:SI 1 "const_int_operand" "")
9447                    (match_operand:SI 2 "const_int_operand" ""))
9448                  (const_int 0)))]
9449   "ix86_match_ccmode (insn, CCNOmode)
9450    && INTVAL (operands[1]) > 0
9451    && INTVAL (operands[2]) >= 0
9452    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9453    && (GET_MODE (operands[0]) == SImode
9454        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
9455        || GET_MODE (operands[0]) == HImode
9456        || GET_MODE (operands[0]) == QImode)"
9457   "#")
9459 (define_insn "*testqi_ext_3_rex64"
9460   [(set (reg FLAGS_REG)
9461         (compare (zero_extract:DI
9462                    (match_operand 0 "nonimmediate_operand" "rm")
9463                    (match_operand:DI 1 "const_int_operand" "")
9464                    (match_operand:DI 2 "const_int_operand" ""))
9465                  (const_int 0)))]
9466   "TARGET_64BIT
9467    && ix86_match_ccmode (insn, CCNOmode)
9468    && INTVAL (operands[1]) > 0
9469    && INTVAL (operands[2]) >= 0
9470    /* Ensure that resulting mask is zero or sign extended operand.  */
9471    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9472        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
9473            && INTVAL (operands[1]) > 32))
9474    && (GET_MODE (operands[0]) == SImode
9475        || GET_MODE (operands[0]) == DImode
9476        || GET_MODE (operands[0]) == HImode
9477        || GET_MODE (operands[0]) == QImode)"
9478   "#")
9480 (define_split
9481   [(set (match_operand 0 "flags_reg_operand" "")
9482         (match_operator 1 "compare_operator"
9483           [(zero_extract
9484              (match_operand 2 "nonimmediate_operand" "")
9485              (match_operand 3 "const_int_operand" "")
9486              (match_operand 4 "const_int_operand" ""))
9487            (const_int 0)]))]
9488   "ix86_match_ccmode (insn, CCNOmode)"
9489   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
9491   rtx val = operands[2];
9492   HOST_WIDE_INT len = INTVAL (operands[3]);
9493   HOST_WIDE_INT pos = INTVAL (operands[4]);
9494   HOST_WIDE_INT mask;
9495   enum machine_mode mode, submode;
9497   mode = GET_MODE (val);
9498   if (MEM_P (val))
9499     {
9500       /* ??? Combine likes to put non-volatile mem extractions in QImode
9501          no matter the size of the test.  So find a mode that works.  */
9502       if (! MEM_VOLATILE_P (val))
9503         {
9504           mode = smallest_mode_for_size (pos + len, MODE_INT);
9505           val = adjust_address (val, mode, 0);
9506         }
9507     }
9508   else if (GET_CODE (val) == SUBREG
9509            && (submode = GET_MODE (SUBREG_REG (val)),
9510                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9511            && pos + len <= GET_MODE_BITSIZE (submode))
9512     {
9513       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
9514       mode = submode;
9515       val = SUBREG_REG (val);
9516     }
9517   else if (mode == HImode && pos + len <= 8)
9518     {
9519       /* Small HImode tests can be converted to QImode.  */
9520       mode = QImode;
9521       val = gen_lowpart (QImode, val);
9522     }
9524   if (len == HOST_BITS_PER_WIDE_INT)
9525     mask = -1;
9526   else
9527     mask = ((HOST_WIDE_INT)1 << len) - 1;
9528   mask <<= pos;
9530   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9533 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9534 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9535 ;; this is relatively important trick.
9536 ;; Do the conversion only post-reload to avoid limiting of the register class
9537 ;; to QI regs.
9538 (define_split
9539   [(set (match_operand 0 "flags_reg_operand" "")
9540         (match_operator 1 "compare_operator"
9541           [(and (match_operand 2 "register_operand" "")
9542                 (match_operand 3 "const_int_operand" ""))
9543            (const_int 0)]))]
9544    "reload_completed
9545     && QI_REG_P (operands[2])
9546     && GET_MODE (operands[2]) != QImode
9547     && ((ix86_match_ccmode (insn, CCZmode)
9548          && !(INTVAL (operands[3]) & ~(255 << 8)))
9549         || (ix86_match_ccmode (insn, CCNOmode)
9550             && !(INTVAL (operands[3]) & ~(127 << 8))))"
9551   [(set (match_dup 0)
9552         (match_op_dup 1
9553           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9554                    (match_dup 3))
9555            (const_int 0)]))]
9556   "operands[2] = gen_lowpart (SImode, operands[2]);
9557    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9559 (define_split
9560   [(set (match_operand 0 "flags_reg_operand" "")
9561         (match_operator 1 "compare_operator"
9562           [(and (match_operand 2 "nonimmediate_operand" "")
9563                 (match_operand 3 "const_int_operand" ""))
9564            (const_int 0)]))]
9565    "reload_completed
9566     && GET_MODE (operands[2]) != QImode
9567     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9568     && ((ix86_match_ccmode (insn, CCZmode)
9569          && !(INTVAL (operands[3]) & ~255))
9570         || (ix86_match_ccmode (insn, CCNOmode)
9571             && !(INTVAL (operands[3]) & ~127)))"
9572   [(set (match_dup 0)
9573         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9574                          (const_int 0)]))]
9575   "operands[2] = gen_lowpart (QImode, operands[2]);
9576    operands[3] = gen_lowpart (QImode, operands[3]);")
9579 ;; %%% This used to optimize known byte-wide and operations to memory,
9580 ;; and sometimes to QImode registers.  If this is considered useful,
9581 ;; it should be done with splitters.
9583 (define_expand "anddi3"
9584   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9585         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9586                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9587   "TARGET_64BIT"
9588   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9590 (define_insn "*anddi_1_rex64"
9591   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9592         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9593                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9594    (clobber (reg:CC FLAGS_REG))]
9595   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9597   switch (get_attr_type (insn))
9598     {
9599     case TYPE_IMOVX:
9600       {
9601         enum machine_mode mode;
9603         gcc_assert (CONST_INT_P (operands[2]));
9604         if (INTVAL (operands[2]) == 0xff)
9605           mode = QImode;
9606         else
9607           {
9608             gcc_assert (INTVAL (operands[2]) == 0xffff);
9609             mode = HImode;
9610           }
9612         operands[1] = gen_lowpart (mode, operands[1]);
9613         if (mode == QImode)
9614           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
9615         else
9616           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
9617       }
9619     default:
9620       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9621       if (get_attr_mode (insn) == MODE_SI)
9622         return "and{l}\t{%k2, %k0|%k0, %k2}";
9623       else
9624         return "and{q}\t{%2, %0|%0, %2}";
9625     }
9627   [(set_attr "type" "alu,alu,alu,imovx")
9628    (set_attr "length_immediate" "*,*,*,0")
9629    (set (attr "prefix_rex")
9630      (if_then_else
9631        (and (eq_attr "type" "imovx")
9632             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
9633                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
9634        (const_string "1")
9635        (const_string "*")))
9636    (set_attr "mode" "SI,DI,DI,SI")])
9638 (define_insn "*anddi_2"
9639   [(set (reg FLAGS_REG)
9640         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9641                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9642                  (const_int 0)))
9643    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9644         (and:DI (match_dup 1) (match_dup 2)))]
9645   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9646    && ix86_binary_operator_ok (AND, DImode, operands)"
9647   "@
9648    and{l}\t{%k2, %k0|%k0, %k2}
9649    and{q}\t{%2, %0|%0, %2}
9650    and{q}\t{%2, %0|%0, %2}"
9651   [(set_attr "type" "alu")
9652    (set_attr "mode" "SI,DI,DI")])
9654 (define_expand "andsi3"
9655   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9656         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9657                 (match_operand:SI 2 "general_operand" "")))]
9658   ""
9659   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9661 (define_insn "*andsi_1"
9662   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9663         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9664                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9665    (clobber (reg:CC FLAGS_REG))]
9666   "ix86_binary_operator_ok (AND, SImode, operands)"
9668   switch (get_attr_type (insn))
9669     {
9670     case TYPE_IMOVX:
9671       {
9672         enum machine_mode mode;
9674         gcc_assert (CONST_INT_P (operands[2]));
9675         if (INTVAL (operands[2]) == 0xff)
9676           mode = QImode;
9677         else
9678           {
9679             gcc_assert (INTVAL (operands[2]) == 0xffff);
9680             mode = HImode;
9681           }
9683         operands[1] = gen_lowpart (mode, operands[1]);
9684         if (mode == QImode)
9685           return "movz{bl|x}\t{%1, %0|%0, %1}";
9686         else
9687           return "movz{wl|x}\t{%1, %0|%0, %1}";
9688       }
9690     default:
9691       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9692       return "and{l}\t{%2, %0|%0, %2}";
9693     }
9695   [(set_attr "type" "alu,alu,imovx")
9696    (set (attr "prefix_rex")
9697      (if_then_else
9698        (and (eq_attr "type" "imovx")
9699             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
9700                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
9701        (const_string "1")
9702        (const_string "*")))
9703    (set_attr "length_immediate" "*,*,0")
9704    (set_attr "mode" "SI")])
9706 (define_split
9707   [(set (match_operand 0 "register_operand" "")
9708         (and (match_dup 0)
9709              (const_int -65536)))
9710    (clobber (reg:CC FLAGS_REG))]
9711   "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9712   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9713   "operands[1] = gen_lowpart (HImode, operands[0]);")
9715 (define_split
9716   [(set (match_operand 0 "ext_register_operand" "")
9717         (and (match_dup 0)
9718              (const_int -256)))
9719    (clobber (reg:CC FLAGS_REG))]
9720   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9721   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9722   "operands[1] = gen_lowpart (QImode, operands[0]);")
9724 (define_split
9725   [(set (match_operand 0 "ext_register_operand" "")
9726         (and (match_dup 0)
9727              (const_int -65281)))
9728    (clobber (reg:CC FLAGS_REG))]
9729   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9730   [(parallel [(set (zero_extract:SI (match_dup 0)
9731                                     (const_int 8)
9732                                     (const_int 8))
9733                    (xor:SI
9734                      (zero_extract:SI (match_dup 0)
9735                                       (const_int 8)
9736                                       (const_int 8))
9737                      (zero_extract:SI (match_dup 0)
9738                                       (const_int 8)
9739                                       (const_int 8))))
9740               (clobber (reg:CC FLAGS_REG))])]
9741   "operands[0] = gen_lowpart (SImode, operands[0]);")
9743 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9744 (define_insn "*andsi_1_zext"
9745   [(set (match_operand:DI 0 "register_operand" "=r")
9746         (zero_extend:DI
9747           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9748                   (match_operand:SI 2 "general_operand" "g"))))
9749    (clobber (reg:CC FLAGS_REG))]
9750   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9751   "and{l}\t{%2, %k0|%k0, %2}"
9752   [(set_attr "type" "alu")
9753    (set_attr "mode" "SI")])
9755 (define_insn "*andsi_2"
9756   [(set (reg FLAGS_REG)
9757         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9758                          (match_operand:SI 2 "general_operand" "g,ri"))
9759                  (const_int 0)))
9760    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9761         (and:SI (match_dup 1) (match_dup 2)))]
9762   "ix86_match_ccmode (insn, CCNOmode)
9763    && ix86_binary_operator_ok (AND, SImode, operands)"
9764   "and{l}\t{%2, %0|%0, %2}"
9765   [(set_attr "type" "alu")
9766    (set_attr "mode" "SI")])
9768 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9769 (define_insn "*andsi_2_zext"
9770   [(set (reg FLAGS_REG)
9771         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9772                          (match_operand:SI 2 "general_operand" "g"))
9773                  (const_int 0)))
9774    (set (match_operand:DI 0 "register_operand" "=r")
9775         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9776   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9777    && ix86_binary_operator_ok (AND, SImode, operands)"
9778   "and{l}\t{%2, %k0|%k0, %2}"
9779   [(set_attr "type" "alu")
9780    (set_attr "mode" "SI")])
9782 (define_expand "andhi3"
9783   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9784         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9785                 (match_operand:HI 2 "general_operand" "")))]
9786   "TARGET_HIMODE_MATH"
9787   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9789 (define_insn "*andhi_1"
9790   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9791         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9792                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9793    (clobber (reg:CC FLAGS_REG))]
9794   "ix86_binary_operator_ok (AND, HImode, operands)"
9796   switch (get_attr_type (insn))
9797     {
9798     case TYPE_IMOVX:
9799       gcc_assert (CONST_INT_P (operands[2]));
9800       gcc_assert (INTVAL (operands[2]) == 0xff);
9801       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9803     default:
9804       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9806       return "and{w}\t{%2, %0|%0, %2}";
9807     }
9809   [(set_attr "type" "alu,alu,imovx")
9810    (set_attr "length_immediate" "*,*,0")
9811    (set (attr "prefix_rex")
9812      (if_then_else
9813        (and (eq_attr "type" "imovx")
9814             (match_operand 1 "ext_QIreg_nomode_operand" ""))
9815        (const_string "1")
9816        (const_string "*")))
9817    (set_attr "mode" "HI,HI,SI")])
9819 (define_insn "*andhi_2"
9820   [(set (reg FLAGS_REG)
9821         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9822                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9823                  (const_int 0)))
9824    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9825         (and:HI (match_dup 1) (match_dup 2)))]
9826   "ix86_match_ccmode (insn, CCNOmode)
9827    && ix86_binary_operator_ok (AND, HImode, operands)"
9828   "and{w}\t{%2, %0|%0, %2}"
9829   [(set_attr "type" "alu")
9830    (set_attr "mode" "HI")])
9832 (define_expand "andqi3"
9833   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9834         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9835                 (match_operand:QI 2 "general_operand" "")))]
9836   "TARGET_QIMODE_MATH"
9837   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9839 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9840 (define_insn "*andqi_1"
9841   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9842         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9843                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9844    (clobber (reg:CC FLAGS_REG))]
9845   "ix86_binary_operator_ok (AND, QImode, operands)"
9846   "@
9847    and{b}\t{%2, %0|%0, %2}
9848    and{b}\t{%2, %0|%0, %2}
9849    and{l}\t{%k2, %k0|%k0, %k2}"
9850   [(set_attr "type" "alu")
9851    (set_attr "mode" "QI,QI,SI")])
9853 (define_insn "*andqi_1_slp"
9854   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9855         (and:QI (match_dup 0)
9856                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9857    (clobber (reg:CC FLAGS_REG))]
9858   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9859    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9860   "and{b}\t{%1, %0|%0, %1}"
9861   [(set_attr "type" "alu1")
9862    (set_attr "mode" "QI")])
9864 (define_insn "*andqi_2_maybe_si"
9865   [(set (reg FLAGS_REG)
9866         (compare (and:QI
9867                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9868                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9869                  (const_int 0)))
9870    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9871         (and:QI (match_dup 1) (match_dup 2)))]
9872   "ix86_binary_operator_ok (AND, QImode, operands)
9873    && ix86_match_ccmode (insn,
9874                          CONST_INT_P (operands[2])
9875                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9877   if (which_alternative == 2)
9878     {
9879       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9880         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9881       return "and{l}\t{%2, %k0|%k0, %2}";
9882     }
9883   return "and{b}\t{%2, %0|%0, %2}";
9885   [(set_attr "type" "alu")
9886    (set_attr "mode" "QI,QI,SI")])
9888 (define_insn "*andqi_2"
9889   [(set (reg FLAGS_REG)
9890         (compare (and:QI
9891                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9892                    (match_operand:QI 2 "general_operand" "qmn,qn"))
9893                  (const_int 0)))
9894    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9895         (and:QI (match_dup 1) (match_dup 2)))]
9896   "ix86_match_ccmode (insn, CCNOmode)
9897    && ix86_binary_operator_ok (AND, QImode, operands)"
9898   "and{b}\t{%2, %0|%0, %2}"
9899   [(set_attr "type" "alu")
9900    (set_attr "mode" "QI")])
9902 (define_insn "*andqi_2_slp"
9903   [(set (reg FLAGS_REG)
9904         (compare (and:QI
9905                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9906                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9907                  (const_int 0)))
9908    (set (strict_low_part (match_dup 0))
9909         (and:QI (match_dup 0) (match_dup 1)))]
9910   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9911    && ix86_match_ccmode (insn, CCNOmode)
9912    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9913   "and{b}\t{%1, %0|%0, %1}"
9914   [(set_attr "type" "alu1")
9915    (set_attr "mode" "QI")])
9917 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9918 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9919 ;; for a QImode operand, which of course failed.
9921 (define_insn "andqi_ext_0"
9922   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9923                          (const_int 8)
9924                          (const_int 8))
9925         (and:SI
9926           (zero_extract:SI
9927             (match_operand 1 "ext_register_operand" "0")
9928             (const_int 8)
9929             (const_int 8))
9930           (match_operand 2 "const_int_operand" "n")))
9931    (clobber (reg:CC FLAGS_REG))]
9932   ""
9933   "and{b}\t{%2, %h0|%h0, %2}"
9934   [(set_attr "type" "alu")
9935    (set_attr "length_immediate" "1")
9936    (set_attr "modrm" "1")
9937    (set_attr "mode" "QI")])
9939 ;; Generated by peephole translating test to and.  This shows up
9940 ;; often in fp comparisons.
9942 (define_insn "*andqi_ext_0_cc"
9943   [(set (reg FLAGS_REG)
9944         (compare
9945           (and:SI
9946             (zero_extract:SI
9947               (match_operand 1 "ext_register_operand" "0")
9948               (const_int 8)
9949               (const_int 8))
9950             (match_operand 2 "const_int_operand" "n"))
9951           (const_int 0)))
9952    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9953                          (const_int 8)
9954                          (const_int 8))
9955         (and:SI
9956           (zero_extract:SI
9957             (match_dup 1)
9958             (const_int 8)
9959             (const_int 8))
9960           (match_dup 2)))]
9961   "ix86_match_ccmode (insn, CCNOmode)"
9962   "and{b}\t{%2, %h0|%h0, %2}"
9963   [(set_attr "type" "alu")
9964    (set_attr "length_immediate" "1")
9965    (set_attr "modrm" "1")
9966    (set_attr "mode" "QI")])
9968 (define_insn "*andqi_ext_1"
9969   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9970                          (const_int 8)
9971                          (const_int 8))
9972         (and:SI
9973           (zero_extract:SI
9974             (match_operand 1 "ext_register_operand" "0")
9975             (const_int 8)
9976             (const_int 8))
9977           (zero_extend:SI
9978             (match_operand:QI 2 "general_operand" "Qm"))))
9979    (clobber (reg:CC FLAGS_REG))]
9980   "!TARGET_64BIT"
9981   "and{b}\t{%2, %h0|%h0, %2}"
9982   [(set_attr "type" "alu")
9983    (set_attr "length_immediate" "0")
9984    (set_attr "mode" "QI")])
9986 (define_insn "*andqi_ext_1_rex64"
9987   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9988                          (const_int 8)
9989                          (const_int 8))
9990         (and:SI
9991           (zero_extract:SI
9992             (match_operand 1 "ext_register_operand" "0")
9993             (const_int 8)
9994             (const_int 8))
9995           (zero_extend:SI
9996             (match_operand 2 "ext_register_operand" "Q"))))
9997    (clobber (reg:CC FLAGS_REG))]
9998   "TARGET_64BIT"
9999   "and{b}\t{%2, %h0|%h0, %2}"
10000   [(set_attr "type" "alu")
10001    (set_attr "length_immediate" "0")
10002    (set_attr "mode" "QI")])
10004 (define_insn "*andqi_ext_2"
10005   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10006                          (const_int 8)
10007                          (const_int 8))
10008         (and:SI
10009           (zero_extract:SI
10010             (match_operand 1 "ext_register_operand" "%0")
10011             (const_int 8)
10012             (const_int 8))
10013           (zero_extract:SI
10014             (match_operand 2 "ext_register_operand" "Q")
10015             (const_int 8)
10016             (const_int 8))))
10017    (clobber (reg:CC FLAGS_REG))]
10018   ""
10019   "and{b}\t{%h2, %h0|%h0, %h2}"
10020   [(set_attr "type" "alu")
10021    (set_attr "length_immediate" "0")
10022    (set_attr "mode" "QI")])
10024 ;; Convert wide AND instructions with immediate operand to shorter QImode
10025 ;; equivalents when possible.
10026 ;; Don't do the splitting with memory operands, since it introduces risk
10027 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
10028 ;; for size, but that can (should?) be handled by generic code instead.
10029 (define_split
10030   [(set (match_operand 0 "register_operand" "")
10031         (and (match_operand 1 "register_operand" "")
10032              (match_operand 2 "const_int_operand" "")))
10033    (clobber (reg:CC FLAGS_REG))]
10034    "reload_completed
10035     && QI_REG_P (operands[0])
10036     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10037     && !(~INTVAL (operands[2]) & ~(255 << 8))
10038     && GET_MODE (operands[0]) != QImode"
10039   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10040                    (and:SI (zero_extract:SI (match_dup 1)
10041                                             (const_int 8) (const_int 8))
10042                            (match_dup 2)))
10043               (clobber (reg:CC FLAGS_REG))])]
10044   "operands[0] = gen_lowpart (SImode, operands[0]);
10045    operands[1] = gen_lowpart (SImode, operands[1]);
10046    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10048 ;; Since AND can be encoded with sign extended immediate, this is only
10049 ;; profitable when 7th bit is not set.
10050 (define_split
10051   [(set (match_operand 0 "register_operand" "")
10052         (and (match_operand 1 "general_operand" "")
10053              (match_operand 2 "const_int_operand" "")))
10054    (clobber (reg:CC FLAGS_REG))]
10055    "reload_completed
10056     && ANY_QI_REG_P (operands[0])
10057     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10058     && !(~INTVAL (operands[2]) & ~255)
10059     && !(INTVAL (operands[2]) & 128)
10060     && GET_MODE (operands[0]) != QImode"
10061   [(parallel [(set (strict_low_part (match_dup 0))
10062                    (and:QI (match_dup 1)
10063                            (match_dup 2)))
10064               (clobber (reg:CC FLAGS_REG))])]
10065   "operands[0] = gen_lowpart (QImode, operands[0]);
10066    operands[1] = gen_lowpart (QImode, operands[1]);
10067    operands[2] = gen_lowpart (QImode, operands[2]);")
10069 ;; Logical inclusive OR instructions
10071 ;; %%% This used to optimize known byte-wide and operations to memory.
10072 ;; If this is considered useful, it should be done with splitters.
10074 (define_expand "iordi3"
10075   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10076         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
10077                 (match_operand:DI 2 "x86_64_general_operand" "")))]
10078   "TARGET_64BIT"
10079   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
10081 (define_insn "*iordi_1_rex64"
10082   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10083         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10084                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
10085    (clobber (reg:CC FLAGS_REG))]
10086   "TARGET_64BIT
10087    && ix86_binary_operator_ok (IOR, DImode, operands)"
10088   "or{q}\t{%2, %0|%0, %2}"
10089   [(set_attr "type" "alu")
10090    (set_attr "mode" "DI")])
10092 (define_insn "*iordi_2_rex64"
10093   [(set (reg FLAGS_REG)
10094         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10095                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
10096                  (const_int 0)))
10097    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
10098         (ior:DI (match_dup 1) (match_dup 2)))]
10099   "TARGET_64BIT
10100    && ix86_match_ccmode (insn, CCNOmode)
10101    && ix86_binary_operator_ok (IOR, DImode, operands)"
10102   "or{q}\t{%2, %0|%0, %2}"
10103   [(set_attr "type" "alu")
10104    (set_attr "mode" "DI")])
10106 (define_insn "*iordi_3_rex64"
10107   [(set (reg FLAGS_REG)
10108         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
10109                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
10110                  (const_int 0)))
10111    (clobber (match_scratch:DI 0 "=r"))]
10112   "TARGET_64BIT
10113    && ix86_match_ccmode (insn, CCNOmode)
10114    && ix86_binary_operator_ok (IOR, DImode, operands)"
10115   "or{q}\t{%2, %0|%0, %2}"
10116   [(set_attr "type" "alu")
10117    (set_attr "mode" "DI")])
10120 (define_expand "iorsi3"
10121   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10122         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
10123                 (match_operand:SI 2 "general_operand" "")))]
10124   ""
10125   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
10127 (define_insn "*iorsi_1"
10128   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10129         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10130                 (match_operand:SI 2 "general_operand" "ri,g")))
10131    (clobber (reg:CC FLAGS_REG))]
10132   "ix86_binary_operator_ok (IOR, SImode, operands)"
10133   "or{l}\t{%2, %0|%0, %2}"
10134   [(set_attr "type" "alu")
10135    (set_attr "mode" "SI")])
10137 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10138 (define_insn "*iorsi_1_zext"
10139   [(set (match_operand:DI 0 "register_operand" "=r")
10140         (zero_extend:DI
10141           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10142                   (match_operand:SI 2 "general_operand" "g"))))
10143    (clobber (reg:CC FLAGS_REG))]
10144   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
10145   "or{l}\t{%2, %k0|%k0, %2}"
10146   [(set_attr "type" "alu")
10147    (set_attr "mode" "SI")])
10149 (define_insn "*iorsi_1_zext_imm"
10150   [(set (match_operand:DI 0 "register_operand" "=r")
10151         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10152                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10153    (clobber (reg:CC FLAGS_REG))]
10154   "TARGET_64BIT"
10155   "or{l}\t{%2, %k0|%k0, %2}"
10156   [(set_attr "type" "alu")
10157    (set_attr "mode" "SI")])
10159 (define_insn "*iorsi_2"
10160   [(set (reg FLAGS_REG)
10161         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10162                          (match_operand:SI 2 "general_operand" "g,ri"))
10163                  (const_int 0)))
10164    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10165         (ior:SI (match_dup 1) (match_dup 2)))]
10166   "ix86_match_ccmode (insn, CCNOmode)
10167    && ix86_binary_operator_ok (IOR, SImode, operands)"
10168   "or{l}\t{%2, %0|%0, %2}"
10169   [(set_attr "type" "alu")
10170    (set_attr "mode" "SI")])
10172 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10173 ;; ??? Special case for immediate operand is missing - it is tricky.
10174 (define_insn "*iorsi_2_zext"
10175   [(set (reg FLAGS_REG)
10176         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10177                          (match_operand:SI 2 "general_operand" "g"))
10178                  (const_int 0)))
10179    (set (match_operand:DI 0 "register_operand" "=r")
10180         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
10181   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10182    && ix86_binary_operator_ok (IOR, SImode, operands)"
10183   "or{l}\t{%2, %k0|%k0, %2}"
10184   [(set_attr "type" "alu")
10185    (set_attr "mode" "SI")])
10187 (define_insn "*iorsi_2_zext_imm"
10188   [(set (reg FLAGS_REG)
10189         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10190                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10191                  (const_int 0)))
10192    (set (match_operand:DI 0 "register_operand" "=r")
10193         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10194   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10195    && ix86_binary_operator_ok (IOR, SImode, operands)"
10196   "or{l}\t{%2, %k0|%k0, %2}"
10197   [(set_attr "type" "alu")
10198    (set_attr "mode" "SI")])
10200 (define_insn "*iorsi_3"
10201   [(set (reg FLAGS_REG)
10202         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10203                          (match_operand:SI 2 "general_operand" "g"))
10204                  (const_int 0)))
10205    (clobber (match_scratch:SI 0 "=r"))]
10206   "ix86_match_ccmode (insn, CCNOmode)
10207    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10208   "or{l}\t{%2, %0|%0, %2}"
10209   [(set_attr "type" "alu")
10210    (set_attr "mode" "SI")])
10212 (define_expand "iorhi3"
10213   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10214         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
10215                 (match_operand:HI 2 "general_operand" "")))]
10216   "TARGET_HIMODE_MATH"
10217   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
10219 (define_insn "*iorhi_1"
10220   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10221         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10222                 (match_operand:HI 2 "general_operand" "rmn,rn")))
10223    (clobber (reg:CC FLAGS_REG))]
10224   "ix86_binary_operator_ok (IOR, HImode, operands)"
10225   "or{w}\t{%2, %0|%0, %2}"
10226   [(set_attr "type" "alu")
10227    (set_attr "mode" "HI")])
10229 (define_insn "*iorhi_2"
10230   [(set (reg FLAGS_REG)
10231         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10232                          (match_operand:HI 2 "general_operand" "rmn,rn"))
10233                  (const_int 0)))
10234    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10235         (ior:HI (match_dup 1) (match_dup 2)))]
10236   "ix86_match_ccmode (insn, CCNOmode)
10237    && ix86_binary_operator_ok (IOR, HImode, operands)"
10238   "or{w}\t{%2, %0|%0, %2}"
10239   [(set_attr "type" "alu")
10240    (set_attr "mode" "HI")])
10242 (define_insn "*iorhi_3"
10243   [(set (reg FLAGS_REG)
10244         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10245                          (match_operand:HI 2 "general_operand" "rmn"))
10246                  (const_int 0)))
10247    (clobber (match_scratch:HI 0 "=r"))]
10248   "ix86_match_ccmode (insn, CCNOmode)
10249    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10250   "or{w}\t{%2, %0|%0, %2}"
10251   [(set_attr "type" "alu")
10252    (set_attr "mode" "HI")])
10254 (define_expand "iorqi3"
10255   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10256         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
10257                 (match_operand:QI 2 "general_operand" "")))]
10258   "TARGET_QIMODE_MATH"
10259   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
10261 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10262 (define_insn "*iorqi_1"
10263   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10264         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10265                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10266    (clobber (reg:CC FLAGS_REG))]
10267   "ix86_binary_operator_ok (IOR, QImode, operands)"
10268   "@
10269    or{b}\t{%2, %0|%0, %2}
10270    or{b}\t{%2, %0|%0, %2}
10271    or{l}\t{%k2, %k0|%k0, %k2}"
10272   [(set_attr "type" "alu")
10273    (set_attr "mode" "QI,QI,SI")])
10275 (define_insn "*iorqi_1_slp"
10276   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
10277         (ior:QI (match_dup 0)
10278                 (match_operand:QI 1 "general_operand" "qmn,qn")))
10279    (clobber (reg:CC FLAGS_REG))]
10280   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10281    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10282   "or{b}\t{%1, %0|%0, %1}"
10283   [(set_attr "type" "alu1")
10284    (set_attr "mode" "QI")])
10286 (define_insn "*iorqi_2"
10287   [(set (reg FLAGS_REG)
10288         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10289                          (match_operand:QI 2 "general_operand" "qmn,qn"))
10290                  (const_int 0)))
10291    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10292         (ior:QI (match_dup 1) (match_dup 2)))]
10293   "ix86_match_ccmode (insn, CCNOmode)
10294    && ix86_binary_operator_ok (IOR, QImode, operands)"
10295   "or{b}\t{%2, %0|%0, %2}"
10296   [(set_attr "type" "alu")
10297    (set_attr "mode" "QI")])
10299 (define_insn "*iorqi_2_slp"
10300   [(set (reg FLAGS_REG)
10301         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10302                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10303                  (const_int 0)))
10304    (set (strict_low_part (match_dup 0))
10305         (ior:QI (match_dup 0) (match_dup 1)))]
10306   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10307    && ix86_match_ccmode (insn, CCNOmode)
10308    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10309   "or{b}\t{%1, %0|%0, %1}"
10310   [(set_attr "type" "alu1")
10311    (set_attr "mode" "QI")])
10313 (define_insn "*iorqi_3"
10314   [(set (reg FLAGS_REG)
10315         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10316                          (match_operand:QI 2 "general_operand" "qmn"))
10317                  (const_int 0)))
10318    (clobber (match_scratch:QI 0 "=q"))]
10319   "ix86_match_ccmode (insn, CCNOmode)
10320    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10321   "or{b}\t{%2, %0|%0, %2}"
10322   [(set_attr "type" "alu")
10323    (set_attr "mode" "QI")])
10325 (define_insn "*iorqi_ext_0"
10326   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10327                          (const_int 8)
10328                          (const_int 8))
10329         (ior:SI
10330           (zero_extract:SI
10331             (match_operand 1 "ext_register_operand" "0")
10332             (const_int 8)
10333             (const_int 8))
10334           (match_operand 2 "const_int_operand" "n")))
10335    (clobber (reg:CC FLAGS_REG))]
10336   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10337   "or{b}\t{%2, %h0|%h0, %2}"
10338   [(set_attr "type" "alu")
10339    (set_attr "length_immediate" "1")
10340    (set_attr "modrm" "1")
10341    (set_attr "mode" "QI")])
10343 (define_insn "*iorqi_ext_1"
10344   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10345                          (const_int 8)
10346                          (const_int 8))
10347         (ior:SI
10348           (zero_extract:SI
10349             (match_operand 1 "ext_register_operand" "0")
10350             (const_int 8)
10351             (const_int 8))
10352           (zero_extend:SI
10353             (match_operand:QI 2 "general_operand" "Qm"))))
10354    (clobber (reg:CC FLAGS_REG))]
10355   "!TARGET_64BIT
10356    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10357   "or{b}\t{%2, %h0|%h0, %2}"
10358   [(set_attr "type" "alu")
10359    (set_attr "length_immediate" "0")
10360    (set_attr "mode" "QI")])
10362 (define_insn "*iorqi_ext_1_rex64"
10363   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10364                          (const_int 8)
10365                          (const_int 8))
10366         (ior:SI
10367           (zero_extract:SI
10368             (match_operand 1 "ext_register_operand" "0")
10369             (const_int 8)
10370             (const_int 8))
10371           (zero_extend:SI
10372             (match_operand 2 "ext_register_operand" "Q"))))
10373    (clobber (reg:CC FLAGS_REG))]
10374   "TARGET_64BIT
10375    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10376   "or{b}\t{%2, %h0|%h0, %2}"
10377   [(set_attr "type" "alu")
10378    (set_attr "length_immediate" "0")
10379    (set_attr "mode" "QI")])
10381 (define_insn "*iorqi_ext_2"
10382   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10383                          (const_int 8)
10384                          (const_int 8))
10385         (ior:SI
10386           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10387                            (const_int 8)
10388                            (const_int 8))
10389           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10390                            (const_int 8)
10391                            (const_int 8))))
10392    (clobber (reg:CC FLAGS_REG))]
10393   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10394   "ior{b}\t{%h2, %h0|%h0, %h2}"
10395   [(set_attr "type" "alu")
10396    (set_attr "length_immediate" "0")
10397    (set_attr "mode" "QI")])
10399 (define_split
10400   [(set (match_operand 0 "register_operand" "")
10401         (ior (match_operand 1 "register_operand" "")
10402              (match_operand 2 "const_int_operand" "")))
10403    (clobber (reg:CC FLAGS_REG))]
10404    "reload_completed
10405     && QI_REG_P (operands[0])
10406     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10407     && !(INTVAL (operands[2]) & ~(255 << 8))
10408     && GET_MODE (operands[0]) != QImode"
10409   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10410                    (ior:SI (zero_extract:SI (match_dup 1)
10411                                             (const_int 8) (const_int 8))
10412                            (match_dup 2)))
10413               (clobber (reg:CC FLAGS_REG))])]
10414   "operands[0] = gen_lowpart (SImode, operands[0]);
10415    operands[1] = gen_lowpart (SImode, operands[1]);
10416    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10418 ;; Since OR can be encoded with sign extended immediate, this is only
10419 ;; profitable when 7th bit is set.
10420 (define_split
10421   [(set (match_operand 0 "register_operand" "")
10422         (ior (match_operand 1 "general_operand" "")
10423              (match_operand 2 "const_int_operand" "")))
10424    (clobber (reg:CC FLAGS_REG))]
10425    "reload_completed
10426     && ANY_QI_REG_P (operands[0])
10427     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10428     && !(INTVAL (operands[2]) & ~255)
10429     && (INTVAL (operands[2]) & 128)
10430     && GET_MODE (operands[0]) != QImode"
10431   [(parallel [(set (strict_low_part (match_dup 0))
10432                    (ior:QI (match_dup 1)
10433                            (match_dup 2)))
10434               (clobber (reg:CC FLAGS_REG))])]
10435   "operands[0] = gen_lowpart (QImode, operands[0]);
10436    operands[1] = gen_lowpart (QImode, operands[1]);
10437    operands[2] = gen_lowpart (QImode, operands[2]);")
10439 ;; Logical XOR instructions
10441 ;; %%% This used to optimize known byte-wide and operations to memory.
10442 ;; If this is considered useful, it should be done with splitters.
10444 (define_expand "xordi3"
10445   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10446         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
10447                 (match_operand:DI 2 "x86_64_general_operand" "")))]
10448   "TARGET_64BIT"
10449   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
10451 (define_insn "*xordi_1_rex64"
10452   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10453         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10454                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
10455    (clobber (reg:CC FLAGS_REG))]
10456   "TARGET_64BIT
10457    && ix86_binary_operator_ok (XOR, DImode, operands)"
10458   "xor{q}\t{%2, %0|%0, %2}"
10459   [(set_attr "type" "alu")
10460    (set_attr "mode" "DI")])
10462 (define_insn "*xordi_2_rex64"
10463   [(set (reg FLAGS_REG)
10464         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10465                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
10466                  (const_int 0)))
10467    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
10468         (xor:DI (match_dup 1) (match_dup 2)))]
10469   "TARGET_64BIT
10470    && ix86_match_ccmode (insn, CCNOmode)
10471    && ix86_binary_operator_ok (XOR, DImode, operands)"
10472   "xor{q}\t{%2, %0|%0, %2}"
10473   [(set_attr "type" "alu")
10474    (set_attr "mode" "DI")])
10476 (define_insn "*xordi_3_rex64"
10477   [(set (reg FLAGS_REG)
10478         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
10479                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
10480                  (const_int 0)))
10481    (clobber (match_scratch:DI 0 "=r"))]
10482   "TARGET_64BIT
10483    && ix86_match_ccmode (insn, CCNOmode)
10484    && ix86_binary_operator_ok (XOR, DImode, operands)"
10485   "xor{q}\t{%2, %0|%0, %2}"
10486   [(set_attr "type" "alu")
10487    (set_attr "mode" "DI")])
10489 (define_expand "xorsi3"
10490   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10491         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
10492                 (match_operand:SI 2 "general_operand" "")))]
10493   ""
10494   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
10496 (define_insn "*xorsi_1"
10497   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10498         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10499                 (match_operand:SI 2 "general_operand" "ri,rm")))
10500    (clobber (reg:CC FLAGS_REG))]
10501   "ix86_binary_operator_ok (XOR, SImode, operands)"
10502   "xor{l}\t{%2, %0|%0, %2}"
10503   [(set_attr "type" "alu")
10504    (set_attr "mode" "SI")])
10506 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10507 ;; Add speccase for immediates
10508 (define_insn "*xorsi_1_zext"
10509   [(set (match_operand:DI 0 "register_operand" "=r")
10510         (zero_extend:DI
10511           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10512                   (match_operand:SI 2 "general_operand" "g"))))
10513    (clobber (reg:CC FLAGS_REG))]
10514   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10515   "xor{l}\t{%2, %k0|%k0, %2}"
10516   [(set_attr "type" "alu")
10517    (set_attr "mode" "SI")])
10519 (define_insn "*xorsi_1_zext_imm"
10520   [(set (match_operand:DI 0 "register_operand" "=r")
10521         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10522                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10523    (clobber (reg:CC FLAGS_REG))]
10524   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10525   "xor{l}\t{%2, %k0|%k0, %2}"
10526   [(set_attr "type" "alu")
10527    (set_attr "mode" "SI")])
10529 (define_insn "*xorsi_2"
10530   [(set (reg FLAGS_REG)
10531         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10532                          (match_operand:SI 2 "general_operand" "g,ri"))
10533                  (const_int 0)))
10534    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10535         (xor:SI (match_dup 1) (match_dup 2)))]
10536   "ix86_match_ccmode (insn, CCNOmode)
10537    && ix86_binary_operator_ok (XOR, SImode, operands)"
10538   "xor{l}\t{%2, %0|%0, %2}"
10539   [(set_attr "type" "alu")
10540    (set_attr "mode" "SI")])
10542 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10543 ;; ??? Special case for immediate operand is missing - it is tricky.
10544 (define_insn "*xorsi_2_zext"
10545   [(set (reg FLAGS_REG)
10546         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10547                          (match_operand:SI 2 "general_operand" "g"))
10548                  (const_int 0)))
10549    (set (match_operand:DI 0 "register_operand" "=r")
10550         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10551   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10552    && ix86_binary_operator_ok (XOR, SImode, operands)"
10553   "xor{l}\t{%2, %k0|%k0, %2}"
10554   [(set_attr "type" "alu")
10555    (set_attr "mode" "SI")])
10557 (define_insn "*xorsi_2_zext_imm"
10558   [(set (reg FLAGS_REG)
10559         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10560                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10561                  (const_int 0)))
10562    (set (match_operand:DI 0 "register_operand" "=r")
10563         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10564   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10565    && ix86_binary_operator_ok (XOR, SImode, operands)"
10566   "xor{l}\t{%2, %k0|%k0, %2}"
10567   [(set_attr "type" "alu")
10568    (set_attr "mode" "SI")])
10570 (define_insn "*xorsi_3"
10571   [(set (reg FLAGS_REG)
10572         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10573                          (match_operand:SI 2 "general_operand" "g"))
10574                  (const_int 0)))
10575    (clobber (match_scratch:SI 0 "=r"))]
10576   "ix86_match_ccmode (insn, CCNOmode)
10577    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10578   "xor{l}\t{%2, %0|%0, %2}"
10579   [(set_attr "type" "alu")
10580    (set_attr "mode" "SI")])
10582 (define_expand "xorhi3"
10583   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10584         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10585                 (match_operand:HI 2 "general_operand" "")))]
10586   "TARGET_HIMODE_MATH"
10587   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10589 (define_insn "*xorhi_1"
10590   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10591         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10592                 (match_operand:HI 2 "general_operand" "rmn,rn")))
10593    (clobber (reg:CC FLAGS_REG))]
10594   "ix86_binary_operator_ok (XOR, HImode, operands)"
10595   "xor{w}\t{%2, %0|%0, %2}"
10596   [(set_attr "type" "alu")
10597    (set_attr "mode" "HI")])
10599 (define_insn "*xorhi_2"
10600   [(set (reg FLAGS_REG)
10601         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10602                          (match_operand:HI 2 "general_operand" "rmn,rn"))
10603                  (const_int 0)))
10604    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10605         (xor:HI (match_dup 1) (match_dup 2)))]
10606   "ix86_match_ccmode (insn, CCNOmode)
10607    && ix86_binary_operator_ok (XOR, HImode, operands)"
10608   "xor{w}\t{%2, %0|%0, %2}"
10609   [(set_attr "type" "alu")
10610    (set_attr "mode" "HI")])
10612 (define_insn "*xorhi_3"
10613   [(set (reg FLAGS_REG)
10614         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10615                          (match_operand:HI 2 "general_operand" "rmn"))
10616                  (const_int 0)))
10617    (clobber (match_scratch:HI 0 "=r"))]
10618   "ix86_match_ccmode (insn, CCNOmode)
10619    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10620   "xor{w}\t{%2, %0|%0, %2}"
10621   [(set_attr "type" "alu")
10622    (set_attr "mode" "HI")])
10624 (define_expand "xorqi3"
10625   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10626         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10627                 (match_operand:QI 2 "general_operand" "")))]
10628   "TARGET_QIMODE_MATH"
10629   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10631 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10632 (define_insn "*xorqi_1"
10633   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10634         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10635                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10636    (clobber (reg:CC FLAGS_REG))]
10637   "ix86_binary_operator_ok (XOR, QImode, operands)"
10638   "@
10639    xor{b}\t{%2, %0|%0, %2}
10640    xor{b}\t{%2, %0|%0, %2}
10641    xor{l}\t{%k2, %k0|%k0, %k2}"
10642   [(set_attr "type" "alu")
10643    (set_attr "mode" "QI,QI,SI")])
10645 (define_insn "*xorqi_1_slp"
10646   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10647         (xor:QI (match_dup 0)
10648                 (match_operand:QI 1 "general_operand" "qn,qmn")))
10649    (clobber (reg:CC FLAGS_REG))]
10650   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10651    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10652   "xor{b}\t{%1, %0|%0, %1}"
10653   [(set_attr "type" "alu1")
10654    (set_attr "mode" "QI")])
10656 (define_insn "*xorqi_ext_0"
10657   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10658                          (const_int 8)
10659                          (const_int 8))
10660         (xor:SI
10661           (zero_extract:SI
10662             (match_operand 1 "ext_register_operand" "0")
10663             (const_int 8)
10664             (const_int 8))
10665           (match_operand 2 "const_int_operand" "n")))
10666    (clobber (reg:CC FLAGS_REG))]
10667   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10668   "xor{b}\t{%2, %h0|%h0, %2}"
10669   [(set_attr "type" "alu")
10670    (set_attr "length_immediate" "1")
10671    (set_attr "modrm" "1")
10672    (set_attr "mode" "QI")])
10674 (define_insn "*xorqi_ext_1"
10675   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10676                          (const_int 8)
10677                          (const_int 8))
10678         (xor:SI
10679           (zero_extract:SI
10680             (match_operand 1 "ext_register_operand" "0")
10681             (const_int 8)
10682             (const_int 8))
10683           (zero_extend:SI
10684             (match_operand:QI 2 "general_operand" "Qm"))))
10685    (clobber (reg:CC FLAGS_REG))]
10686   "!TARGET_64BIT
10687    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10688   "xor{b}\t{%2, %h0|%h0, %2}"
10689   [(set_attr "type" "alu")
10690    (set_attr "length_immediate" "0")
10691    (set_attr "mode" "QI")])
10693 (define_insn "*xorqi_ext_1_rex64"
10694   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10695                          (const_int 8)
10696                          (const_int 8))
10697         (xor:SI
10698           (zero_extract:SI
10699             (match_operand 1 "ext_register_operand" "0")
10700             (const_int 8)
10701             (const_int 8))
10702           (zero_extend:SI
10703             (match_operand 2 "ext_register_operand" "Q"))))
10704    (clobber (reg:CC FLAGS_REG))]
10705   "TARGET_64BIT
10706    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10707   "xor{b}\t{%2, %h0|%h0, %2}"
10708   [(set_attr "type" "alu")
10709    (set_attr "length_immediate" "0")
10710    (set_attr "mode" "QI")])
10712 (define_insn "*xorqi_ext_2"
10713   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10714                          (const_int 8)
10715                          (const_int 8))
10716         (xor:SI
10717           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10718                            (const_int 8)
10719                            (const_int 8))
10720           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10721                            (const_int 8)
10722                            (const_int 8))))
10723    (clobber (reg:CC FLAGS_REG))]
10724   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10725   "xor{b}\t{%h2, %h0|%h0, %h2}"
10726   [(set_attr "type" "alu")
10727    (set_attr "length_immediate" "0")
10728    (set_attr "mode" "QI")])
10730 (define_insn "*xorqi_cc_1"
10731   [(set (reg FLAGS_REG)
10732         (compare
10733           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10734                   (match_operand:QI 2 "general_operand" "qmn,qn"))
10735           (const_int 0)))
10736    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10737         (xor:QI (match_dup 1) (match_dup 2)))]
10738   "ix86_match_ccmode (insn, CCNOmode)
10739    && ix86_binary_operator_ok (XOR, QImode, operands)"
10740   "xor{b}\t{%2, %0|%0, %2}"
10741   [(set_attr "type" "alu")
10742    (set_attr "mode" "QI")])
10744 (define_insn "*xorqi_2_slp"
10745   [(set (reg FLAGS_REG)
10746         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10747                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10748                  (const_int 0)))
10749    (set (strict_low_part (match_dup 0))
10750         (xor:QI (match_dup 0) (match_dup 1)))]
10751   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10752    && ix86_match_ccmode (insn, CCNOmode)
10753    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10754   "xor{b}\t{%1, %0|%0, %1}"
10755   [(set_attr "type" "alu1")
10756    (set_attr "mode" "QI")])
10758 (define_insn "*xorqi_cc_2"
10759   [(set (reg FLAGS_REG)
10760         (compare
10761           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10762                   (match_operand:QI 2 "general_operand" "qmn"))
10763           (const_int 0)))
10764    (clobber (match_scratch:QI 0 "=q"))]
10765   "ix86_match_ccmode (insn, CCNOmode)
10766    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10767   "xor{b}\t{%2, %0|%0, %2}"
10768   [(set_attr "type" "alu")
10769    (set_attr "mode" "QI")])
10771 (define_insn "*xorqi_cc_ext_1"
10772   [(set (reg FLAGS_REG)
10773         (compare
10774           (xor:SI
10775             (zero_extract:SI
10776               (match_operand 1 "ext_register_operand" "0")
10777               (const_int 8)
10778               (const_int 8))
10779             (match_operand:QI 2 "general_operand" "qmn"))
10780           (const_int 0)))
10781    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10782                          (const_int 8)
10783                          (const_int 8))
10784         (xor:SI
10785           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10786           (match_dup 2)))]
10787   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10788   "xor{b}\t{%2, %h0|%h0, %2}"
10789   [(set_attr "type" "alu")
10790    (set_attr "modrm" "1")
10791    (set_attr "mode" "QI")])
10793 (define_insn "*xorqi_cc_ext_1_rex64"
10794   [(set (reg FLAGS_REG)
10795         (compare
10796           (xor:SI
10797             (zero_extract:SI
10798               (match_operand 1 "ext_register_operand" "0")
10799               (const_int 8)
10800               (const_int 8))
10801             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10802           (const_int 0)))
10803    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10804                          (const_int 8)
10805                          (const_int 8))
10806         (xor:SI
10807           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10808           (match_dup 2)))]
10809   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10810   "xor{b}\t{%2, %h0|%h0, %2}"
10811   [(set_attr "type" "alu")
10812    (set_attr "modrm" "1")
10813    (set_attr "mode" "QI")])
10815 (define_expand "xorqi_cc_ext_1"
10816   [(parallel [
10817      (set (reg:CCNO FLAGS_REG)
10818           (compare:CCNO
10819             (xor:SI
10820               (zero_extract:SI
10821                 (match_operand 1 "ext_register_operand" "")
10822                 (const_int 8)
10823                 (const_int 8))
10824               (match_operand:QI 2 "general_operand" ""))
10825             (const_int 0)))
10826      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10827                            (const_int 8)
10828                            (const_int 8))
10829           (xor:SI
10830             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10831             (match_dup 2)))])]
10832   ""
10833   "")
10835 (define_split
10836   [(set (match_operand 0 "register_operand" "")
10837         (xor (match_operand 1 "register_operand" "")
10838              (match_operand 2 "const_int_operand" "")))
10839    (clobber (reg:CC FLAGS_REG))]
10840    "reload_completed
10841     && QI_REG_P (operands[0])
10842     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10843     && !(INTVAL (operands[2]) & ~(255 << 8))
10844     && GET_MODE (operands[0]) != QImode"
10845   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10846                    (xor:SI (zero_extract:SI (match_dup 1)
10847                                             (const_int 8) (const_int 8))
10848                            (match_dup 2)))
10849               (clobber (reg:CC FLAGS_REG))])]
10850   "operands[0] = gen_lowpart (SImode, operands[0]);
10851    operands[1] = gen_lowpart (SImode, operands[1]);
10852    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10854 ;; Since XOR can be encoded with sign extended immediate, this is only
10855 ;; profitable when 7th bit is set.
10856 (define_split
10857   [(set (match_operand 0 "register_operand" "")
10858         (xor (match_operand 1 "general_operand" "")
10859              (match_operand 2 "const_int_operand" "")))
10860    (clobber (reg:CC FLAGS_REG))]
10861    "reload_completed
10862     && ANY_QI_REG_P (operands[0])
10863     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10864     && !(INTVAL (operands[2]) & ~255)
10865     && (INTVAL (operands[2]) & 128)
10866     && GET_MODE (operands[0]) != QImode"
10867   [(parallel [(set (strict_low_part (match_dup 0))
10868                    (xor:QI (match_dup 1)
10869                            (match_dup 2)))
10870               (clobber (reg:CC FLAGS_REG))])]
10871   "operands[0] = gen_lowpart (QImode, operands[0]);
10872    operands[1] = gen_lowpart (QImode, operands[1]);
10873    operands[2] = gen_lowpart (QImode, operands[2]);")
10875 ;; Negation instructions
10877 (define_expand "negti2"
10878   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10879         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10880   "TARGET_64BIT"
10881   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10883 (define_insn "*negti2_1"
10884   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10885         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10886    (clobber (reg:CC FLAGS_REG))]
10887   "TARGET_64BIT
10888    && ix86_unary_operator_ok (NEG, TImode, operands)"
10889   "#")
10891 (define_split
10892   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10893         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10894    (clobber (reg:CC FLAGS_REG))]
10895   "TARGET_64BIT && reload_completed"
10896   [(parallel
10897     [(set (reg:CCZ FLAGS_REG)
10898           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10899      (set (match_dup 0) (neg:DI (match_dup 1)))])
10900    (parallel
10901     [(set (match_dup 2)
10902           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10903                             (match_dup 3))
10904                    (const_int 0)))
10905      (clobber (reg:CC FLAGS_REG))])
10906    (parallel
10907     [(set (match_dup 2)
10908           (neg:DI (match_dup 2)))
10909      (clobber (reg:CC FLAGS_REG))])]
10910   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10912 (define_expand "negdi2"
10913   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10914         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10915   ""
10916   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10918 (define_insn "*negdi2_1"
10919   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10920         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10921    (clobber (reg:CC FLAGS_REG))]
10922   "!TARGET_64BIT
10923    && ix86_unary_operator_ok (NEG, DImode, operands)"
10924   "#")
10926 (define_split
10927   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10928         (neg:DI (match_operand:DI 1 "general_operand" "")))
10929    (clobber (reg:CC FLAGS_REG))]
10930   "!TARGET_64BIT && reload_completed"
10931   [(parallel
10932     [(set (reg:CCZ FLAGS_REG)
10933           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10934      (set (match_dup 0) (neg:SI (match_dup 1)))])
10935    (parallel
10936     [(set (match_dup 2)
10937           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10938                             (match_dup 3))
10939                    (const_int 0)))
10940      (clobber (reg:CC FLAGS_REG))])
10941    (parallel
10942     [(set (match_dup 2)
10943           (neg:SI (match_dup 2)))
10944      (clobber (reg:CC FLAGS_REG))])]
10945   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10947 (define_insn "*negdi2_1_rex64"
10948   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10949         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10950    (clobber (reg:CC FLAGS_REG))]
10951   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10952   "neg{q}\t%0"
10953   [(set_attr "type" "negnot")
10954    (set_attr "mode" "DI")])
10956 ;; The problem with neg is that it does not perform (compare x 0),
10957 ;; it really performs (compare 0 x), which leaves us with the zero
10958 ;; flag being the only useful item.
10960 (define_insn "*negdi2_cmpz_rex64"
10961   [(set (reg:CCZ FLAGS_REG)
10962         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10963                      (const_int 0)))
10964    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10965         (neg:DI (match_dup 1)))]
10966   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10967   "neg{q}\t%0"
10968   [(set_attr "type" "negnot")
10969    (set_attr "mode" "DI")])
10972 (define_expand "negsi2"
10973   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10974         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10975   ""
10976   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10978 (define_insn "*negsi2_1"
10979   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10980         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10981    (clobber (reg:CC FLAGS_REG))]
10982   "ix86_unary_operator_ok (NEG, SImode, operands)"
10983   "neg{l}\t%0"
10984   [(set_attr "type" "negnot")
10985    (set_attr "mode" "SI")])
10987 ;; Combine is quite creative about this pattern.
10988 (define_insn "*negsi2_1_zext"
10989   [(set (match_operand:DI 0 "register_operand" "=r")
10990         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10991                                         (const_int 32)))
10992                      (const_int 32)))
10993    (clobber (reg:CC FLAGS_REG))]
10994   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10995   "neg{l}\t%k0"
10996   [(set_attr "type" "negnot")
10997    (set_attr "mode" "SI")])
10999 ;; The problem with neg is that it does not perform (compare x 0),
11000 ;; it really performs (compare 0 x), which leaves us with the zero
11001 ;; flag being the only useful item.
11003 (define_insn "*negsi2_cmpz"
11004   [(set (reg:CCZ FLAGS_REG)
11005         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
11006                      (const_int 0)))
11007    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11008         (neg:SI (match_dup 1)))]
11009   "ix86_unary_operator_ok (NEG, SImode, operands)"
11010   "neg{l}\t%0"
11011   [(set_attr "type" "negnot")
11012    (set_attr "mode" "SI")])
11014 (define_insn "*negsi2_cmpz_zext"
11015   [(set (reg:CCZ FLAGS_REG)
11016         (compare:CCZ (lshiftrt:DI
11017                        (neg:DI (ashift:DI
11018                                  (match_operand:DI 1 "register_operand" "0")
11019                                  (const_int 32)))
11020                        (const_int 32))
11021                      (const_int 0)))
11022    (set (match_operand:DI 0 "register_operand" "=r")
11023         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
11024                                         (const_int 32)))
11025                      (const_int 32)))]
11026   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
11027   "neg{l}\t%k0"
11028   [(set_attr "type" "negnot")
11029    (set_attr "mode" "SI")])
11031 (define_expand "neghi2"
11032   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11033         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
11034   "TARGET_HIMODE_MATH"
11035   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
11037 (define_insn "*neghi2_1"
11038   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11039         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
11040    (clobber (reg:CC FLAGS_REG))]
11041   "ix86_unary_operator_ok (NEG, HImode, operands)"
11042   "neg{w}\t%0"
11043   [(set_attr "type" "negnot")
11044    (set_attr "mode" "HI")])
11046 (define_insn "*neghi2_cmpz"
11047   [(set (reg:CCZ FLAGS_REG)
11048         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11049                      (const_int 0)))
11050    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11051         (neg:HI (match_dup 1)))]
11052   "ix86_unary_operator_ok (NEG, HImode, operands)"
11053   "neg{w}\t%0"
11054   [(set_attr "type" "negnot")
11055    (set_attr "mode" "HI")])
11057 (define_expand "negqi2"
11058   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11059         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11060   "TARGET_QIMODE_MATH"
11061   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
11063 (define_insn "*negqi2_1"
11064   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11065         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
11066    (clobber (reg:CC FLAGS_REG))]
11067   "ix86_unary_operator_ok (NEG, QImode, operands)"
11068   "neg{b}\t%0"
11069   [(set_attr "type" "negnot")
11070    (set_attr "mode" "QI")])
11072 (define_insn "*negqi2_cmpz"
11073   [(set (reg:CCZ FLAGS_REG)
11074         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11075                      (const_int 0)))
11076    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11077         (neg:QI (match_dup 1)))]
11078   "ix86_unary_operator_ok (NEG, QImode, operands)"
11079   "neg{b}\t%0"
11080   [(set_attr "type" "negnot")
11081    (set_attr "mode" "QI")])
11083 ;; Changing of sign for FP values is doable using integer unit too.
11085 (define_expand "<code><mode>2"
11086   [(set (match_operand:X87MODEF 0 "register_operand" "")
11087         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
11088   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
11089   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
11091 (define_insn "*absneg<mode>2_mixed"
11092   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
11093         (match_operator:MODEF 3 "absneg_operator"
11094           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
11095    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
11096    (clobber (reg:CC FLAGS_REG))]
11097   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
11098   "#")
11100 (define_insn "*absneg<mode>2_sse"
11101   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
11102         (match_operator:MODEF 3 "absneg_operator"
11103           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
11104    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
11105    (clobber (reg:CC FLAGS_REG))]
11106   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
11107   "#")
11109 (define_insn "*absneg<mode>2_i387"
11110   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
11111         (match_operator:X87MODEF 3 "absneg_operator"
11112           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
11113    (use (match_operand 2 "" ""))
11114    (clobber (reg:CC FLAGS_REG))]
11115   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
11116   "#")
11118 (define_expand "<code>tf2"
11119   [(set (match_operand:TF 0 "register_operand" "")
11120         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
11121   "TARGET_SSE2"
11122   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
11124 (define_insn "*absnegtf2_sse"
11125   [(set (match_operand:TF 0 "register_operand" "=x,x")
11126         (match_operator:TF 3 "absneg_operator"
11127           [(match_operand:TF 1 "register_operand" "0,x")]))
11128    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
11129    (clobber (reg:CC FLAGS_REG))]
11130   "TARGET_SSE2"
11131   "#")
11133 ;; Splitters for fp abs and neg.
11135 (define_split
11136   [(set (match_operand 0 "fp_register_operand" "")
11137         (match_operator 1 "absneg_operator" [(match_dup 0)]))
11138    (use (match_operand 2 "" ""))
11139    (clobber (reg:CC FLAGS_REG))]
11140   "reload_completed"
11141   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
11143 (define_split
11144   [(set (match_operand 0 "register_operand" "")
11145         (match_operator 3 "absneg_operator"
11146           [(match_operand 1 "register_operand" "")]))
11147    (use (match_operand 2 "nonimmediate_operand" ""))
11148    (clobber (reg:CC FLAGS_REG))]
11149   "reload_completed && SSE_REG_P (operands[0])"
11150   [(set (match_dup 0) (match_dup 3))]
11152   enum machine_mode mode = GET_MODE (operands[0]);
11153   enum machine_mode vmode = GET_MODE (operands[2]);
11154   rtx tmp;
11156   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
11157   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
11158   if (operands_match_p (operands[0], operands[2]))
11159     {
11160       tmp = operands[1];
11161       operands[1] = operands[2];
11162       operands[2] = tmp;
11163     }
11164   if (GET_CODE (operands[3]) == ABS)
11165     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
11166   else
11167     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
11168   operands[3] = tmp;
11171 (define_split
11172   [(set (match_operand:SF 0 "register_operand" "")
11173         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
11174    (use (match_operand:V4SF 2 "" ""))
11175    (clobber (reg:CC FLAGS_REG))]
11176   "reload_completed"
11177   [(parallel [(set (match_dup 0) (match_dup 1))
11178               (clobber (reg:CC FLAGS_REG))])]
11180   rtx tmp;
11181   operands[0] = gen_lowpart (SImode, operands[0]);
11182   if (GET_CODE (operands[1]) == ABS)
11183     {
11184       tmp = gen_int_mode (0x7fffffff, SImode);
11185       tmp = gen_rtx_AND (SImode, operands[0], tmp);
11186     }
11187   else
11188     {
11189       tmp = gen_int_mode (0x80000000, SImode);
11190       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11191     }
11192   operands[1] = tmp;
11195 (define_split
11196   [(set (match_operand:DF 0 "register_operand" "")
11197         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
11198    (use (match_operand 2 "" ""))
11199    (clobber (reg:CC FLAGS_REG))]
11200   "reload_completed"
11201   [(parallel [(set (match_dup 0) (match_dup 1))
11202               (clobber (reg:CC FLAGS_REG))])]
11204   rtx tmp;
11205   if (TARGET_64BIT)
11206     {
11207       tmp = gen_lowpart (DImode, operands[0]);
11208       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
11209       operands[0] = tmp;
11211       if (GET_CODE (operands[1]) == ABS)
11212         tmp = const0_rtx;
11213       else
11214         tmp = gen_rtx_NOT (DImode, tmp);
11215     }
11216   else
11217     {
11218       operands[0] = gen_highpart (SImode, operands[0]);
11219       if (GET_CODE (operands[1]) == ABS)
11220         {
11221           tmp = gen_int_mode (0x7fffffff, SImode);
11222           tmp = gen_rtx_AND (SImode, operands[0], tmp);
11223         }
11224       else
11225         {
11226           tmp = gen_int_mode (0x80000000, SImode);
11227           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11228         }
11229     }
11230   operands[1] = tmp;
11233 (define_split
11234   [(set (match_operand:XF 0 "register_operand" "")
11235         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
11236    (use (match_operand 2 "" ""))
11237    (clobber (reg:CC FLAGS_REG))]
11238   "reload_completed"
11239   [(parallel [(set (match_dup 0) (match_dup 1))
11240               (clobber (reg:CC FLAGS_REG))])]
11242   rtx tmp;
11243   operands[0] = gen_rtx_REG (SImode,
11244                              true_regnum (operands[0])
11245                              + (TARGET_64BIT ? 1 : 2));
11246   if (GET_CODE (operands[1]) == ABS)
11247     {
11248       tmp = GEN_INT (0x7fff);
11249       tmp = gen_rtx_AND (SImode, operands[0], tmp);
11250     }
11251   else
11252     {
11253       tmp = GEN_INT (0x8000);
11254       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11255     }
11256   operands[1] = tmp;
11259 ;; Conditionalize these after reload. If they match before reload, we
11260 ;; lose the clobber and ability to use integer instructions.
11262 (define_insn "*<code><mode>2_1"
11263   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
11264         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
11265   "TARGET_80387
11266    && (reload_completed
11267        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
11268   "f<absnegprefix>"
11269   [(set_attr "type" "fsgn")
11270    (set_attr "mode" "<MODE>")])
11272 (define_insn "*<code>extendsfdf2"
11273   [(set (match_operand:DF 0 "register_operand" "=f")
11274         (absneg:DF (float_extend:DF
11275                      (match_operand:SF 1 "register_operand" "0"))))]
11276   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
11277   "f<absnegprefix>"
11278   [(set_attr "type" "fsgn")
11279    (set_attr "mode" "DF")])
11281 (define_insn "*<code>extendsfxf2"
11282   [(set (match_operand:XF 0 "register_operand" "=f")
11283         (absneg:XF (float_extend:XF
11284                      (match_operand:SF 1 "register_operand" "0"))))]
11285   "TARGET_80387"
11286   "f<absnegprefix>"
11287   [(set_attr "type" "fsgn")
11288    (set_attr "mode" "XF")])
11290 (define_insn "*<code>extenddfxf2"
11291   [(set (match_operand:XF 0 "register_operand" "=f")
11292         (absneg:XF (float_extend:XF
11293                       (match_operand:DF 1 "register_operand" "0"))))]
11294   "TARGET_80387"
11295   "f<absnegprefix>"
11296   [(set_attr "type" "fsgn")
11297    (set_attr "mode" "XF")])
11299 ;; Copysign instructions
11301 (define_mode_iterator CSGNMODE [SF DF TF])
11302 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
11304 (define_expand "copysign<mode>3"
11305   [(match_operand:CSGNMODE 0 "register_operand" "")
11306    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
11307    (match_operand:CSGNMODE 2 "register_operand" "")]
11308   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11309    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
11311   ix86_expand_copysign (operands);
11312   DONE;
11315 (define_insn_and_split "copysign<mode>3_const"
11316   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
11317         (unspec:CSGNMODE
11318           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
11319            (match_operand:CSGNMODE 2 "register_operand" "0")
11320            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
11321           UNSPEC_COPYSIGN))]
11322   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11323    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
11324   "#"
11325   "&& reload_completed"
11326   [(const_int 0)]
11328   ix86_split_copysign_const (operands);
11329   DONE;
11332 (define_insn "copysign<mode>3_var"
11333   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
11334         (unspec:CSGNMODE
11335           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
11336            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
11337            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
11338            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
11339           UNSPEC_COPYSIGN))
11340    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
11341   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11342    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
11343   "#")
11345 (define_split
11346   [(set (match_operand:CSGNMODE 0 "register_operand" "")
11347         (unspec:CSGNMODE
11348           [(match_operand:CSGNMODE 2 "register_operand" "")
11349            (match_operand:CSGNMODE 3 "register_operand" "")
11350            (match_operand:<CSGNVMODE> 4 "" "")
11351            (match_operand:<CSGNVMODE> 5 "" "")]
11352           UNSPEC_COPYSIGN))
11353    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
11354   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11355     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
11356    && reload_completed"
11357   [(const_int 0)]
11359   ix86_split_copysign_var (operands);
11360   DONE;
11363 ;; One complement instructions
11365 (define_expand "one_cmpldi2"
11366   [(set (match_operand:DI 0 "nonimmediate_operand" "")
11367         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
11368   "TARGET_64BIT"
11369   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
11371 (define_insn "*one_cmpldi2_1_rex64"
11372   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11373         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
11374   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
11375   "not{q}\t%0"
11376   [(set_attr "type" "negnot")
11377    (set_attr "mode" "DI")])
11379 (define_insn "*one_cmpldi2_2_rex64"
11380   [(set (reg FLAGS_REG)
11381         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
11382                  (const_int 0)))
11383    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11384         (not:DI (match_dup 1)))]
11385   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11386    && ix86_unary_operator_ok (NOT, DImode, operands)"
11387   "#"
11388   [(set_attr "type" "alu1")
11389    (set_attr "mode" "DI")])
11391 (define_split
11392   [(set (match_operand 0 "flags_reg_operand" "")
11393         (match_operator 2 "compare_operator"
11394           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
11395            (const_int 0)]))
11396    (set (match_operand:DI 1 "nonimmediate_operand" "")
11397         (not:DI (match_dup 3)))]
11398   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
11399   [(parallel [(set (match_dup 0)
11400                    (match_op_dup 2
11401                      [(xor:DI (match_dup 3) (const_int -1))
11402                       (const_int 0)]))
11403               (set (match_dup 1)
11404                    (xor:DI (match_dup 3) (const_int -1)))])]
11405   "")
11407 (define_expand "one_cmplsi2"
11408   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11409         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
11410   ""
11411   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
11413 (define_insn "*one_cmplsi2_1"
11414   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11415         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
11416   "ix86_unary_operator_ok (NOT, SImode, operands)"
11417   "not{l}\t%0"
11418   [(set_attr "type" "negnot")
11419    (set_attr "mode" "SI")])
11421 ;; ??? Currently never generated - xor is used instead.
11422 (define_insn "*one_cmplsi2_1_zext"
11423   [(set (match_operand:DI 0 "register_operand" "=r")
11424         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
11425   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
11426   "not{l}\t%k0"
11427   [(set_attr "type" "negnot")
11428    (set_attr "mode" "SI")])
11430 (define_insn "*one_cmplsi2_2"
11431   [(set (reg FLAGS_REG)
11432         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
11433                  (const_int 0)))
11434    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11435         (not:SI (match_dup 1)))]
11436   "ix86_match_ccmode (insn, CCNOmode)
11437    && ix86_unary_operator_ok (NOT, SImode, operands)"
11438   "#"
11439   [(set_attr "type" "alu1")
11440    (set_attr "mode" "SI")])
11442 (define_split
11443   [(set (match_operand 0 "flags_reg_operand" "")
11444         (match_operator 2 "compare_operator"
11445           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
11446            (const_int 0)]))
11447    (set (match_operand:SI 1 "nonimmediate_operand" "")
11448         (not:SI (match_dup 3)))]
11449   "ix86_match_ccmode (insn, CCNOmode)"
11450   [(parallel [(set (match_dup 0)
11451                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11452                                     (const_int 0)]))
11453               (set (match_dup 1)
11454                    (xor:SI (match_dup 3) (const_int -1)))])]
11455   "")
11457 ;; ??? Currently never generated - xor is used instead.
11458 (define_insn "*one_cmplsi2_2_zext"
11459   [(set (reg FLAGS_REG)
11460         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
11461                  (const_int 0)))
11462    (set (match_operand:DI 0 "register_operand" "=r")
11463         (zero_extend:DI (not:SI (match_dup 1))))]
11464   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11465    && ix86_unary_operator_ok (NOT, SImode, operands)"
11466   "#"
11467   [(set_attr "type" "alu1")
11468    (set_attr "mode" "SI")])
11470 (define_split
11471   [(set (match_operand 0 "flags_reg_operand" "")
11472         (match_operator 2 "compare_operator"
11473           [(not:SI (match_operand:SI 3 "register_operand" ""))
11474            (const_int 0)]))
11475    (set (match_operand:DI 1 "register_operand" "")
11476         (zero_extend:DI (not:SI (match_dup 3))))]
11477   "ix86_match_ccmode (insn, CCNOmode)"
11478   [(parallel [(set (match_dup 0)
11479                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11480                                     (const_int 0)]))
11481               (set (match_dup 1)
11482                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
11483   "")
11485 (define_expand "one_cmplhi2"
11486   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11487         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
11488   "TARGET_HIMODE_MATH"
11489   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
11491 (define_insn "*one_cmplhi2_1"
11492   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11493         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
11494   "ix86_unary_operator_ok (NOT, HImode, operands)"
11495   "not{w}\t%0"
11496   [(set_attr "type" "negnot")
11497    (set_attr "mode" "HI")])
11499 (define_insn "*one_cmplhi2_2"
11500   [(set (reg FLAGS_REG)
11501         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11502                  (const_int 0)))
11503    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11504         (not:HI (match_dup 1)))]
11505   "ix86_match_ccmode (insn, CCNOmode)
11506    && ix86_unary_operator_ok (NEG, HImode, operands)"
11507   "#"
11508   [(set_attr "type" "alu1")
11509    (set_attr "mode" "HI")])
11511 (define_split
11512   [(set (match_operand 0 "flags_reg_operand" "")
11513         (match_operator 2 "compare_operator"
11514           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11515            (const_int 0)]))
11516    (set (match_operand:HI 1 "nonimmediate_operand" "")
11517         (not:HI (match_dup 3)))]
11518   "ix86_match_ccmode (insn, CCNOmode)"
11519   [(parallel [(set (match_dup 0)
11520                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11521                                     (const_int 0)]))
11522               (set (match_dup 1)
11523                    (xor:HI (match_dup 3) (const_int -1)))])]
11524   "")
11526 ;; %%% Potential partial reg stall on alternative 1.  What to do?
11527 (define_expand "one_cmplqi2"
11528   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11529         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11530   "TARGET_QIMODE_MATH"
11531   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11533 (define_insn "*one_cmplqi2_1"
11534   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11535         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11536   "ix86_unary_operator_ok (NOT, QImode, operands)"
11537   "@
11538    not{b}\t%0
11539    not{l}\t%k0"
11540   [(set_attr "type" "negnot")
11541    (set_attr "mode" "QI,SI")])
11543 (define_insn "*one_cmplqi2_2"
11544   [(set (reg FLAGS_REG)
11545         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11546                  (const_int 0)))
11547    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11548         (not:QI (match_dup 1)))]
11549   "ix86_match_ccmode (insn, CCNOmode)
11550    && ix86_unary_operator_ok (NOT, QImode, operands)"
11551   "#"
11552   [(set_attr "type" "alu1")
11553    (set_attr "mode" "QI")])
11555 (define_split
11556   [(set (match_operand 0 "flags_reg_operand" "")
11557         (match_operator 2 "compare_operator"
11558           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11559            (const_int 0)]))
11560    (set (match_operand:QI 1 "nonimmediate_operand" "")
11561         (not:QI (match_dup 3)))]
11562   "ix86_match_ccmode (insn, CCNOmode)"
11563   [(parallel [(set (match_dup 0)
11564                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11565                                     (const_int 0)]))
11566               (set (match_dup 1)
11567                    (xor:QI (match_dup 3) (const_int -1)))])]
11568   "")
11570 ;; Arithmetic shift instructions
11572 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11573 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
11574 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11575 ;; from the assembler input.
11577 ;; This instruction shifts the target reg/mem as usual, but instead of
11578 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
11579 ;; is a left shift double, bits are taken from the high order bits of
11580 ;; reg, else if the insn is a shift right double, bits are taken from the
11581 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
11582 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11584 ;; Since sh[lr]d does not change the `reg' operand, that is done
11585 ;; separately, making all shifts emit pairs of shift double and normal
11586 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
11587 ;; support a 63 bit shift, each shift where the count is in a reg expands
11588 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11590 ;; If the shift count is a constant, we need never emit more than one
11591 ;; shift pair, instead using moves and sign extension for counts greater
11592 ;; than 31.
11594 (define_expand "ashlti3"
11595   [(set (match_operand:TI 0 "register_operand" "")
11596         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11597                    (match_operand:QI 2 "nonmemory_operand" "")))]
11598   "TARGET_64BIT"
11599   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11601 ;; This pattern must be defined before *ashlti3_1 to prevent
11602 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11604 (define_insn "*avx_ashlti3"
11605   [(set (match_operand:TI 0 "register_operand" "=x")
11606         (ashift:TI (match_operand:TI 1 "register_operand" "x")
11607                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11608   "TARGET_AVX"
11610   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11611   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11613   [(set_attr "type" "sseishft")
11614    (set_attr "prefix" "vex")
11615    (set_attr "length_immediate" "1")
11616    (set_attr "mode" "TI")])
11618 (define_insn "sse2_ashlti3"
11619   [(set (match_operand:TI 0 "register_operand" "=x")
11620         (ashift:TI (match_operand:TI 1 "register_operand" "0")
11621                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11622   "TARGET_SSE2"
11624   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11625   return "pslldq\t{%2, %0|%0, %2}";
11627   [(set_attr "type" "sseishft")
11628    (set_attr "prefix_data16" "1")
11629    (set_attr "length_immediate" "1")
11630    (set_attr "mode" "TI")])
11632 (define_insn "*ashlti3_1"
11633   [(set (match_operand:TI 0 "register_operand" "=&r,r")
11634         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11635                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11636    (clobber (reg:CC FLAGS_REG))]
11637   "TARGET_64BIT"
11638   "#"
11639   [(set_attr "type" "multi")])
11641 (define_peephole2
11642   [(match_scratch:DI 3 "r")
11643    (parallel [(set (match_operand:TI 0 "register_operand" "")
11644                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11645                               (match_operand:QI 2 "nonmemory_operand" "")))
11646               (clobber (reg:CC FLAGS_REG))])
11647    (match_dup 3)]
11648   "TARGET_64BIT"
11649   [(const_int 0)]
11650   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11652 (define_split
11653   [(set (match_operand:TI 0 "register_operand" "")
11654         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11655                    (match_operand:QI 2 "nonmemory_operand" "")))
11656    (clobber (reg:CC FLAGS_REG))]
11657   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11658                     ? epilogue_completed : reload_completed)"
11659   [(const_int 0)]
11660   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11662 (define_insn "x86_64_shld"
11663   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11664         (ior:DI (ashift:DI (match_dup 0)
11665                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11666                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11667                   (minus:QI (const_int 64) (match_dup 2)))))
11668    (clobber (reg:CC FLAGS_REG))]
11669   "TARGET_64BIT"
11670   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11671   [(set_attr "type" "ishift")
11672    (set_attr "prefix_0f" "1")
11673    (set_attr "mode" "DI")
11674    (set_attr "athlon_decode" "vector")
11675    (set_attr "amdfam10_decode" "vector")])
11677 (define_expand "x86_64_shift_adj_1"
11678   [(set (reg:CCZ FLAGS_REG)
11679         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11680                              (const_int 64))
11681                      (const_int 0)))
11682    (set (match_operand:DI 0 "register_operand" "")
11683         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11684                          (match_operand:DI 1 "register_operand" "")
11685                          (match_dup 0)))
11686    (set (match_dup 1)
11687         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11688                          (match_operand:DI 3 "register_operand" "r")
11689                          (match_dup 1)))]
11690   "TARGET_64BIT"
11691   "")
11693 (define_expand "x86_64_shift_adj_2"
11694   [(use (match_operand:DI 0 "register_operand" ""))
11695    (use (match_operand:DI 1 "register_operand" ""))
11696    (use (match_operand:QI 2 "register_operand" ""))]
11697   "TARGET_64BIT"
11699   rtx label = gen_label_rtx ();
11700   rtx tmp;
11702   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11704   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11705   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11706   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11707                               gen_rtx_LABEL_REF (VOIDmode, label),
11708                               pc_rtx);
11709   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11710   JUMP_LABEL (tmp) = label;
11712   emit_move_insn (operands[0], operands[1]);
11713   ix86_expand_clear (operands[1]);
11715   emit_label (label);
11716   LABEL_NUSES (label) = 1;
11718   DONE;
11721 (define_expand "ashldi3"
11722   [(set (match_operand:DI 0 "shiftdi_operand" "")
11723         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11724                    (match_operand:QI 2 "nonmemory_operand" "")))]
11725   ""
11726   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11728 (define_insn "*ashldi3_1_rex64"
11729   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11730         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11731                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11732    (clobber (reg:CC FLAGS_REG))]
11733   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11735   switch (get_attr_type (insn))
11736     {
11737     case TYPE_ALU:
11738       gcc_assert (operands[2] == const1_rtx);
11739       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11740       return "add{q}\t%0, %0";
11742     case TYPE_LEA:
11743       gcc_assert (CONST_INT_P (operands[2]));
11744       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11745       operands[1] = gen_rtx_MULT (DImode, operands[1],
11746                                   GEN_INT (1 << INTVAL (operands[2])));
11747       return "lea{q}\t{%a1, %0|%0, %a1}";
11749     default:
11750       if (REG_P (operands[2]))
11751         return "sal{q}\t{%b2, %0|%0, %b2}";
11752       else if (operands[2] == const1_rtx
11753                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11754         return "sal{q}\t%0";
11755       else
11756         return "sal{q}\t{%2, %0|%0, %2}";
11757     }
11759   [(set (attr "type")
11760      (cond [(eq_attr "alternative" "1")
11761               (const_string "lea")
11762             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11763                           (const_int 0))
11764                       (match_operand 0 "register_operand" ""))
11765                  (match_operand 2 "const1_operand" ""))
11766               (const_string "alu")
11767            ]
11768            (const_string "ishift")))
11769    (set (attr "length_immediate")
11770      (if_then_else
11771        (ior (eq_attr "type" "alu")
11772             (and (eq_attr "type" "ishift")
11773                  (and (match_operand 2 "const1_operand" "")
11774                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11775                           (const_int 0)))))
11776        (const_string "0")
11777        (const_string "*")))
11778    (set_attr "mode" "DI")])
11780 ;; Convert lea to the lea pattern to avoid flags dependency.
11781 (define_split
11782   [(set (match_operand:DI 0 "register_operand" "")
11783         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11784                    (match_operand:QI 2 "immediate_operand" "")))
11785    (clobber (reg:CC FLAGS_REG))]
11786   "TARGET_64BIT && reload_completed
11787    && true_regnum (operands[0]) != true_regnum (operands[1])"
11788   [(set (match_dup 0)
11789         (mult:DI (match_dup 1)
11790                  (match_dup 2)))]
11791   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11793 ;; This pattern can't accept a variable shift count, since shifts by
11794 ;; zero don't affect the flags.  We assume that shifts by constant
11795 ;; zero are optimized away.
11796 (define_insn "*ashldi3_cmp_rex64"
11797   [(set (reg FLAGS_REG)
11798         (compare
11799           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11800                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11801           (const_int 0)))
11802    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11803         (ashift:DI (match_dup 1) (match_dup 2)))]
11804   "TARGET_64BIT
11805    && (optimize_function_for_size_p (cfun)
11806        || !TARGET_PARTIAL_FLAG_REG_STALL
11807        || (operands[2] == const1_rtx
11808            && (TARGET_SHIFT1
11809                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11810    && ix86_match_ccmode (insn, CCGOCmode)
11811    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11813   switch (get_attr_type (insn))
11814     {
11815     case TYPE_ALU:
11816       gcc_assert (operands[2] == const1_rtx);
11817       return "add{q}\t%0, %0";
11819     default:
11820       if (REG_P (operands[2]))
11821         return "sal{q}\t{%b2, %0|%0, %b2}";
11822       else if (operands[2] == const1_rtx
11823                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11824         return "sal{q}\t%0";
11825       else
11826         return "sal{q}\t{%2, %0|%0, %2}";
11827     }
11829   [(set (attr "type")
11830      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11831                           (const_int 0))
11832                       (match_operand 0 "register_operand" ""))
11833                  (match_operand 2 "const1_operand" ""))
11834               (const_string "alu")
11835            ]
11836            (const_string "ishift")))
11837    (set (attr "length_immediate")
11838      (if_then_else
11839        (ior (eq_attr "type" "alu")
11840             (and (eq_attr "type" "ishift")
11841                  (and (match_operand 2 "const1_operand" "")
11842                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11843                           (const_int 0)))))
11844        (const_string "0")
11845        (const_string "*")))
11846    (set_attr "mode" "DI")])
11848 (define_insn "*ashldi3_cconly_rex64"
11849   [(set (reg FLAGS_REG)
11850         (compare
11851           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11852                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11853           (const_int 0)))
11854    (clobber (match_scratch:DI 0 "=r"))]
11855   "TARGET_64BIT
11856    && (optimize_function_for_size_p (cfun)
11857        || !TARGET_PARTIAL_FLAG_REG_STALL
11858        || (operands[2] == const1_rtx
11859            && (TARGET_SHIFT1
11860                || TARGET_DOUBLE_WITH_ADD)))
11861    && ix86_match_ccmode (insn, CCGOCmode)
11862    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11864   switch (get_attr_type (insn))
11865     {
11866     case TYPE_ALU:
11867       gcc_assert (operands[2] == const1_rtx);
11868       return "add{q}\t%0, %0";
11870     default:
11871       if (REG_P (operands[2]))
11872         return "sal{q}\t{%b2, %0|%0, %b2}";
11873       else if (operands[2] == const1_rtx
11874                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11875         return "sal{q}\t%0";
11876       else
11877         return "sal{q}\t{%2, %0|%0, %2}";
11878     }
11880   [(set (attr "type")
11881      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11882                           (const_int 0))
11883                       (match_operand 0 "register_operand" ""))
11884                  (match_operand 2 "const1_operand" ""))
11885               (const_string "alu")
11886            ]
11887            (const_string "ishift")))
11888    (set (attr "length_immediate")
11889      (if_then_else
11890        (ior (eq_attr "type" "alu")
11891             (and (eq_attr "type" "ishift")
11892                  (and (match_operand 2 "const1_operand" "")
11893                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11894                           (const_int 0)))))
11895        (const_string "0")
11896        (const_string "*")))
11897    (set_attr "mode" "DI")])
11899 (define_insn "*ashldi3_1"
11900   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11901         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11902                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11903    (clobber (reg:CC FLAGS_REG))]
11904   "!TARGET_64BIT"
11905   "#"
11906   [(set_attr "type" "multi")])
11908 ;; By default we don't ask for a scratch register, because when DImode
11909 ;; values are manipulated, registers are already at a premium.  But if
11910 ;; we have one handy, we won't turn it away.
11911 (define_peephole2
11912   [(match_scratch:SI 3 "r")
11913    (parallel [(set (match_operand:DI 0 "register_operand" "")
11914                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11915                               (match_operand:QI 2 "nonmemory_operand" "")))
11916               (clobber (reg:CC FLAGS_REG))])
11917    (match_dup 3)]
11918   "!TARGET_64BIT && TARGET_CMOVE"
11919   [(const_int 0)]
11920   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11922 (define_split
11923   [(set (match_operand:DI 0 "register_operand" "")
11924         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11925                    (match_operand:QI 2 "nonmemory_operand" "")))
11926    (clobber (reg:CC FLAGS_REG))]
11927   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11928                      ? epilogue_completed : reload_completed)"
11929   [(const_int 0)]
11930   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11932 (define_insn "x86_shld"
11933   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11934         (ior:SI (ashift:SI (match_dup 0)
11935                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11936                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11937                   (minus:QI (const_int 32) (match_dup 2)))))
11938    (clobber (reg:CC FLAGS_REG))]
11939   ""
11940   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11941   [(set_attr "type" "ishift")
11942    (set_attr "prefix_0f" "1")
11943    (set_attr "mode" "SI")
11944    (set_attr "pent_pair" "np")
11945    (set_attr "athlon_decode" "vector")
11946    (set_attr "amdfam10_decode" "vector")])
11948 (define_expand "x86_shift_adj_1"
11949   [(set (reg:CCZ FLAGS_REG)
11950         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11951                              (const_int 32))
11952                      (const_int 0)))
11953    (set (match_operand:SI 0 "register_operand" "")
11954         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11955                          (match_operand:SI 1 "register_operand" "")
11956                          (match_dup 0)))
11957    (set (match_dup 1)
11958         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11959                          (match_operand:SI 3 "register_operand" "r")
11960                          (match_dup 1)))]
11961   "TARGET_CMOVE"
11962   "")
11964 (define_expand "x86_shift_adj_2"
11965   [(use (match_operand:SI 0 "register_operand" ""))
11966    (use (match_operand:SI 1 "register_operand" ""))
11967    (use (match_operand:QI 2 "register_operand" ""))]
11968   ""
11970   rtx label = gen_label_rtx ();
11971   rtx tmp;
11973   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11975   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11976   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11977   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11978                               gen_rtx_LABEL_REF (VOIDmode, label),
11979                               pc_rtx);
11980   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11981   JUMP_LABEL (tmp) = label;
11983   emit_move_insn (operands[0], operands[1]);
11984   ix86_expand_clear (operands[1]);
11986   emit_label (label);
11987   LABEL_NUSES (label) = 1;
11989   DONE;
11992 (define_expand "ashlsi3"
11993   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11994         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11995                    (match_operand:QI 2 "nonmemory_operand" "")))]
11996   ""
11997   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11999 (define_insn "*ashlsi3_1"
12000   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
12001         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
12002                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
12003    (clobber (reg:CC FLAGS_REG))]
12004   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12006   switch (get_attr_type (insn))
12007     {
12008     case TYPE_ALU:
12009       gcc_assert (operands[2] == const1_rtx);
12010       gcc_assert (rtx_equal_p (operands[0], operands[1]));
12011       return "add{l}\t%0, %0";
12013     case TYPE_LEA:
12014       return "#";
12016     default:
12017       if (REG_P (operands[2]))
12018         return "sal{l}\t{%b2, %0|%0, %b2}";
12019       else if (operands[2] == const1_rtx
12020                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12021         return "sal{l}\t%0";
12022       else
12023         return "sal{l}\t{%2, %0|%0, %2}";
12024     }
12026   [(set (attr "type")
12027      (cond [(eq_attr "alternative" "1")
12028               (const_string "lea")
12029             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12030                           (const_int 0))
12031                       (match_operand 0 "register_operand" ""))
12032                  (match_operand 2 "const1_operand" ""))
12033               (const_string "alu")
12034            ]
12035            (const_string "ishift")))
12036    (set (attr "length_immediate")
12037      (if_then_else
12038        (ior (eq_attr "type" "alu")
12039             (and (eq_attr "type" "ishift")
12040                  (and (match_operand 2 "const1_operand" "")
12041                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12042                           (const_int 0)))))
12043        (const_string "0")
12044        (const_string "*")))
12045    (set_attr "mode" "SI")])
12047 ;; Convert lea to the lea pattern to avoid flags dependency.
12048 (define_split
12049   [(set (match_operand 0 "register_operand" "")
12050         (ashift (match_operand 1 "index_register_operand" "")
12051                 (match_operand:QI 2 "const_int_operand" "")))
12052    (clobber (reg:CC FLAGS_REG))]
12053   "reload_completed
12054    && true_regnum (operands[0]) != true_regnum (operands[1])
12055    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
12056   [(const_int 0)]
12058   rtx pat;
12059   enum machine_mode mode = GET_MODE (operands[0]);
12061   if (GET_MODE_SIZE (mode) < 4)
12062     operands[0] = gen_lowpart (SImode, operands[0]);
12063   if (mode != Pmode)
12064     operands[1] = gen_lowpart (Pmode, operands[1]);
12065   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
12067   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
12068   if (Pmode != SImode)
12069     pat = gen_rtx_SUBREG (SImode, pat, 0);
12070   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
12071   DONE;
12074 ;; Rare case of shifting RSP is handled by generating move and shift
12075 (define_split
12076   [(set (match_operand 0 "register_operand" "")
12077         (ashift (match_operand 1 "register_operand" "")
12078                 (match_operand:QI 2 "const_int_operand" "")))
12079    (clobber (reg:CC FLAGS_REG))]
12080   "reload_completed
12081    && true_regnum (operands[0]) != true_regnum (operands[1])"
12082   [(const_int 0)]
12084   rtx pat, clob;
12085   emit_move_insn (operands[0], operands[1]);
12086   pat = gen_rtx_SET (VOIDmode, operands[0],
12087                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
12088                                      operands[0], operands[2]));
12089   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
12090   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
12091   DONE;
12094 (define_insn "*ashlsi3_1_zext"
12095   [(set (match_operand:DI 0 "register_operand" "=r,r")
12096         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
12097                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
12098    (clobber (reg:CC FLAGS_REG))]
12099   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12101   switch (get_attr_type (insn))
12102     {
12103     case TYPE_ALU:
12104       gcc_assert (operands[2] == const1_rtx);
12105       return "add{l}\t%k0, %k0";
12107     case TYPE_LEA:
12108       return "#";
12110     default:
12111       if (REG_P (operands[2]))
12112         return "sal{l}\t{%b2, %k0|%k0, %b2}";
12113       else if (operands[2] == const1_rtx
12114                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12115         return "sal{l}\t%k0";
12116       else
12117         return "sal{l}\t{%2, %k0|%k0, %2}";
12118     }
12120   [(set (attr "type")
12121      (cond [(eq_attr "alternative" "1")
12122               (const_string "lea")
12123             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12124                      (const_int 0))
12125                  (match_operand 2 "const1_operand" ""))
12126               (const_string "alu")
12127            ]
12128            (const_string "ishift")))
12129    (set (attr "length_immediate")
12130      (if_then_else
12131        (ior (eq_attr "type" "alu")
12132             (and (eq_attr "type" "ishift")
12133                  (and (match_operand 2 "const1_operand" "")
12134                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12135                           (const_int 0)))))
12136        (const_string "0")
12137        (const_string "*")))
12138    (set_attr "mode" "SI")])
12140 ;; Convert lea to the lea pattern to avoid flags dependency.
12141 (define_split
12142   [(set (match_operand:DI 0 "register_operand" "")
12143         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
12144                                 (match_operand:QI 2 "const_int_operand" ""))))
12145    (clobber (reg:CC FLAGS_REG))]
12146   "TARGET_64BIT && reload_completed
12147    && true_regnum (operands[0]) != true_regnum (operands[1])"
12148   [(set (match_dup 0) (zero_extend:DI
12149                         (subreg:SI (mult:SI (match_dup 1)
12150                                             (match_dup 2)) 0)))]
12152   operands[1] = gen_lowpart (Pmode, operands[1]);
12153   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
12156 ;; This pattern can't accept a variable shift count, since shifts by
12157 ;; zero don't affect the flags.  We assume that shifts by constant
12158 ;; zero are optimized away.
12159 (define_insn "*ashlsi3_cmp"
12160   [(set (reg FLAGS_REG)
12161         (compare
12162           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12163                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12164           (const_int 0)))
12165    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12166         (ashift:SI (match_dup 1) (match_dup 2)))]
12167    "(optimize_function_for_size_p (cfun)
12168      || !TARGET_PARTIAL_FLAG_REG_STALL
12169      || (operands[2] == const1_rtx
12170          && (TARGET_SHIFT1
12171              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12172    && ix86_match_ccmode (insn, CCGOCmode)
12173    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12175   switch (get_attr_type (insn))
12176     {
12177     case TYPE_ALU:
12178       gcc_assert (operands[2] == const1_rtx);
12179       return "add{l}\t%0, %0";
12181     default:
12182       if (REG_P (operands[2]))
12183         return "sal{l}\t{%b2, %0|%0, %b2}";
12184       else if (operands[2] == const1_rtx
12185                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12186         return "sal{l}\t%0";
12187       else
12188         return "sal{l}\t{%2, %0|%0, %2}";
12189     }
12191   [(set (attr "type")
12192      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12193                           (const_int 0))
12194                       (match_operand 0 "register_operand" ""))
12195                  (match_operand 2 "const1_operand" ""))
12196               (const_string "alu")
12197            ]
12198            (const_string "ishift")))
12199    (set (attr "length_immediate")
12200      (if_then_else
12201        (ior (eq_attr "type" "alu")
12202             (and (eq_attr "type" "ishift")
12203                  (and (match_operand 2 "const1_operand" "")
12204                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12205                           (const_int 0)))))
12206        (const_string "0")
12207        (const_string "*")))
12208    (set_attr "mode" "SI")])
12210 (define_insn "*ashlsi3_cconly"
12211   [(set (reg FLAGS_REG)
12212         (compare
12213           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12214                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12215           (const_int 0)))
12216    (clobber (match_scratch:SI 0 "=r"))]
12217   "(optimize_function_for_size_p (cfun)
12218     || !TARGET_PARTIAL_FLAG_REG_STALL
12219     || (operands[2] == const1_rtx
12220         && (TARGET_SHIFT1
12221             || TARGET_DOUBLE_WITH_ADD)))
12222    && ix86_match_ccmode (insn, CCGOCmode)
12223    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12225   switch (get_attr_type (insn))
12226     {
12227     case TYPE_ALU:
12228       gcc_assert (operands[2] == const1_rtx);
12229       return "add{l}\t%0, %0";
12231     default:
12232       if (REG_P (operands[2]))
12233         return "sal{l}\t{%b2, %0|%0, %b2}";
12234       else if (operands[2] == const1_rtx
12235                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12236         return "sal{l}\t%0";
12237       else
12238         return "sal{l}\t{%2, %0|%0, %2}";
12239     }
12241   [(set (attr "type")
12242      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12243                           (const_int 0))
12244                       (match_operand 0 "register_operand" ""))
12245                  (match_operand 2 "const1_operand" ""))
12246               (const_string "alu")
12247            ]
12248            (const_string "ishift")))
12249    (set (attr "length_immediate")
12250      (if_then_else
12251        (ior (eq_attr "type" "alu")
12252             (and (eq_attr "type" "ishift")
12253                  (and (match_operand 2 "const1_operand" "")
12254                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12255                           (const_int 0)))))
12256        (const_string "0")
12257        (const_string "*")))
12258    (set_attr "mode" "SI")])
12260 (define_insn "*ashlsi3_cmp_zext"
12261   [(set (reg FLAGS_REG)
12262         (compare
12263           (ashift:SI (match_operand:SI 1 "register_operand" "0")
12264                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12265           (const_int 0)))
12266    (set (match_operand:DI 0 "register_operand" "=r")
12267         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
12268   "TARGET_64BIT
12269    && (optimize_function_for_size_p (cfun)
12270        || !TARGET_PARTIAL_FLAG_REG_STALL
12271        || (operands[2] == const1_rtx
12272            && (TARGET_SHIFT1
12273                || TARGET_DOUBLE_WITH_ADD)))
12274    && ix86_match_ccmode (insn, CCGOCmode)
12275    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12277   switch (get_attr_type (insn))
12278     {
12279     case TYPE_ALU:
12280       gcc_assert (operands[2] == const1_rtx);
12281       return "add{l}\t%k0, %k0";
12283     default:
12284       if (REG_P (operands[2]))
12285         return "sal{l}\t{%b2, %k0|%k0, %b2}";
12286       else if (operands[2] == const1_rtx
12287                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12288         return "sal{l}\t%k0";
12289       else
12290         return "sal{l}\t{%2, %k0|%k0, %2}";
12291     }
12293   [(set (attr "type")
12294      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12295                      (const_int 0))
12296                  (match_operand 2 "const1_operand" ""))
12297               (const_string "alu")
12298            ]
12299            (const_string "ishift")))
12300    (set (attr "length_immediate")
12301      (if_then_else
12302        (ior (eq_attr "type" "alu")
12303             (and (eq_attr "type" "ishift")
12304                  (and (match_operand 2 "const1_operand" "")
12305                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12306                           (const_int 0)))))
12307        (const_string "0")
12308        (const_string "*")))
12309    (set_attr "mode" "SI")])
12311 (define_expand "ashlhi3"
12312   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12313         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
12314                    (match_operand:QI 2 "nonmemory_operand" "")))]
12315   "TARGET_HIMODE_MATH"
12316   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
12318 (define_insn "*ashlhi3_1_lea"
12319   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
12320         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
12321                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
12322    (clobber (reg:CC FLAGS_REG))]
12323   "!TARGET_PARTIAL_REG_STALL
12324    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12326   switch (get_attr_type (insn))
12327     {
12328     case TYPE_LEA:
12329       return "#";
12330     case TYPE_ALU:
12331       gcc_assert (operands[2] == const1_rtx);
12332       return "add{w}\t%0, %0";
12334     default:
12335       if (REG_P (operands[2]))
12336         return "sal{w}\t{%b2, %0|%0, %b2}";
12337       else if (operands[2] == const1_rtx
12338                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12339         return "sal{w}\t%0";
12340       else
12341         return "sal{w}\t{%2, %0|%0, %2}";
12342     }
12344   [(set (attr "type")
12345      (cond [(eq_attr "alternative" "1")
12346               (const_string "lea")
12347             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12348                           (const_int 0))
12349                       (match_operand 0 "register_operand" ""))
12350                  (match_operand 2 "const1_operand" ""))
12351               (const_string "alu")
12352            ]
12353            (const_string "ishift")))
12354    (set (attr "length_immediate")
12355      (if_then_else
12356        (ior (eq_attr "type" "alu")
12357             (and (eq_attr "type" "ishift")
12358                  (and (match_operand 2 "const1_operand" "")
12359                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12360                           (const_int 0)))))
12361        (const_string "0")
12362        (const_string "*")))
12363    (set_attr "mode" "HI,SI")])
12365 (define_insn "*ashlhi3_1"
12366   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12367         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12368                    (match_operand:QI 2 "nonmemory_operand" "cI")))
12369    (clobber (reg:CC FLAGS_REG))]
12370   "TARGET_PARTIAL_REG_STALL
12371    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12373   switch (get_attr_type (insn))
12374     {
12375     case TYPE_ALU:
12376       gcc_assert (operands[2] == const1_rtx);
12377       return "add{w}\t%0, %0";
12379     default:
12380       if (REG_P (operands[2]))
12381         return "sal{w}\t{%b2, %0|%0, %b2}";
12382       else if (operands[2] == const1_rtx
12383                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12384         return "sal{w}\t%0";
12385       else
12386         return "sal{w}\t{%2, %0|%0, %2}";
12387     }
12389   [(set (attr "type")
12390      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12391                           (const_int 0))
12392                       (match_operand 0 "register_operand" ""))
12393                  (match_operand 2 "const1_operand" ""))
12394               (const_string "alu")
12395            ]
12396            (const_string "ishift")))
12397    (set (attr "length_immediate")
12398      (if_then_else
12399        (ior (eq_attr "type" "alu")
12400             (and (eq_attr "type" "ishift")
12401                  (and (match_operand 2 "const1_operand" "")
12402                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12403                           (const_int 0)))))
12404        (const_string "0")
12405        (const_string "*")))
12406    (set_attr "mode" "HI")])
12408 ;; This pattern can't accept a variable shift count, since shifts by
12409 ;; zero don't affect the flags.  We assume that shifts by constant
12410 ;; zero are optimized away.
12411 (define_insn "*ashlhi3_cmp"
12412   [(set (reg FLAGS_REG)
12413         (compare
12414           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12415                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12416           (const_int 0)))
12417    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12418         (ashift:HI (match_dup 1) (match_dup 2)))]
12419   "(optimize_function_for_size_p (cfun)
12420     || !TARGET_PARTIAL_FLAG_REG_STALL
12421     || (operands[2] == const1_rtx
12422         && (TARGET_SHIFT1
12423             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12424    && ix86_match_ccmode (insn, CCGOCmode)
12425    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12427   switch (get_attr_type (insn))
12428     {
12429     case TYPE_ALU:
12430       gcc_assert (operands[2] == const1_rtx);
12431       return "add{w}\t%0, %0";
12433     default:
12434       if (REG_P (operands[2]))
12435         return "sal{w}\t{%b2, %0|%0, %b2}";
12436       else if (operands[2] == const1_rtx
12437                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12438         return "sal{w}\t%0";
12439       else
12440         return "sal{w}\t{%2, %0|%0, %2}";
12441     }
12443   [(set (attr "type")
12444      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12445                           (const_int 0))
12446                       (match_operand 0 "register_operand" ""))
12447                  (match_operand 2 "const1_operand" ""))
12448               (const_string "alu")
12449            ]
12450            (const_string "ishift")))
12451    (set (attr "length_immediate")
12452      (if_then_else
12453        (ior (eq_attr "type" "alu")
12454             (and (eq_attr "type" "ishift")
12455                  (and (match_operand 2 "const1_operand" "")
12456                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12457                           (const_int 0)))))
12458        (const_string "0")
12459        (const_string "*")))
12460    (set_attr "mode" "HI")])
12462 (define_insn "*ashlhi3_cconly"
12463   [(set (reg FLAGS_REG)
12464         (compare
12465           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12466                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12467           (const_int 0)))
12468    (clobber (match_scratch:HI 0 "=r"))]
12469   "(optimize_function_for_size_p (cfun)
12470     || !TARGET_PARTIAL_FLAG_REG_STALL
12471     || (operands[2] == const1_rtx
12472         && (TARGET_SHIFT1
12473             || TARGET_DOUBLE_WITH_ADD)))
12474    && ix86_match_ccmode (insn, CCGOCmode)
12475    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12477   switch (get_attr_type (insn))
12478     {
12479     case TYPE_ALU:
12480       gcc_assert (operands[2] == const1_rtx);
12481       return "add{w}\t%0, %0";
12483     default:
12484       if (REG_P (operands[2]))
12485         return "sal{w}\t{%b2, %0|%0, %b2}";
12486       else if (operands[2] == const1_rtx
12487                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12488         return "sal{w}\t%0";
12489       else
12490         return "sal{w}\t{%2, %0|%0, %2}";
12491     }
12493   [(set (attr "type")
12494      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12495                           (const_int 0))
12496                       (match_operand 0 "register_operand" ""))
12497                  (match_operand 2 "const1_operand" ""))
12498               (const_string "alu")
12499            ]
12500            (const_string "ishift")))
12501    (set (attr "length_immediate")
12502      (if_then_else
12503        (ior (eq_attr "type" "alu")
12504             (and (eq_attr "type" "ishift")
12505                  (and (match_operand 2 "const1_operand" "")
12506                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12507                           (const_int 0)))))
12508        (const_string "0")
12509        (const_string "*")))
12510    (set_attr "mode" "HI")])
12512 (define_expand "ashlqi3"
12513   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12514         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
12515                    (match_operand:QI 2 "nonmemory_operand" "")))]
12516   "TARGET_QIMODE_MATH"
12517   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
12519 ;; %%% Potential partial reg stall on alternative 2.  What to do?
12521 (define_insn "*ashlqi3_1_lea"
12522   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
12523         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
12524                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
12525    (clobber (reg:CC FLAGS_REG))]
12526   "!TARGET_PARTIAL_REG_STALL
12527    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12529   switch (get_attr_type (insn))
12530     {
12531     case TYPE_LEA:
12532       return "#";
12533     case TYPE_ALU:
12534       gcc_assert (operands[2] == const1_rtx);
12535       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
12536         return "add{l}\t%k0, %k0";
12537       else
12538         return "add{b}\t%0, %0";
12540     default:
12541       if (REG_P (operands[2]))
12542         {
12543           if (get_attr_mode (insn) == MODE_SI)
12544             return "sal{l}\t{%b2, %k0|%k0, %b2}";
12545           else
12546             return "sal{b}\t{%b2, %0|%0, %b2}";
12547         }
12548       else if (operands[2] == const1_rtx
12549                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12550         {
12551           if (get_attr_mode (insn) == MODE_SI)
12552             return "sal{l}\t%0";
12553           else
12554             return "sal{b}\t%0";
12555         }
12556       else
12557         {
12558           if (get_attr_mode (insn) == MODE_SI)
12559             return "sal{l}\t{%2, %k0|%k0, %2}";
12560           else
12561             return "sal{b}\t{%2, %0|%0, %2}";
12562         }
12563     }
12565   [(set (attr "type")
12566      (cond [(eq_attr "alternative" "2")
12567               (const_string "lea")
12568             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12569                           (const_int 0))
12570                       (match_operand 0 "register_operand" ""))
12571                  (match_operand 2 "const1_operand" ""))
12572               (const_string "alu")
12573            ]
12574            (const_string "ishift")))
12575    (set (attr "length_immediate")
12576      (if_then_else
12577        (ior (eq_attr "type" "alu")
12578             (and (eq_attr "type" "ishift")
12579                  (and (match_operand 2 "const1_operand" "")
12580                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12581                           (const_int 0)))))
12582        (const_string "0")
12583        (const_string "*")))
12584    (set_attr "mode" "QI,SI,SI")])
12586 (define_insn "*ashlqi3_1"
12587   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
12588         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12589                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
12590    (clobber (reg:CC FLAGS_REG))]
12591   "TARGET_PARTIAL_REG_STALL
12592    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12594   switch (get_attr_type (insn))
12595     {
12596     case TYPE_ALU:
12597       gcc_assert (operands[2] == const1_rtx);
12598       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
12599         return "add{l}\t%k0, %k0";
12600       else
12601         return "add{b}\t%0, %0";
12603     default:
12604       if (REG_P (operands[2]))
12605         {
12606           if (get_attr_mode (insn) == MODE_SI)
12607             return "sal{l}\t{%b2, %k0|%k0, %b2}";
12608           else
12609             return "sal{b}\t{%b2, %0|%0, %b2}";
12610         }
12611       else if (operands[2] == const1_rtx
12612                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12613         {
12614           if (get_attr_mode (insn) == MODE_SI)
12615             return "sal{l}\t%0";
12616           else
12617             return "sal{b}\t%0";
12618         }
12619       else
12620         {
12621           if (get_attr_mode (insn) == MODE_SI)
12622             return "sal{l}\t{%2, %k0|%k0, %2}";
12623           else
12624             return "sal{b}\t{%2, %0|%0, %2}";
12625         }
12626     }
12628   [(set (attr "type")
12629      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12630                           (const_int 0))
12631                       (match_operand 0 "register_operand" ""))
12632                  (match_operand 2 "const1_operand" ""))
12633               (const_string "alu")
12634            ]
12635            (const_string "ishift")))
12636    (set (attr "length_immediate")
12637      (if_then_else
12638        (ior (eq_attr "type" "alu")
12639             (and (eq_attr "type" "ishift")
12640                  (and (match_operand 2 "const1_operand" "")
12641                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12642                           (const_int 0)))))
12643        (const_string "0")
12644        (const_string "*")))
12645    (set_attr "mode" "QI,SI")])
12647 ;; This pattern can't accept a variable shift count, since shifts by
12648 ;; zero don't affect the flags.  We assume that shifts by constant
12649 ;; zero are optimized away.
12650 (define_insn "*ashlqi3_cmp"
12651   [(set (reg FLAGS_REG)
12652         (compare
12653           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12654                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12655           (const_int 0)))
12656    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12657         (ashift:QI (match_dup 1) (match_dup 2)))]
12658   "(optimize_function_for_size_p (cfun)
12659     || !TARGET_PARTIAL_FLAG_REG_STALL
12660     || (operands[2] == const1_rtx
12661         && (TARGET_SHIFT1
12662             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12663    && ix86_match_ccmode (insn, CCGOCmode)
12664    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12666   switch (get_attr_type (insn))
12667     {
12668     case TYPE_ALU:
12669       gcc_assert (operands[2] == const1_rtx);
12670       return "add{b}\t%0, %0";
12672     default:
12673       if (REG_P (operands[2]))
12674         return "sal{b}\t{%b2, %0|%0, %b2}";
12675       else if (operands[2] == const1_rtx
12676                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12677         return "sal{b}\t%0";
12678       else
12679         return "sal{b}\t{%2, %0|%0, %2}";
12680     }
12682   [(set (attr "type")
12683      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12684                           (const_int 0))
12685                       (match_operand 0 "register_operand" ""))
12686                  (match_operand 2 "const1_operand" ""))
12687               (const_string "alu")
12688            ]
12689            (const_string "ishift")))
12690    (set (attr "length_immediate")
12691      (if_then_else
12692        (ior (eq_attr "type" "alu")
12693             (and (eq_attr "type" "ishift")
12694                  (and (match_operand 2 "const1_operand" "")
12695                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12696                           (const_int 0)))))
12697        (const_string "0")
12698        (const_string "*")))
12699    (set_attr "mode" "QI")])
12701 (define_insn "*ashlqi3_cconly"
12702   [(set (reg FLAGS_REG)
12703         (compare
12704           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12705                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12706           (const_int 0)))
12707    (clobber (match_scratch:QI 0 "=q"))]
12708   "(optimize_function_for_size_p (cfun)
12709     || !TARGET_PARTIAL_FLAG_REG_STALL
12710     || (operands[2] == const1_rtx
12711         && (TARGET_SHIFT1
12712             || TARGET_DOUBLE_WITH_ADD)))
12713    && ix86_match_ccmode (insn, CCGOCmode)
12714    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12716   switch (get_attr_type (insn))
12717     {
12718     case TYPE_ALU:
12719       gcc_assert (operands[2] == const1_rtx);
12720       return "add{b}\t%0, %0";
12722     default:
12723       if (REG_P (operands[2]))
12724         return "sal{b}\t{%b2, %0|%0, %b2}";
12725       else if (operands[2] == const1_rtx
12726                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12727         return "sal{b}\t%0";
12728       else
12729         return "sal{b}\t{%2, %0|%0, %2}";
12730     }
12732   [(set (attr "type")
12733      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12734                           (const_int 0))
12735                       (match_operand 0 "register_operand" ""))
12736                  (match_operand 2 "const1_operand" ""))
12737               (const_string "alu")
12738            ]
12739            (const_string "ishift")))
12740    (set (attr "length_immediate")
12741      (if_then_else
12742        (ior (eq_attr "type" "alu")
12743             (and (eq_attr "type" "ishift")
12744                  (and (match_operand 2 "const1_operand" "")
12745                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12746                           (const_int 0)))))
12747        (const_string "0")
12748        (const_string "*")))
12749    (set_attr "mode" "QI")])
12751 ;; See comment above `ashldi3' about how this works.
12753 (define_expand "ashrti3"
12754   [(set (match_operand:TI 0 "register_operand" "")
12755         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12756                      (match_operand:QI 2 "nonmemory_operand" "")))]
12757   "TARGET_64BIT"
12758   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12760 (define_insn "*ashrti3_1"
12761   [(set (match_operand:TI 0 "register_operand" "=r")
12762         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12763                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12764    (clobber (reg:CC FLAGS_REG))]
12765   "TARGET_64BIT"
12766   "#"
12767   [(set_attr "type" "multi")])
12769 (define_peephole2
12770   [(match_scratch:DI 3 "r")
12771    (parallel [(set (match_operand:TI 0 "register_operand" "")
12772                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12773                                 (match_operand:QI 2 "nonmemory_operand" "")))
12774               (clobber (reg:CC FLAGS_REG))])
12775    (match_dup 3)]
12776   "TARGET_64BIT"
12777   [(const_int 0)]
12778   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12780 (define_split
12781   [(set (match_operand:TI 0 "register_operand" "")
12782         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12783                      (match_operand:QI 2 "nonmemory_operand" "")))
12784    (clobber (reg:CC FLAGS_REG))]
12785   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12786                     ? epilogue_completed : reload_completed)"
12787   [(const_int 0)]
12788   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12790 (define_insn "x86_64_shrd"
12791   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12792         (ior:DI (ashiftrt:DI (match_dup 0)
12793                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
12794                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12795                   (minus:QI (const_int 64) (match_dup 2)))))
12796    (clobber (reg:CC FLAGS_REG))]
12797   "TARGET_64BIT"
12798   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12799   [(set_attr "type" "ishift")
12800    (set_attr "prefix_0f" "1")
12801    (set_attr "mode" "DI")
12802    (set_attr "athlon_decode" "vector")
12803    (set_attr "amdfam10_decode" "vector")])
12805 (define_expand "ashrdi3"
12806   [(set (match_operand:DI 0 "shiftdi_operand" "")
12807         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12808                      (match_operand:QI 2 "nonmemory_operand" "")))]
12809   ""
12810   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12812 (define_expand "x86_64_shift_adj_3"
12813   [(use (match_operand:DI 0 "register_operand" ""))
12814    (use (match_operand:DI 1 "register_operand" ""))
12815    (use (match_operand:QI 2 "register_operand" ""))]
12816   ""
12818   rtx label = gen_label_rtx ();
12819   rtx tmp;
12821   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12823   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12824   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12825   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12826                               gen_rtx_LABEL_REF (VOIDmode, label),
12827                               pc_rtx);
12828   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12829   JUMP_LABEL (tmp) = label;
12831   emit_move_insn (operands[0], operands[1]);
12832   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12834   emit_label (label);
12835   LABEL_NUSES (label) = 1;
12837   DONE;
12840 (define_insn "ashrdi3_63_rex64"
12841   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12842         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12843                      (match_operand:DI 2 "const_int_operand" "i,i")))
12844    (clobber (reg:CC FLAGS_REG))]
12845   "TARGET_64BIT && INTVAL (operands[2]) == 63
12846    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12847    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12848   "@
12849    {cqto|cqo}
12850    sar{q}\t{%2, %0|%0, %2}"
12851   [(set_attr "type" "imovx,ishift")
12852    (set_attr "prefix_0f" "0,*")
12853    (set_attr "length_immediate" "0,*")
12854    (set_attr "modrm" "0,1")
12855    (set_attr "mode" "DI")])
12857 (define_insn "*ashrdi3_1_one_bit_rex64"
12858   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12859         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12860                      (match_operand:QI 2 "const1_operand" "")))
12861    (clobber (reg:CC FLAGS_REG))]
12862   "TARGET_64BIT
12863    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12864    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12865   "sar{q}\t%0"
12866   [(set_attr "type" "ishift")
12867    (set_attr "length_immediate" "0")
12868    (set_attr "mode" "DI")])
12870 (define_insn "*ashrdi3_1_rex64"
12871   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12872         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12873                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12874    (clobber (reg:CC FLAGS_REG))]
12875   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12876   "@
12877    sar{q}\t{%2, %0|%0, %2}
12878    sar{q}\t{%b2, %0|%0, %b2}"
12879   [(set_attr "type" "ishift")
12880    (set_attr "mode" "DI")])
12882 ;; This pattern can't accept a variable shift count, since shifts by
12883 ;; zero don't affect the flags.  We assume that shifts by constant
12884 ;; zero are optimized away.
12885 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12886   [(set (reg FLAGS_REG)
12887         (compare
12888           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12889                        (match_operand:QI 2 "const1_operand" ""))
12890           (const_int 0)))
12891    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12892         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12893   "TARGET_64BIT
12894    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12895    && ix86_match_ccmode (insn, CCGOCmode)
12896    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12897   "sar{q}\t%0"
12898   [(set_attr "type" "ishift")
12899    (set_attr "length_immediate" "0")
12900    (set_attr "mode" "DI")])
12902 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12903   [(set (reg FLAGS_REG)
12904         (compare
12905           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12906                        (match_operand:QI 2 "const1_operand" ""))
12907           (const_int 0)))
12908    (clobber (match_scratch:DI 0 "=r"))]
12909   "TARGET_64BIT
12910    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12911    && ix86_match_ccmode (insn, CCGOCmode)
12912    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12913   "sar{q}\t%0"
12914   [(set_attr "type" "ishift")
12915    (set_attr "length_immediate" "0")
12916    (set_attr "mode" "DI")])
12918 ;; This pattern can't accept a variable shift count, since shifts by
12919 ;; zero don't affect the flags.  We assume that shifts by constant
12920 ;; zero are optimized away.
12921 (define_insn "*ashrdi3_cmp_rex64"
12922   [(set (reg FLAGS_REG)
12923         (compare
12924           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12925                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12926           (const_int 0)))
12927    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12928         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12929   "TARGET_64BIT
12930    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12931    && ix86_match_ccmode (insn, CCGOCmode)
12932    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12933   "sar{q}\t{%2, %0|%0, %2}"
12934   [(set_attr "type" "ishift")
12935    (set_attr "mode" "DI")])
12937 (define_insn "*ashrdi3_cconly_rex64"
12938   [(set (reg FLAGS_REG)
12939         (compare
12940           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12941                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12942           (const_int 0)))
12943    (clobber (match_scratch:DI 0 "=r"))]
12944   "TARGET_64BIT
12945    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12946    && ix86_match_ccmode (insn, CCGOCmode)
12947    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12948   "sar{q}\t{%2, %0|%0, %2}"
12949   [(set_attr "type" "ishift")
12950    (set_attr "mode" "DI")])
12952 (define_insn "*ashrdi3_1"
12953   [(set (match_operand:DI 0 "register_operand" "=r")
12954         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12955                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12956    (clobber (reg:CC FLAGS_REG))]
12957   "!TARGET_64BIT"
12958   "#"
12959   [(set_attr "type" "multi")])
12961 ;; By default we don't ask for a scratch register, because when DImode
12962 ;; values are manipulated, registers are already at a premium.  But if
12963 ;; we have one handy, we won't turn it away.
12964 (define_peephole2
12965   [(match_scratch:SI 3 "r")
12966    (parallel [(set (match_operand:DI 0 "register_operand" "")
12967                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12968                                 (match_operand:QI 2 "nonmemory_operand" "")))
12969               (clobber (reg:CC FLAGS_REG))])
12970    (match_dup 3)]
12971   "!TARGET_64BIT && TARGET_CMOVE"
12972   [(const_int 0)]
12973   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12975 (define_split
12976   [(set (match_operand:DI 0 "register_operand" "")
12977         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12978                      (match_operand:QI 2 "nonmemory_operand" "")))
12979    (clobber (reg:CC FLAGS_REG))]
12980   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12981                      ? epilogue_completed : reload_completed)"
12982   [(const_int 0)]
12983   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12985 (define_insn "x86_shrd"
12986   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12987         (ior:SI (ashiftrt:SI (match_dup 0)
12988                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
12989                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12990                   (minus:QI (const_int 32) (match_dup 2)))))
12991    (clobber (reg:CC FLAGS_REG))]
12992   ""
12993   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12994   [(set_attr "type" "ishift")
12995    (set_attr "prefix_0f" "1")
12996    (set_attr "pent_pair" "np")
12997    (set_attr "mode" "SI")])
12999 (define_expand "x86_shift_adj_3"
13000   [(use (match_operand:SI 0 "register_operand" ""))
13001    (use (match_operand:SI 1 "register_operand" ""))
13002    (use (match_operand:QI 2 "register_operand" ""))]
13003   ""
13005   rtx label = gen_label_rtx ();
13006   rtx tmp;
13008   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
13010   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
13011   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
13012   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
13013                               gen_rtx_LABEL_REF (VOIDmode, label),
13014                               pc_rtx);
13015   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
13016   JUMP_LABEL (tmp) = label;
13018   emit_move_insn (operands[0], operands[1]);
13019   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
13021   emit_label (label);
13022   LABEL_NUSES (label) = 1;
13024   DONE;
13027 (define_expand "ashrsi3_31"
13028   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
13029                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
13030                                 (match_operand:SI 2 "const_int_operand" "i,i")))
13031               (clobber (reg:CC FLAGS_REG))])]
13032   "")
13034 (define_insn "*ashrsi3_31"
13035   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
13036         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
13037                      (match_operand:SI 2 "const_int_operand" "i,i")))
13038    (clobber (reg:CC FLAGS_REG))]
13039   "INTVAL (operands[2]) == 31
13040    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
13041    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13042   "@
13043    {cltd|cdq}
13044    sar{l}\t{%2, %0|%0, %2}"
13045   [(set_attr "type" "imovx,ishift")
13046    (set_attr "prefix_0f" "0,*")
13047    (set_attr "length_immediate" "0,*")
13048    (set_attr "modrm" "0,1")
13049    (set_attr "mode" "SI")])
13051 (define_insn "*ashrsi3_31_zext"
13052   [(set (match_operand:DI 0 "register_operand" "=*d,r")
13053         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
13054                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
13055    (clobber (reg:CC FLAGS_REG))]
13056   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
13057    && INTVAL (operands[2]) == 31
13058    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13059   "@
13060    {cltd|cdq}
13061    sar{l}\t{%2, %k0|%k0, %2}"
13062   [(set_attr "type" "imovx,ishift")
13063    (set_attr "prefix_0f" "0,*")
13064    (set_attr "length_immediate" "0,*")
13065    (set_attr "modrm" "0,1")
13066    (set_attr "mode" "SI")])
13068 (define_expand "ashrsi3"
13069   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13070         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13071                      (match_operand:QI 2 "nonmemory_operand" "")))]
13072   ""
13073   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
13075 (define_insn "*ashrsi3_1_one_bit"
13076   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13077         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13078                      (match_operand:QI 2 "const1_operand" "")))
13079    (clobber (reg:CC FLAGS_REG))]
13080   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13081    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13082   "sar{l}\t%0"
13083   [(set_attr "type" "ishift")
13084    (set_attr "length_immediate" "0")
13085    (set_attr "mode" "SI")])
13087 (define_insn "*ashrsi3_1_one_bit_zext"
13088   [(set (match_operand:DI 0 "register_operand" "=r")
13089         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
13090                                      (match_operand:QI 2 "const1_operand" ""))))
13091    (clobber (reg:CC FLAGS_REG))]
13092   "TARGET_64BIT
13093    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13094    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13095   "sar{l}\t%k0"
13096   [(set_attr "type" "ishift")
13097    (set_attr "length_immediate" "0")
13098    (set_attr "mode" "SI")])
13100 (define_insn "*ashrsi3_1"
13101   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13102         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13103                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13104    (clobber (reg:CC FLAGS_REG))]
13105   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13106   "@
13107    sar{l}\t{%2, %0|%0, %2}
13108    sar{l}\t{%b2, %0|%0, %b2}"
13109   [(set_attr "type" "ishift")
13110    (set_attr "mode" "SI")])
13112 (define_insn "*ashrsi3_1_zext"
13113   [(set (match_operand:DI 0 "register_operand" "=r,r")
13114         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
13115                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13116    (clobber (reg:CC FLAGS_REG))]
13117   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13118   "@
13119    sar{l}\t{%2, %k0|%k0, %2}
13120    sar{l}\t{%b2, %k0|%k0, %b2}"
13121   [(set_attr "type" "ishift")
13122    (set_attr "mode" "SI")])
13124 ;; This pattern can't accept a variable shift count, since shifts by
13125 ;; zero don't affect the flags.  We assume that shifts by constant
13126 ;; zero are optimized away.
13127 (define_insn "*ashrsi3_one_bit_cmp"
13128   [(set (reg FLAGS_REG)
13129         (compare
13130           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13131                        (match_operand:QI 2 "const1_operand" ""))
13132           (const_int 0)))
13133    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13134         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
13135   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13136    && ix86_match_ccmode (insn, CCGOCmode)
13137    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13138   "sar{l}\t%0"
13139   [(set_attr "type" "ishift")
13140    (set_attr "length_immediate" "0")
13141    (set_attr "mode" "SI")])
13143 (define_insn "*ashrsi3_one_bit_cconly"
13144   [(set (reg FLAGS_REG)
13145         (compare
13146           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13147                        (match_operand:QI 2 "const1_operand" ""))
13148           (const_int 0)))
13149    (clobber (match_scratch:SI 0 "=r"))]
13150   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13151    && ix86_match_ccmode (insn, CCGOCmode)
13152    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13153   "sar{l}\t%0"
13154   [(set_attr "type" "ishift")
13155    (set_attr "length_immediate" "0")
13156    (set_attr "mode" "SI")])
13158 (define_insn "*ashrsi3_one_bit_cmp_zext"
13159   [(set (reg FLAGS_REG)
13160         (compare
13161           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
13162                        (match_operand:QI 2 "const1_operand" ""))
13163           (const_int 0)))
13164    (set (match_operand:DI 0 "register_operand" "=r")
13165         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
13166   "TARGET_64BIT
13167    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13168    && ix86_match_ccmode (insn, CCmode)
13169    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13170   "sar{l}\t%k0"
13171   [(set_attr "type" "ishift")
13172    (set_attr "length_immediate" "0")
13173    (set_attr "mode" "SI")])
13175 ;; This pattern can't accept a variable shift count, since shifts by
13176 ;; zero don't affect the flags.  We assume that shifts by constant
13177 ;; zero are optimized away.
13178 (define_insn "*ashrsi3_cmp"
13179   [(set (reg FLAGS_REG)
13180         (compare
13181           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13182                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13183           (const_int 0)))
13184    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13185         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
13186   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13187    && ix86_match_ccmode (insn, CCGOCmode)
13188    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13189   "sar{l}\t{%2, %0|%0, %2}"
13190   [(set_attr "type" "ishift")
13191    (set_attr "mode" "SI")])
13193 (define_insn "*ashrsi3_cconly"
13194   [(set (reg FLAGS_REG)
13195         (compare
13196           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13197                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13198           (const_int 0)))
13199    (clobber (match_scratch:SI 0 "=r"))]
13200   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13201    && ix86_match_ccmode (insn, CCGOCmode)
13202    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13203   "sar{l}\t{%2, %0|%0, %2}"
13204   [(set_attr "type" "ishift")
13205    (set_attr "mode" "SI")])
13207 (define_insn "*ashrsi3_cmp_zext"
13208   [(set (reg FLAGS_REG)
13209         (compare
13210           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
13211                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13212           (const_int 0)))
13213    (set (match_operand:DI 0 "register_operand" "=r")
13214         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
13215   "TARGET_64BIT
13216    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13217    && ix86_match_ccmode (insn, CCGOCmode)
13218    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13219   "sar{l}\t{%2, %k0|%k0, %2}"
13220   [(set_attr "type" "ishift")
13221    (set_attr "mode" "SI")])
13223 (define_expand "ashrhi3"
13224   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13225         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13226                      (match_operand:QI 2 "nonmemory_operand" "")))]
13227   "TARGET_HIMODE_MATH"
13228   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
13230 (define_insn "*ashrhi3_1_one_bit"
13231   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13232         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13233                      (match_operand:QI 2 "const1_operand" "")))
13234    (clobber (reg:CC FLAGS_REG))]
13235   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13236    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13237   "sar{w}\t%0"
13238   [(set_attr "type" "ishift")
13239    (set_attr "length_immediate" "0")
13240    (set_attr "mode" "HI")])
13242 (define_insn "*ashrhi3_1"
13243   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13244         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13245                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13246    (clobber (reg:CC FLAGS_REG))]
13247   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13248   "@
13249    sar{w}\t{%2, %0|%0, %2}
13250    sar{w}\t{%b2, %0|%0, %b2}"
13251   [(set_attr "type" "ishift")
13252    (set_attr "mode" "HI")])
13254 ;; This pattern can't accept a variable shift count, since shifts by
13255 ;; zero don't affect the flags.  We assume that shifts by constant
13256 ;; zero are optimized away.
13257 (define_insn "*ashrhi3_one_bit_cmp"
13258   [(set (reg FLAGS_REG)
13259         (compare
13260           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13261                        (match_operand:QI 2 "const1_operand" ""))
13262           (const_int 0)))
13263    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13264         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
13265   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13266    && ix86_match_ccmode (insn, CCGOCmode)
13267    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13268   "sar{w}\t%0"
13269   [(set_attr "type" "ishift")
13270    (set_attr "length_immediate" "0")
13271    (set_attr "mode" "HI")])
13273 (define_insn "*ashrhi3_one_bit_cconly"
13274   [(set (reg FLAGS_REG)
13275         (compare
13276           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13277                        (match_operand:QI 2 "const1_operand" ""))
13278           (const_int 0)))
13279    (clobber (match_scratch:HI 0 "=r"))]
13280   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13281    && ix86_match_ccmode (insn, CCGOCmode)
13282    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13283   "sar{w}\t%0"
13284   [(set_attr "type" "ishift")
13285    (set_attr "length_immediate" "0")
13286    (set_attr "mode" "HI")])
13288 ;; This pattern can't accept a variable shift count, since shifts by
13289 ;; zero don't affect the flags.  We assume that shifts by constant
13290 ;; zero are optimized away.
13291 (define_insn "*ashrhi3_cmp"
13292   [(set (reg FLAGS_REG)
13293         (compare
13294           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13295                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13296           (const_int 0)))
13297    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13298         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
13299   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13300    && ix86_match_ccmode (insn, CCGOCmode)
13301    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13302   "sar{w}\t{%2, %0|%0, %2}"
13303   [(set_attr "type" "ishift")
13304    (set_attr "mode" "HI")])
13306 (define_insn "*ashrhi3_cconly"
13307   [(set (reg FLAGS_REG)
13308         (compare
13309           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13310                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13311           (const_int 0)))
13312    (clobber (match_scratch:HI 0 "=r"))]
13313   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13314    && ix86_match_ccmode (insn, CCGOCmode)
13315    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13316   "sar{w}\t{%2, %0|%0, %2}"
13317   [(set_attr "type" "ishift")
13318    (set_attr "mode" "HI")])
13320 (define_expand "ashrqi3"
13321   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13322         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13323                      (match_operand:QI 2 "nonmemory_operand" "")))]
13324   "TARGET_QIMODE_MATH"
13325   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
13327 (define_insn "*ashrqi3_1_one_bit"
13328   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13329         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13330                      (match_operand:QI 2 "const1_operand" "")))
13331    (clobber (reg:CC FLAGS_REG))]
13332   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13333    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13334   "sar{b}\t%0"
13335   [(set_attr "type" "ishift")
13336    (set_attr "length_immediate" "0")
13337    (set_attr "mode" "QI")])
13339 (define_insn "*ashrqi3_1_one_bit_slp"
13340   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13341         (ashiftrt:QI (match_dup 0)
13342                      (match_operand:QI 1 "const1_operand" "")))
13343    (clobber (reg:CC FLAGS_REG))]
13344   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13345    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13346    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13347   "sar{b}\t%0"
13348   [(set_attr "type" "ishift1")
13349    (set_attr "length_immediate" "0")
13350    (set_attr "mode" "QI")])
13352 (define_insn "*ashrqi3_1"
13353   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13354         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13355                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13356    (clobber (reg:CC FLAGS_REG))]
13357   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13358   "@
13359    sar{b}\t{%2, %0|%0, %2}
13360    sar{b}\t{%b2, %0|%0, %b2}"
13361   [(set_attr "type" "ishift")
13362    (set_attr "mode" "QI")])
13364 (define_insn "*ashrqi3_1_slp"
13365   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13366         (ashiftrt:QI (match_dup 0)
13367                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13368    (clobber (reg:CC FLAGS_REG))]
13369   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13370    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13371   "@
13372    sar{b}\t{%1, %0|%0, %1}
13373    sar{b}\t{%b1, %0|%0, %b1}"
13374   [(set_attr "type" "ishift1")
13375    (set_attr "mode" "QI")])
13377 ;; This pattern can't accept a variable shift count, since shifts by
13378 ;; zero don't affect the flags.  We assume that shifts by constant
13379 ;; zero are optimized away.
13380 (define_insn "*ashrqi3_one_bit_cmp"
13381   [(set (reg FLAGS_REG)
13382         (compare
13383           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13384                        (match_operand:QI 2 "const1_operand" "I"))
13385           (const_int 0)))
13386    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13387         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
13388   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13389    && ix86_match_ccmode (insn, CCGOCmode)
13390    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13391   "sar{b}\t%0"
13392   [(set_attr "type" "ishift")
13393    (set_attr "length_immediate" "0")
13394    (set_attr "mode" "QI")])
13396 (define_insn "*ashrqi3_one_bit_cconly"
13397   [(set (reg FLAGS_REG)
13398         (compare
13399           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13400                        (match_operand:QI 2 "const1_operand" ""))
13401           (const_int 0)))
13402    (clobber (match_scratch:QI 0 "=q"))]
13403   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13404    && ix86_match_ccmode (insn, CCGOCmode)
13405    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13406   "sar{b}\t%0"
13407   [(set_attr "type" "ishift")
13408    (set_attr "length_immediate" "0")
13409    (set_attr "mode" "QI")])
13411 ;; This pattern can't accept a variable shift count, since shifts by
13412 ;; zero don't affect the flags.  We assume that shifts by constant
13413 ;; zero are optimized away.
13414 (define_insn "*ashrqi3_cmp"
13415   [(set (reg FLAGS_REG)
13416         (compare
13417           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13418                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13419           (const_int 0)))
13420    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13421         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
13422   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13423    && ix86_match_ccmode (insn, CCGOCmode)
13424    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13425   "sar{b}\t{%2, %0|%0, %2}"
13426   [(set_attr "type" "ishift")
13427    (set_attr "mode" "QI")])
13429 (define_insn "*ashrqi3_cconly"
13430   [(set (reg FLAGS_REG)
13431         (compare
13432           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13433                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13434           (const_int 0)))
13435    (clobber (match_scratch:QI 0 "=q"))]
13436   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13437    && ix86_match_ccmode (insn, CCGOCmode)
13438    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13439   "sar{b}\t{%2, %0|%0, %2}"
13440   [(set_attr "type" "ishift")
13441    (set_attr "mode" "QI")])
13444 ;; Logical shift instructions
13446 ;; See comment above `ashldi3' about how this works.
13448 (define_expand "lshrti3"
13449   [(set (match_operand:TI 0 "register_operand" "")
13450         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13451                      (match_operand:QI 2 "nonmemory_operand" "")))]
13452   "TARGET_64BIT"
13453   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
13455 ;; This pattern must be defined before *lshrti3_1 to prevent
13456 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
13458 (define_insn "*avx_lshrti3"
13459   [(set (match_operand:TI 0 "register_operand" "=x")
13460         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
13461                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
13462   "TARGET_AVX"
13464   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
13465   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
13467   [(set_attr "type" "sseishft")
13468    (set_attr "prefix" "vex")
13469    (set_attr "length_immediate" "1")
13470    (set_attr "mode" "TI")])
13472 (define_insn "sse2_lshrti3"
13473   [(set (match_operand:TI 0 "register_operand" "=x")
13474         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
13475                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
13476   "TARGET_SSE2"
13478   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
13479   return "psrldq\t{%2, %0|%0, %2}";
13481   [(set_attr "type" "sseishft")
13482    (set_attr "prefix_data16" "1")
13483    (set_attr "length_immediate" "1")
13484    (set_attr "mode" "TI")])
13486 (define_insn "*lshrti3_1"
13487   [(set (match_operand:TI 0 "register_operand" "=r")
13488         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
13489                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
13490    (clobber (reg:CC FLAGS_REG))]
13491   "TARGET_64BIT"
13492   "#"
13493   [(set_attr "type" "multi")])
13495 (define_peephole2
13496   [(match_scratch:DI 3 "r")
13497    (parallel [(set (match_operand:TI 0 "register_operand" "")
13498                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13499                                 (match_operand:QI 2 "nonmemory_operand" "")))
13500               (clobber (reg:CC FLAGS_REG))])
13501    (match_dup 3)]
13502   "TARGET_64BIT"
13503   [(const_int 0)]
13504   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
13506 (define_split
13507   [(set (match_operand:TI 0 "register_operand" "")
13508         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13509                      (match_operand:QI 2 "nonmemory_operand" "")))
13510    (clobber (reg:CC FLAGS_REG))]
13511   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13512                     ? epilogue_completed : reload_completed)"
13513   [(const_int 0)]
13514   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
13516 (define_expand "lshrdi3"
13517   [(set (match_operand:DI 0 "shiftdi_operand" "")
13518         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
13519                      (match_operand:QI 2 "nonmemory_operand" "")))]
13520   ""
13521   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
13523 (define_insn "*lshrdi3_1_one_bit_rex64"
13524   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13525         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13526                      (match_operand:QI 2 "const1_operand" "")))
13527    (clobber (reg:CC FLAGS_REG))]
13528   "TARGET_64BIT
13529    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13530    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13531   "shr{q}\t%0"
13532   [(set_attr "type" "ishift")
13533    (set_attr "length_immediate" "0")
13534    (set_attr "mode" "DI")])
13536 (define_insn "*lshrdi3_1_rex64"
13537   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13538         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13539                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13540    (clobber (reg:CC FLAGS_REG))]
13541   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13542   "@
13543    shr{q}\t{%2, %0|%0, %2}
13544    shr{q}\t{%b2, %0|%0, %b2}"
13545   [(set_attr "type" "ishift")
13546    (set_attr "mode" "DI")])
13548 ;; This pattern can't accept a variable shift count, since shifts by
13549 ;; zero don't affect the flags.  We assume that shifts by constant
13550 ;; zero are optimized away.
13551 (define_insn "*lshrdi3_cmp_one_bit_rex64"
13552   [(set (reg FLAGS_REG)
13553         (compare
13554           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13555                        (match_operand:QI 2 "const1_operand" ""))
13556           (const_int 0)))
13557    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13558         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
13559   "TARGET_64BIT
13560    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13561    && ix86_match_ccmode (insn, CCGOCmode)
13562    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13563   "shr{q}\t%0"
13564   [(set_attr "type" "ishift")
13565    (set_attr "length_immediate" "0")
13566    (set_attr "mode" "DI")])
13568 (define_insn "*lshrdi3_cconly_one_bit_rex64"
13569   [(set (reg FLAGS_REG)
13570         (compare
13571           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13572                        (match_operand:QI 2 "const1_operand" ""))
13573           (const_int 0)))
13574    (clobber (match_scratch:DI 0 "=r"))]
13575   "TARGET_64BIT
13576    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13577    && ix86_match_ccmode (insn, CCGOCmode)
13578    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13579   "shr{q}\t%0"
13580   [(set_attr "type" "ishift")
13581    (set_attr "length_immediate" "0")
13582    (set_attr "mode" "DI")])
13584 ;; This pattern can't accept a variable shift count, since shifts by
13585 ;; zero don't affect the flags.  We assume that shifts by constant
13586 ;; zero are optimized away.
13587 (define_insn "*lshrdi3_cmp_rex64"
13588   [(set (reg FLAGS_REG)
13589         (compare
13590           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13591                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
13592           (const_int 0)))
13593    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13594         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
13595   "TARGET_64BIT
13596    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13597    && ix86_match_ccmode (insn, CCGOCmode)
13598    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13599   "shr{q}\t{%2, %0|%0, %2}"
13600   [(set_attr "type" "ishift")
13601    (set_attr "mode" "DI")])
13603 (define_insn "*lshrdi3_cconly_rex64"
13604   [(set (reg FLAGS_REG)
13605         (compare
13606           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13607                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
13608           (const_int 0)))
13609    (clobber (match_scratch:DI 0 "=r"))]
13610   "TARGET_64BIT
13611    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13612    && ix86_match_ccmode (insn, CCGOCmode)
13613    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13614   "shr{q}\t{%2, %0|%0, %2}"
13615   [(set_attr "type" "ishift")
13616    (set_attr "mode" "DI")])
13618 (define_insn "*lshrdi3_1"
13619   [(set (match_operand:DI 0 "register_operand" "=r")
13620         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
13621                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
13622    (clobber (reg:CC FLAGS_REG))]
13623   "!TARGET_64BIT"
13624   "#"
13625   [(set_attr "type" "multi")])
13627 ;; By default we don't ask for a scratch register, because when DImode
13628 ;; values are manipulated, registers are already at a premium.  But if
13629 ;; we have one handy, we won't turn it away.
13630 (define_peephole2
13631   [(match_scratch:SI 3 "r")
13632    (parallel [(set (match_operand:DI 0 "register_operand" "")
13633                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13634                                 (match_operand:QI 2 "nonmemory_operand" "")))
13635               (clobber (reg:CC FLAGS_REG))])
13636    (match_dup 3)]
13637   "!TARGET_64BIT && TARGET_CMOVE"
13638   [(const_int 0)]
13639   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
13641 (define_split
13642   [(set (match_operand:DI 0 "register_operand" "")
13643         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13644                      (match_operand:QI 2 "nonmemory_operand" "")))
13645    (clobber (reg:CC FLAGS_REG))]
13646   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13647                      ? epilogue_completed : reload_completed)"
13648   [(const_int 0)]
13649   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
13651 (define_expand "lshrsi3"
13652   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13653         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13654                      (match_operand:QI 2 "nonmemory_operand" "")))]
13655   ""
13656   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13658 (define_insn "*lshrsi3_1_one_bit"
13659   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13660         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13661                      (match_operand:QI 2 "const1_operand" "")))
13662    (clobber (reg:CC FLAGS_REG))]
13663   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13664    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13665   "shr{l}\t%0"
13666   [(set_attr "type" "ishift")
13667    (set_attr "length_immediate" "0")
13668    (set_attr "mode" "SI")])
13670 (define_insn "*lshrsi3_1_one_bit_zext"
13671   [(set (match_operand:DI 0 "register_operand" "=r")
13672         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13673                      (match_operand:QI 2 "const1_operand" "")))
13674    (clobber (reg:CC FLAGS_REG))]
13675   "TARGET_64BIT
13676    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13677    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13678   "shr{l}\t%k0"
13679   [(set_attr "type" "ishift")
13680    (set_attr "length_immediate" "0")
13681    (set_attr "mode" "SI")])
13683 (define_insn "*lshrsi3_1"
13684   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13685         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13686                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13687    (clobber (reg:CC FLAGS_REG))]
13688   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13689   "@
13690    shr{l}\t{%2, %0|%0, %2}
13691    shr{l}\t{%b2, %0|%0, %b2}"
13692   [(set_attr "type" "ishift")
13693    (set_attr "mode" "SI")])
13695 (define_insn "*lshrsi3_1_zext"
13696   [(set (match_operand:DI 0 "register_operand" "=r,r")
13697         (zero_extend:DI
13698           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13699                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13700    (clobber (reg:CC FLAGS_REG))]
13701   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13702   "@
13703    shr{l}\t{%2, %k0|%k0, %2}
13704    shr{l}\t{%b2, %k0|%k0, %b2}"
13705   [(set_attr "type" "ishift")
13706    (set_attr "mode" "SI")])
13708 ;; This pattern can't accept a variable shift count, since shifts by
13709 ;; zero don't affect the flags.  We assume that shifts by constant
13710 ;; zero are optimized away.
13711 (define_insn "*lshrsi3_one_bit_cmp"
13712   [(set (reg FLAGS_REG)
13713         (compare
13714           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13715                        (match_operand:QI 2 "const1_operand" ""))
13716           (const_int 0)))
13717    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13718         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13719   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13720    && ix86_match_ccmode (insn, CCGOCmode)
13721    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13722   "shr{l}\t%0"
13723   [(set_attr "type" "ishift")
13724    (set_attr "length_immediate" "0")
13725    (set_attr "mode" "SI")])
13727 (define_insn "*lshrsi3_one_bit_cconly"
13728   [(set (reg FLAGS_REG)
13729         (compare
13730           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13731                        (match_operand:QI 2 "const1_operand" ""))
13732           (const_int 0)))
13733    (clobber (match_scratch:SI 0 "=r"))]
13734   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13735    && ix86_match_ccmode (insn, CCGOCmode)
13736    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13737   "shr{l}\t%0"
13738   [(set_attr "type" "ishift")
13739    (set_attr "length_immediate" "0")
13740    (set_attr "mode" "SI")])
13742 (define_insn "*lshrsi3_cmp_one_bit_zext"
13743   [(set (reg FLAGS_REG)
13744         (compare
13745           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13746                        (match_operand:QI 2 "const1_operand" ""))
13747           (const_int 0)))
13748    (set (match_operand:DI 0 "register_operand" "=r")
13749         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13750   "TARGET_64BIT
13751    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13752    && ix86_match_ccmode (insn, CCGOCmode)
13753    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13754   "shr{l}\t%k0"
13755   [(set_attr "type" "ishift")
13756    (set_attr "length_immediate" "0")
13757    (set_attr "mode" "SI")])
13759 ;; This pattern can't accept a variable shift count, since shifts by
13760 ;; zero don't affect the flags.  We assume that shifts by constant
13761 ;; zero are optimized away.
13762 (define_insn "*lshrsi3_cmp"
13763   [(set (reg FLAGS_REG)
13764         (compare
13765           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13766                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13767           (const_int 0)))
13768    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13769         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13770   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13771    && ix86_match_ccmode (insn, CCGOCmode)
13772    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13773   "shr{l}\t{%2, %0|%0, %2}"
13774   [(set_attr "type" "ishift")
13775    (set_attr "mode" "SI")])
13777 (define_insn "*lshrsi3_cconly"
13778   [(set (reg FLAGS_REG)
13779       (compare
13780         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13781                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
13782         (const_int 0)))
13783    (clobber (match_scratch:SI 0 "=r"))]
13784   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13785    && ix86_match_ccmode (insn, CCGOCmode)
13786    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13787   "shr{l}\t{%2, %0|%0, %2}"
13788   [(set_attr "type" "ishift")
13789    (set_attr "mode" "SI")])
13791 (define_insn "*lshrsi3_cmp_zext"
13792   [(set (reg FLAGS_REG)
13793         (compare
13794           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13795                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13796           (const_int 0)))
13797    (set (match_operand:DI 0 "register_operand" "=r")
13798         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13799   "TARGET_64BIT
13800    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13801    && ix86_match_ccmode (insn, CCGOCmode)
13802    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13803   "shr{l}\t{%2, %k0|%k0, %2}"
13804   [(set_attr "type" "ishift")
13805    (set_attr "mode" "SI")])
13807 (define_expand "lshrhi3"
13808   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13809         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13810                      (match_operand:QI 2 "nonmemory_operand" "")))]
13811   "TARGET_HIMODE_MATH"
13812   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13814 (define_insn "*lshrhi3_1_one_bit"
13815   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13816         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13817                      (match_operand:QI 2 "const1_operand" "")))
13818    (clobber (reg:CC FLAGS_REG))]
13819   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13820    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13821   "shr{w}\t%0"
13822   [(set_attr "type" "ishift")
13823    (set_attr "length_immediate" "0")
13824    (set_attr "mode" "HI")])
13826 (define_insn "*lshrhi3_1"
13827   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13828         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13829                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13830    (clobber (reg:CC FLAGS_REG))]
13831   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13832   "@
13833    shr{w}\t{%2, %0|%0, %2}
13834    shr{w}\t{%b2, %0|%0, %b2}"
13835   [(set_attr "type" "ishift")
13836    (set_attr "mode" "HI")])
13838 ;; This pattern can't accept a variable shift count, since shifts by
13839 ;; zero don't affect the flags.  We assume that shifts by constant
13840 ;; zero are optimized away.
13841 (define_insn "*lshrhi3_one_bit_cmp"
13842   [(set (reg FLAGS_REG)
13843         (compare
13844           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13845                        (match_operand:QI 2 "const1_operand" ""))
13846           (const_int 0)))
13847    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13848         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13849   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13850    && ix86_match_ccmode (insn, CCGOCmode)
13851    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13852   "shr{w}\t%0"
13853   [(set_attr "type" "ishift")
13854    (set_attr "length_immediate" "0")
13855    (set_attr "mode" "HI")])
13857 (define_insn "*lshrhi3_one_bit_cconly"
13858   [(set (reg FLAGS_REG)
13859         (compare
13860           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13861                        (match_operand:QI 2 "const1_operand" ""))
13862           (const_int 0)))
13863    (clobber (match_scratch:HI 0 "=r"))]
13864   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13865    && ix86_match_ccmode (insn, CCGOCmode)
13866    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13867   "shr{w}\t%0"
13868   [(set_attr "type" "ishift")
13869    (set_attr "length_immediate" "0")
13870    (set_attr "mode" "HI")])
13872 ;; This pattern can't accept a variable shift count, since shifts by
13873 ;; zero don't affect the flags.  We assume that shifts by constant
13874 ;; zero are optimized away.
13875 (define_insn "*lshrhi3_cmp"
13876   [(set (reg FLAGS_REG)
13877         (compare
13878           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13879                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13880           (const_int 0)))
13881    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13882         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13883   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13884    && ix86_match_ccmode (insn, CCGOCmode)
13885    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13886   "shr{w}\t{%2, %0|%0, %2}"
13887   [(set_attr "type" "ishift")
13888    (set_attr "mode" "HI")])
13890 (define_insn "*lshrhi3_cconly"
13891   [(set (reg FLAGS_REG)
13892         (compare
13893           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13894                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13895           (const_int 0)))
13896    (clobber (match_scratch:HI 0 "=r"))]
13897   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13898    && ix86_match_ccmode (insn, CCGOCmode)
13899    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13900   "shr{w}\t{%2, %0|%0, %2}"
13901   [(set_attr "type" "ishift")
13902    (set_attr "mode" "HI")])
13904 (define_expand "lshrqi3"
13905   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13906         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13907                      (match_operand:QI 2 "nonmemory_operand" "")))]
13908   "TARGET_QIMODE_MATH"
13909   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13911 (define_insn "*lshrqi3_1_one_bit"
13912   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13913         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13914                      (match_operand:QI 2 "const1_operand" "")))
13915    (clobber (reg:CC FLAGS_REG))]
13916   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13917    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13918   "shr{b}\t%0"
13919   [(set_attr "type" "ishift")
13920    (set_attr "length_immediate" "0")
13921    (set_attr "mode" "QI")])
13923 (define_insn "*lshrqi3_1_one_bit_slp"
13924   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13925         (lshiftrt:QI (match_dup 0)
13926                      (match_operand:QI 1 "const1_operand" "")))
13927    (clobber (reg:CC FLAGS_REG))]
13928   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13929    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13930   "shr{b}\t%0"
13931   [(set_attr "type" "ishift1")
13932    (set_attr "length_immediate" "0")
13933    (set_attr "mode" "QI")])
13935 (define_insn "*lshrqi3_1"
13936   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13937         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13938                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13939    (clobber (reg:CC FLAGS_REG))]
13940   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13941   "@
13942    shr{b}\t{%2, %0|%0, %2}
13943    shr{b}\t{%b2, %0|%0, %b2}"
13944   [(set_attr "type" "ishift")
13945    (set_attr "mode" "QI")])
13947 (define_insn "*lshrqi3_1_slp"
13948   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13949         (lshiftrt:QI (match_dup 0)
13950                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13951    (clobber (reg:CC FLAGS_REG))]
13952   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13953    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13954   "@
13955    shr{b}\t{%1, %0|%0, %1}
13956    shr{b}\t{%b1, %0|%0, %b1}"
13957   [(set_attr "type" "ishift1")
13958    (set_attr "mode" "QI")])
13960 ;; This pattern can't accept a variable shift count, since shifts by
13961 ;; zero don't affect the flags.  We assume that shifts by constant
13962 ;; zero are optimized away.
13963 (define_insn "*lshrqi2_one_bit_cmp"
13964   [(set (reg FLAGS_REG)
13965         (compare
13966           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13967                        (match_operand:QI 2 "const1_operand" ""))
13968           (const_int 0)))
13969    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13970         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13971   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13972    && ix86_match_ccmode (insn, CCGOCmode)
13973    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13974   "shr{b}\t%0"
13975   [(set_attr "type" "ishift")
13976    (set_attr "length_immediate" "0")
13977    (set_attr "mode" "QI")])
13979 (define_insn "*lshrqi2_one_bit_cconly"
13980   [(set (reg FLAGS_REG)
13981         (compare
13982           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13983                        (match_operand:QI 2 "const1_operand" ""))
13984           (const_int 0)))
13985    (clobber (match_scratch:QI 0 "=q"))]
13986   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13987    && ix86_match_ccmode (insn, CCGOCmode)
13988    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13989   "shr{b}\t%0"
13990   [(set_attr "type" "ishift")
13991    (set_attr "length_immediate" "0")
13992    (set_attr "mode" "QI")])
13994 ;; This pattern can't accept a variable shift count, since shifts by
13995 ;; zero don't affect the flags.  We assume that shifts by constant
13996 ;; zero are optimized away.
13997 (define_insn "*lshrqi2_cmp"
13998   [(set (reg FLAGS_REG)
13999         (compare
14000           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14001                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
14002           (const_int 0)))
14003    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14004         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
14005   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
14006    && ix86_match_ccmode (insn, CCGOCmode)
14007    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
14008   "shr{b}\t{%2, %0|%0, %2}"
14009   [(set_attr "type" "ishift")
14010    (set_attr "mode" "QI")])
14012 (define_insn "*lshrqi2_cconly"
14013   [(set (reg FLAGS_REG)
14014         (compare
14015           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14016                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
14017           (const_int 0)))
14018    (clobber (match_scratch:QI 0 "=q"))]
14019   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
14020    && ix86_match_ccmode (insn, CCGOCmode)
14021    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
14022   "shr{b}\t{%2, %0|%0, %2}"
14023   [(set_attr "type" "ishift")
14024    (set_attr "mode" "QI")])
14026 ;; Rotate instructions
14028 (define_expand "rotldi3"
14029   [(set (match_operand:DI 0 "shiftdi_operand" "")
14030         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
14031                    (match_operand:QI 2 "nonmemory_operand" "")))]
14032  ""
14034   if (TARGET_64BIT)
14035     {
14036       ix86_expand_binary_operator (ROTATE, DImode, operands);
14037       DONE;
14038     }
14039   if (!const_1_to_31_operand (operands[2], VOIDmode))
14040     FAIL;
14041   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
14042   DONE;
14045 ;; Implement rotation using two double-precision shift instructions
14046 ;; and a scratch register.
14047 (define_insn_and_split "ix86_rotldi3"
14048  [(set (match_operand:DI 0 "register_operand" "=r")
14049        (rotate:DI (match_operand:DI 1 "register_operand" "0")
14050                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
14051   (clobber (reg:CC FLAGS_REG))
14052   (clobber (match_scratch:SI 3 "=&r"))]
14053  "!TARGET_64BIT"
14054  ""
14055  "&& reload_completed"
14056  [(set (match_dup 3) (match_dup 4))
14057   (parallel
14058    [(set (match_dup 4)
14059          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
14060                  (lshiftrt:SI (match_dup 5)
14061                               (minus:QI (const_int 32) (match_dup 2)))))
14062     (clobber (reg:CC FLAGS_REG))])
14063   (parallel
14064    [(set (match_dup 5)
14065          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
14066                  (lshiftrt:SI (match_dup 3)
14067                               (minus:QI (const_int 32) (match_dup 2)))))
14068     (clobber (reg:CC FLAGS_REG))])]
14069  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
14071 (define_insn "*rotlsi3_1_one_bit_rex64"
14072   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
14073         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
14074                    (match_operand:QI 2 "const1_operand" "")))
14075    (clobber (reg:CC FLAGS_REG))]
14076   "TARGET_64BIT
14077    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14078    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
14079   "rol{q}\t%0"
14080   [(set_attr "type" "rotate")
14081    (set_attr "length_immediate" "0")
14082    (set_attr "mode" "DI")])
14084 (define_insn "*rotldi3_1_rex64"
14085   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
14086         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
14087                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
14088    (clobber (reg:CC FLAGS_REG))]
14089   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
14090   "@
14091    rol{q}\t{%2, %0|%0, %2}
14092    rol{q}\t{%b2, %0|%0, %b2}"
14093   [(set_attr "type" "rotate")
14094    (set_attr "mode" "DI")])
14096 (define_expand "rotlsi3"
14097   [(set (match_operand:SI 0 "nonimmediate_operand" "")
14098         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
14099                    (match_operand:QI 2 "nonmemory_operand" "")))]
14100   ""
14101   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
14103 (define_insn "*rotlsi3_1_one_bit"
14104   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
14105         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
14106                    (match_operand:QI 2 "const1_operand" "")))
14107    (clobber (reg:CC FLAGS_REG))]
14108   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14109    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
14110   "rol{l}\t%0"
14111   [(set_attr "type" "rotate")
14112    (set_attr "length_immediate" "0")
14113    (set_attr "mode" "SI")])
14115 (define_insn "*rotlsi3_1_one_bit_zext"
14116   [(set (match_operand:DI 0 "register_operand" "=r")
14117         (zero_extend:DI
14118           (rotate:SI (match_operand:SI 1 "register_operand" "0")
14119                      (match_operand:QI 2 "const1_operand" ""))))
14120    (clobber (reg:CC FLAGS_REG))]
14121   "TARGET_64BIT
14122    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14123    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
14124   "rol{l}\t%k0"
14125   [(set_attr "type" "rotate")
14126    (set_attr "length_immediate" "0")
14127    (set_attr "mode" "SI")])
14129 (define_insn "*rotlsi3_1"
14130   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
14131         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
14132                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
14133    (clobber (reg:CC FLAGS_REG))]
14134   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
14135   "@
14136    rol{l}\t{%2, %0|%0, %2}
14137    rol{l}\t{%b2, %0|%0, %b2}"
14138   [(set_attr "type" "rotate")
14139    (set_attr "mode" "SI")])
14141 (define_insn "*rotlsi3_1_zext"
14142   [(set (match_operand:DI 0 "register_operand" "=r,r")
14143         (zero_extend:DI
14144           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
14145                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
14146    (clobber (reg:CC FLAGS_REG))]
14147   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
14148   "@
14149    rol{l}\t{%2, %k0|%k0, %2}
14150    rol{l}\t{%b2, %k0|%k0, %b2}"
14151   [(set_attr "type" "rotate")
14152    (set_attr "mode" "SI")])
14154 (define_expand "rotlhi3"
14155   [(set (match_operand:HI 0 "nonimmediate_operand" "")
14156         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
14157                    (match_operand:QI 2 "nonmemory_operand" "")))]
14158   "TARGET_HIMODE_MATH"
14159   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
14161 (define_insn "*rotlhi3_1_one_bit"
14162   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
14163         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
14164                    (match_operand:QI 2 "const1_operand" "")))
14165    (clobber (reg:CC FLAGS_REG))]
14166   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14167    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
14168   "rol{w}\t%0"
14169   [(set_attr "type" "rotate")
14170    (set_attr "length_immediate" "0")
14171    (set_attr "mode" "HI")])
14173 (define_insn "*rotlhi3_1"
14174   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
14175         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
14176                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
14177    (clobber (reg:CC FLAGS_REG))]
14178   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
14179   "@
14180    rol{w}\t{%2, %0|%0, %2}
14181    rol{w}\t{%b2, %0|%0, %b2}"
14182   [(set_attr "type" "rotate")
14183    (set_attr "mode" "HI")])
14185 (define_split
14186  [(set (match_operand:HI 0 "register_operand" "")
14187        (rotate:HI (match_dup 0) (const_int 8)))
14188   (clobber (reg:CC FLAGS_REG))]
14189  "reload_completed"
14190  [(parallel [(set (strict_low_part (match_dup 0))
14191                   (bswap:HI (match_dup 0)))
14192              (clobber (reg:CC FLAGS_REG))])]
14193  "")
14195 (define_expand "rotlqi3"
14196   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14197         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
14198                    (match_operand:QI 2 "nonmemory_operand" "")))]
14199   "TARGET_QIMODE_MATH"
14200   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
14202 (define_insn "*rotlqi3_1_one_bit_slp"
14203   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14204         (rotate:QI (match_dup 0)
14205                    (match_operand:QI 1 "const1_operand" "")))
14206    (clobber (reg:CC FLAGS_REG))]
14207   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14208    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
14209   "rol{b}\t%0"
14210   [(set_attr "type" "rotate1")
14211    (set_attr "length_immediate" "0")
14212    (set_attr "mode" "QI")])
14214 (define_insn "*rotlqi3_1_one_bit"
14215   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14216         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14217                    (match_operand:QI 2 "const1_operand" "")))
14218    (clobber (reg:CC FLAGS_REG))]
14219   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14220    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
14221   "rol{b}\t%0"
14222   [(set_attr "type" "rotate")
14223    (set_attr "length_immediate" "0")
14224    (set_attr "mode" "QI")])
14226 (define_insn "*rotlqi3_1_slp"
14227   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
14228         (rotate:QI (match_dup 0)
14229                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
14230    (clobber (reg:CC FLAGS_REG))]
14231   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14232    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14233   "@
14234    rol{b}\t{%1, %0|%0, %1}
14235    rol{b}\t{%b1, %0|%0, %b1}"
14236   [(set_attr "type" "rotate1")
14237    (set_attr "mode" "QI")])
14239 (define_insn "*rotlqi3_1"
14240   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
14241         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
14242                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
14243    (clobber (reg:CC FLAGS_REG))]
14244   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
14245   "@
14246    rol{b}\t{%2, %0|%0, %2}
14247    rol{b}\t{%b2, %0|%0, %b2}"
14248   [(set_attr "type" "rotate")
14249    (set_attr "mode" "QI")])
14251 (define_expand "rotrdi3"
14252   [(set (match_operand:DI 0 "shiftdi_operand" "")
14253         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
14254                    (match_operand:QI 2 "nonmemory_operand" "")))]
14255  ""
14257   if (TARGET_64BIT)
14258     {
14259       ix86_expand_binary_operator (ROTATERT, DImode, operands);
14260       DONE;
14261     }
14262   if (!const_1_to_31_operand (operands[2], VOIDmode))
14263     FAIL;
14264   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
14265   DONE;
14268 ;; Implement rotation using two double-precision shift instructions
14269 ;; and a scratch register.
14270 (define_insn_and_split "ix86_rotrdi3"
14271  [(set (match_operand:DI 0 "register_operand" "=r")
14272        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
14273                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
14274   (clobber (reg:CC FLAGS_REG))
14275   (clobber (match_scratch:SI 3 "=&r"))]
14276  "!TARGET_64BIT"
14277  ""
14278  "&& reload_completed"
14279  [(set (match_dup 3) (match_dup 4))
14280   (parallel
14281    [(set (match_dup 4)
14282          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
14283                  (ashift:SI (match_dup 5)
14284                             (minus:QI (const_int 32) (match_dup 2)))))
14285     (clobber (reg:CC FLAGS_REG))])
14286   (parallel
14287    [(set (match_dup 5)
14288          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
14289                  (ashift:SI (match_dup 3)
14290                             (minus:QI (const_int 32) (match_dup 2)))))
14291     (clobber (reg:CC FLAGS_REG))])]
14292  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
14294 (define_insn "*rotrdi3_1_one_bit_rex64"
14295   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
14296         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
14297                      (match_operand:QI 2 "const1_operand" "")))
14298    (clobber (reg:CC FLAGS_REG))]
14299   "TARGET_64BIT
14300    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14301    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
14302   "ror{q}\t%0"
14303   [(set_attr "type" "rotate")
14304    (set_attr "length_immediate" "0")
14305    (set_attr "mode" "DI")])
14307 (define_insn "*rotrdi3_1_rex64"
14308   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
14309         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
14310                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
14311    (clobber (reg:CC FLAGS_REG))]
14312   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
14313   "@
14314    ror{q}\t{%2, %0|%0, %2}
14315    ror{q}\t{%b2, %0|%0, %b2}"
14316   [(set_attr "type" "rotate")
14317    (set_attr "mode" "DI")])
14319 (define_expand "rotrsi3"
14320   [(set (match_operand:SI 0 "nonimmediate_operand" "")
14321         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
14322                      (match_operand:QI 2 "nonmemory_operand" "")))]
14323   ""
14324   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
14326 (define_insn "*rotrsi3_1_one_bit"
14327   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
14328         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
14329                      (match_operand:QI 2 "const1_operand" "")))
14330    (clobber (reg:CC FLAGS_REG))]
14331   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14332    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14333   "ror{l}\t%0"
14334   [(set_attr "type" "rotate")
14335    (set_attr "length_immediate" "0")
14336    (set_attr "mode" "SI")])
14338 (define_insn "*rotrsi3_1_one_bit_zext"
14339   [(set (match_operand:DI 0 "register_operand" "=r")
14340         (zero_extend:DI
14341           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
14342                        (match_operand:QI 2 "const1_operand" ""))))
14343    (clobber (reg:CC FLAGS_REG))]
14344   "TARGET_64BIT
14345    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14346    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14347   "ror{l}\t%k0"
14348   [(set_attr "type" "rotate")
14349    (set_attr "length_immediate" "0")
14350    (set_attr "mode" "SI")])
14352 (define_insn "*rotrsi3_1"
14353   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
14354         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
14355                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
14356    (clobber (reg:CC FLAGS_REG))]
14357   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14358   "@
14359    ror{l}\t{%2, %0|%0, %2}
14360    ror{l}\t{%b2, %0|%0, %b2}"
14361   [(set_attr "type" "rotate")
14362    (set_attr "mode" "SI")])
14364 (define_insn "*rotrsi3_1_zext"
14365   [(set (match_operand:DI 0 "register_operand" "=r,r")
14366         (zero_extend:DI
14367           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
14368                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
14369    (clobber (reg:CC FLAGS_REG))]
14370   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14371   "@
14372    ror{l}\t{%2, %k0|%k0, %2}
14373    ror{l}\t{%b2, %k0|%k0, %b2}"
14374   [(set_attr "type" "rotate")
14375    (set_attr "mode" "SI")])
14377 (define_expand "rotrhi3"
14378   [(set (match_operand:HI 0 "nonimmediate_operand" "")
14379         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
14380                      (match_operand:QI 2 "nonmemory_operand" "")))]
14381   "TARGET_HIMODE_MATH"
14382   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
14384 (define_insn "*rotrhi3_one_bit"
14385   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
14386         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
14387                      (match_operand:QI 2 "const1_operand" "")))
14388    (clobber (reg:CC FLAGS_REG))]
14389   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14390    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
14391   "ror{w}\t%0"
14392   [(set_attr "type" "rotate")
14393    (set_attr "length_immediate" "0")
14394    (set_attr "mode" "HI")])
14396 (define_insn "*rotrhi3_1"
14397   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
14398         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
14399                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
14400    (clobber (reg:CC FLAGS_REG))]
14401   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
14402   "@
14403    ror{w}\t{%2, %0|%0, %2}
14404    ror{w}\t{%b2, %0|%0, %b2}"
14405   [(set_attr "type" "rotate")
14406    (set_attr "mode" "HI")])
14408 (define_split
14409  [(set (match_operand:HI 0 "register_operand" "")
14410        (rotatert:HI (match_dup 0) (const_int 8)))
14411   (clobber (reg:CC FLAGS_REG))]
14412  "reload_completed"
14413  [(parallel [(set (strict_low_part (match_dup 0))
14414                   (bswap:HI (match_dup 0)))
14415              (clobber (reg:CC FLAGS_REG))])]
14416  "")
14418 (define_expand "rotrqi3"
14419   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14420         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
14421                      (match_operand:QI 2 "nonmemory_operand" "")))]
14422   "TARGET_QIMODE_MATH"
14423   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
14425 (define_insn "*rotrqi3_1_one_bit"
14426   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14427         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14428                      (match_operand:QI 2 "const1_operand" "")))
14429    (clobber (reg:CC FLAGS_REG))]
14430   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14431    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
14432   "ror{b}\t%0"
14433   [(set_attr "type" "rotate")
14434    (set_attr "length_immediate" "0")
14435    (set_attr "mode" "QI")])
14437 (define_insn "*rotrqi3_1_one_bit_slp"
14438   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14439         (rotatert:QI (match_dup 0)
14440                      (match_operand:QI 1 "const1_operand" "")))
14441    (clobber (reg:CC FLAGS_REG))]
14442   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14443    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
14444   "ror{b}\t%0"
14445   [(set_attr "type" "rotate1")
14446    (set_attr "length_immediate" "0")
14447    (set_attr "mode" "QI")])
14449 (define_insn "*rotrqi3_1"
14450   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
14451         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
14452                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
14453    (clobber (reg:CC FLAGS_REG))]
14454   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
14455   "@
14456    ror{b}\t{%2, %0|%0, %2}
14457    ror{b}\t{%b2, %0|%0, %b2}"
14458   [(set_attr "type" "rotate")
14459    (set_attr "mode" "QI")])
14461 (define_insn "*rotrqi3_1_slp"
14462   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
14463         (rotatert:QI (match_dup 0)
14464                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
14465    (clobber (reg:CC FLAGS_REG))]
14466   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14467    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14468   "@
14469    ror{b}\t{%1, %0|%0, %1}
14470    ror{b}\t{%b1, %0|%0, %b1}"
14471   [(set_attr "type" "rotate1")
14472    (set_attr "mode" "QI")])
14474 ;; Bit set / bit test instructions
14476 (define_expand "extv"
14477   [(set (match_operand:SI 0 "register_operand" "")
14478         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
14479                          (match_operand:SI 2 "const8_operand" "")
14480                          (match_operand:SI 3 "const8_operand" "")))]
14481   ""
14483   /* Handle extractions from %ah et al.  */
14484   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
14485     FAIL;
14487   /* From mips.md: extract_bit_field doesn't verify that our source
14488      matches the predicate, so check it again here.  */
14489   if (! ext_register_operand (operands[1], VOIDmode))
14490     FAIL;
14493 (define_expand "extzv"
14494   [(set (match_operand:SI 0 "register_operand" "")
14495         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
14496                          (match_operand:SI 2 "const8_operand" "")
14497                          (match_operand:SI 3 "const8_operand" "")))]
14498   ""
14500   /* Handle extractions from %ah et al.  */
14501   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
14502     FAIL;
14504   /* From mips.md: extract_bit_field doesn't verify that our source
14505      matches the predicate, so check it again here.  */
14506   if (! ext_register_operand (operands[1], VOIDmode))
14507     FAIL;
14510 (define_expand "insv"
14511   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
14512                       (match_operand 1 "const8_operand" "")
14513                       (match_operand 2 "const8_operand" ""))
14514         (match_operand 3 "register_operand" ""))]
14515   ""
14517   /* Handle insertions to %ah et al.  */
14518   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
14519     FAIL;
14521   /* From mips.md: insert_bit_field doesn't verify that our source
14522      matches the predicate, so check it again here.  */
14523   if (! ext_register_operand (operands[0], VOIDmode))
14524     FAIL;
14526   if (TARGET_64BIT)
14527     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
14528   else
14529     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
14531   DONE;
14534 ;; %%% bts, btr, btc, bt.
14535 ;; In general these instructions are *slow* when applied to memory,
14536 ;; since they enforce atomic operation.  When applied to registers,
14537 ;; it depends on the cpu implementation.  They're never faster than
14538 ;; the corresponding and/ior/xor operations, so with 32-bit there's
14539 ;; no point.  But in 64-bit, we can't hold the relevant immediates
14540 ;; within the instruction itself, so operating on bits in the high
14541 ;; 32-bits of a register becomes easier.
14543 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
14544 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
14545 ;; negdf respectively, so they can never be disabled entirely.
14547 (define_insn "*btsq"
14548   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14549                          (const_int 1)
14550                          (match_operand:DI 1 "const_0_to_63_operand" ""))
14551         (const_int 1))
14552    (clobber (reg:CC FLAGS_REG))]
14553   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14554   "bts{q}\t{%1, %0|%0, %1}"
14555   [(set_attr "type" "alu1")
14556    (set_attr "prefix_0f" "1")
14557    (set_attr "mode" "DI")])
14559 (define_insn "*btrq"
14560   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14561                          (const_int 1)
14562                          (match_operand:DI 1 "const_0_to_63_operand" ""))
14563         (const_int 0))
14564    (clobber (reg:CC FLAGS_REG))]
14565   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14566   "btr{q}\t{%1, %0|%0, %1}"
14567   [(set_attr "type" "alu1")
14568    (set_attr "prefix_0f" "1")
14569    (set_attr "mode" "DI")])
14571 (define_insn "*btcq"
14572   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14573                          (const_int 1)
14574                          (match_operand:DI 1 "const_0_to_63_operand" ""))
14575         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
14576    (clobber (reg:CC FLAGS_REG))]
14577   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14578   "btc{q}\t{%1, %0|%0, %1}"
14579   [(set_attr "type" "alu1")
14580    (set_attr "prefix_0f" "1")
14581    (set_attr "mode" "DI")])
14583 ;; Allow Nocona to avoid these instructions if a register is available.
14585 (define_peephole2
14586   [(match_scratch:DI 2 "r")
14587    (parallel [(set (zero_extract:DI
14588                      (match_operand:DI 0 "register_operand" "")
14589                      (const_int 1)
14590                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14591                    (const_int 1))
14592               (clobber (reg:CC FLAGS_REG))])]
14593   "TARGET_64BIT && !TARGET_USE_BT"
14594   [(const_int 0)]
14596   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14597   rtx op1;
14599   if (HOST_BITS_PER_WIDE_INT >= 64)
14600     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14601   else if (i < HOST_BITS_PER_WIDE_INT)
14602     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14603   else
14604     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14606   op1 = immed_double_const (lo, hi, DImode);
14607   if (i >= 31)
14608     {
14609       emit_move_insn (operands[2], op1);
14610       op1 = operands[2];
14611     }
14613   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
14614   DONE;
14617 (define_peephole2
14618   [(match_scratch:DI 2 "r")
14619    (parallel [(set (zero_extract:DI
14620                      (match_operand:DI 0 "register_operand" "")
14621                      (const_int 1)
14622                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14623                    (const_int 0))
14624               (clobber (reg:CC FLAGS_REG))])]
14625   "TARGET_64BIT && !TARGET_USE_BT"
14626   [(const_int 0)]
14628   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14629   rtx op1;
14631   if (HOST_BITS_PER_WIDE_INT >= 64)
14632     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14633   else if (i < HOST_BITS_PER_WIDE_INT)
14634     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14635   else
14636     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14638   op1 = immed_double_const (~lo, ~hi, DImode);
14639   if (i >= 32)
14640     {
14641       emit_move_insn (operands[2], op1);
14642       op1 = operands[2];
14643     }
14645   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14646   DONE;
14649 (define_peephole2
14650   [(match_scratch:DI 2 "r")
14651    (parallel [(set (zero_extract:DI
14652                      (match_operand:DI 0 "register_operand" "")
14653                      (const_int 1)
14654                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14655               (not:DI (zero_extract:DI
14656                         (match_dup 0) (const_int 1) (match_dup 1))))
14657               (clobber (reg:CC FLAGS_REG))])]
14658   "TARGET_64BIT && !TARGET_USE_BT"
14659   [(const_int 0)]
14661   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14662   rtx op1;
14664   if (HOST_BITS_PER_WIDE_INT >= 64)
14665     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14666   else if (i < HOST_BITS_PER_WIDE_INT)
14667     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14668   else
14669     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14671   op1 = immed_double_const (lo, hi, DImode);
14672   if (i >= 31)
14673     {
14674       emit_move_insn (operands[2], op1);
14675       op1 = operands[2];
14676     }
14678   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14679   DONE;
14682 (define_insn "*btdi_rex64"
14683   [(set (reg:CCC FLAGS_REG)
14684         (compare:CCC
14685           (zero_extract:DI
14686             (match_operand:DI 0 "register_operand" "r")
14687             (const_int 1)
14688             (match_operand:DI 1 "nonmemory_operand" "rN"))
14689           (const_int 0)))]
14690   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14691   "bt{q}\t{%1, %0|%0, %1}"
14692   [(set_attr "type" "alu1")
14693    (set_attr "prefix_0f" "1")
14694    (set_attr "mode" "DI")])
14696 (define_insn "*btsi"
14697   [(set (reg:CCC FLAGS_REG)
14698         (compare:CCC
14699           (zero_extract:SI
14700             (match_operand:SI 0 "register_operand" "r")
14701             (const_int 1)
14702             (match_operand:SI 1 "nonmemory_operand" "rN"))
14703           (const_int 0)))]
14704   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14705   "bt{l}\t{%1, %0|%0, %1}"
14706   [(set_attr "type" "alu1")
14707    (set_attr "prefix_0f" "1")
14708    (set_attr "mode" "SI")])
14710 ;; Store-flag instructions.
14712 ;; For all sCOND expanders, also expand the compare or test insn that
14713 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
14715 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
14716 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
14717 ;; way, which can later delete the movzx if only QImode is needed.
14719 (define_insn "*setcc_1"
14720   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14721         (match_operator:QI 1 "ix86_comparison_operator"
14722           [(reg FLAGS_REG) (const_int 0)]))]
14723   ""
14724   "set%C1\t%0"
14725   [(set_attr "type" "setcc")
14726    (set_attr "mode" "QI")])
14728 (define_insn "*setcc_2"
14729   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14730         (match_operator:QI 1 "ix86_comparison_operator"
14731           [(reg FLAGS_REG) (const_int 0)]))]
14732   ""
14733   "set%C1\t%0"
14734   [(set_attr "type" "setcc")
14735    (set_attr "mode" "QI")])
14737 ;; In general it is not safe to assume too much about CCmode registers,
14738 ;; so simplify-rtx stops when it sees a second one.  Under certain
14739 ;; conditions this is safe on x86, so help combine not create
14741 ;;      seta    %al
14742 ;;      testb   %al, %al
14743 ;;      sete    %al
14745 (define_split
14746   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14747         (ne:QI (match_operator 1 "ix86_comparison_operator"
14748                  [(reg FLAGS_REG) (const_int 0)])
14749             (const_int 0)))]
14750   ""
14751   [(set (match_dup 0) (match_dup 1))]
14753   PUT_MODE (operands[1], QImode);
14756 (define_split
14757   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14758         (ne:QI (match_operator 1 "ix86_comparison_operator"
14759                  [(reg FLAGS_REG) (const_int 0)])
14760             (const_int 0)))]
14761   ""
14762   [(set (match_dup 0) (match_dup 1))]
14764   PUT_MODE (operands[1], QImode);
14767 (define_split
14768   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14769         (eq:QI (match_operator 1 "ix86_comparison_operator"
14770                  [(reg FLAGS_REG) (const_int 0)])
14771             (const_int 0)))]
14772   ""
14773   [(set (match_dup 0) (match_dup 1))]
14775   rtx new_op1 = copy_rtx (operands[1]);
14776   operands[1] = new_op1;
14777   PUT_MODE (new_op1, QImode);
14778   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14779                                              GET_MODE (XEXP (new_op1, 0))));
14781   /* Make sure that (a) the CCmode we have for the flags is strong
14782      enough for the reversed compare or (b) we have a valid FP compare.  */
14783   if (! ix86_comparison_operator (new_op1, VOIDmode))
14784     FAIL;
14787 (define_split
14788   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14789         (eq:QI (match_operator 1 "ix86_comparison_operator"
14790                  [(reg FLAGS_REG) (const_int 0)])
14791             (const_int 0)))]
14792   ""
14793   [(set (match_dup 0) (match_dup 1))]
14795   rtx new_op1 = copy_rtx (operands[1]);
14796   operands[1] = new_op1;
14797   PUT_MODE (new_op1, QImode);
14798   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14799                                              GET_MODE (XEXP (new_op1, 0))));
14801   /* Make sure that (a) the CCmode we have for the flags is strong
14802      enough for the reversed compare or (b) we have a valid FP compare.  */
14803   if (! ix86_comparison_operator (new_op1, VOIDmode))
14804     FAIL;
14807 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14808 ;; subsequent logical operations are used to imitate conditional moves.
14809 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14810 ;; it directly.
14812 (define_insn "*avx_setcc<mode>"
14813   [(set (match_operand:MODEF 0 "register_operand" "=x")
14814         (match_operator:MODEF 1 "avx_comparison_float_operator"
14815           [(match_operand:MODEF 2 "register_operand" "x")
14816            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14817   "TARGET_AVX"
14818   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14819   [(set_attr "type" "ssecmp")
14820    (set_attr "prefix" "vex")
14821    (set_attr "length_immediate" "1")
14822    (set_attr "mode" "<MODE>")])
14824 (define_insn "*sse_setcc<mode>"
14825   [(set (match_operand:MODEF 0 "register_operand" "=x")
14826         (match_operator:MODEF 1 "sse_comparison_operator"
14827           [(match_operand:MODEF 2 "register_operand" "0")
14828            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14829   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14830   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14831   [(set_attr "type" "ssecmp")
14832    (set_attr "length_immediate" "1")
14833    (set_attr "mode" "<MODE>")])
14835 (define_insn "*sse5_setcc<mode>"
14836   [(set (match_operand:MODEF 0 "register_operand" "=x")
14837         (match_operator:MODEF 1 "sse5_comparison_float_operator"
14838           [(match_operand:MODEF 2 "register_operand" "x")
14839            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14840   "TARGET_SSE5"
14841   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14842   [(set_attr "type" "sse4arg")
14843    (set_attr "length_immediate" "1")
14844    (set_attr "mode" "<MODE>")])
14847 ;; Basic conditional jump instructions.
14848 ;; We ignore the overflow flag for signed branch instructions.
14850 (define_insn "*jcc_1"
14851   [(set (pc)
14852         (if_then_else (match_operator 1 "ix86_comparison_operator"
14853                                       [(reg FLAGS_REG) (const_int 0)])
14854                       (label_ref (match_operand 0 "" ""))
14855                       (pc)))]
14856   ""
14857   "%+j%C1\t%l0"
14858   [(set_attr "type" "ibr")
14859    (set_attr "modrm" "0")
14860    (set (attr "length")
14861            (if_then_else (and (ge (minus (match_dup 0) (pc))
14862                                   (const_int -126))
14863                               (lt (minus (match_dup 0) (pc))
14864                                   (const_int 128)))
14865              (const_int 2)
14866              (const_int 6)))])
14868 (define_insn "*jcc_2"
14869   [(set (pc)
14870         (if_then_else (match_operator 1 "ix86_comparison_operator"
14871                                       [(reg FLAGS_REG) (const_int 0)])
14872                       (pc)
14873                       (label_ref (match_operand 0 "" ""))))]
14874   ""
14875   "%+j%c1\t%l0"
14876   [(set_attr "type" "ibr")
14877    (set_attr "modrm" "0")
14878    (set (attr "length")
14879            (if_then_else (and (ge (minus (match_dup 0) (pc))
14880                                   (const_int -126))
14881                               (lt (minus (match_dup 0) (pc))
14882                                   (const_int 128)))
14883              (const_int 2)
14884              (const_int 6)))])
14886 ;; In general it is not safe to assume too much about CCmode registers,
14887 ;; so simplify-rtx stops when it sees a second one.  Under certain
14888 ;; conditions this is safe on x86, so help combine not create
14890 ;;      seta    %al
14891 ;;      testb   %al, %al
14892 ;;      je      Lfoo
14894 (define_split
14895   [(set (pc)
14896         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14897                                       [(reg FLAGS_REG) (const_int 0)])
14898                           (const_int 0))
14899                       (label_ref (match_operand 1 "" ""))
14900                       (pc)))]
14901   ""
14902   [(set (pc)
14903         (if_then_else (match_dup 0)
14904                       (label_ref (match_dup 1))
14905                       (pc)))]
14907   PUT_MODE (operands[0], VOIDmode);
14910 (define_split
14911   [(set (pc)
14912         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14913                                       [(reg FLAGS_REG) (const_int 0)])
14914                           (const_int 0))
14915                       (label_ref (match_operand 1 "" ""))
14916                       (pc)))]
14917   ""
14918   [(set (pc)
14919         (if_then_else (match_dup 0)
14920                       (label_ref (match_dup 1))
14921                       (pc)))]
14923   rtx new_op0 = copy_rtx (operands[0]);
14924   operands[0] = new_op0;
14925   PUT_MODE (new_op0, VOIDmode);
14926   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14927                                              GET_MODE (XEXP (new_op0, 0))));
14929   /* Make sure that (a) the CCmode we have for the flags is strong
14930      enough for the reversed compare or (b) we have a valid FP compare.  */
14931   if (! ix86_comparison_operator (new_op0, VOIDmode))
14932     FAIL;
14935 ;; zero_extend in SImode is correct, since this is what combine pass
14936 ;; generates from shift insn with QImode operand.  Actually, the mode of
14937 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14938 ;; appropriate modulo of the bit offset value.
14940 (define_insn_and_split "*jcc_btdi_rex64"
14941   [(set (pc)
14942         (if_then_else (match_operator 0 "bt_comparison_operator"
14943                         [(zero_extract:DI
14944                            (match_operand:DI 1 "register_operand" "r")
14945                            (const_int 1)
14946                            (zero_extend:SI
14947                              (match_operand:QI 2 "register_operand" "r")))
14948                          (const_int 0)])
14949                       (label_ref (match_operand 3 "" ""))
14950                       (pc)))
14951    (clobber (reg:CC FLAGS_REG))]
14952   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14953   "#"
14954   "&& 1"
14955   [(set (reg:CCC FLAGS_REG)
14956         (compare:CCC
14957           (zero_extract:DI
14958             (match_dup 1)
14959             (const_int 1)
14960             (match_dup 2))
14961           (const_int 0)))
14962    (set (pc)
14963         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14964                       (label_ref (match_dup 3))
14965                       (pc)))]
14967   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14969   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14972 ;; avoid useless masking of bit offset operand
14973 (define_insn_and_split "*jcc_btdi_mask_rex64"
14974   [(set (pc)
14975         (if_then_else (match_operator 0 "bt_comparison_operator"
14976                         [(zero_extract:DI
14977                            (match_operand:DI 1 "register_operand" "r")
14978                            (const_int 1)
14979                            (and:SI
14980                              (match_operand:SI 2 "register_operand" "r")
14981                              (match_operand:SI 3 "const_int_operand" "n")))])
14982                       (label_ref (match_operand 4 "" ""))
14983                       (pc)))
14984    (clobber (reg:CC FLAGS_REG))]
14985   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14986    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14987   "#"
14988   "&& 1"
14989   [(set (reg:CCC FLAGS_REG)
14990         (compare:CCC
14991           (zero_extract:DI
14992             (match_dup 1)
14993             (const_int 1)
14994             (match_dup 2))
14995           (const_int 0)))
14996    (set (pc)
14997         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14998                       (label_ref (match_dup 4))
14999                       (pc)))]
15001   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
15003   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
15006 (define_insn_and_split "*jcc_btsi"
15007   [(set (pc)
15008         (if_then_else (match_operator 0 "bt_comparison_operator"
15009                         [(zero_extract:SI
15010                            (match_operand:SI 1 "register_operand" "r")
15011                            (const_int 1)
15012                            (zero_extend:SI
15013                              (match_operand:QI 2 "register_operand" "r")))
15014                          (const_int 0)])
15015                       (label_ref (match_operand 3 "" ""))
15016                       (pc)))
15017    (clobber (reg:CC FLAGS_REG))]
15018   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
15019   "#"
15020   "&& 1"
15021   [(set (reg:CCC FLAGS_REG)
15022         (compare:CCC
15023           (zero_extract:SI
15024             (match_dup 1)
15025             (const_int 1)
15026             (match_dup 2))
15027           (const_int 0)))
15028    (set (pc)
15029         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15030                       (label_ref (match_dup 3))
15031                       (pc)))]
15033   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
15035   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
15038 ;; avoid useless masking of bit offset operand
15039 (define_insn_and_split "*jcc_btsi_mask"
15040   [(set (pc)
15041         (if_then_else (match_operator 0 "bt_comparison_operator"
15042                         [(zero_extract:SI
15043                            (match_operand:SI 1 "register_operand" "r")
15044                            (const_int 1)
15045                            (and:SI
15046                              (match_operand:SI 2 "register_operand" "r")
15047                              (match_operand:SI 3 "const_int_operand" "n")))])
15048                       (label_ref (match_operand 4 "" ""))
15049                       (pc)))
15050    (clobber (reg:CC FLAGS_REG))]
15051   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
15052    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
15053   "#"
15054   "&& 1"
15055   [(set (reg:CCC FLAGS_REG)
15056         (compare:CCC
15057           (zero_extract:SI
15058             (match_dup 1)
15059             (const_int 1)
15060             (match_dup 2))
15061           (const_int 0)))
15062    (set (pc)
15063         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15064                       (label_ref (match_dup 4))
15065                       (pc)))]
15066   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
15068 (define_insn_and_split "*jcc_btsi_1"
15069   [(set (pc)
15070         (if_then_else (match_operator 0 "bt_comparison_operator"
15071                         [(and:SI
15072                            (lshiftrt:SI
15073                              (match_operand:SI 1 "register_operand" "r")
15074                              (match_operand:QI 2 "register_operand" "r"))
15075                            (const_int 1))
15076                          (const_int 0)])
15077                       (label_ref (match_operand 3 "" ""))
15078                       (pc)))
15079    (clobber (reg:CC FLAGS_REG))]
15080   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
15081   "#"
15082   "&& 1"
15083   [(set (reg:CCC FLAGS_REG)
15084         (compare:CCC
15085           (zero_extract:SI
15086             (match_dup 1)
15087             (const_int 1)
15088             (match_dup 2))
15089           (const_int 0)))
15090    (set (pc)
15091         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15092                       (label_ref (match_dup 3))
15093                       (pc)))]
15095   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
15097   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
15100 ;; avoid useless masking of bit offset operand
15101 (define_insn_and_split "*jcc_btsi_mask_1"
15102   [(set (pc)
15103         (if_then_else
15104           (match_operator 0 "bt_comparison_operator"
15105             [(and:SI
15106                (lshiftrt:SI
15107                  (match_operand:SI 1 "register_operand" "r")
15108                  (subreg:QI
15109                    (and:SI
15110                      (match_operand:SI 2 "register_operand" "r")
15111                      (match_operand:SI 3 "const_int_operand" "n")) 0))
15112                (const_int 1))
15113              (const_int 0)])
15114           (label_ref (match_operand 4 "" ""))
15115           (pc)))
15116    (clobber (reg:CC FLAGS_REG))]
15117   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
15118    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
15119   "#"
15120   "&& 1"
15121   [(set (reg:CCC FLAGS_REG)
15122         (compare:CCC
15123           (zero_extract:SI
15124             (match_dup 1)
15125             (const_int 1)
15126             (match_dup 2))
15127           (const_int 0)))
15128    (set (pc)
15129         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15130                       (label_ref (match_dup 4))
15131                       (pc)))]
15132   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
15134 ;; Define combination compare-and-branch fp compare instructions to help
15135 ;; combine.
15137 (define_insn "*fp_jcc_3_387"
15138   [(set (pc)
15139         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15140                         [(match_operand 1 "register_operand" "f")
15141                          (match_operand 2 "nonimmediate_operand" "fm")])
15142           (label_ref (match_operand 3 "" ""))
15143           (pc)))
15144    (clobber (reg:CCFP FPSR_REG))
15145    (clobber (reg:CCFP FLAGS_REG))
15146    (clobber (match_scratch:HI 4 "=a"))]
15147   "TARGET_80387
15148    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
15149    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15150    && SELECT_CC_MODE (GET_CODE (operands[0]),
15151                       operands[1], operands[2]) == CCFPmode
15152    && !TARGET_CMOVE"
15153   "#")
15155 (define_insn "*fp_jcc_4_387"
15156   [(set (pc)
15157         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15158                         [(match_operand 1 "register_operand" "f")
15159                          (match_operand 2 "nonimmediate_operand" "fm")])
15160           (pc)
15161           (label_ref (match_operand 3 "" ""))))
15162    (clobber (reg:CCFP FPSR_REG))
15163    (clobber (reg:CCFP FLAGS_REG))
15164    (clobber (match_scratch:HI 4 "=a"))]
15165   "TARGET_80387
15166    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
15167    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15168    && SELECT_CC_MODE (GET_CODE (operands[0]),
15169                       operands[1], operands[2]) == CCFPmode
15170    && !TARGET_CMOVE"
15171   "#")
15173 (define_insn "*fp_jcc_5_387"
15174   [(set (pc)
15175         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15176                         [(match_operand 1 "register_operand" "f")
15177                          (match_operand 2 "register_operand" "f")])
15178           (label_ref (match_operand 3 "" ""))
15179           (pc)))
15180    (clobber (reg:CCFP FPSR_REG))
15181    (clobber (reg:CCFP FLAGS_REG))
15182    (clobber (match_scratch:HI 4 "=a"))]
15183   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15184    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15185    && !TARGET_CMOVE"
15186   "#")
15188 (define_insn "*fp_jcc_6_387"
15189   [(set (pc)
15190         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15191                         [(match_operand 1 "register_operand" "f")
15192                          (match_operand 2 "register_operand" "f")])
15193           (pc)
15194           (label_ref (match_operand 3 "" ""))))
15195    (clobber (reg:CCFP FPSR_REG))
15196    (clobber (reg:CCFP FLAGS_REG))
15197    (clobber (match_scratch:HI 4 "=a"))]
15198   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15199    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15200    && !TARGET_CMOVE"
15201   "#")
15203 (define_insn "*fp_jcc_7_387"
15204   [(set (pc)
15205         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15206                         [(match_operand 1 "register_operand" "f")
15207                          (match_operand 2 "const0_operand" "")])
15208           (label_ref (match_operand 3 "" ""))
15209           (pc)))
15210    (clobber (reg:CCFP FPSR_REG))
15211    (clobber (reg:CCFP FLAGS_REG))
15212    (clobber (match_scratch:HI 4 "=a"))]
15213   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15214    && GET_MODE (operands[1]) == GET_MODE (operands[2])
15215    && SELECT_CC_MODE (GET_CODE (operands[0]),
15216                       operands[1], operands[2]) == CCFPmode
15217    && !TARGET_CMOVE"
15218   "#")
15220 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
15221 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
15222 ;; with a precedence over other operators and is always put in the first
15223 ;; place. Swap condition and operands to match ficom instruction.
15225 (define_insn "*fp_jcc_8<mode>_387"
15226   [(set (pc)
15227         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15228                         [(match_operator 1 "float_operator"
15229                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
15230                            (match_operand 3 "register_operand" "f,f")])
15231           (label_ref (match_operand 4 "" ""))
15232           (pc)))
15233    (clobber (reg:CCFP FPSR_REG))
15234    (clobber (reg:CCFP FLAGS_REG))
15235    (clobber (match_scratch:HI 5 "=a,a"))]
15236   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
15237    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
15238    && GET_MODE (operands[1]) == GET_MODE (operands[3])
15239    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
15240    && !TARGET_CMOVE"
15241   "#")
15243 (define_split
15244   [(set (pc)
15245         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15246                         [(match_operand 1 "register_operand" "")
15247                          (match_operand 2 "nonimmediate_operand" "")])
15248           (match_operand 3 "" "")
15249           (match_operand 4 "" "")))
15250    (clobber (reg:CCFP FPSR_REG))
15251    (clobber (reg:CCFP FLAGS_REG))]
15252   "reload_completed"
15253   [(const_int 0)]
15255   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
15256                         operands[3], operands[4], NULL_RTX, NULL_RTX);
15257   DONE;
15260 (define_split
15261   [(set (pc)
15262         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15263                         [(match_operand 1 "register_operand" "")
15264                          (match_operand 2 "general_operand" "")])
15265           (match_operand 3 "" "")
15266           (match_operand 4 "" "")))
15267    (clobber (reg:CCFP FPSR_REG))
15268    (clobber (reg:CCFP FLAGS_REG))
15269    (clobber (match_scratch:HI 5 "=a"))]
15270   "reload_completed"
15271   [(const_int 0)]
15273   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
15274                         operands[3], operands[4], operands[5], NULL_RTX);
15275   DONE;
15278 (define_split
15279   [(set (pc)
15280         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15281                         [(match_operator 1 "float_operator"
15282                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
15283                            (match_operand 3 "register_operand" "")])
15284           (match_operand 4 "" "")
15285           (match_operand 5 "" "")))
15286    (clobber (reg:CCFP FPSR_REG))
15287    (clobber (reg:CCFP FLAGS_REG))
15288    (clobber (match_scratch:HI 6 "=a"))]
15289   "reload_completed"
15290   [(const_int 0)]
15292   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
15293   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
15294                         operands[3], operands[7],
15295                         operands[4], operands[5], operands[6], NULL_RTX);
15296   DONE;
15299 ;; %%% Kill this when reload knows how to do it.
15300 (define_split
15301   [(set (pc)
15302         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
15303                         [(match_operator 1 "float_operator"
15304                            [(match_operand:X87MODEI12 2 "register_operand" "")])
15305                            (match_operand 3 "register_operand" "")])
15306           (match_operand 4 "" "")
15307           (match_operand 5 "" "")))
15308    (clobber (reg:CCFP FPSR_REG))
15309    (clobber (reg:CCFP FLAGS_REG))
15310    (clobber (match_scratch:HI 6 "=a"))]
15311   "reload_completed"
15312   [(const_int 0)]
15314   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15315   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
15316   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
15317                         operands[3], operands[7],
15318                         operands[4], operands[5], operands[6], operands[2]);
15319   DONE;
15322 ;; Unconditional and other jump instructions
15324 (define_insn "jump"
15325   [(set (pc)
15326         (label_ref (match_operand 0 "" "")))]
15327   ""
15328   "jmp\t%l0"
15329   [(set_attr "type" "ibr")
15330    (set (attr "length")
15331            (if_then_else (and (ge (minus (match_dup 0) (pc))
15332                                   (const_int -126))
15333                               (lt (minus (match_dup 0) (pc))
15334                                   (const_int 128)))
15335              (const_int 2)
15336              (const_int 5)))
15337    (set_attr "modrm" "0")])
15339 (define_expand "indirect_jump"
15340   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
15341   ""
15342   "")
15344 (define_insn "*indirect_jump"
15345   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
15346   ""
15347   "jmp\t%A0"
15348   [(set_attr "type" "ibr")
15349    (set_attr "length_immediate" "0")])
15351 (define_expand "tablejump"
15352   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
15353               (use (label_ref (match_operand 1 "" "")))])]
15354   ""
15356   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
15357      relative.  Convert the relative address to an absolute address.  */
15358   if (flag_pic)
15359     {
15360       rtx op0, op1;
15361       enum rtx_code code;
15363       /* We can't use @GOTOFF for text labels on VxWorks;
15364          see gotoff_operand.  */
15365       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
15366         {
15367           code = PLUS;
15368           op0 = operands[0];
15369           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
15370         }
15371       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
15372         {
15373           code = PLUS;
15374           op0 = operands[0];
15375           op1 = pic_offset_table_rtx;
15376         }
15377       else
15378         {
15379           code = MINUS;
15380           op0 = pic_offset_table_rtx;
15381           op1 = operands[0];
15382         }
15384       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
15385                                          OPTAB_DIRECT);
15386     }
15389 (define_insn "*tablejump_1"
15390   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
15391    (use (label_ref (match_operand 1 "" "")))]
15392   ""
15393   "jmp\t%A0"
15394   [(set_attr "type" "ibr")
15395    (set_attr "length_immediate" "0")])
15397 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
15399 (define_peephole2
15400   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
15401    (set (match_operand:QI 1 "register_operand" "")
15402         (match_operator:QI 2 "ix86_comparison_operator"
15403           [(reg FLAGS_REG) (const_int 0)]))
15404    (set (match_operand 3 "q_regs_operand" "")
15405         (zero_extend (match_dup 1)))]
15406   "(peep2_reg_dead_p (3, operands[1])
15407     || operands_match_p (operands[1], operands[3]))
15408    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
15409   [(set (match_dup 4) (match_dup 0))
15410    (set (strict_low_part (match_dup 5))
15411         (match_dup 2))]
15413   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
15414   operands[5] = gen_lowpart (QImode, operands[3]);
15415   ix86_expand_clear (operands[3]);
15418 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
15420 (define_peephole2
15421   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
15422    (set (match_operand:QI 1 "register_operand" "")
15423         (match_operator:QI 2 "ix86_comparison_operator"
15424           [(reg FLAGS_REG) (const_int 0)]))
15425    (parallel [(set (match_operand 3 "q_regs_operand" "")
15426                    (zero_extend (match_dup 1)))
15427               (clobber (reg:CC FLAGS_REG))])]
15428   "(peep2_reg_dead_p (3, operands[1])
15429     || operands_match_p (operands[1], operands[3]))
15430    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
15431   [(set (match_dup 4) (match_dup 0))
15432    (set (strict_low_part (match_dup 5))
15433         (match_dup 2))]
15435   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
15436   operands[5] = gen_lowpart (QImode, operands[3]);
15437   ix86_expand_clear (operands[3]);
15440 ;; Call instructions.
15442 ;; The predicates normally associated with named expanders are not properly
15443 ;; checked for calls.  This is a bug in the generic code, but it isn't that
15444 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
15446 ;; Call subroutine returning no value.
15448 (define_expand "call_pop"
15449   [(parallel [(call (match_operand:QI 0 "" "")
15450                     (match_operand:SI 1 "" ""))
15451               (set (reg:SI SP_REG)
15452                    (plus:SI (reg:SI SP_REG)
15453                             (match_operand:SI 3 "" "")))])]
15454   "!TARGET_64BIT"
15456   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
15457   DONE;
15460 (define_insn "*call_pop_0"
15461   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
15462          (match_operand:SI 1 "" ""))
15463    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15464                             (match_operand:SI 2 "immediate_operand" "")))]
15465   "!TARGET_64BIT"
15467   if (SIBLING_CALL_P (insn))
15468     return "jmp\t%P0";
15469   else
15470     return "call\t%P0";
15472   [(set_attr "type" "call")])
15474 (define_insn "*call_pop_1"
15475   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15476          (match_operand:SI 1 "" ""))
15477    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15478                             (match_operand:SI 2 "immediate_operand" "i")))]
15479   "!TARGET_64BIT"
15481   if (constant_call_address_operand (operands[0], Pmode))
15482     {
15483       if (SIBLING_CALL_P (insn))
15484         return "jmp\t%P0";
15485       else
15486         return "call\t%P0";
15487     }
15488   if (SIBLING_CALL_P (insn))
15489     return "jmp\t%A0";
15490   else
15491     return "call\t%A0";
15493   [(set_attr "type" "call")])
15495 (define_expand "call"
15496   [(call (match_operand:QI 0 "" "")
15497          (match_operand 1 "" ""))
15498    (use (match_operand 2 "" ""))]
15499   ""
15501   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15502   DONE;
15505 (define_expand "sibcall"
15506   [(call (match_operand:QI 0 "" "")
15507          (match_operand 1 "" ""))
15508    (use (match_operand 2 "" ""))]
15509   ""
15511   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15512   DONE;
15515 (define_insn "*call_0"
15516   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15517          (match_operand 1 "" ""))]
15518   ""
15520   if (SIBLING_CALL_P (insn))
15521     return "jmp\t%P0";
15522   else
15523     return "call\t%P0";
15525   [(set_attr "type" "call")])
15527 (define_insn "*call_1"
15528   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15529          (match_operand 1 "" ""))]
15530   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15532   if (constant_call_address_operand (operands[0], Pmode))
15533     return "call\t%P0";
15534   return "call\t%A0";
15536   [(set_attr "type" "call")])
15538 (define_insn "*sibcall_1"
15539   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
15540          (match_operand 1 "" ""))]
15541   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15542   "@
15543    jmp\t%P0
15544    jmp\t%A0"
15545   [(set_attr "type" "call")])
15547 (define_insn "*call_1_rex64"
15548   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15549          (match_operand 1 "" ""))]
15550   "!SIBLING_CALL_P (insn) && TARGET_64BIT
15551    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15553   if (constant_call_address_operand (operands[0], Pmode))
15554     return "call\t%P0";
15555   return "call\t%A0";
15557   [(set_attr "type" "call")])
15559 (define_insn "*call_1_rex64_ms_sysv"
15560   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15561          (match_operand 1 "" ""))
15562    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15563    (clobber (reg:TI XMM6_REG))
15564    (clobber (reg:TI XMM7_REG))
15565    (clobber (reg:TI XMM8_REG))
15566    (clobber (reg:TI XMM9_REG))
15567    (clobber (reg:TI XMM10_REG))
15568    (clobber (reg:TI XMM11_REG))
15569    (clobber (reg:TI XMM12_REG))
15570    (clobber (reg:TI XMM13_REG))
15571    (clobber (reg:TI XMM14_REG))
15572    (clobber (reg:TI XMM15_REG))
15573    (clobber (reg:DI SI_REG))
15574    (clobber (reg:DI DI_REG))]
15575   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15577   if (constant_call_address_operand (operands[0], Pmode))
15578     return "call\t%P0";
15579   return "call\t%A0";
15581   [(set_attr "type" "call")])
15583 (define_insn "*call_1_rex64_large"
15584   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15585          (match_operand 1 "" ""))]
15586   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15587   "call\t%A0"
15588   [(set_attr "type" "call")])
15590 (define_insn "*sibcall_1_rex64"
15591   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
15592          (match_operand 1 "" ""))]
15593   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15594   "@
15595    jmp\t%P0
15596    jmp\t%A0"
15597   [(set_attr "type" "call")])
15599 ;; Call subroutine, returning value in operand 0
15600 (define_expand "call_value_pop"
15601   [(parallel [(set (match_operand 0 "" "")
15602                    (call (match_operand:QI 1 "" "")
15603                          (match_operand:SI 2 "" "")))
15604               (set (reg:SI SP_REG)
15605                    (plus:SI (reg:SI SP_REG)
15606                             (match_operand:SI 4 "" "")))])]
15607   "!TARGET_64BIT"
15609   ix86_expand_call (operands[0], operands[1], operands[2],
15610                     operands[3], operands[4], 0);
15611   DONE;
15614 (define_expand "call_value"
15615   [(set (match_operand 0 "" "")
15616         (call (match_operand:QI 1 "" "")
15617               (match_operand:SI 2 "" "")))
15618    (use (match_operand:SI 3 "" ""))]
15619   ;; Operand 2 not used on the i386.
15620   ""
15622   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15623   DONE;
15626 (define_expand "sibcall_value"
15627   [(set (match_operand 0 "" "")
15628         (call (match_operand:QI 1 "" "")
15629               (match_operand:SI 2 "" "")))
15630    (use (match_operand:SI 3 "" ""))]
15631   ;; Operand 2 not used on the i386.
15632   ""
15634   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15635   DONE;
15638 ;; Call subroutine returning any type.
15640 (define_expand "untyped_call"
15641   [(parallel [(call (match_operand 0 "" "")
15642                     (const_int 0))
15643               (match_operand 1 "" "")
15644               (match_operand 2 "" "")])]
15645   ""
15647   int i;
15649   /* In order to give reg-stack an easier job in validating two
15650      coprocessor registers as containing a possible return value,
15651      simply pretend the untyped call returns a complex long double
15652      value. 
15654      We can't use SSE_REGPARM_MAX here since callee is unprototyped
15655      and should have the default ABI.  */
15657   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15658                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15659                     operands[0], const0_rtx,
15660                     GEN_INT ((TARGET_64BIT
15661                               ? (ix86_abi == SYSV_ABI
15662                                  ? X86_64_SSE_REGPARM_MAX
15663                                  : X86_64_MS_SSE_REGPARM_MAX)
15664                               : X86_32_SSE_REGPARM_MAX)
15665                              - 1),
15666                     NULL, 0);
15668   for (i = 0; i < XVECLEN (operands[2], 0); i++)
15669     {
15670       rtx set = XVECEXP (operands[2], 0, i);
15671       emit_move_insn (SET_DEST (set), SET_SRC (set));
15672     }
15674   /* The optimizer does not know that the call sets the function value
15675      registers we stored in the result block.  We avoid problems by
15676      claiming that all hard registers are used and clobbered at this
15677      point.  */
15678   emit_insn (gen_blockage ());
15680   DONE;
15683 ;; Prologue and epilogue instructions
15685 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15686 ;; all of memory.  This blocks insns from being moved across this point.
15688 (define_insn "blockage"
15689   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15690   ""
15691   ""
15692   [(set_attr "length" "0")])
15694 ;; Do not schedule instructions accessing memory across this point.
15696 (define_expand "memory_blockage"
15697   [(set (match_dup 0)
15698         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15699   ""
15701   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15702   MEM_VOLATILE_P (operands[0]) = 1;
15705 (define_insn "*memory_blockage"
15706   [(set (match_operand:BLK 0 "" "")
15707         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15708   ""
15709   ""
15710   [(set_attr "length" "0")])
15712 ;; As USE insns aren't meaningful after reload, this is used instead
15713 ;; to prevent deleting instructions setting registers for PIC code
15714 (define_insn "prologue_use"
15715   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15716   ""
15717   ""
15718   [(set_attr "length" "0")])
15720 ;; Insn emitted into the body of a function to return from a function.
15721 ;; This is only done if the function's epilogue is known to be simple.
15722 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15724 (define_expand "return"
15725   [(return)]
15726   "ix86_can_use_return_insn_p ()"
15728   if (crtl->args.pops_args)
15729     {
15730       rtx popc = GEN_INT (crtl->args.pops_args);
15731       emit_jump_insn (gen_return_pop_internal (popc));
15732       DONE;
15733     }
15736 (define_insn "return_internal"
15737   [(return)]
15738   "reload_completed"
15739   "ret"
15740   [(set_attr "length" "1")
15741    (set_attr "atom_unit" "jeu")
15742    (set_attr "length_immediate" "0")
15743    (set_attr "modrm" "0")])
15745 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15746 ;; instruction Athlon and K8 have.
15748 (define_insn "return_internal_long"
15749   [(return)
15750    (unspec [(const_int 0)] UNSPEC_REP)]
15751   "reload_completed"
15752   "rep\;ret"
15753   [(set_attr "length" "2")
15754    (set_attr "atom_unit" "jeu")
15755    (set_attr "length_immediate" "0")
15756    (set_attr "prefix_rep" "1")
15757    (set_attr "modrm" "0")])
15759 (define_insn "return_pop_internal"
15760   [(return)
15761    (use (match_operand:SI 0 "const_int_operand" ""))]
15762   "reload_completed"
15763   "ret\t%0"
15764   [(set_attr "length" "3")
15765    (set_attr "atom_unit" "jeu")
15766    (set_attr "length_immediate" "2")
15767    (set_attr "modrm" "0")])
15769 (define_insn "return_indirect_internal"
15770   [(return)
15771    (use (match_operand:SI 0 "register_operand" "r"))]
15772   "reload_completed"
15773   "jmp\t%A0"
15774   [(set_attr "type" "ibr")
15775    (set_attr "length_immediate" "0")])
15777 (define_insn "nop"
15778   [(const_int 0)]
15779   ""
15780   "nop"
15781   [(set_attr "length" "1")
15782    (set_attr "length_immediate" "0")
15783    (set_attr "modrm" "0")])
15785 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
15786 ;; branch prediction penalty for the third jump in a 16-byte
15787 ;; block on K8.
15789 (define_insn "pad"
15790   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15791   ""
15793 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
15794   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
15795 #else
15796   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15797      The align insn is used to avoid 3 jump instructions in the row to improve
15798      branch prediction and the benefits hardly outweigh the cost of extra 8
15799      nops on the average inserted by full alignment pseudo operation.  */
15800 #endif
15801   return "";
15803   [(set_attr "length" "16")])
15805 (define_expand "prologue"
15806   [(const_int 0)]
15807   ""
15808   "ix86_expand_prologue (); DONE;")
15810 (define_insn "set_got"
15811   [(set (match_operand:SI 0 "register_operand" "=r")
15812         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15813    (clobber (reg:CC FLAGS_REG))]
15814   "!TARGET_64BIT"
15815   { return output_set_got (operands[0], NULL_RTX); }
15816   [(set_attr "type" "multi")
15817    (set_attr "length" "12")])
15819 (define_insn "set_got_labelled"
15820   [(set (match_operand:SI 0 "register_operand" "=r")
15821         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15822          UNSPEC_SET_GOT))
15823    (clobber (reg:CC FLAGS_REG))]
15824   "!TARGET_64BIT"
15825   { return output_set_got (operands[0], operands[1]); }
15826   [(set_attr "type" "multi")
15827    (set_attr "length" "12")])
15829 (define_insn "set_got_rex64"
15830   [(set (match_operand:DI 0 "register_operand" "=r")
15831         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15832   "TARGET_64BIT"
15833   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15834   [(set_attr "type" "lea")
15835    (set_attr "length_address" "4")
15836    (set_attr "mode" "DI")])
15838 (define_insn "set_rip_rex64"
15839   [(set (match_operand:DI 0 "register_operand" "=r")
15840         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15841   "TARGET_64BIT"
15842   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15843   [(set_attr "type" "lea")
15844    (set_attr "length_address" "4")
15845    (set_attr "mode" "DI")])
15847 (define_insn "set_got_offset_rex64"
15848   [(set (match_operand:DI 0 "register_operand" "=r")
15849         (unspec:DI
15850           [(label_ref (match_operand 1 "" ""))]
15851           UNSPEC_SET_GOT_OFFSET))]
15852   "TARGET_64BIT"
15853   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15854   [(set_attr "type" "imov")
15855    (set_attr "length_immediate" "0")
15856    (set_attr "length_address" "8")
15857    (set_attr "mode" "DI")])
15859 (define_expand "epilogue"
15860   [(const_int 0)]
15861   ""
15862   "ix86_expand_epilogue (1); DONE;")
15864 (define_expand "sibcall_epilogue"
15865   [(const_int 0)]
15866   ""
15867   "ix86_expand_epilogue (0); DONE;")
15869 (define_expand "eh_return"
15870   [(use (match_operand 0 "register_operand" ""))]
15871   ""
15873   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15875   /* Tricky bit: we write the address of the handler to which we will
15876      be returning into someone else's stack frame, one word below the
15877      stack address we wish to restore.  */
15878   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15879   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15880   tmp = gen_rtx_MEM (Pmode, tmp);
15881   emit_move_insn (tmp, ra);
15883   emit_jump_insn (gen_eh_return_internal ());
15884   emit_barrier ();
15885   DONE;
15888 (define_insn_and_split "eh_return_internal"
15889   [(eh_return)]
15890   ""
15891   "#"
15892   "epilogue_completed"
15893   [(const_int 0)]
15894   "ix86_expand_epilogue (2); DONE;")
15896 (define_insn "leave"
15897   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15898    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15899    (clobber (mem:BLK (scratch)))]
15900   "!TARGET_64BIT"
15901   "leave"
15902   [(set_attr "type" "leave")])
15904 (define_insn "leave_rex64"
15905   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15906    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15907    (clobber (mem:BLK (scratch)))]
15908   "TARGET_64BIT"
15909   "leave"
15910   [(set_attr "type" "leave")])
15912 (define_expand "ffssi2"
15913   [(parallel
15914      [(set (match_operand:SI 0 "register_operand" "")
15915            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15916       (clobber (match_scratch:SI 2 ""))
15917       (clobber (reg:CC FLAGS_REG))])]
15918   ""
15920   if (TARGET_CMOVE)
15921     {
15922       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15923       DONE;
15924     }
15927 (define_expand "ffs_cmove"
15928   [(set (match_dup 2) (const_int -1))
15929    (parallel [(set (reg:CCZ FLAGS_REG)
15930                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15931                                 (const_int 0)))
15932               (set (match_operand:SI 0 "register_operand" "")
15933                    (ctz:SI (match_dup 1)))])
15934    (set (match_dup 0) (if_then_else:SI
15935                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15936                         (match_dup 2)
15937                         (match_dup 0)))
15938    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15939               (clobber (reg:CC FLAGS_REG))])]
15940   "TARGET_CMOVE"
15941   "operands[2] = gen_reg_rtx (SImode);")
15943 (define_insn_and_split "*ffs_no_cmove"
15944   [(set (match_operand:SI 0 "register_operand" "=r")
15945         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15946    (clobber (match_scratch:SI 2 "=&q"))
15947    (clobber (reg:CC FLAGS_REG))]
15948   "!TARGET_CMOVE"
15949   "#"
15950   "&& reload_completed"
15951   [(parallel [(set (reg:CCZ FLAGS_REG)
15952                    (compare:CCZ (match_dup 1) (const_int 0)))
15953               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15954    (set (strict_low_part (match_dup 3))
15955         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15956    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15957               (clobber (reg:CC FLAGS_REG))])
15958    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15959               (clobber (reg:CC FLAGS_REG))])
15960    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15961               (clobber (reg:CC FLAGS_REG))])]
15963   operands[3] = gen_lowpart (QImode, operands[2]);
15964   ix86_expand_clear (operands[2]);
15967 (define_insn "*ffssi_1"
15968   [(set (reg:CCZ FLAGS_REG)
15969         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15970                      (const_int 0)))
15971    (set (match_operand:SI 0 "register_operand" "=r")
15972         (ctz:SI (match_dup 1)))]
15973   ""
15974   "bsf{l}\t{%1, %0|%0, %1}"
15975   [(set_attr "type" "alu1")
15976    (set_attr "prefix_0f" "1")
15977    (set_attr "mode" "SI")])
15979 (define_expand "ffsdi2"
15980   [(set (match_dup 2) (const_int -1))
15981    (parallel [(set (reg:CCZ FLAGS_REG)
15982                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15983                                 (const_int 0)))
15984               (set (match_operand:DI 0 "register_operand" "")
15985                    (ctz:DI (match_dup 1)))])
15986    (set (match_dup 0) (if_then_else:DI
15987                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15988                         (match_dup 2)
15989                         (match_dup 0)))
15990    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15991               (clobber (reg:CC FLAGS_REG))])]
15992   "TARGET_64BIT"
15993   "operands[2] = gen_reg_rtx (DImode);")
15995 (define_insn "*ffsdi_1"
15996   [(set (reg:CCZ FLAGS_REG)
15997         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15998                      (const_int 0)))
15999    (set (match_operand:DI 0 "register_operand" "=r")
16000         (ctz:DI (match_dup 1)))]
16001   "TARGET_64BIT"
16002   "bsf{q}\t{%1, %0|%0, %1}"
16003   [(set_attr "type" "alu1")
16004    (set_attr "prefix_0f" "1")
16005    (set_attr "mode" "DI")])
16007 (define_insn "ctzsi2"
16008   [(set (match_operand:SI 0 "register_operand" "=r")
16009         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
16010    (clobber (reg:CC FLAGS_REG))]
16011   ""
16012   "bsf{l}\t{%1, %0|%0, %1}"
16013   [(set_attr "type" "alu1")
16014    (set_attr "prefix_0f" "1")
16015    (set_attr "mode" "SI")])
16017 (define_insn "ctzdi2"
16018   [(set (match_operand:DI 0 "register_operand" "=r")
16019         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
16020    (clobber (reg:CC FLAGS_REG))]
16021   "TARGET_64BIT"
16022   "bsf{q}\t{%1, %0|%0, %1}"
16023   [(set_attr "type" "alu1")
16024    (set_attr "prefix_0f" "1")
16025    (set_attr "mode" "DI")])
16027 (define_expand "clzsi2"
16028   [(parallel
16029      [(set (match_operand:SI 0 "register_operand" "")
16030            (minus:SI (const_int 31)
16031                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
16032       (clobber (reg:CC FLAGS_REG))])
16033    (parallel
16034      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
16035       (clobber (reg:CC FLAGS_REG))])]
16036   ""
16038   if (TARGET_ABM)
16039     {
16040       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
16041       DONE;
16042     }
16045 (define_insn "clzsi2_abm"
16046   [(set (match_operand:SI 0 "register_operand" "=r")
16047         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
16048    (clobber (reg:CC FLAGS_REG))]
16049   "TARGET_ABM"
16050   "lzcnt{l}\t{%1, %0|%0, %1}"
16051   [(set_attr "prefix_rep" "1")
16052    (set_attr "type" "bitmanip")
16053    (set_attr "mode" "SI")])
16055 (define_insn "bsr"
16056   [(set (match_operand:SI 0 "register_operand" "=r")
16057         (minus:SI (const_int 31)
16058                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
16059    (clobber (reg:CC FLAGS_REG))]
16060   ""
16061   "bsr{l}\t{%1, %0|%0, %1}"
16062   [(set_attr "type" "alu1")
16063    (set_attr "prefix_0f" "1")
16064    (set_attr "mode" "SI")])
16066 (define_insn "popcount<mode>2"
16067   [(set (match_operand:SWI248 0 "register_operand" "=r")
16068         (popcount:SWI248
16069           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
16070    (clobber (reg:CC FLAGS_REG))]
16071   "TARGET_POPCNT"
16073 #if TARGET_MACHO
16074   return "popcnt\t{%1, %0|%0, %1}";
16075 #else
16076   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16077 #endif
16079   [(set_attr "prefix_rep" "1")
16080    (set_attr "type" "bitmanip")
16081    (set_attr "mode" "<MODE>")])
16083 (define_insn "*popcount<mode>2_cmp"
16084   [(set (reg FLAGS_REG)
16085         (compare
16086           (popcount:SWI248
16087             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
16088           (const_int 0)))
16089    (set (match_operand:SWI248 0 "register_operand" "=r")
16090         (popcount:SWI248 (match_dup 1)))]
16091   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
16093 #if TARGET_MACHO
16094   return "popcnt\t{%1, %0|%0, %1}";
16095 #else
16096   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16097 #endif
16099   [(set_attr "prefix_rep" "1")
16100    (set_attr "type" "bitmanip")
16101    (set_attr "mode" "<MODE>")])
16103 (define_insn "*popcountsi2_cmp_zext"
16104   [(set (reg FLAGS_REG)
16105         (compare
16106           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
16107           (const_int 0)))
16108    (set (match_operand:DI 0 "register_operand" "=r")
16109         (zero_extend:DI(popcount:SI (match_dup 1))))]
16110   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
16112 #if TARGET_MACHO
16113   return "popcnt\t{%1, %0|%0, %1}";
16114 #else
16115   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16116 #endif
16118   [(set_attr "prefix_rep" "1")
16119    (set_attr "type" "bitmanip")
16120    (set_attr "mode" "SI")])
16122 (define_expand "bswapsi2"
16123   [(set (match_operand:SI 0 "register_operand" "")
16124         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
16125   ""
16127   if (!(TARGET_BSWAP || TARGET_MOVBE))
16128     {
16129       rtx x = operands[0];
16131       emit_move_insn (x, operands[1]);
16132       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
16133       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
16134       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
16135       DONE;
16136     }
16139 (define_insn "*bswapsi_movbe"
16140   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
16141         (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
16142   "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
16143   "@
16144     bswap\t%0
16145     movbe\t{%1, %0|%0, %1}
16146     movbe\t{%1, %0|%0, %1}"
16147   [(set_attr "type" "*,imov,imov")
16148    (set_attr "modrm" "*,1,1")
16149    (set_attr "prefix_0f" "1")
16150    (set_attr "prefix_extra" "*,1,1")
16151    (set_attr "length" "2,*,*")
16152    (set_attr "mode" "SI")])
16154 (define_insn "*bswapsi_1"
16155   [(set (match_operand:SI 0 "register_operand" "=r")
16156         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
16157   "TARGET_BSWAP"
16158   "bswap\t%0"
16159   [(set_attr "prefix_0f" "1")
16160    (set_attr "length" "2")])
16162 (define_insn "*bswaphi_lowpart_1"
16163   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
16164         (bswap:HI (match_dup 0)))
16165    (clobber (reg:CC FLAGS_REG))]
16166   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
16167   "@
16168     xchg{b}\t{%h0, %b0|%b0, %h0}
16169     rol{w}\t{$8, %0|%0, 8}"
16170   [(set_attr "length" "2,4")
16171    (set_attr "mode" "QI,HI")])
16173 (define_insn "bswaphi_lowpart"
16174   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
16175         (bswap:HI (match_dup 0)))
16176    (clobber (reg:CC FLAGS_REG))]
16177   ""
16178   "rol{w}\t{$8, %0|%0, 8}"
16179   [(set_attr "length" "4")
16180    (set_attr "mode" "HI")])
16182 (define_expand "bswapdi2"
16183   [(set (match_operand:DI 0 "register_operand" "")
16184         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
16185   "TARGET_64BIT"
16186   "")
16188 (define_insn "*bswapdi_movbe"
16189   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
16190         (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
16191   "TARGET_64BIT && TARGET_MOVBE
16192    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
16193   "@
16194     bswap\t%0
16195     movbe\t{%1, %0|%0, %1}
16196     movbe\t{%1, %0|%0, %1}"
16197   [(set_attr "type" "*,imov,imov")
16198    (set_attr "modrm" "*,1,1")
16199    (set_attr "prefix_0f" "1")
16200    (set_attr "prefix_extra" "*,1,1")
16201    (set_attr "length" "3,*,*")
16202    (set_attr "mode" "DI")])
16204 (define_insn "*bswapdi_1"
16205   [(set (match_operand:DI 0 "register_operand" "=r")
16206         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
16207   "TARGET_64BIT"
16208   "bswap\t%0"
16209   [(set_attr "prefix_0f" "1")
16210    (set_attr "length" "3")])
16212 (define_expand "clzdi2"
16213   [(parallel
16214      [(set (match_operand:DI 0 "register_operand" "")
16215            (minus:DI (const_int 63)
16216                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
16217       (clobber (reg:CC FLAGS_REG))])
16218    (parallel
16219      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
16220       (clobber (reg:CC FLAGS_REG))])]
16221   "TARGET_64BIT"
16223   if (TARGET_ABM)
16224     {
16225       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
16226       DONE;
16227     }
16230 (define_insn "clzdi2_abm"
16231   [(set (match_operand:DI 0 "register_operand" "=r")
16232         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
16233    (clobber (reg:CC FLAGS_REG))]
16234   "TARGET_64BIT && TARGET_ABM"
16235   "lzcnt{q}\t{%1, %0|%0, %1}"
16236   [(set_attr "prefix_rep" "1")
16237    (set_attr "type" "bitmanip")
16238    (set_attr "mode" "DI")])
16240 (define_insn "bsr_rex64"
16241   [(set (match_operand:DI 0 "register_operand" "=r")
16242         (minus:DI (const_int 63)
16243                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
16244    (clobber (reg:CC FLAGS_REG))]
16245   "TARGET_64BIT"
16246   "bsr{q}\t{%1, %0|%0, %1}"
16247   [(set_attr "type" "alu1")
16248    (set_attr "prefix_0f" "1")
16249    (set_attr "mode" "DI")])
16251 (define_expand "clzhi2"
16252   [(parallel
16253      [(set (match_operand:HI 0 "register_operand" "")
16254            (minus:HI (const_int 15)
16255                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
16256       (clobber (reg:CC FLAGS_REG))])
16257    (parallel
16258      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
16259       (clobber (reg:CC FLAGS_REG))])]
16260   ""
16262   if (TARGET_ABM)
16263     {
16264       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
16265       DONE;
16266     }
16269 (define_insn "clzhi2_abm"
16270   [(set (match_operand:HI 0 "register_operand" "=r")
16271         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
16272    (clobber (reg:CC FLAGS_REG))]
16273   "TARGET_ABM"
16274   "lzcnt{w}\t{%1, %0|%0, %1}"
16275   [(set_attr "prefix_rep" "1")
16276    (set_attr "type" "bitmanip")
16277    (set_attr "mode" "HI")])
16279 (define_insn "*bsrhi"
16280   [(set (match_operand:HI 0 "register_operand" "=r")
16281         (minus:HI (const_int 15)
16282                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
16283    (clobber (reg:CC FLAGS_REG))]
16284   ""
16285   "bsr{w}\t{%1, %0|%0, %1}"
16286   [(set_attr "type" "alu1")
16287    (set_attr "prefix_0f" "1")
16288    (set_attr "mode" "HI")])
16290 (define_expand "paritydi2"
16291   [(set (match_operand:DI 0 "register_operand" "")
16292         (parity:DI (match_operand:DI 1 "register_operand" "")))]
16293   "! TARGET_POPCNT"
16295   rtx scratch = gen_reg_rtx (QImode);
16296   rtx cond;
16298   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
16299                                 NULL_RTX, operands[1]));
16301   cond = gen_rtx_fmt_ee (ORDERED, QImode,
16302                          gen_rtx_REG (CCmode, FLAGS_REG),
16303                          const0_rtx);
16304   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
16306   if (TARGET_64BIT)
16307     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
16308   else
16309     {
16310       rtx tmp = gen_reg_rtx (SImode);
16312       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
16313       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
16314     }
16315   DONE;
16318 (define_insn_and_split "paritydi2_cmp"
16319   [(set (reg:CC FLAGS_REG)
16320         (parity:CC (match_operand:DI 3 "register_operand" "0")))
16321    (clobber (match_scratch:DI 0 "=r"))
16322    (clobber (match_scratch:SI 1 "=&r"))
16323    (clobber (match_scratch:HI 2 "=Q"))]
16324   "! TARGET_POPCNT"
16325   "#"
16326   "&& reload_completed"
16327   [(parallel
16328      [(set (match_dup 1)
16329            (xor:SI (match_dup 1) (match_dup 4)))
16330       (clobber (reg:CC FLAGS_REG))])
16331    (parallel
16332      [(set (reg:CC FLAGS_REG)
16333            (parity:CC (match_dup 1)))
16334       (clobber (match_dup 1))
16335       (clobber (match_dup 2))])]
16337   operands[4] = gen_lowpart (SImode, operands[3]);
16339   if (TARGET_64BIT)
16340     {
16341       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
16342       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
16343     }
16344   else
16345     operands[1] = gen_highpart (SImode, operands[3]);
16348 (define_expand "paritysi2"
16349   [(set (match_operand:SI 0 "register_operand" "")
16350         (parity:SI (match_operand:SI 1 "register_operand" "")))]
16351   "! TARGET_POPCNT"
16353   rtx scratch = gen_reg_rtx (QImode);
16354   rtx cond;
16356   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
16358   cond = gen_rtx_fmt_ee (ORDERED, QImode,
16359                          gen_rtx_REG (CCmode, FLAGS_REG),
16360                          const0_rtx);
16361   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
16363   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16364   DONE;
16367 (define_insn_and_split "paritysi2_cmp"
16368   [(set (reg:CC FLAGS_REG)
16369         (parity:CC (match_operand:SI 2 "register_operand" "0")))
16370    (clobber (match_scratch:SI 0 "=r"))
16371    (clobber (match_scratch:HI 1 "=&Q"))]
16372   "! TARGET_POPCNT"
16373   "#"
16374   "&& reload_completed"
16375   [(parallel
16376      [(set (match_dup 1)
16377            (xor:HI (match_dup 1) (match_dup 3)))
16378       (clobber (reg:CC FLAGS_REG))])
16379    (parallel
16380      [(set (reg:CC FLAGS_REG)
16381            (parity:CC (match_dup 1)))
16382       (clobber (match_dup 1))])]
16384   operands[3] = gen_lowpart (HImode, operands[2]);
16386   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
16387   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
16390 (define_insn "*parityhi2_cmp"
16391   [(set (reg:CC FLAGS_REG)
16392         (parity:CC (match_operand:HI 1 "register_operand" "0")))
16393    (clobber (match_scratch:HI 0 "=Q"))]
16394   "! TARGET_POPCNT"
16395   "xor{b}\t{%h0, %b0|%b0, %h0}"
16396   [(set_attr "length" "2")
16397    (set_attr "mode" "HI")])
16399 (define_insn "*parityqi2_cmp"
16400   [(set (reg:CC FLAGS_REG)
16401         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
16402   "! TARGET_POPCNT"
16403   "test{b}\t%0, %0"
16404   [(set_attr "length" "2")
16405    (set_attr "mode" "QI")])
16407 ;; Thread-local storage patterns for ELF.
16409 ;; Note that these code sequences must appear exactly as shown
16410 ;; in order to allow linker relaxation.
16412 (define_insn "*tls_global_dynamic_32_gnu"
16413   [(set (match_operand:SI 0 "register_operand" "=a")
16414         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16415                     (match_operand:SI 2 "tls_symbolic_operand" "")
16416                     (match_operand:SI 3 "call_insn_operand" "")]
16417                     UNSPEC_TLS_GD))
16418    (clobber (match_scratch:SI 4 "=d"))
16419    (clobber (match_scratch:SI 5 "=c"))
16420    (clobber (reg:CC FLAGS_REG))]
16421   "!TARGET_64BIT && TARGET_GNU_TLS"
16422   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
16423   [(set_attr "type" "multi")
16424    (set_attr "length" "12")])
16426 (define_insn "*tls_global_dynamic_32_sun"
16427   [(set (match_operand:SI 0 "register_operand" "=a")
16428         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16429                     (match_operand:SI 2 "tls_symbolic_operand" "")
16430                     (match_operand:SI 3 "call_insn_operand" "")]
16431                     UNSPEC_TLS_GD))
16432    (clobber (match_scratch:SI 4 "=d"))
16433    (clobber (match_scratch:SI 5 "=c"))
16434    (clobber (reg:CC FLAGS_REG))]
16435   "!TARGET_64BIT && TARGET_SUN_TLS"
16436   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
16437         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
16438   [(set_attr "type" "multi")
16439    (set_attr "length" "14")])
16441 (define_expand "tls_global_dynamic_32"
16442   [(parallel [(set (match_operand:SI 0 "register_operand" "")
16443                    (unspec:SI
16444                     [(match_dup 2)
16445                      (match_operand:SI 1 "tls_symbolic_operand" "")
16446                      (match_dup 3)]
16447                     UNSPEC_TLS_GD))
16448               (clobber (match_scratch:SI 4 ""))
16449               (clobber (match_scratch:SI 5 ""))
16450               (clobber (reg:CC FLAGS_REG))])]
16451   ""
16453   if (flag_pic)
16454     operands[2] = pic_offset_table_rtx;
16455   else
16456     {
16457       operands[2] = gen_reg_rtx (Pmode);
16458       emit_insn (gen_set_got (operands[2]));
16459     }
16460   if (TARGET_GNU2_TLS)
16461     {
16462        emit_insn (gen_tls_dynamic_gnu2_32
16463                   (operands[0], operands[1], operands[2]));
16464        DONE;
16465     }
16466   operands[3] = ix86_tls_get_addr ();
16469 (define_insn "*tls_global_dynamic_64"
16470   [(set (match_operand:DI 0 "register_operand" "=a")
16471         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
16472                  (match_operand:DI 3 "" "")))
16473    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16474               UNSPEC_TLS_GD)]
16475   "TARGET_64BIT"
16476   { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
16477   [(set_attr "type" "multi")
16478    (set_attr "length" "16")])
16480 (define_expand "tls_global_dynamic_64"
16481   [(parallel [(set (match_operand:DI 0 "register_operand" "")
16482                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
16483               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16484                          UNSPEC_TLS_GD)])]
16485   ""
16487   if (TARGET_GNU2_TLS)
16488     {
16489        emit_insn (gen_tls_dynamic_gnu2_64
16490                   (operands[0], operands[1]));
16491        DONE;
16492     }
16493   operands[2] = ix86_tls_get_addr ();
16496 (define_insn "*tls_local_dynamic_base_32_gnu"
16497   [(set (match_operand:SI 0 "register_operand" "=a")
16498         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16499                     (match_operand:SI 2 "call_insn_operand" "")]
16500                    UNSPEC_TLS_LD_BASE))
16501    (clobber (match_scratch:SI 3 "=d"))
16502    (clobber (match_scratch:SI 4 "=c"))
16503    (clobber (reg:CC FLAGS_REG))]
16504   "!TARGET_64BIT && TARGET_GNU_TLS"
16505   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
16506   [(set_attr "type" "multi")
16507    (set_attr "length" "11")])
16509 (define_insn "*tls_local_dynamic_base_32_sun"
16510   [(set (match_operand:SI 0 "register_operand" "=a")
16511         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16512                     (match_operand:SI 2 "call_insn_operand" "")]
16513                    UNSPEC_TLS_LD_BASE))
16514    (clobber (match_scratch:SI 3 "=d"))
16515    (clobber (match_scratch:SI 4 "=c"))
16516    (clobber (reg:CC FLAGS_REG))]
16517   "!TARGET_64BIT && TARGET_SUN_TLS"
16518   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
16519         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
16520   [(set_attr "type" "multi")
16521    (set_attr "length" "13")])
16523 (define_expand "tls_local_dynamic_base_32"
16524   [(parallel [(set (match_operand:SI 0 "register_operand" "")
16525                    (unspec:SI [(match_dup 1) (match_dup 2)]
16526                               UNSPEC_TLS_LD_BASE))
16527               (clobber (match_scratch:SI 3 ""))
16528               (clobber (match_scratch:SI 4 ""))
16529               (clobber (reg:CC FLAGS_REG))])]
16530   ""
16532   if (flag_pic)
16533     operands[1] = pic_offset_table_rtx;
16534   else
16535     {
16536       operands[1] = gen_reg_rtx (Pmode);
16537       emit_insn (gen_set_got (operands[1]));
16538     }
16539   if (TARGET_GNU2_TLS)
16540     {
16541        emit_insn (gen_tls_dynamic_gnu2_32
16542                   (operands[0], ix86_tls_module_base (), operands[1]));
16543        DONE;
16544     }
16545   operands[2] = ix86_tls_get_addr ();
16548 (define_insn "*tls_local_dynamic_base_64"
16549   [(set (match_operand:DI 0 "register_operand" "=a")
16550         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
16551                  (match_operand:DI 2 "" "")))
16552    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16553   "TARGET_64BIT"
16554   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16555   [(set_attr "type" "multi")
16556    (set_attr "length" "12")])
16558 (define_expand "tls_local_dynamic_base_64"
16559   [(parallel [(set (match_operand:DI 0 "register_operand" "")
16560                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16561               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16562   ""
16564   if (TARGET_GNU2_TLS)
16565     {
16566        emit_insn (gen_tls_dynamic_gnu2_64
16567                   (operands[0], ix86_tls_module_base ()));
16568        DONE;
16569     }
16570   operands[1] = ix86_tls_get_addr ();
16573 ;; Local dynamic of a single variable is a lose.  Show combine how
16574 ;; to convert that back to global dynamic.
16576 (define_insn_and_split "*tls_local_dynamic_32_once"
16577   [(set (match_operand:SI 0 "register_operand" "=a")
16578         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16579                              (match_operand:SI 2 "call_insn_operand" "")]
16580                             UNSPEC_TLS_LD_BASE)
16581                  (const:SI (unspec:SI
16582                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
16583                             UNSPEC_DTPOFF))))
16584    (clobber (match_scratch:SI 4 "=d"))
16585    (clobber (match_scratch:SI 5 "=c"))
16586    (clobber (reg:CC FLAGS_REG))]
16587   ""
16588   "#"
16589   ""
16590   [(parallel [(set (match_dup 0)
16591                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16592                               UNSPEC_TLS_GD))
16593               (clobber (match_dup 4))
16594               (clobber (match_dup 5))
16595               (clobber (reg:CC FLAGS_REG))])]
16596   "")
16598 ;; Load and add the thread base pointer from %gs:0.
16600 (define_insn "*load_tp_si"
16601   [(set (match_operand:SI 0 "register_operand" "=r")
16602         (unspec:SI [(const_int 0)] UNSPEC_TP))]
16603   "!TARGET_64BIT"
16604   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16605   [(set_attr "type" "imov")
16606    (set_attr "modrm" "0")
16607    (set_attr "length" "7")
16608    (set_attr "memory" "load")
16609    (set_attr "imm_disp" "false")])
16611 (define_insn "*add_tp_si"
16612   [(set (match_operand:SI 0 "register_operand" "=r")
16613         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16614                  (match_operand:SI 1 "register_operand" "0")))
16615    (clobber (reg:CC FLAGS_REG))]
16616   "!TARGET_64BIT"
16617   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16618   [(set_attr "type" "alu")
16619    (set_attr "modrm" "0")
16620    (set_attr "length" "7")
16621    (set_attr "memory" "load")
16622    (set_attr "imm_disp" "false")])
16624 (define_insn "*load_tp_di"
16625   [(set (match_operand:DI 0 "register_operand" "=r")
16626         (unspec:DI [(const_int 0)] UNSPEC_TP))]
16627   "TARGET_64BIT"
16628   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16629   [(set_attr "type" "imov")
16630    (set_attr "modrm" "0")
16631    (set_attr "length" "7")
16632    (set_attr "memory" "load")
16633    (set_attr "imm_disp" "false")])
16635 (define_insn "*add_tp_di"
16636   [(set (match_operand:DI 0 "register_operand" "=r")
16637         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16638                  (match_operand:DI 1 "register_operand" "0")))
16639    (clobber (reg:CC FLAGS_REG))]
16640   "TARGET_64BIT"
16641   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16642   [(set_attr "type" "alu")
16643    (set_attr "modrm" "0")
16644    (set_attr "length" "7")
16645    (set_attr "memory" "load")
16646    (set_attr "imm_disp" "false")])
16648 ;; GNU2 TLS patterns can be split.
16650 (define_expand "tls_dynamic_gnu2_32"
16651   [(set (match_dup 3)
16652         (plus:SI (match_operand:SI 2 "register_operand" "")
16653                  (const:SI
16654                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16655                              UNSPEC_TLSDESC))))
16656    (parallel
16657     [(set (match_operand:SI 0 "register_operand" "")
16658           (unspec:SI [(match_dup 1) (match_dup 3)
16659                       (match_dup 2) (reg:SI SP_REG)]
16660                       UNSPEC_TLSDESC))
16661      (clobber (reg:CC FLAGS_REG))])]
16662   "!TARGET_64BIT && TARGET_GNU2_TLS"
16664   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
16665   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16668 (define_insn "*tls_dynamic_lea_32"
16669   [(set (match_operand:SI 0 "register_operand" "=r")
16670         (plus:SI (match_operand:SI 1 "register_operand" "b")
16671                  (const:SI
16672                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16673                               UNSPEC_TLSDESC))))]
16674   "!TARGET_64BIT && TARGET_GNU2_TLS"
16675   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16676   [(set_attr "type" "lea")
16677    (set_attr "mode" "SI")
16678    (set_attr "length" "6")
16679    (set_attr "length_address" "4")])
16681 (define_insn "*tls_dynamic_call_32"
16682   [(set (match_operand:SI 0 "register_operand" "=a")
16683         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16684                     (match_operand:SI 2 "register_operand" "0")
16685                     ;; we have to make sure %ebx still points to the GOT
16686                     (match_operand:SI 3 "register_operand" "b")
16687                     (reg:SI SP_REG)]
16688                    UNSPEC_TLSDESC))
16689    (clobber (reg:CC FLAGS_REG))]
16690   "!TARGET_64BIT && TARGET_GNU2_TLS"
16691   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16692   [(set_attr "type" "call")
16693    (set_attr "length" "2")
16694    (set_attr "length_address" "0")])
16696 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16697   [(set (match_operand:SI 0 "register_operand" "=&a")
16698         (plus:SI
16699          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16700                      (match_operand:SI 4 "" "")
16701                      (match_operand:SI 2 "register_operand" "b")
16702                      (reg:SI SP_REG)]
16703                     UNSPEC_TLSDESC)
16704          (const:SI (unspec:SI
16705                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
16706                     UNSPEC_DTPOFF))))
16707    (clobber (reg:CC FLAGS_REG))]
16708   "!TARGET_64BIT && TARGET_GNU2_TLS"
16709   "#"
16710   ""
16711   [(set (match_dup 0) (match_dup 5))]
16713   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
16714   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16717 (define_expand "tls_dynamic_gnu2_64"
16718   [(set (match_dup 2)
16719         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16720                    UNSPEC_TLSDESC))
16721    (parallel
16722     [(set (match_operand:DI 0 "register_operand" "")
16723           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16724                      UNSPEC_TLSDESC))
16725      (clobber (reg:CC FLAGS_REG))])]
16726   "TARGET_64BIT && TARGET_GNU2_TLS"
16728   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
16729   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16732 (define_insn "*tls_dynamic_lea_64"
16733   [(set (match_operand:DI 0 "register_operand" "=r")
16734         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16735                    UNSPEC_TLSDESC))]
16736   "TARGET_64BIT && TARGET_GNU2_TLS"
16737   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16738   [(set_attr "type" "lea")
16739    (set_attr "mode" "DI")
16740    (set_attr "length" "7")
16741    (set_attr "length_address" "4")])
16743 (define_insn "*tls_dynamic_call_64"
16744   [(set (match_operand:DI 0 "register_operand" "=a")
16745         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16746                     (match_operand:DI 2 "register_operand" "0")
16747                     (reg:DI SP_REG)]
16748                    UNSPEC_TLSDESC))
16749    (clobber (reg:CC FLAGS_REG))]
16750   "TARGET_64BIT && TARGET_GNU2_TLS"
16751   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16752   [(set_attr "type" "call")
16753    (set_attr "length" "2")
16754    (set_attr "length_address" "0")])
16756 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16757   [(set (match_operand:DI 0 "register_operand" "=&a")
16758         (plus:DI
16759          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16760                      (match_operand:DI 3 "" "")
16761                      (reg:DI SP_REG)]
16762                     UNSPEC_TLSDESC)
16763          (const:DI (unspec:DI
16764                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16765                     UNSPEC_DTPOFF))))
16766    (clobber (reg:CC FLAGS_REG))]
16767   "TARGET_64BIT && TARGET_GNU2_TLS"
16768   "#"
16769   ""
16770   [(set (match_dup 0) (match_dup 4))]
16772   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
16773   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16778 ;; These patterns match the binary 387 instructions for addM3, subM3,
16779 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16780 ;; SFmode.  The first is the normal insn, the second the same insn but
16781 ;; with one operand a conversion, and the third the same insn but with
16782 ;; the other operand a conversion.  The conversion may be SFmode or
16783 ;; SImode if the target mode DFmode, but only SImode if the target mode
16784 ;; is SFmode.
16786 ;; Gcc is slightly more smart about handling normal two address instructions
16787 ;; so use special patterns for add and mull.
16789 (define_insn "*fop_<mode>_comm_mixed_avx"
16790   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16791         (match_operator:MODEF 3 "binary_fp_operator"
16792           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16793            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16794   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16795    && COMMUTATIVE_ARITH_P (operands[3])
16796    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16797   "* return output_387_binary_op (insn, operands);"
16798   [(set (attr "type")
16799         (if_then_else (eq_attr "alternative" "1")
16800            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16801               (const_string "ssemul")
16802               (const_string "sseadd"))
16803            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16804               (const_string "fmul")
16805               (const_string "fop"))))
16806    (set_attr "prefix" "orig,maybe_vex")
16807    (set_attr "mode" "<MODE>")])
16809 (define_insn "*fop_<mode>_comm_mixed"
16810   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16811         (match_operator:MODEF 3 "binary_fp_operator"
16812           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16813            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16814   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16815    && COMMUTATIVE_ARITH_P (operands[3])
16816    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16817   "* return output_387_binary_op (insn, operands);"
16818   [(set (attr "type")
16819         (if_then_else (eq_attr "alternative" "1")
16820            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16821               (const_string "ssemul")
16822               (const_string "sseadd"))
16823            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16824               (const_string "fmul")
16825               (const_string "fop"))))
16826    (set_attr "mode" "<MODE>")])
16828 (define_insn "*fop_<mode>_comm_avx"
16829   [(set (match_operand:MODEF 0 "register_operand" "=x")
16830         (match_operator:MODEF 3 "binary_fp_operator"
16831           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16832            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16833   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16834    && COMMUTATIVE_ARITH_P (operands[3])
16835    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16836   "* return output_387_binary_op (insn, operands);"
16837   [(set (attr "type")
16838         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16839            (const_string "ssemul")
16840            (const_string "sseadd")))
16841    (set_attr "prefix" "vex")
16842    (set_attr "mode" "<MODE>")])
16844 (define_insn "*fop_<mode>_comm_sse"
16845   [(set (match_operand:MODEF 0 "register_operand" "=x")
16846         (match_operator:MODEF 3 "binary_fp_operator"
16847           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16848            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16849   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16850    && COMMUTATIVE_ARITH_P (operands[3])
16851    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16852   "* return output_387_binary_op (insn, operands);"
16853   [(set (attr "type")
16854         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16855            (const_string "ssemul")
16856            (const_string "sseadd")))
16857    (set_attr "mode" "<MODE>")])
16859 (define_insn "*fop_<mode>_comm_i387"
16860   [(set (match_operand:MODEF 0 "register_operand" "=f")
16861         (match_operator:MODEF 3 "binary_fp_operator"
16862           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16863            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16864   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16865    && COMMUTATIVE_ARITH_P (operands[3])
16866    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16867   "* return output_387_binary_op (insn, operands);"
16868   [(set (attr "type")
16869         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16870            (const_string "fmul")
16871            (const_string "fop")))
16872    (set_attr "mode" "<MODE>")])
16874 (define_insn "*fop_<mode>_1_mixed_avx"
16875   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16876         (match_operator:MODEF 3 "binary_fp_operator"
16877           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16878            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16879   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16880    && !COMMUTATIVE_ARITH_P (operands[3])
16881    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16882   "* return output_387_binary_op (insn, operands);"
16883   [(set (attr "type")
16884         (cond [(and (eq_attr "alternative" "2")
16885                     (match_operand:MODEF 3 "mult_operator" ""))
16886                  (const_string "ssemul")
16887                (and (eq_attr "alternative" "2")
16888                     (match_operand:MODEF 3 "div_operator" ""))
16889                  (const_string "ssediv")
16890                (eq_attr "alternative" "2")
16891                  (const_string "sseadd")
16892                (match_operand:MODEF 3 "mult_operator" "")
16893                  (const_string "fmul")
16894                (match_operand:MODEF 3 "div_operator" "")
16895                  (const_string "fdiv")
16896               ]
16897               (const_string "fop")))
16898    (set_attr "prefix" "orig,orig,maybe_vex")
16899    (set_attr "mode" "<MODE>")])
16901 (define_insn "*fop_<mode>_1_mixed"
16902   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16903         (match_operator:MODEF 3 "binary_fp_operator"
16904           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16905            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16906   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16907    && !COMMUTATIVE_ARITH_P (operands[3])
16908    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16909   "* return output_387_binary_op (insn, operands);"
16910   [(set (attr "type")
16911         (cond [(and (eq_attr "alternative" "2")
16912                     (match_operand:MODEF 3 "mult_operator" ""))
16913                  (const_string "ssemul")
16914                (and (eq_attr "alternative" "2")
16915                     (match_operand:MODEF 3 "div_operator" ""))
16916                  (const_string "ssediv")
16917                (eq_attr "alternative" "2")
16918                  (const_string "sseadd")
16919                (match_operand:MODEF 3 "mult_operator" "")
16920                  (const_string "fmul")
16921                (match_operand:MODEF 3 "div_operator" "")
16922                  (const_string "fdiv")
16923               ]
16924               (const_string "fop")))
16925    (set_attr "mode" "<MODE>")])
16927 (define_insn "*rcpsf2_sse"
16928   [(set (match_operand:SF 0 "register_operand" "=x")
16929         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16930                    UNSPEC_RCP))]
16931   "TARGET_SSE_MATH"
16932   "%vrcpss\t{%1, %d0|%d0, %1}"
16933   [(set_attr "type" "sse")
16934    (set_attr "atom_sse_attr" "rcp")
16935    (set_attr "prefix" "maybe_vex")
16936    (set_attr "mode" "SF")])
16938 (define_insn "*fop_<mode>_1_avx"
16939   [(set (match_operand:MODEF 0 "register_operand" "=x")
16940         (match_operator:MODEF 3 "binary_fp_operator"
16941           [(match_operand:MODEF 1 "register_operand" "x")
16942            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16943   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16944    && !COMMUTATIVE_ARITH_P (operands[3])"
16945   "* return output_387_binary_op (insn, operands);"
16946   [(set (attr "type")
16947         (cond [(match_operand:MODEF 3 "mult_operator" "")
16948                  (const_string "ssemul")
16949                (match_operand:MODEF 3 "div_operator" "")
16950                  (const_string "ssediv")
16951               ]
16952               (const_string "sseadd")))
16953    (set_attr "prefix" "vex")
16954    (set_attr "mode" "<MODE>")])
16956 (define_insn "*fop_<mode>_1_sse"
16957   [(set (match_operand:MODEF 0 "register_operand" "=x")
16958         (match_operator:MODEF 3 "binary_fp_operator"
16959           [(match_operand:MODEF 1 "register_operand" "0")
16960            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16961   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16962    && !COMMUTATIVE_ARITH_P (operands[3])"
16963   "* return output_387_binary_op (insn, operands);"
16964   [(set (attr "type")
16965         (cond [(match_operand:MODEF 3 "mult_operator" "")
16966                  (const_string "ssemul")
16967                (match_operand:MODEF 3 "div_operator" "")
16968                  (const_string "ssediv")
16969               ]
16970               (const_string "sseadd")))
16971    (set_attr "mode" "<MODE>")])
16973 ;; This pattern is not fully shadowed by the pattern above.
16974 (define_insn "*fop_<mode>_1_i387"
16975   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16976         (match_operator:MODEF 3 "binary_fp_operator"
16977           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16978            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16979   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16980    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16981    && !COMMUTATIVE_ARITH_P (operands[3])
16982    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16983   "* return output_387_binary_op (insn, operands);"
16984   [(set (attr "type")
16985         (cond [(match_operand:MODEF 3 "mult_operator" "")
16986                  (const_string "fmul")
16987                (match_operand:MODEF 3 "div_operator" "")
16988                  (const_string "fdiv")
16989               ]
16990               (const_string "fop")))
16991    (set_attr "mode" "<MODE>")])
16993 ;; ??? Add SSE splitters for these!
16994 (define_insn "*fop_<MODEF:mode>_2_i387"
16995   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16996         (match_operator:MODEF 3 "binary_fp_operator"
16997           [(float:MODEF
16998              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16999            (match_operand:MODEF 2 "register_operand" "0,0")]))]
17000   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
17001    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
17002    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17003   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17004   [(set (attr "type")
17005         (cond [(match_operand:MODEF 3 "mult_operator" "")
17006                  (const_string "fmul")
17007                (match_operand:MODEF 3 "div_operator" "")
17008                  (const_string "fdiv")
17009               ]
17010               (const_string "fop")))
17011    (set_attr "fp_int_src" "true")
17012    (set_attr "mode" "<X87MODEI12:MODE>")])
17014 (define_insn "*fop_<MODEF:mode>_3_i387"
17015   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
17016         (match_operator:MODEF 3 "binary_fp_operator"
17017           [(match_operand:MODEF 1 "register_operand" "0,0")
17018            (float:MODEF
17019              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
17020   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
17021    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
17022    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17023   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17024   [(set (attr "type")
17025         (cond [(match_operand:MODEF 3 "mult_operator" "")
17026                  (const_string "fmul")
17027                (match_operand:MODEF 3 "div_operator" "")
17028                  (const_string "fdiv")
17029               ]
17030               (const_string "fop")))
17031    (set_attr "fp_int_src" "true")
17032    (set_attr "mode" "<MODE>")])
17034 (define_insn "*fop_df_4_i387"
17035   [(set (match_operand:DF 0 "register_operand" "=f,f")
17036         (match_operator:DF 3 "binary_fp_operator"
17037            [(float_extend:DF
17038              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
17039             (match_operand:DF 2 "register_operand" "0,f")]))]
17040   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17041    && !(TARGET_SSE2 && TARGET_SSE_MATH)
17042    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
17043   "* return output_387_binary_op (insn, operands);"
17044   [(set (attr "type")
17045         (cond [(match_operand:DF 3 "mult_operator" "")
17046                  (const_string "fmul")
17047                (match_operand:DF 3 "div_operator" "")
17048                  (const_string "fdiv")
17049               ]
17050               (const_string "fop")))
17051    (set_attr "mode" "SF")])
17053 (define_insn "*fop_df_5_i387"
17054   [(set (match_operand:DF 0 "register_operand" "=f,f")
17055         (match_operator:DF 3 "binary_fp_operator"
17056           [(match_operand:DF 1 "register_operand" "0,f")
17057            (float_extend:DF
17058             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
17059   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17060    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
17061   "* return output_387_binary_op (insn, operands);"
17062   [(set (attr "type")
17063         (cond [(match_operand:DF 3 "mult_operator" "")
17064                  (const_string "fmul")
17065                (match_operand:DF 3 "div_operator" "")
17066                  (const_string "fdiv")
17067               ]
17068               (const_string "fop")))
17069    (set_attr "mode" "SF")])
17071 (define_insn "*fop_df_6_i387"
17072   [(set (match_operand:DF 0 "register_operand" "=f,f")
17073         (match_operator:DF 3 "binary_fp_operator"
17074           [(float_extend:DF
17075             (match_operand:SF 1 "register_operand" "0,f"))
17076            (float_extend:DF
17077             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
17078   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17079    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
17080   "* return output_387_binary_op (insn, operands);"
17081   [(set (attr "type")
17082         (cond [(match_operand:DF 3 "mult_operator" "")
17083                  (const_string "fmul")
17084                (match_operand:DF 3 "div_operator" "")
17085                  (const_string "fdiv")
17086               ]
17087               (const_string "fop")))
17088    (set_attr "mode" "SF")])
17090 (define_insn "*fop_xf_comm_i387"
17091   [(set (match_operand:XF 0 "register_operand" "=f")
17092         (match_operator:XF 3 "binary_fp_operator"
17093                         [(match_operand:XF 1 "register_operand" "%0")
17094                          (match_operand:XF 2 "register_operand" "f")]))]
17095   "TARGET_80387
17096    && COMMUTATIVE_ARITH_P (operands[3])"
17097   "* return output_387_binary_op (insn, operands);"
17098   [(set (attr "type")
17099         (if_then_else (match_operand:XF 3 "mult_operator" "")
17100            (const_string "fmul")
17101            (const_string "fop")))
17102    (set_attr "mode" "XF")])
17104 (define_insn "*fop_xf_1_i387"
17105   [(set (match_operand:XF 0 "register_operand" "=f,f")
17106         (match_operator:XF 3 "binary_fp_operator"
17107                         [(match_operand:XF 1 "register_operand" "0,f")
17108                          (match_operand:XF 2 "register_operand" "f,0")]))]
17109   "TARGET_80387
17110    && !COMMUTATIVE_ARITH_P (operands[3])"
17111   "* return output_387_binary_op (insn, operands);"
17112   [(set (attr "type")
17113         (cond [(match_operand:XF 3 "mult_operator" "")
17114                  (const_string "fmul")
17115                (match_operand:XF 3 "div_operator" "")
17116                  (const_string "fdiv")
17117               ]
17118               (const_string "fop")))
17119    (set_attr "mode" "XF")])
17121 (define_insn "*fop_xf_2_i387"
17122   [(set (match_operand:XF 0 "register_operand" "=f,f")
17123         (match_operator:XF 3 "binary_fp_operator"
17124           [(float:XF
17125              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
17126            (match_operand:XF 2 "register_operand" "0,0")]))]
17127   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17128   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17129   [(set (attr "type")
17130         (cond [(match_operand:XF 3 "mult_operator" "")
17131                  (const_string "fmul")
17132                (match_operand:XF 3 "div_operator" "")
17133                  (const_string "fdiv")
17134               ]
17135               (const_string "fop")))
17136    (set_attr "fp_int_src" "true")
17137    (set_attr "mode" "<MODE>")])
17139 (define_insn "*fop_xf_3_i387"
17140   [(set (match_operand:XF 0 "register_operand" "=f,f")
17141         (match_operator:XF 3 "binary_fp_operator"
17142           [(match_operand:XF 1 "register_operand" "0,0")
17143            (float:XF
17144              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
17145   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17146   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17147   [(set (attr "type")
17148         (cond [(match_operand:XF 3 "mult_operator" "")
17149                  (const_string "fmul")
17150                (match_operand:XF 3 "div_operator" "")
17151                  (const_string "fdiv")
17152               ]
17153               (const_string "fop")))
17154    (set_attr "fp_int_src" "true")
17155    (set_attr "mode" "<MODE>")])
17157 (define_insn "*fop_xf_4_i387"
17158   [(set (match_operand:XF 0 "register_operand" "=f,f")
17159         (match_operator:XF 3 "binary_fp_operator"
17160            [(float_extend:XF
17161               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
17162             (match_operand:XF 2 "register_operand" "0,f")]))]
17163   "TARGET_80387"
17164   "* return output_387_binary_op (insn, operands);"
17165   [(set (attr "type")
17166         (cond [(match_operand:XF 3 "mult_operator" "")
17167                  (const_string "fmul")
17168                (match_operand:XF 3 "div_operator" "")
17169                  (const_string "fdiv")
17170               ]
17171               (const_string "fop")))
17172    (set_attr "mode" "<MODE>")])
17174 (define_insn "*fop_xf_5_i387"
17175   [(set (match_operand:XF 0 "register_operand" "=f,f")
17176         (match_operator:XF 3 "binary_fp_operator"
17177           [(match_operand:XF 1 "register_operand" "0,f")
17178            (float_extend:XF
17179              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
17180   "TARGET_80387"
17181   "* return output_387_binary_op (insn, operands);"
17182   [(set (attr "type")
17183         (cond [(match_operand:XF 3 "mult_operator" "")
17184                  (const_string "fmul")
17185                (match_operand:XF 3 "div_operator" "")
17186                  (const_string "fdiv")
17187               ]
17188               (const_string "fop")))
17189    (set_attr "mode" "<MODE>")])
17191 (define_insn "*fop_xf_6_i387"
17192   [(set (match_operand:XF 0 "register_operand" "=f,f")
17193         (match_operator:XF 3 "binary_fp_operator"
17194           [(float_extend:XF
17195              (match_operand:MODEF 1 "register_operand" "0,f"))
17196            (float_extend:XF
17197              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
17198   "TARGET_80387"
17199   "* return output_387_binary_op (insn, operands);"
17200   [(set (attr "type")
17201         (cond [(match_operand:XF 3 "mult_operator" "")
17202                  (const_string "fmul")
17203                (match_operand:XF 3 "div_operator" "")
17204                  (const_string "fdiv")
17205               ]
17206               (const_string "fop")))
17207    (set_attr "mode" "<MODE>")])
17209 (define_split
17210   [(set (match_operand 0 "register_operand" "")
17211         (match_operator 3 "binary_fp_operator"
17212            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
17213             (match_operand 2 "register_operand" "")]))]
17214   "reload_completed
17215    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
17216    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
17217   [(const_int 0)]
17219   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
17220   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
17221   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
17222                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
17223                                           GET_MODE (operands[3]),
17224                                           operands[4],
17225                                           operands[2])));
17226   ix86_free_from_memory (GET_MODE (operands[1]));
17227   DONE;
17230 (define_split
17231   [(set (match_operand 0 "register_operand" "")
17232         (match_operator 3 "binary_fp_operator"
17233            [(match_operand 1 "register_operand" "")
17234             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
17235   "reload_completed
17236    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
17237    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
17238   [(const_int 0)]
17240   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
17241   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
17242   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
17243                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
17244                                           GET_MODE (operands[3]),
17245                                           operands[1],
17246                                           operands[4])));
17247   ix86_free_from_memory (GET_MODE (operands[2]));
17248   DONE;
17251 ;; FPU special functions.
17253 ;; This pattern implements a no-op XFmode truncation for
17254 ;; all fancy i386 XFmode math functions.
17256 (define_insn "truncxf<mode>2_i387_noop_unspec"
17257   [(set (match_operand:MODEF 0 "register_operand" "=f")
17258         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
17259         UNSPEC_TRUNC_NOOP))]
17260   "TARGET_USE_FANCY_MATH_387"
17261   "* return output_387_reg_move (insn, operands);"
17262   [(set_attr "type" "fmov")
17263    (set_attr "mode" "<MODE>")])
17265 (define_insn "sqrtxf2"
17266   [(set (match_operand:XF 0 "register_operand" "=f")
17267         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
17268   "TARGET_USE_FANCY_MATH_387"
17269   "fsqrt"
17270   [(set_attr "type" "fpspc")
17271    (set_attr "mode" "XF")
17272    (set_attr "athlon_decode" "direct")
17273    (set_attr "amdfam10_decode" "direct")])
17275 (define_insn "sqrt_extend<mode>xf2_i387"
17276   [(set (match_operand:XF 0 "register_operand" "=f")
17277         (sqrt:XF
17278           (float_extend:XF
17279             (match_operand:MODEF 1 "register_operand" "0"))))]
17280   "TARGET_USE_FANCY_MATH_387"
17281   "fsqrt"
17282   [(set_attr "type" "fpspc")
17283    (set_attr "mode" "XF")
17284    (set_attr "athlon_decode" "direct")
17285    (set_attr "amdfam10_decode" "direct")])
17287 (define_insn "*rsqrtsf2_sse"
17288   [(set (match_operand:SF 0 "register_operand" "=x")
17289         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
17290                    UNSPEC_RSQRT))]
17291   "TARGET_SSE_MATH"
17292   "%vrsqrtss\t{%1, %d0|%d0, %1}"
17293   [(set_attr "type" "sse")
17294    (set_attr "atom_sse_attr" "rcp")
17295    (set_attr "prefix" "maybe_vex")
17296    (set_attr "mode" "SF")])
17298 (define_expand "rsqrtsf2"
17299   [(set (match_operand:SF 0 "register_operand" "")
17300         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
17301                    UNSPEC_RSQRT))]
17302   "TARGET_SSE_MATH"
17304   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
17305   DONE;
17308 (define_insn "*sqrt<mode>2_sse"
17309   [(set (match_operand:MODEF 0 "register_operand" "=x")
17310         (sqrt:MODEF
17311           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
17312   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17313   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
17314   [(set_attr "type" "sse")
17315    (set_attr "atom_sse_attr" "sqrt")
17316    (set_attr "prefix" "maybe_vex")
17317    (set_attr "mode" "<MODE>")
17318    (set_attr "athlon_decode" "*")
17319    (set_attr "amdfam10_decode" "*")])
17321 (define_expand "sqrt<mode>2"
17322   [(set (match_operand:MODEF 0 "register_operand" "")
17323         (sqrt:MODEF
17324           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
17325   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
17326    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17328   if (<MODE>mode == SFmode
17329       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
17330       && flag_finite_math_only && !flag_trapping_math
17331       && flag_unsafe_math_optimizations)
17332     {
17333       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
17334       DONE;
17335     }
17337   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
17338     {
17339       rtx op0 = gen_reg_rtx (XFmode);
17340       rtx op1 = force_reg (<MODE>mode, operands[1]);
17342       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
17343       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
17344       DONE;
17345    }
17348 (define_insn "fpremxf4_i387"
17349   [(set (match_operand:XF 0 "register_operand" "=f")
17350         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17351                     (match_operand:XF 3 "register_operand" "1")]
17352                    UNSPEC_FPREM_F))
17353    (set (match_operand:XF 1 "register_operand" "=u")
17354         (unspec:XF [(match_dup 2) (match_dup 3)]
17355                    UNSPEC_FPREM_U))
17356    (set (reg:CCFP FPSR_REG)
17357         (unspec:CCFP [(match_dup 2) (match_dup 3)]
17358                      UNSPEC_C2_FLAG))]
17359   "TARGET_USE_FANCY_MATH_387"
17360   "fprem"
17361   [(set_attr "type" "fpspc")
17362    (set_attr "mode" "XF")])
17364 (define_expand "fmodxf3"
17365   [(use (match_operand:XF 0 "register_operand" ""))
17366    (use (match_operand:XF 1 "general_operand" ""))
17367    (use (match_operand:XF 2 "general_operand" ""))]
17368   "TARGET_USE_FANCY_MATH_387"
17370   rtx label = gen_label_rtx ();
17372   rtx op1 = gen_reg_rtx (XFmode);
17373   rtx op2 = gen_reg_rtx (XFmode);
17375   emit_move_insn (op2, operands[2]);
17376   emit_move_insn (op1, operands[1]);
17378   emit_label (label);
17379   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
17380   ix86_emit_fp_unordered_jump (label);
17381   LABEL_NUSES (label) = 1;
17383   emit_move_insn (operands[0], op1);
17384   DONE;
17387 (define_expand "fmod<mode>3"
17388   [(use (match_operand:MODEF 0 "register_operand" ""))
17389    (use (match_operand:MODEF 1 "general_operand" ""))
17390    (use (match_operand:MODEF 2 "general_operand" ""))]
17391   "TARGET_USE_FANCY_MATH_387"
17393   rtx label = gen_label_rtx ();
17395   rtx op1 = gen_reg_rtx (XFmode);
17396   rtx op2 = gen_reg_rtx (XFmode);
17398   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17399   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17401   emit_label (label);
17402   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
17403   ix86_emit_fp_unordered_jump (label);
17404   LABEL_NUSES (label) = 1;
17406   /* Truncate the result properly for strict SSE math.  */
17407   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17408       && !TARGET_MIX_SSE_I387)
17409     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17410   else
17411     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17413   DONE;
17416 (define_insn "fprem1xf4_i387"
17417   [(set (match_operand:XF 0 "register_operand" "=f")
17418         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17419                     (match_operand:XF 3 "register_operand" "1")]
17420                    UNSPEC_FPREM1_F))
17421    (set (match_operand:XF 1 "register_operand" "=u")
17422         (unspec:XF [(match_dup 2) (match_dup 3)]
17423                    UNSPEC_FPREM1_U))
17424    (set (reg:CCFP FPSR_REG)
17425         (unspec:CCFP [(match_dup 2) (match_dup 3)]
17426                      UNSPEC_C2_FLAG))]
17427   "TARGET_USE_FANCY_MATH_387"
17428   "fprem1"
17429   [(set_attr "type" "fpspc")
17430    (set_attr "mode" "XF")])
17432 (define_expand "remainderxf3"
17433   [(use (match_operand:XF 0 "register_operand" ""))
17434    (use (match_operand:XF 1 "general_operand" ""))
17435    (use (match_operand:XF 2 "general_operand" ""))]
17436   "TARGET_USE_FANCY_MATH_387"
17438   rtx label = gen_label_rtx ();
17440   rtx op1 = gen_reg_rtx (XFmode);
17441   rtx op2 = gen_reg_rtx (XFmode);
17443   emit_move_insn (op2, operands[2]);
17444   emit_move_insn (op1, operands[1]);
17446   emit_label (label);
17447   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17448   ix86_emit_fp_unordered_jump (label);
17449   LABEL_NUSES (label) = 1;
17451   emit_move_insn (operands[0], op1);
17452   DONE;
17455 (define_expand "remainder<mode>3"
17456   [(use (match_operand:MODEF 0 "register_operand" ""))
17457    (use (match_operand:MODEF 1 "general_operand" ""))
17458    (use (match_operand:MODEF 2 "general_operand" ""))]
17459   "TARGET_USE_FANCY_MATH_387"
17461   rtx label = gen_label_rtx ();
17463   rtx op1 = gen_reg_rtx (XFmode);
17464   rtx op2 = gen_reg_rtx (XFmode);
17466   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17467   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17469   emit_label (label);
17471   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17472   ix86_emit_fp_unordered_jump (label);
17473   LABEL_NUSES (label) = 1;
17475   /* Truncate the result properly for strict SSE math.  */
17476   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17477       && !TARGET_MIX_SSE_I387)
17478     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17479   else
17480     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17482   DONE;
17485 (define_insn "*sinxf2_i387"
17486   [(set (match_operand:XF 0 "register_operand" "=f")
17487         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
17488   "TARGET_USE_FANCY_MATH_387
17489    && flag_unsafe_math_optimizations"
17490   "fsin"
17491   [(set_attr "type" "fpspc")
17492    (set_attr "mode" "XF")])
17494 (define_insn "*sin_extend<mode>xf2_i387"
17495   [(set (match_operand:XF 0 "register_operand" "=f")
17496         (unspec:XF [(float_extend:XF
17497                       (match_operand:MODEF 1 "register_operand" "0"))]
17498                    UNSPEC_SIN))]
17499   "TARGET_USE_FANCY_MATH_387
17500    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17501        || TARGET_MIX_SSE_I387)
17502    && flag_unsafe_math_optimizations"
17503   "fsin"
17504   [(set_attr "type" "fpspc")
17505    (set_attr "mode" "XF")])
17507 (define_insn "*cosxf2_i387"
17508   [(set (match_operand:XF 0 "register_operand" "=f")
17509         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
17510   "TARGET_USE_FANCY_MATH_387
17511    && flag_unsafe_math_optimizations"
17512   "fcos"
17513   [(set_attr "type" "fpspc")
17514    (set_attr "mode" "XF")])
17516 (define_insn "*cos_extend<mode>xf2_i387"
17517   [(set (match_operand:XF 0 "register_operand" "=f")
17518         (unspec:XF [(float_extend:XF
17519                       (match_operand:MODEF 1 "register_operand" "0"))]
17520                    UNSPEC_COS))]
17521   "TARGET_USE_FANCY_MATH_387
17522    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17523        || TARGET_MIX_SSE_I387)
17524    && flag_unsafe_math_optimizations"
17525   "fcos"
17526   [(set_attr "type" "fpspc")
17527    (set_attr "mode" "XF")])
17529 ;; When sincos pattern is defined, sin and cos builtin functions will be
17530 ;; expanded to sincos pattern with one of its outputs left unused.
17531 ;; CSE pass will figure out if two sincos patterns can be combined,
17532 ;; otherwise sincos pattern will be split back to sin or cos pattern,
17533 ;; depending on the unused output.
17535 (define_insn "sincosxf3"
17536   [(set (match_operand:XF 0 "register_operand" "=f")
17537         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17538                    UNSPEC_SINCOS_COS))
17539    (set (match_operand:XF 1 "register_operand" "=u")
17540         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17541   "TARGET_USE_FANCY_MATH_387
17542    && flag_unsafe_math_optimizations"
17543   "fsincos"
17544   [(set_attr "type" "fpspc")
17545    (set_attr "mode" "XF")])
17547 (define_split
17548   [(set (match_operand:XF 0 "register_operand" "")
17549         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17550                    UNSPEC_SINCOS_COS))
17551    (set (match_operand:XF 1 "register_operand" "")
17552         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17553   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17554    && !(reload_completed || reload_in_progress)"
17555   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
17556   "")
17558 (define_split
17559   [(set (match_operand:XF 0 "register_operand" "")
17560         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17561                    UNSPEC_SINCOS_COS))
17562    (set (match_operand:XF 1 "register_operand" "")
17563         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17564   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17565    && !(reload_completed || reload_in_progress)"
17566   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17567   "")
17569 (define_insn "sincos_extend<mode>xf3_i387"
17570   [(set (match_operand:XF 0 "register_operand" "=f")
17571         (unspec:XF [(float_extend:XF
17572                       (match_operand:MODEF 2 "register_operand" "0"))]
17573                    UNSPEC_SINCOS_COS))
17574    (set (match_operand:XF 1 "register_operand" "=u")
17575         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17576   "TARGET_USE_FANCY_MATH_387
17577    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17578        || TARGET_MIX_SSE_I387)
17579    && flag_unsafe_math_optimizations"
17580   "fsincos"
17581   [(set_attr "type" "fpspc")
17582    (set_attr "mode" "XF")])
17584 (define_split
17585   [(set (match_operand:XF 0 "register_operand" "")
17586         (unspec:XF [(float_extend:XF
17587                       (match_operand:MODEF 2 "register_operand" ""))]
17588                    UNSPEC_SINCOS_COS))
17589    (set (match_operand:XF 1 "register_operand" "")
17590         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17591   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17592    && !(reload_completed || reload_in_progress)"
17593   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17594   "")
17596 (define_split
17597   [(set (match_operand:XF 0 "register_operand" "")
17598         (unspec:XF [(float_extend:XF
17599                       (match_operand:MODEF 2 "register_operand" ""))]
17600                    UNSPEC_SINCOS_COS))
17601    (set (match_operand:XF 1 "register_operand" "")
17602         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17603   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17604    && !(reload_completed || reload_in_progress)"
17605   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17606   "")
17608 (define_expand "sincos<mode>3"
17609   [(use (match_operand:MODEF 0 "register_operand" ""))
17610    (use (match_operand:MODEF 1 "register_operand" ""))
17611    (use (match_operand:MODEF 2 "register_operand" ""))]
17612   "TARGET_USE_FANCY_MATH_387
17613    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17614        || TARGET_MIX_SSE_I387)
17615    && flag_unsafe_math_optimizations"
17617   rtx op0 = gen_reg_rtx (XFmode);
17618   rtx op1 = gen_reg_rtx (XFmode);
17620   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17621   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17622   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17623   DONE;
17626 (define_insn "fptanxf4_i387"
17627   [(set (match_operand:XF 0 "register_operand" "=f")
17628         (match_operand:XF 3 "const_double_operand" "F"))
17629    (set (match_operand:XF 1 "register_operand" "=u")
17630         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17631                    UNSPEC_TAN))]
17632   "TARGET_USE_FANCY_MATH_387
17633    && flag_unsafe_math_optimizations
17634    && standard_80387_constant_p (operands[3]) == 2"
17635   "fptan"
17636   [(set_attr "type" "fpspc")
17637    (set_attr "mode" "XF")])
17639 (define_insn "fptan_extend<mode>xf4_i387"
17640   [(set (match_operand:MODEF 0 "register_operand" "=f")
17641         (match_operand:MODEF 3 "const_double_operand" "F"))
17642    (set (match_operand:XF 1 "register_operand" "=u")
17643         (unspec:XF [(float_extend:XF
17644                       (match_operand:MODEF 2 "register_operand" "0"))]
17645                    UNSPEC_TAN))]
17646   "TARGET_USE_FANCY_MATH_387
17647    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17648        || TARGET_MIX_SSE_I387)
17649    && flag_unsafe_math_optimizations
17650    && standard_80387_constant_p (operands[3]) == 2"
17651   "fptan"
17652   [(set_attr "type" "fpspc")
17653    (set_attr "mode" "XF")])
17655 (define_expand "tanxf2"
17656   [(use (match_operand:XF 0 "register_operand" ""))
17657    (use (match_operand:XF 1 "register_operand" ""))]
17658   "TARGET_USE_FANCY_MATH_387
17659    && flag_unsafe_math_optimizations"
17661   rtx one = gen_reg_rtx (XFmode);
17662   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17664   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17665   DONE;
17668 (define_expand "tan<mode>2"
17669   [(use (match_operand:MODEF 0 "register_operand" ""))
17670    (use (match_operand:MODEF 1 "register_operand" ""))]
17671   "TARGET_USE_FANCY_MATH_387
17672    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17673        || TARGET_MIX_SSE_I387)
17674    && flag_unsafe_math_optimizations"
17676   rtx op0 = gen_reg_rtx (XFmode);
17678   rtx one = gen_reg_rtx (<MODE>mode);
17679   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17681   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17682                                              operands[1], op2));
17683   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17684   DONE;
17687 (define_insn "*fpatanxf3_i387"
17688   [(set (match_operand:XF 0 "register_operand" "=f")
17689         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17690                     (match_operand:XF 2 "register_operand" "u")]
17691                    UNSPEC_FPATAN))
17692    (clobber (match_scratch:XF 3 "=2"))]
17693   "TARGET_USE_FANCY_MATH_387
17694    && flag_unsafe_math_optimizations"
17695   "fpatan"
17696   [(set_attr "type" "fpspc")
17697    (set_attr "mode" "XF")])
17699 (define_insn "fpatan_extend<mode>xf3_i387"
17700   [(set (match_operand:XF 0 "register_operand" "=f")
17701         (unspec:XF [(float_extend:XF
17702                       (match_operand:MODEF 1 "register_operand" "0"))
17703                     (float_extend:XF
17704                       (match_operand:MODEF 2 "register_operand" "u"))]
17705                    UNSPEC_FPATAN))
17706    (clobber (match_scratch:XF 3 "=2"))]
17707   "TARGET_USE_FANCY_MATH_387
17708    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17709        || TARGET_MIX_SSE_I387)
17710    && flag_unsafe_math_optimizations"
17711   "fpatan"
17712   [(set_attr "type" "fpspc")
17713    (set_attr "mode" "XF")])
17715 (define_expand "atan2xf3"
17716   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17717                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
17718                                (match_operand:XF 1 "register_operand" "")]
17719                               UNSPEC_FPATAN))
17720               (clobber (match_scratch:XF 3 ""))])]
17721   "TARGET_USE_FANCY_MATH_387
17722    && flag_unsafe_math_optimizations"
17723   "")
17725 (define_expand "atan2<mode>3"
17726   [(use (match_operand:MODEF 0 "register_operand" ""))
17727    (use (match_operand:MODEF 1 "register_operand" ""))
17728    (use (match_operand:MODEF 2 "register_operand" ""))]
17729   "TARGET_USE_FANCY_MATH_387
17730    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17731        || TARGET_MIX_SSE_I387)
17732    && flag_unsafe_math_optimizations"
17734   rtx op0 = gen_reg_rtx (XFmode);
17736   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17737   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17738   DONE;
17741 (define_expand "atanxf2"
17742   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17743                    (unspec:XF [(match_dup 2)
17744                                (match_operand:XF 1 "register_operand" "")]
17745                               UNSPEC_FPATAN))
17746               (clobber (match_scratch:XF 3 ""))])]
17747   "TARGET_USE_FANCY_MATH_387
17748    && flag_unsafe_math_optimizations"
17750   operands[2] = gen_reg_rtx (XFmode);
17751   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17754 (define_expand "atan<mode>2"
17755   [(use (match_operand:MODEF 0 "register_operand" ""))
17756    (use (match_operand:MODEF 1 "register_operand" ""))]
17757   "TARGET_USE_FANCY_MATH_387
17758    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17759        || TARGET_MIX_SSE_I387)
17760    && flag_unsafe_math_optimizations"
17762   rtx op0 = gen_reg_rtx (XFmode);
17764   rtx op2 = gen_reg_rtx (<MODE>mode);
17765   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17767   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17768   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17769   DONE;
17772 (define_expand "asinxf2"
17773   [(set (match_dup 2)
17774         (mult:XF (match_operand:XF 1 "register_operand" "")
17775                  (match_dup 1)))
17776    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17777    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17778    (parallel [(set (match_operand:XF 0 "register_operand" "")
17779                    (unspec:XF [(match_dup 5) (match_dup 1)]
17780                               UNSPEC_FPATAN))
17781               (clobber (match_scratch:XF 6 ""))])]
17782   "TARGET_USE_FANCY_MATH_387
17783    && flag_unsafe_math_optimizations"
17785   int i;
17787   if (optimize_insn_for_size_p ())
17788     FAIL;
17790   for (i = 2; i < 6; i++)
17791     operands[i] = gen_reg_rtx (XFmode);
17793   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17796 (define_expand "asin<mode>2"
17797   [(use (match_operand:MODEF 0 "register_operand" ""))
17798    (use (match_operand:MODEF 1 "general_operand" ""))]
17799  "TARGET_USE_FANCY_MATH_387
17800    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17801        || TARGET_MIX_SSE_I387)
17802    && flag_unsafe_math_optimizations"
17804   rtx op0 = gen_reg_rtx (XFmode);
17805   rtx op1 = gen_reg_rtx (XFmode);
17807   if (optimize_insn_for_size_p ())
17808     FAIL;
17810   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17811   emit_insn (gen_asinxf2 (op0, op1));
17812   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17813   DONE;
17816 (define_expand "acosxf2"
17817   [(set (match_dup 2)
17818         (mult:XF (match_operand:XF 1 "register_operand" "")
17819                  (match_dup 1)))
17820    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17821    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17822    (parallel [(set (match_operand:XF 0 "register_operand" "")
17823                    (unspec:XF [(match_dup 1) (match_dup 5)]
17824                               UNSPEC_FPATAN))
17825               (clobber (match_scratch:XF 6 ""))])]
17826   "TARGET_USE_FANCY_MATH_387
17827    && flag_unsafe_math_optimizations"
17829   int i;
17831   if (optimize_insn_for_size_p ())
17832     FAIL;
17834   for (i = 2; i < 6; i++)
17835     operands[i] = gen_reg_rtx (XFmode);
17837   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17840 (define_expand "acos<mode>2"
17841   [(use (match_operand:MODEF 0 "register_operand" ""))
17842    (use (match_operand:MODEF 1 "general_operand" ""))]
17843  "TARGET_USE_FANCY_MATH_387
17844    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17845        || TARGET_MIX_SSE_I387)
17846    && flag_unsafe_math_optimizations"
17848   rtx op0 = gen_reg_rtx (XFmode);
17849   rtx op1 = gen_reg_rtx (XFmode);
17851   if (optimize_insn_for_size_p ())
17852     FAIL;
17854   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17855   emit_insn (gen_acosxf2 (op0, op1));
17856   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17857   DONE;
17860 (define_insn "fyl2xxf3_i387"
17861   [(set (match_operand:XF 0 "register_operand" "=f")
17862         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17863                     (match_operand:XF 2 "register_operand" "u")]
17864                    UNSPEC_FYL2X))
17865    (clobber (match_scratch:XF 3 "=2"))]
17866   "TARGET_USE_FANCY_MATH_387
17867    && flag_unsafe_math_optimizations"
17868   "fyl2x"
17869   [(set_attr "type" "fpspc")
17870    (set_attr "mode" "XF")])
17872 (define_insn "fyl2x_extend<mode>xf3_i387"
17873   [(set (match_operand:XF 0 "register_operand" "=f")
17874         (unspec:XF [(float_extend:XF
17875                       (match_operand:MODEF 1 "register_operand" "0"))
17876                     (match_operand:XF 2 "register_operand" "u")]
17877                    UNSPEC_FYL2X))
17878    (clobber (match_scratch:XF 3 "=2"))]
17879   "TARGET_USE_FANCY_MATH_387
17880    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17881        || TARGET_MIX_SSE_I387)
17882    && flag_unsafe_math_optimizations"
17883   "fyl2x"
17884   [(set_attr "type" "fpspc")
17885    (set_attr "mode" "XF")])
17887 (define_expand "logxf2"
17888   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17889                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17890                                (match_dup 2)] UNSPEC_FYL2X))
17891               (clobber (match_scratch:XF 3 ""))])]
17892   "TARGET_USE_FANCY_MATH_387
17893    && flag_unsafe_math_optimizations"
17895   operands[2] = gen_reg_rtx (XFmode);
17896   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17899 (define_expand "log<mode>2"
17900   [(use (match_operand:MODEF 0 "register_operand" ""))
17901    (use (match_operand:MODEF 1 "register_operand" ""))]
17902   "TARGET_USE_FANCY_MATH_387
17903    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17904        || TARGET_MIX_SSE_I387)
17905    && flag_unsafe_math_optimizations"
17907   rtx op0 = gen_reg_rtx (XFmode);
17909   rtx op2 = gen_reg_rtx (XFmode);
17910   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17912   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17913   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17914   DONE;
17917 (define_expand "log10xf2"
17918   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17919                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17920                                (match_dup 2)] UNSPEC_FYL2X))
17921               (clobber (match_scratch:XF 3 ""))])]
17922   "TARGET_USE_FANCY_MATH_387
17923    && flag_unsafe_math_optimizations"
17925   operands[2] = gen_reg_rtx (XFmode);
17926   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17929 (define_expand "log10<mode>2"
17930   [(use (match_operand:MODEF 0 "register_operand" ""))
17931    (use (match_operand:MODEF 1 "register_operand" ""))]
17932   "TARGET_USE_FANCY_MATH_387
17933    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17934        || TARGET_MIX_SSE_I387)
17935    && flag_unsafe_math_optimizations"
17937   rtx op0 = gen_reg_rtx (XFmode);
17939   rtx op2 = gen_reg_rtx (XFmode);
17940   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17942   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17943   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17944   DONE;
17947 (define_expand "log2xf2"
17948   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17949                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17950                                (match_dup 2)] UNSPEC_FYL2X))
17951               (clobber (match_scratch:XF 3 ""))])]
17952   "TARGET_USE_FANCY_MATH_387
17953    && flag_unsafe_math_optimizations"
17955   operands[2] = gen_reg_rtx (XFmode);
17956   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17959 (define_expand "log2<mode>2"
17960   [(use (match_operand:MODEF 0 "register_operand" ""))
17961    (use (match_operand:MODEF 1 "register_operand" ""))]
17962   "TARGET_USE_FANCY_MATH_387
17963    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17964        || TARGET_MIX_SSE_I387)
17965    && flag_unsafe_math_optimizations"
17967   rtx op0 = gen_reg_rtx (XFmode);
17969   rtx op2 = gen_reg_rtx (XFmode);
17970   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17972   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17973   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17974   DONE;
17977 (define_insn "fyl2xp1xf3_i387"
17978   [(set (match_operand:XF 0 "register_operand" "=f")
17979         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17980                     (match_operand:XF 2 "register_operand" "u")]
17981                    UNSPEC_FYL2XP1))
17982    (clobber (match_scratch:XF 3 "=2"))]
17983   "TARGET_USE_FANCY_MATH_387
17984    && flag_unsafe_math_optimizations"
17985   "fyl2xp1"
17986   [(set_attr "type" "fpspc")
17987    (set_attr "mode" "XF")])
17989 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17990   [(set (match_operand:XF 0 "register_operand" "=f")
17991         (unspec:XF [(float_extend:XF
17992                       (match_operand:MODEF 1 "register_operand" "0"))
17993                     (match_operand:XF 2 "register_operand" "u")]
17994                    UNSPEC_FYL2XP1))
17995    (clobber (match_scratch:XF 3 "=2"))]
17996   "TARGET_USE_FANCY_MATH_387
17997    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17998        || TARGET_MIX_SSE_I387)
17999    && flag_unsafe_math_optimizations"
18000   "fyl2xp1"
18001   [(set_attr "type" "fpspc")
18002    (set_attr "mode" "XF")])
18004 (define_expand "log1pxf2"
18005   [(use (match_operand:XF 0 "register_operand" ""))
18006    (use (match_operand:XF 1 "register_operand" ""))]
18007   "TARGET_USE_FANCY_MATH_387
18008    && flag_unsafe_math_optimizations"
18010   if (optimize_insn_for_size_p ())
18011     FAIL;
18013   ix86_emit_i387_log1p (operands[0], operands[1]);
18014   DONE;
18017 (define_expand "log1p<mode>2"
18018   [(use (match_operand:MODEF 0 "register_operand" ""))
18019    (use (match_operand:MODEF 1 "register_operand" ""))]
18020   "TARGET_USE_FANCY_MATH_387
18021    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18022        || TARGET_MIX_SSE_I387)
18023    && flag_unsafe_math_optimizations"
18025   rtx op0;
18027   if (optimize_insn_for_size_p ())
18028     FAIL;
18030   op0 = gen_reg_rtx (XFmode);
18032   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
18034   ix86_emit_i387_log1p (op0, operands[1]);
18035   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18036   DONE;
18039 (define_insn "fxtractxf3_i387"
18040   [(set (match_operand:XF 0 "register_operand" "=f")
18041         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
18042                    UNSPEC_XTRACT_FRACT))
18043    (set (match_operand:XF 1 "register_operand" "=u")
18044         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
18045   "TARGET_USE_FANCY_MATH_387
18046    && flag_unsafe_math_optimizations"
18047   "fxtract"
18048   [(set_attr "type" "fpspc")
18049    (set_attr "mode" "XF")])
18051 (define_insn "fxtract_extend<mode>xf3_i387"
18052   [(set (match_operand:XF 0 "register_operand" "=f")
18053         (unspec:XF [(float_extend:XF
18054                       (match_operand:MODEF 2 "register_operand" "0"))]
18055                    UNSPEC_XTRACT_FRACT))
18056    (set (match_operand:XF 1 "register_operand" "=u")
18057         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
18058   "TARGET_USE_FANCY_MATH_387
18059    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18060        || TARGET_MIX_SSE_I387)
18061    && flag_unsafe_math_optimizations"
18062   "fxtract"
18063   [(set_attr "type" "fpspc")
18064    (set_attr "mode" "XF")])
18066 (define_expand "logbxf2"
18067   [(parallel [(set (match_dup 2)
18068                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18069                               UNSPEC_XTRACT_FRACT))
18070               (set (match_operand:XF 0 "register_operand" "")
18071                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
18072   "TARGET_USE_FANCY_MATH_387
18073    && flag_unsafe_math_optimizations"
18075   operands[2] = gen_reg_rtx (XFmode);
18078 (define_expand "logb<mode>2"
18079   [(use (match_operand:MODEF 0 "register_operand" ""))
18080    (use (match_operand:MODEF 1 "register_operand" ""))]
18081   "TARGET_USE_FANCY_MATH_387
18082    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18083        || TARGET_MIX_SSE_I387)
18084    && flag_unsafe_math_optimizations"
18086   rtx op0 = gen_reg_rtx (XFmode);
18087   rtx op1 = gen_reg_rtx (XFmode);
18089   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18090   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
18091   DONE;
18094 (define_expand "ilogbxf2"
18095   [(use (match_operand:SI 0 "register_operand" ""))
18096    (use (match_operand:XF 1 "register_operand" ""))]
18097   "TARGET_USE_FANCY_MATH_387
18098    && flag_unsafe_math_optimizations"
18100   rtx op0, op1;
18102   if (optimize_insn_for_size_p ())
18103     FAIL;
18105   op0 = gen_reg_rtx (XFmode);
18106   op1 = gen_reg_rtx (XFmode);
18108   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
18109   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
18110   DONE;
18113 (define_expand "ilogb<mode>2"
18114   [(use (match_operand:SI 0 "register_operand" ""))
18115    (use (match_operand:MODEF 1 "register_operand" ""))]
18116   "TARGET_USE_FANCY_MATH_387
18117    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18118        || TARGET_MIX_SSE_I387)
18119    && flag_unsafe_math_optimizations"
18121   rtx op0, op1;
18123   if (optimize_insn_for_size_p ())
18124     FAIL;
18126   op0 = gen_reg_rtx (XFmode);
18127   op1 = gen_reg_rtx (XFmode);
18129   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18130   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
18131   DONE;
18134 (define_insn "*f2xm1xf2_i387"
18135   [(set (match_operand:XF 0 "register_operand" "=f")
18136         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18137                    UNSPEC_F2XM1))]
18138   "TARGET_USE_FANCY_MATH_387
18139    && flag_unsafe_math_optimizations"
18140   "f2xm1"
18141   [(set_attr "type" "fpspc")
18142    (set_attr "mode" "XF")])
18144 (define_insn "*fscalexf4_i387"
18145   [(set (match_operand:XF 0 "register_operand" "=f")
18146         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
18147                     (match_operand:XF 3 "register_operand" "1")]
18148                    UNSPEC_FSCALE_FRACT))
18149    (set (match_operand:XF 1 "register_operand" "=u")
18150         (unspec:XF [(match_dup 2) (match_dup 3)]
18151                    UNSPEC_FSCALE_EXP))]
18152   "TARGET_USE_FANCY_MATH_387
18153    && flag_unsafe_math_optimizations"
18154   "fscale"
18155   [(set_attr "type" "fpspc")
18156    (set_attr "mode" "XF")])
18158 (define_expand "expNcorexf3"
18159   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
18160                                (match_operand:XF 2 "register_operand" "")))
18161    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
18162    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
18163    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
18164    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
18165    (parallel [(set (match_operand:XF 0 "register_operand" "")
18166                    (unspec:XF [(match_dup 8) (match_dup 4)]
18167                               UNSPEC_FSCALE_FRACT))
18168               (set (match_dup 9)
18169                    (unspec:XF [(match_dup 8) (match_dup 4)]
18170                               UNSPEC_FSCALE_EXP))])]
18171   "TARGET_USE_FANCY_MATH_387
18172    && flag_unsafe_math_optimizations"
18174   int i;
18176   if (optimize_insn_for_size_p ())
18177     FAIL;
18179   for (i = 3; i < 10; i++)
18180     operands[i] = gen_reg_rtx (XFmode);
18182   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
18185 (define_expand "expxf2"
18186   [(use (match_operand:XF 0 "register_operand" ""))
18187    (use (match_operand:XF 1 "register_operand" ""))]
18188   "TARGET_USE_FANCY_MATH_387
18189    && flag_unsafe_math_optimizations"
18191   rtx op2;
18193   if (optimize_insn_for_size_p ())
18194     FAIL;
18196   op2 = gen_reg_rtx (XFmode);
18197   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
18199   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18200   DONE;
18203 (define_expand "exp<mode>2"
18204   [(use (match_operand:MODEF 0 "register_operand" ""))
18205    (use (match_operand:MODEF 1 "general_operand" ""))]
18206  "TARGET_USE_FANCY_MATH_387
18207    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18208        || TARGET_MIX_SSE_I387)
18209    && flag_unsafe_math_optimizations"
18211   rtx op0, op1;
18213   if (optimize_insn_for_size_p ())
18214     FAIL;
18216   op0 = gen_reg_rtx (XFmode);
18217   op1 = gen_reg_rtx (XFmode);
18219   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18220   emit_insn (gen_expxf2 (op0, op1));
18221   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18222   DONE;
18225 (define_expand "exp10xf2"
18226   [(use (match_operand:XF 0 "register_operand" ""))
18227    (use (match_operand:XF 1 "register_operand" ""))]
18228   "TARGET_USE_FANCY_MATH_387
18229    && flag_unsafe_math_optimizations"
18231   rtx op2;
18233   if (optimize_insn_for_size_p ())
18234     FAIL;
18236   op2 = gen_reg_rtx (XFmode);
18237   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
18239   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18240   DONE;
18243 (define_expand "exp10<mode>2"
18244   [(use (match_operand:MODEF 0 "register_operand" ""))
18245    (use (match_operand:MODEF 1 "general_operand" ""))]
18246  "TARGET_USE_FANCY_MATH_387
18247    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18248        || TARGET_MIX_SSE_I387)
18249    && flag_unsafe_math_optimizations"
18251   rtx op0, op1;
18253   if (optimize_insn_for_size_p ())
18254     FAIL;
18256   op0 = gen_reg_rtx (XFmode);
18257   op1 = gen_reg_rtx (XFmode);
18259   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18260   emit_insn (gen_exp10xf2 (op0, op1));
18261   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18262   DONE;
18265 (define_expand "exp2xf2"
18266   [(use (match_operand:XF 0 "register_operand" ""))
18267    (use (match_operand:XF 1 "register_operand" ""))]
18268   "TARGET_USE_FANCY_MATH_387
18269    && flag_unsafe_math_optimizations"
18271   rtx op2;
18273   if (optimize_insn_for_size_p ())
18274     FAIL;
18276   op2 = gen_reg_rtx (XFmode);
18277   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
18279   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18280   DONE;
18283 (define_expand "exp2<mode>2"
18284   [(use (match_operand:MODEF 0 "register_operand" ""))
18285    (use (match_operand:MODEF 1 "general_operand" ""))]
18286  "TARGET_USE_FANCY_MATH_387
18287    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18288        || TARGET_MIX_SSE_I387)
18289    && flag_unsafe_math_optimizations"
18291   rtx op0, op1;
18293   if (optimize_insn_for_size_p ())
18294     FAIL;
18296   op0 = gen_reg_rtx (XFmode);
18297   op1 = gen_reg_rtx (XFmode);
18299   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18300   emit_insn (gen_exp2xf2 (op0, op1));
18301   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18302   DONE;
18305 (define_expand "expm1xf2"
18306   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
18307                                (match_dup 2)))
18308    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
18309    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
18310    (set (match_dup 9) (float_extend:XF (match_dup 13)))
18311    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
18312    (parallel [(set (match_dup 7)
18313                    (unspec:XF [(match_dup 6) (match_dup 4)]
18314                               UNSPEC_FSCALE_FRACT))
18315               (set (match_dup 8)
18316                    (unspec:XF [(match_dup 6) (match_dup 4)]
18317                               UNSPEC_FSCALE_EXP))])
18318    (parallel [(set (match_dup 10)
18319                    (unspec:XF [(match_dup 9) (match_dup 8)]
18320                               UNSPEC_FSCALE_FRACT))
18321               (set (match_dup 11)
18322                    (unspec:XF [(match_dup 9) (match_dup 8)]
18323                               UNSPEC_FSCALE_EXP))])
18324    (set (match_dup 12) (minus:XF (match_dup 10)
18325                                  (float_extend:XF (match_dup 13))))
18326    (set (match_operand:XF 0 "register_operand" "")
18327         (plus:XF (match_dup 12) (match_dup 7)))]
18328   "TARGET_USE_FANCY_MATH_387
18329    && flag_unsafe_math_optimizations"
18331   int i;
18333   if (optimize_insn_for_size_p ())
18334     FAIL;
18336   for (i = 2; i < 13; i++)
18337     operands[i] = gen_reg_rtx (XFmode);
18339   operands[13]
18340     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
18342   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
18345 (define_expand "expm1<mode>2"
18346   [(use (match_operand:MODEF 0 "register_operand" ""))
18347    (use (match_operand:MODEF 1 "general_operand" ""))]
18348  "TARGET_USE_FANCY_MATH_387
18349    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18350        || TARGET_MIX_SSE_I387)
18351    && flag_unsafe_math_optimizations"
18353   rtx op0, op1;
18355   if (optimize_insn_for_size_p ())
18356     FAIL;
18358   op0 = gen_reg_rtx (XFmode);
18359   op1 = gen_reg_rtx (XFmode);
18361   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18362   emit_insn (gen_expm1xf2 (op0, op1));
18363   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18364   DONE;
18367 (define_expand "ldexpxf3"
18368   [(set (match_dup 3)
18369         (float:XF (match_operand:SI 2 "register_operand" "")))
18370    (parallel [(set (match_operand:XF 0 " register_operand" "")
18371                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
18372                                (match_dup 3)]
18373                               UNSPEC_FSCALE_FRACT))
18374               (set (match_dup 4)
18375                    (unspec:XF [(match_dup 1) (match_dup 3)]
18376                               UNSPEC_FSCALE_EXP))])]
18377   "TARGET_USE_FANCY_MATH_387
18378    && flag_unsafe_math_optimizations"
18380   if (optimize_insn_for_size_p ())
18381     FAIL;
18383   operands[3] = gen_reg_rtx (XFmode);
18384   operands[4] = gen_reg_rtx (XFmode);
18387 (define_expand "ldexp<mode>3"
18388   [(use (match_operand:MODEF 0 "register_operand" ""))
18389    (use (match_operand:MODEF 1 "general_operand" ""))
18390    (use (match_operand:SI 2 "register_operand" ""))]
18391  "TARGET_USE_FANCY_MATH_387
18392    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18393        || TARGET_MIX_SSE_I387)
18394    && flag_unsafe_math_optimizations"
18396   rtx op0, op1;
18398   if (optimize_insn_for_size_p ())
18399     FAIL;
18401   op0 = gen_reg_rtx (XFmode);
18402   op1 = gen_reg_rtx (XFmode);
18404   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18405   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
18406   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18407   DONE;
18410 (define_expand "scalbxf3"
18411   [(parallel [(set (match_operand:XF 0 " register_operand" "")
18412                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
18413                                (match_operand:XF 2 "register_operand" "")]
18414                               UNSPEC_FSCALE_FRACT))
18415               (set (match_dup 3)
18416                    (unspec:XF [(match_dup 1) (match_dup 2)]
18417                               UNSPEC_FSCALE_EXP))])]
18418   "TARGET_USE_FANCY_MATH_387
18419    && flag_unsafe_math_optimizations"
18421   if (optimize_insn_for_size_p ())
18422     FAIL;
18424   operands[3] = gen_reg_rtx (XFmode);
18427 (define_expand "scalb<mode>3"
18428   [(use (match_operand:MODEF 0 "register_operand" ""))
18429    (use (match_operand:MODEF 1 "general_operand" ""))
18430    (use (match_operand:MODEF 2 "general_operand" ""))]
18431  "TARGET_USE_FANCY_MATH_387
18432    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18433        || TARGET_MIX_SSE_I387)
18434    && flag_unsafe_math_optimizations"
18436   rtx op0, op1, op2;
18438   if (optimize_insn_for_size_p ())
18439     FAIL;
18441   op0 = gen_reg_rtx (XFmode);
18442   op1 = gen_reg_rtx (XFmode);
18443   op2 = gen_reg_rtx (XFmode);
18445   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18446   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
18447   emit_insn (gen_scalbxf3 (op0, op1, op2));
18448   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18449   DONE;
18452 (define_expand "significandxf2"
18453   [(parallel [(set (match_operand:XF 0 "register_operand" "")
18454                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18455                               UNSPEC_XTRACT_FRACT))
18456               (set (match_dup 2)
18457                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
18458   "TARGET_USE_FANCY_MATH_387
18459    && flag_unsafe_math_optimizations"
18461   operands[2] = gen_reg_rtx (XFmode);
18464 (define_expand "significand<mode>2"
18465   [(use (match_operand:MODEF 0 "register_operand" ""))
18466    (use (match_operand:MODEF 1 "register_operand" ""))]
18467   "TARGET_USE_FANCY_MATH_387
18468    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18469        || TARGET_MIX_SSE_I387)
18470    && flag_unsafe_math_optimizations"
18472   rtx op0 = gen_reg_rtx (XFmode);
18473   rtx op1 = gen_reg_rtx (XFmode);
18475   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18476   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18477   DONE;
18481 (define_insn "sse4_1_round<mode>2"
18482   [(set (match_operand:MODEF 0 "register_operand" "=x")
18483         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
18484                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
18485                       UNSPEC_ROUND))]
18486   "TARGET_ROUND"
18487   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
18488   [(set_attr "type" "ssecvt")
18489    (set_attr "prefix_extra" "1")
18490    (set_attr "prefix" "maybe_vex")
18491    (set_attr "mode" "<MODE>")])
18493 (define_insn "rintxf2"
18494   [(set (match_operand:XF 0 "register_operand" "=f")
18495         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18496                    UNSPEC_FRNDINT))]
18497   "TARGET_USE_FANCY_MATH_387
18498    && flag_unsafe_math_optimizations"
18499   "frndint"
18500   [(set_attr "type" "fpspc")
18501    (set_attr "mode" "XF")])
18503 (define_expand "rint<mode>2"
18504   [(use (match_operand:MODEF 0 "register_operand" ""))
18505    (use (match_operand:MODEF 1 "register_operand" ""))]
18506   "(TARGET_USE_FANCY_MATH_387
18507     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18508         || TARGET_MIX_SSE_I387)
18509     && flag_unsafe_math_optimizations)
18510    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18511        && !flag_trapping_math)"
18513   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18514       && !flag_trapping_math)
18515     {
18516       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18517         FAIL;
18518       if (TARGET_ROUND)
18519         emit_insn (gen_sse4_1_round<mode>2
18520                    (operands[0], operands[1], GEN_INT (0x04)));
18521       else
18522         ix86_expand_rint (operand0, operand1);
18523     }
18524   else
18525     {
18526       rtx op0 = gen_reg_rtx (XFmode);
18527       rtx op1 = gen_reg_rtx (XFmode);
18529       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18530       emit_insn (gen_rintxf2 (op0, op1));
18532       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18533     }
18534   DONE;
18537 (define_expand "round<mode>2"
18538   [(match_operand:MODEF 0 "register_operand" "")
18539    (match_operand:MODEF 1 "nonimmediate_operand" "")]
18540   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18541    && !flag_trapping_math && !flag_rounding_math"
18543   if (optimize_insn_for_size_p ())
18544     FAIL;
18545   if (TARGET_64BIT || (<MODE>mode != DFmode))
18546     ix86_expand_round (operand0, operand1);
18547   else
18548     ix86_expand_rounddf_32 (operand0, operand1);
18549   DONE;
18552 (define_insn_and_split "*fistdi2_1"
18553   [(set (match_operand:DI 0 "nonimmediate_operand" "")
18554         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18555                    UNSPEC_FIST))]
18556   "TARGET_USE_FANCY_MATH_387
18557    && can_create_pseudo_p ()"
18558   "#"
18559   "&& 1"
18560   [(const_int 0)]
18562   if (memory_operand (operands[0], VOIDmode))
18563     emit_insn (gen_fistdi2 (operands[0], operands[1]));
18564   else
18565     {
18566       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
18567       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
18568                                          operands[2]));
18569     }
18570   DONE;
18572   [(set_attr "type" "fpspc")
18573    (set_attr "mode" "DI")])
18575 (define_insn "fistdi2"
18576   [(set (match_operand:DI 0 "memory_operand" "=m")
18577         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18578                    UNSPEC_FIST))
18579    (clobber (match_scratch:XF 2 "=&1f"))]
18580   "TARGET_USE_FANCY_MATH_387"
18581   "* return output_fix_trunc (insn, operands, 0);"
18582   [(set_attr "type" "fpspc")
18583    (set_attr "mode" "DI")])
18585 (define_insn "fistdi2_with_temp"
18586   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18587         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18588                    UNSPEC_FIST))
18589    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18590    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18591   "TARGET_USE_FANCY_MATH_387"
18592   "#"
18593   [(set_attr "type" "fpspc")
18594    (set_attr "mode" "DI")])
18596 (define_split
18597   [(set (match_operand:DI 0 "register_operand" "")
18598         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18599                    UNSPEC_FIST))
18600    (clobber (match_operand:DI 2 "memory_operand" ""))
18601    (clobber (match_scratch 3 ""))]
18602   "reload_completed"
18603   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18604               (clobber (match_dup 3))])
18605    (set (match_dup 0) (match_dup 2))]
18606   "")
18608 (define_split
18609   [(set (match_operand:DI 0 "memory_operand" "")
18610         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18611                    UNSPEC_FIST))
18612    (clobber (match_operand:DI 2 "memory_operand" ""))
18613    (clobber (match_scratch 3 ""))]
18614   "reload_completed"
18615   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18616               (clobber (match_dup 3))])]
18617   "")
18619 (define_insn_and_split "*fist<mode>2_1"
18620   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18621         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18622                            UNSPEC_FIST))]
18623   "TARGET_USE_FANCY_MATH_387
18624    && can_create_pseudo_p ()"
18625   "#"
18626   "&& 1"
18627   [(const_int 0)]
18629   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18630   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18631                                         operands[2]));
18632   DONE;
18634   [(set_attr "type" "fpspc")
18635    (set_attr "mode" "<MODE>")])
18637 (define_insn "fist<mode>2"
18638   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18639         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18640                            UNSPEC_FIST))]
18641   "TARGET_USE_FANCY_MATH_387"
18642   "* return output_fix_trunc (insn, operands, 0);"
18643   [(set_attr "type" "fpspc")
18644    (set_attr "mode" "<MODE>")])
18646 (define_insn "fist<mode>2_with_temp"
18647   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18648         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18649                            UNSPEC_FIST))
18650    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18651   "TARGET_USE_FANCY_MATH_387"
18652   "#"
18653   [(set_attr "type" "fpspc")
18654    (set_attr "mode" "<MODE>")])
18656 (define_split
18657   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18658         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18659                            UNSPEC_FIST))
18660    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18661   "reload_completed"
18662   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18663    (set (match_dup 0) (match_dup 2))]
18664   "")
18666 (define_split
18667   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18668         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18669                            UNSPEC_FIST))
18670    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18671   "reload_completed"
18672   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18673   "")
18675 (define_expand "lrintxf<mode>2"
18676   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18677      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18678                       UNSPEC_FIST))]
18679   "TARGET_USE_FANCY_MATH_387"
18680   "")
18682 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18683   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18684      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18685                         UNSPEC_FIX_NOTRUNC))]
18686   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18687    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18688   "")
18690 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18691   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18692    (match_operand:MODEF 1 "register_operand" "")]
18693   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18694    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18695    && !flag_trapping_math && !flag_rounding_math"
18697   if (optimize_insn_for_size_p ())
18698     FAIL;
18699   ix86_expand_lround (operand0, operand1);
18700   DONE;
18703 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18704 (define_insn_and_split "frndintxf2_floor"
18705   [(set (match_operand:XF 0 "register_operand" "")
18706         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18707          UNSPEC_FRNDINT_FLOOR))
18708    (clobber (reg:CC FLAGS_REG))]
18709   "TARGET_USE_FANCY_MATH_387
18710    && flag_unsafe_math_optimizations
18711    && can_create_pseudo_p ()"
18712   "#"
18713   "&& 1"
18714   [(const_int 0)]
18716   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18718   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18719   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18721   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18722                                         operands[2], operands[3]));
18723   DONE;
18725   [(set_attr "type" "frndint")
18726    (set_attr "i387_cw" "floor")
18727    (set_attr "mode" "XF")])
18729 (define_insn "frndintxf2_floor_i387"
18730   [(set (match_operand:XF 0 "register_operand" "=f")
18731         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18732          UNSPEC_FRNDINT_FLOOR))
18733    (use (match_operand:HI 2 "memory_operand" "m"))
18734    (use (match_operand:HI 3 "memory_operand" "m"))]
18735   "TARGET_USE_FANCY_MATH_387
18736    && flag_unsafe_math_optimizations"
18737   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18738   [(set_attr "type" "frndint")
18739    (set_attr "i387_cw" "floor")
18740    (set_attr "mode" "XF")])
18742 (define_expand "floorxf2"
18743   [(use (match_operand:XF 0 "register_operand" ""))
18744    (use (match_operand:XF 1 "register_operand" ""))]
18745   "TARGET_USE_FANCY_MATH_387
18746    && flag_unsafe_math_optimizations"
18748   if (optimize_insn_for_size_p ())
18749     FAIL;
18750   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18751   DONE;
18754 (define_expand "floor<mode>2"
18755   [(use (match_operand:MODEF 0 "register_operand" ""))
18756    (use (match_operand:MODEF 1 "register_operand" ""))]
18757   "(TARGET_USE_FANCY_MATH_387
18758     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18759         || TARGET_MIX_SSE_I387)
18760     && flag_unsafe_math_optimizations)
18761    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18762        && !flag_trapping_math)"
18764   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18765       && !flag_trapping_math
18766       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18767     {
18768       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18769         FAIL;
18770       if (TARGET_ROUND)
18771         emit_insn (gen_sse4_1_round<mode>2
18772                    (operands[0], operands[1], GEN_INT (0x01)));
18773       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18774         ix86_expand_floorceil (operand0, operand1, true);
18775       else
18776         ix86_expand_floorceildf_32 (operand0, operand1, true);
18777     }
18778   else
18779     {
18780       rtx op0, op1;
18782       if (optimize_insn_for_size_p ())
18783         FAIL;
18785       op0 = gen_reg_rtx (XFmode);
18786       op1 = gen_reg_rtx (XFmode);
18787       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18788       emit_insn (gen_frndintxf2_floor (op0, op1));
18790       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18791     }
18792   DONE;
18795 (define_insn_and_split "*fist<mode>2_floor_1"
18796   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18797         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18798          UNSPEC_FIST_FLOOR))
18799    (clobber (reg:CC FLAGS_REG))]
18800   "TARGET_USE_FANCY_MATH_387
18801    && flag_unsafe_math_optimizations
18802    && can_create_pseudo_p ()"
18803   "#"
18804   "&& 1"
18805   [(const_int 0)]
18807   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18809   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18810   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18811   if (memory_operand (operands[0], VOIDmode))
18812     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18813                                       operands[2], operands[3]));
18814   else
18815     {
18816       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18817       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18818                                                   operands[2], operands[3],
18819                                                   operands[4]));
18820     }
18821   DONE;
18823   [(set_attr "type" "fistp")
18824    (set_attr "i387_cw" "floor")
18825    (set_attr "mode" "<MODE>")])
18827 (define_insn "fistdi2_floor"
18828   [(set (match_operand:DI 0 "memory_operand" "=m")
18829         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18830          UNSPEC_FIST_FLOOR))
18831    (use (match_operand:HI 2 "memory_operand" "m"))
18832    (use (match_operand:HI 3 "memory_operand" "m"))
18833    (clobber (match_scratch:XF 4 "=&1f"))]
18834   "TARGET_USE_FANCY_MATH_387
18835    && flag_unsafe_math_optimizations"
18836   "* return output_fix_trunc (insn, operands, 0);"
18837   [(set_attr "type" "fistp")
18838    (set_attr "i387_cw" "floor")
18839    (set_attr "mode" "DI")])
18841 (define_insn "fistdi2_floor_with_temp"
18842   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18843         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18844          UNSPEC_FIST_FLOOR))
18845    (use (match_operand:HI 2 "memory_operand" "m,m"))
18846    (use (match_operand:HI 3 "memory_operand" "m,m"))
18847    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18848    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18849   "TARGET_USE_FANCY_MATH_387
18850    && flag_unsafe_math_optimizations"
18851   "#"
18852   [(set_attr "type" "fistp")
18853    (set_attr "i387_cw" "floor")
18854    (set_attr "mode" "DI")])
18856 (define_split
18857   [(set (match_operand:DI 0 "register_operand" "")
18858         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18859          UNSPEC_FIST_FLOOR))
18860    (use (match_operand:HI 2 "memory_operand" ""))
18861    (use (match_operand:HI 3 "memory_operand" ""))
18862    (clobber (match_operand:DI 4 "memory_operand" ""))
18863    (clobber (match_scratch 5 ""))]
18864   "reload_completed"
18865   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18866               (use (match_dup 2))
18867               (use (match_dup 3))
18868               (clobber (match_dup 5))])
18869    (set (match_dup 0) (match_dup 4))]
18870   "")
18872 (define_split
18873   [(set (match_operand:DI 0 "memory_operand" "")
18874         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18875          UNSPEC_FIST_FLOOR))
18876    (use (match_operand:HI 2 "memory_operand" ""))
18877    (use (match_operand:HI 3 "memory_operand" ""))
18878    (clobber (match_operand:DI 4 "memory_operand" ""))
18879    (clobber (match_scratch 5 ""))]
18880   "reload_completed"
18881   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18882               (use (match_dup 2))
18883               (use (match_dup 3))
18884               (clobber (match_dup 5))])]
18885   "")
18887 (define_insn "fist<mode>2_floor"
18888   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18889         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18890          UNSPEC_FIST_FLOOR))
18891    (use (match_operand:HI 2 "memory_operand" "m"))
18892    (use (match_operand:HI 3 "memory_operand" "m"))]
18893   "TARGET_USE_FANCY_MATH_387
18894    && flag_unsafe_math_optimizations"
18895   "* return output_fix_trunc (insn, operands, 0);"
18896   [(set_attr "type" "fistp")
18897    (set_attr "i387_cw" "floor")
18898    (set_attr "mode" "<MODE>")])
18900 (define_insn "fist<mode>2_floor_with_temp"
18901   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18902         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18903          UNSPEC_FIST_FLOOR))
18904    (use (match_operand:HI 2 "memory_operand" "m,m"))
18905    (use (match_operand:HI 3 "memory_operand" "m,m"))
18906    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18907   "TARGET_USE_FANCY_MATH_387
18908    && flag_unsafe_math_optimizations"
18909   "#"
18910   [(set_attr "type" "fistp")
18911    (set_attr "i387_cw" "floor")
18912    (set_attr "mode" "<MODE>")])
18914 (define_split
18915   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18916         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18917          UNSPEC_FIST_FLOOR))
18918    (use (match_operand:HI 2 "memory_operand" ""))
18919    (use (match_operand:HI 3 "memory_operand" ""))
18920    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18921   "reload_completed"
18922   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18923                                   UNSPEC_FIST_FLOOR))
18924               (use (match_dup 2))
18925               (use (match_dup 3))])
18926    (set (match_dup 0) (match_dup 4))]
18927   "")
18929 (define_split
18930   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18931         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18932          UNSPEC_FIST_FLOOR))
18933    (use (match_operand:HI 2 "memory_operand" ""))
18934    (use (match_operand:HI 3 "memory_operand" ""))
18935    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18936   "reload_completed"
18937   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18938                                   UNSPEC_FIST_FLOOR))
18939               (use (match_dup 2))
18940               (use (match_dup 3))])]
18941   "")
18943 (define_expand "lfloorxf<mode>2"
18944   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18945                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18946                     UNSPEC_FIST_FLOOR))
18947               (clobber (reg:CC FLAGS_REG))])]
18948   "TARGET_USE_FANCY_MATH_387
18949    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18950    && flag_unsafe_math_optimizations"
18951   "")
18953 (define_expand "lfloor<mode>di2"
18954   [(match_operand:DI 0 "nonimmediate_operand" "")
18955    (match_operand:MODEF 1 "register_operand" "")]
18956   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18957    && !flag_trapping_math"
18959   if (optimize_insn_for_size_p ())
18960     FAIL;
18961   ix86_expand_lfloorceil (operand0, operand1, true);
18962   DONE;
18965 (define_expand "lfloor<mode>si2"
18966   [(match_operand:SI 0 "nonimmediate_operand" "")
18967    (match_operand:MODEF 1 "register_operand" "")]
18968   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18969    && !flag_trapping_math"
18971   if (optimize_insn_for_size_p () && TARGET_64BIT)
18972     FAIL;
18973   ix86_expand_lfloorceil (operand0, operand1, true);
18974   DONE;
18977 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18978 (define_insn_and_split "frndintxf2_ceil"
18979   [(set (match_operand:XF 0 "register_operand" "")
18980         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18981          UNSPEC_FRNDINT_CEIL))
18982    (clobber (reg:CC FLAGS_REG))]
18983   "TARGET_USE_FANCY_MATH_387
18984    && flag_unsafe_math_optimizations
18985    && can_create_pseudo_p ()"
18986   "#"
18987   "&& 1"
18988   [(const_int 0)]
18990   ix86_optimize_mode_switching[I387_CEIL] = 1;
18992   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18993   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18995   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18996                                        operands[2], operands[3]));
18997   DONE;
18999   [(set_attr "type" "frndint")
19000    (set_attr "i387_cw" "ceil")
19001    (set_attr "mode" "XF")])
19003 (define_insn "frndintxf2_ceil_i387"
19004   [(set (match_operand:XF 0 "register_operand" "=f")
19005         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19006          UNSPEC_FRNDINT_CEIL))
19007    (use (match_operand:HI 2 "memory_operand" "m"))
19008    (use (match_operand:HI 3 "memory_operand" "m"))]
19009   "TARGET_USE_FANCY_MATH_387
19010    && flag_unsafe_math_optimizations"
19011   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
19012   [(set_attr "type" "frndint")
19013    (set_attr "i387_cw" "ceil")
19014    (set_attr "mode" "XF")])
19016 (define_expand "ceilxf2"
19017   [(use (match_operand:XF 0 "register_operand" ""))
19018    (use (match_operand:XF 1 "register_operand" ""))]
19019   "TARGET_USE_FANCY_MATH_387
19020    && flag_unsafe_math_optimizations"
19022   if (optimize_insn_for_size_p ())
19023     FAIL;
19024   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
19025   DONE;
19028 (define_expand "ceil<mode>2"
19029   [(use (match_operand:MODEF 0 "register_operand" ""))
19030    (use (match_operand:MODEF 1 "register_operand" ""))]
19031   "(TARGET_USE_FANCY_MATH_387
19032     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19033         || TARGET_MIX_SSE_I387)
19034     && flag_unsafe_math_optimizations)
19035    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19036        && !flag_trapping_math)"
19038   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19039       && !flag_trapping_math
19040       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
19041     {
19042       if (TARGET_ROUND)
19043         emit_insn (gen_sse4_1_round<mode>2
19044                    (operands[0], operands[1], GEN_INT (0x02)));
19045       else if (optimize_insn_for_size_p ())
19046         FAIL;
19047       else if (TARGET_64BIT || (<MODE>mode != DFmode))
19048         ix86_expand_floorceil (operand0, operand1, false);
19049       else
19050         ix86_expand_floorceildf_32 (operand0, operand1, false);
19051     }
19052   else
19053     {
19054       rtx op0, op1;
19056       if (optimize_insn_for_size_p ())
19057         FAIL;
19059       op0 = gen_reg_rtx (XFmode);
19060       op1 = gen_reg_rtx (XFmode);
19061       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19062       emit_insn (gen_frndintxf2_ceil (op0, op1));
19064       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19065     }
19066   DONE;
19069 (define_insn_and_split "*fist<mode>2_ceil_1"
19070   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19071         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
19072          UNSPEC_FIST_CEIL))
19073    (clobber (reg:CC FLAGS_REG))]
19074   "TARGET_USE_FANCY_MATH_387
19075    && flag_unsafe_math_optimizations
19076    && can_create_pseudo_p ()"
19077   "#"
19078   "&& 1"
19079   [(const_int 0)]
19081   ix86_optimize_mode_switching[I387_CEIL] = 1;
19083   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19084   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
19085   if (memory_operand (operands[0], VOIDmode))
19086     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
19087                                      operands[2], operands[3]));
19088   else
19089     {
19090       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
19091       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
19092                                                  operands[2], operands[3],
19093                                                  operands[4]));
19094     }
19095   DONE;
19097   [(set_attr "type" "fistp")
19098    (set_attr "i387_cw" "ceil")
19099    (set_attr "mode" "<MODE>")])
19101 (define_insn "fistdi2_ceil"
19102   [(set (match_operand:DI 0 "memory_operand" "=m")
19103         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
19104          UNSPEC_FIST_CEIL))
19105    (use (match_operand:HI 2 "memory_operand" "m"))
19106    (use (match_operand:HI 3 "memory_operand" "m"))
19107    (clobber (match_scratch:XF 4 "=&1f"))]
19108   "TARGET_USE_FANCY_MATH_387
19109    && flag_unsafe_math_optimizations"
19110   "* return output_fix_trunc (insn, operands, 0);"
19111   [(set_attr "type" "fistp")
19112    (set_attr "i387_cw" "ceil")
19113    (set_attr "mode" "DI")])
19115 (define_insn "fistdi2_ceil_with_temp"
19116   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
19117         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
19118          UNSPEC_FIST_CEIL))
19119    (use (match_operand:HI 2 "memory_operand" "m,m"))
19120    (use (match_operand:HI 3 "memory_operand" "m,m"))
19121    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
19122    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
19123   "TARGET_USE_FANCY_MATH_387
19124    && flag_unsafe_math_optimizations"
19125   "#"
19126   [(set_attr "type" "fistp")
19127    (set_attr "i387_cw" "ceil")
19128    (set_attr "mode" "DI")])
19130 (define_split
19131   [(set (match_operand:DI 0 "register_operand" "")
19132         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
19133          UNSPEC_FIST_CEIL))
19134    (use (match_operand:HI 2 "memory_operand" ""))
19135    (use (match_operand:HI 3 "memory_operand" ""))
19136    (clobber (match_operand:DI 4 "memory_operand" ""))
19137    (clobber (match_scratch 5 ""))]
19138   "reload_completed"
19139   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
19140               (use (match_dup 2))
19141               (use (match_dup 3))
19142               (clobber (match_dup 5))])
19143    (set (match_dup 0) (match_dup 4))]
19144   "")
19146 (define_split
19147   [(set (match_operand:DI 0 "memory_operand" "")
19148         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
19149          UNSPEC_FIST_CEIL))
19150    (use (match_operand:HI 2 "memory_operand" ""))
19151    (use (match_operand:HI 3 "memory_operand" ""))
19152    (clobber (match_operand:DI 4 "memory_operand" ""))
19153    (clobber (match_scratch 5 ""))]
19154   "reload_completed"
19155   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
19156               (use (match_dup 2))
19157               (use (match_dup 3))
19158               (clobber (match_dup 5))])]
19159   "")
19161 (define_insn "fist<mode>2_ceil"
19162   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
19163         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
19164          UNSPEC_FIST_CEIL))
19165    (use (match_operand:HI 2 "memory_operand" "m"))
19166    (use (match_operand:HI 3 "memory_operand" "m"))]
19167   "TARGET_USE_FANCY_MATH_387
19168    && flag_unsafe_math_optimizations"
19169   "* return output_fix_trunc (insn, operands, 0);"
19170   [(set_attr "type" "fistp")
19171    (set_attr "i387_cw" "ceil")
19172    (set_attr "mode" "<MODE>")])
19174 (define_insn "fist<mode>2_ceil_with_temp"
19175   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
19176         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
19177          UNSPEC_FIST_CEIL))
19178    (use (match_operand:HI 2 "memory_operand" "m,m"))
19179    (use (match_operand:HI 3 "memory_operand" "m,m"))
19180    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
19181   "TARGET_USE_FANCY_MATH_387
19182    && flag_unsafe_math_optimizations"
19183   "#"
19184   [(set_attr "type" "fistp")
19185    (set_attr "i387_cw" "ceil")
19186    (set_attr "mode" "<MODE>")])
19188 (define_split
19189   [(set (match_operand:X87MODEI12 0 "register_operand" "")
19190         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19191          UNSPEC_FIST_CEIL))
19192    (use (match_operand:HI 2 "memory_operand" ""))
19193    (use (match_operand:HI 3 "memory_operand" ""))
19194    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19195   "reload_completed"
19196   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
19197                                   UNSPEC_FIST_CEIL))
19198               (use (match_dup 2))
19199               (use (match_dup 3))])
19200    (set (match_dup 0) (match_dup 4))]
19201   "")
19203 (define_split
19204   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
19205         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19206          UNSPEC_FIST_CEIL))
19207    (use (match_operand:HI 2 "memory_operand" ""))
19208    (use (match_operand:HI 3 "memory_operand" ""))
19209    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19210   "reload_completed"
19211   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
19212                                   UNSPEC_FIST_CEIL))
19213               (use (match_dup 2))
19214               (use (match_dup 3))])]
19215   "")
19217 (define_expand "lceilxf<mode>2"
19218   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19219                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
19220                     UNSPEC_FIST_CEIL))
19221               (clobber (reg:CC FLAGS_REG))])]
19222   "TARGET_USE_FANCY_MATH_387
19223    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
19224    && flag_unsafe_math_optimizations"
19225   "")
19227 (define_expand "lceil<mode>di2"
19228   [(match_operand:DI 0 "nonimmediate_operand" "")
19229    (match_operand:MODEF 1 "register_operand" "")]
19230   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
19231    && !flag_trapping_math"
19233   ix86_expand_lfloorceil (operand0, operand1, false);
19234   DONE;
19237 (define_expand "lceil<mode>si2"
19238   [(match_operand:SI 0 "nonimmediate_operand" "")
19239    (match_operand:MODEF 1 "register_operand" "")]
19240   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19241    && !flag_trapping_math"
19243   ix86_expand_lfloorceil (operand0, operand1, false);
19244   DONE;
19247 ;; Rounding mode control word calculation could clobber FLAGS_REG.
19248 (define_insn_and_split "frndintxf2_trunc"
19249   [(set (match_operand:XF 0 "register_operand" "")
19250         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
19251          UNSPEC_FRNDINT_TRUNC))
19252    (clobber (reg:CC FLAGS_REG))]
19253   "TARGET_USE_FANCY_MATH_387
19254    && flag_unsafe_math_optimizations
19255    && can_create_pseudo_p ()"
19256   "#"
19257   "&& 1"
19258   [(const_int 0)]
19260   ix86_optimize_mode_switching[I387_TRUNC] = 1;
19262   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19263   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
19265   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
19266                                         operands[2], operands[3]));
19267   DONE;
19269   [(set_attr "type" "frndint")
19270    (set_attr "i387_cw" "trunc")
19271    (set_attr "mode" "XF")])
19273 (define_insn "frndintxf2_trunc_i387"
19274   [(set (match_operand:XF 0 "register_operand" "=f")
19275         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19276          UNSPEC_FRNDINT_TRUNC))
19277    (use (match_operand:HI 2 "memory_operand" "m"))
19278    (use (match_operand:HI 3 "memory_operand" "m"))]
19279   "TARGET_USE_FANCY_MATH_387
19280    && flag_unsafe_math_optimizations"
19281   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
19282   [(set_attr "type" "frndint")
19283    (set_attr "i387_cw" "trunc")
19284    (set_attr "mode" "XF")])
19286 (define_expand "btruncxf2"
19287   [(use (match_operand:XF 0 "register_operand" ""))
19288    (use (match_operand:XF 1 "register_operand" ""))]
19289   "TARGET_USE_FANCY_MATH_387
19290    && flag_unsafe_math_optimizations"
19292   if (optimize_insn_for_size_p ())
19293     FAIL;
19294   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
19295   DONE;
19298 (define_expand "btrunc<mode>2"
19299   [(use (match_operand:MODEF 0 "register_operand" ""))
19300    (use (match_operand:MODEF 1 "register_operand" ""))]
19301   "(TARGET_USE_FANCY_MATH_387
19302     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19303         || TARGET_MIX_SSE_I387)
19304     && flag_unsafe_math_optimizations)
19305    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19306        && !flag_trapping_math)"
19308   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19309       && !flag_trapping_math
19310       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
19311     {
19312       if (TARGET_ROUND)
19313         emit_insn (gen_sse4_1_round<mode>2
19314                    (operands[0], operands[1], GEN_INT (0x03)));
19315       else if (optimize_insn_for_size_p ())
19316         FAIL;
19317       else if (TARGET_64BIT || (<MODE>mode != DFmode))
19318         ix86_expand_trunc (operand0, operand1);
19319       else
19320         ix86_expand_truncdf_32 (operand0, operand1);
19321     }
19322   else
19323     {
19324       rtx op0, op1;
19326       if (optimize_insn_for_size_p ())
19327         FAIL;
19329       op0 = gen_reg_rtx (XFmode);
19330       op1 = gen_reg_rtx (XFmode);
19331       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19332       emit_insn (gen_frndintxf2_trunc (op0, op1));
19334       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19335     }
19336   DONE;
19339 ;; Rounding mode control word calculation could clobber FLAGS_REG.
19340 (define_insn_and_split "frndintxf2_mask_pm"
19341   [(set (match_operand:XF 0 "register_operand" "")
19342         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
19343          UNSPEC_FRNDINT_MASK_PM))
19344    (clobber (reg:CC FLAGS_REG))]
19345   "TARGET_USE_FANCY_MATH_387
19346    && flag_unsafe_math_optimizations
19347    && can_create_pseudo_p ()"
19348   "#"
19349   "&& 1"
19350   [(const_int 0)]
19352   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
19354   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19355   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
19357   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
19358                                           operands[2], operands[3]));
19359   DONE;
19361   [(set_attr "type" "frndint")
19362    (set_attr "i387_cw" "mask_pm")
19363    (set_attr "mode" "XF")])
19365 (define_insn "frndintxf2_mask_pm_i387"
19366   [(set (match_operand:XF 0 "register_operand" "=f")
19367         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19368          UNSPEC_FRNDINT_MASK_PM))
19369    (use (match_operand:HI 2 "memory_operand" "m"))
19370    (use (match_operand:HI 3 "memory_operand" "m"))]
19371   "TARGET_USE_FANCY_MATH_387
19372    && flag_unsafe_math_optimizations"
19373   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
19374   [(set_attr "type" "frndint")
19375    (set_attr "i387_cw" "mask_pm")
19376    (set_attr "mode" "XF")])
19378 (define_expand "nearbyintxf2"
19379   [(use (match_operand:XF 0 "register_operand" ""))
19380    (use (match_operand:XF 1 "register_operand" ""))]
19381   "TARGET_USE_FANCY_MATH_387
19382    && flag_unsafe_math_optimizations"
19384   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
19386   DONE;
19389 (define_expand "nearbyint<mode>2"
19390   [(use (match_operand:MODEF 0 "register_operand" ""))
19391    (use (match_operand:MODEF 1 "register_operand" ""))]
19392   "TARGET_USE_FANCY_MATH_387
19393    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19394        || TARGET_MIX_SSE_I387)
19395    && flag_unsafe_math_optimizations"
19397   rtx op0 = gen_reg_rtx (XFmode);
19398   rtx op1 = gen_reg_rtx (XFmode);
19400   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19401   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
19403   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19404   DONE;
19407 (define_insn "fxam<mode>2_i387"
19408   [(set (match_operand:HI 0 "register_operand" "=a")
19409         (unspec:HI
19410           [(match_operand:X87MODEF 1 "register_operand" "f")]
19411           UNSPEC_FXAM))]
19412   "TARGET_USE_FANCY_MATH_387"
19413   "fxam\n\tfnstsw\t%0"
19414   [(set_attr "type" "multi")
19415    (set_attr "length" "4")
19416    (set_attr "unit" "i387")
19417    (set_attr "mode" "<MODE>")])
19419 (define_insn_and_split "fxam<mode>2_i387_with_temp"
19420   [(set (match_operand:HI 0 "register_operand" "")
19421         (unspec:HI
19422           [(match_operand:MODEF 1 "memory_operand" "")]
19423           UNSPEC_FXAM_MEM))]
19424   "TARGET_USE_FANCY_MATH_387
19425    && can_create_pseudo_p ()"
19426   "#"
19427   "&& 1"
19428   [(set (match_dup 2)(match_dup 1))
19429    (set (match_dup 0)
19430         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
19432   operands[2] = gen_reg_rtx (<MODE>mode);
19434   MEM_VOLATILE_P (operands[1]) = 1;
19436   [(set_attr "type" "multi")
19437    (set_attr "unit" "i387")
19438    (set_attr "mode" "<MODE>")])
19440 (define_expand "isinfxf2"
19441   [(use (match_operand:SI 0 "register_operand" ""))
19442    (use (match_operand:XF 1 "register_operand" ""))]
19443   "TARGET_USE_FANCY_MATH_387
19444    && TARGET_C99_FUNCTIONS"
19446   rtx mask = GEN_INT (0x45);
19447   rtx val = GEN_INT (0x05);
19449   rtx cond;
19451   rtx scratch = gen_reg_rtx (HImode);
19452   rtx res = gen_reg_rtx (QImode);
19454   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
19456   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19457   emit_insn (gen_cmpqi_ext_3 (scratch, val));
19458   cond = gen_rtx_fmt_ee (EQ, QImode,
19459                          gen_rtx_REG (CCmode, FLAGS_REG),
19460                          const0_rtx);
19461   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19462   emit_insn (gen_zero_extendqisi2 (operands[0], res));
19463   DONE;
19466 (define_expand "isinf<mode>2"
19467   [(use (match_operand:SI 0 "register_operand" ""))
19468    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
19469   "TARGET_USE_FANCY_MATH_387
19470    && TARGET_C99_FUNCTIONS
19471    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19473   rtx mask = GEN_INT (0x45);
19474   rtx val = GEN_INT (0x05);
19476   rtx cond;
19478   rtx scratch = gen_reg_rtx (HImode);
19479   rtx res = gen_reg_rtx (QImode);
19481   /* Remove excess precision by forcing value through memory. */
19482   if (memory_operand (operands[1], VOIDmode))
19483     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
19484   else
19485     {
19486       enum ix86_stack_slot slot = (virtuals_instantiated
19487                                    ? SLOT_TEMP
19488                                    : SLOT_VIRTUAL);
19489       rtx temp = assign_386_stack_local (<MODE>mode, slot);
19491       emit_move_insn (temp, operands[1]);
19492       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
19493     }
19495   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19496   emit_insn (gen_cmpqi_ext_3 (scratch, val));
19497   cond = gen_rtx_fmt_ee (EQ, QImode,
19498                          gen_rtx_REG (CCmode, FLAGS_REG),
19499                          const0_rtx);
19500   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19501   emit_insn (gen_zero_extendqisi2 (operands[0], res));
19502   DONE;
19505 (define_expand "signbit<mode>2"
19506   [(use (match_operand:SI 0 "register_operand" ""))
19507    (use (match_operand:X87MODEF 1 "register_operand" ""))]
19508   "TARGET_USE_FANCY_MATH_387
19509    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19511   rtx mask = GEN_INT (0x0200);
19513   rtx scratch = gen_reg_rtx (HImode);
19515   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
19516   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
19517   DONE;
19520 ;; Block operation instructions
19522 (define_insn "cld"
19523   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
19524   ""
19525   "cld"
19526   [(set_attr "length" "1")
19527    (set_attr "length_immediate" "0")
19528    (set_attr "modrm" "0")])
19530 (define_expand "movmemsi"
19531   [(use (match_operand:BLK 0 "memory_operand" ""))
19532    (use (match_operand:BLK 1 "memory_operand" ""))
19533    (use (match_operand:SI 2 "nonmemory_operand" ""))
19534    (use (match_operand:SI 3 "const_int_operand" ""))
19535    (use (match_operand:SI 4 "const_int_operand" ""))
19536    (use (match_operand:SI 5 "const_int_operand" ""))]
19537   ""
19539  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19540                          operands[4], operands[5]))
19541    DONE;
19542  else
19543    FAIL;
19546 (define_expand "movmemdi"
19547   [(use (match_operand:BLK 0 "memory_operand" ""))
19548    (use (match_operand:BLK 1 "memory_operand" ""))
19549    (use (match_operand:DI 2 "nonmemory_operand" ""))
19550    (use (match_operand:DI 3 "const_int_operand" ""))
19551    (use (match_operand:SI 4 "const_int_operand" ""))
19552    (use (match_operand:SI 5 "const_int_operand" ""))]
19553   "TARGET_64BIT"
19555  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19556                          operands[4], operands[5]))
19557    DONE;
19558  else
19559    FAIL;
19562 ;; Most CPUs don't like single string operations
19563 ;; Handle this case here to simplify previous expander.
19565 (define_expand "strmov"
19566   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
19567    (set (match_operand 1 "memory_operand" "") (match_dup 4))
19568    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
19569               (clobber (reg:CC FLAGS_REG))])
19570    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
19571               (clobber (reg:CC FLAGS_REG))])]
19572   ""
19574   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
19576   /* If .md ever supports :P for Pmode, these can be directly
19577      in the pattern above.  */
19578   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
19579   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
19581   /* Can't use this if the user has appropriated esi or edi.  */
19582   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19583       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
19584     {
19585       emit_insn (gen_strmov_singleop (operands[0], operands[1],
19586                                       operands[2], operands[3],
19587                                       operands[5], operands[6]));
19588       DONE;
19589     }
19591   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19594 (define_expand "strmov_singleop"
19595   [(parallel [(set (match_operand 1 "memory_operand" "")
19596                    (match_operand 3 "memory_operand" ""))
19597               (set (match_operand 0 "register_operand" "")
19598                    (match_operand 4 "" ""))
19599               (set (match_operand 2 "register_operand" "")
19600                    (match_operand 5 "" ""))])]
19601   ""
19602   "ix86_current_function_needs_cld = 1;")
19604 (define_insn "*strmovdi_rex_1"
19605   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19606         (mem:DI (match_operand:DI 3 "register_operand" "1")))
19607    (set (match_operand:DI 0 "register_operand" "=D")
19608         (plus:DI (match_dup 2)
19609                  (const_int 8)))
19610    (set (match_operand:DI 1 "register_operand" "=S")
19611         (plus:DI (match_dup 3)
19612                  (const_int 8)))]
19613   "TARGET_64BIT"
19614   "movsq"
19615   [(set_attr "type" "str")
19616    (set_attr "mode" "DI")
19617    (set_attr "memory" "both")])
19619 (define_insn "*strmovsi_1"
19620   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19621         (mem:SI (match_operand:SI 3 "register_operand" "1")))
19622    (set (match_operand:SI 0 "register_operand" "=D")
19623         (plus:SI (match_dup 2)
19624                  (const_int 4)))
19625    (set (match_operand:SI 1 "register_operand" "=S")
19626         (plus:SI (match_dup 3)
19627                  (const_int 4)))]
19628   "!TARGET_64BIT"
19629   "movs{l|d}"
19630   [(set_attr "type" "str")
19631    (set_attr "mode" "SI")
19632    (set_attr "memory" "both")])
19634 (define_insn "*strmovsi_rex_1"
19635   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19636         (mem:SI (match_operand:DI 3 "register_operand" "1")))
19637    (set (match_operand:DI 0 "register_operand" "=D")
19638         (plus:DI (match_dup 2)
19639                  (const_int 4)))
19640    (set (match_operand:DI 1 "register_operand" "=S")
19641         (plus:DI (match_dup 3)
19642                  (const_int 4)))]
19643   "TARGET_64BIT"
19644   "movs{l|d}"
19645   [(set_attr "type" "str")
19646    (set_attr "mode" "SI")
19647    (set_attr "memory" "both")])
19649 (define_insn "*strmovhi_1"
19650   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19651         (mem:HI (match_operand:SI 3 "register_operand" "1")))
19652    (set (match_operand:SI 0 "register_operand" "=D")
19653         (plus:SI (match_dup 2)
19654                  (const_int 2)))
19655    (set (match_operand:SI 1 "register_operand" "=S")
19656         (plus:SI (match_dup 3)
19657                  (const_int 2)))]
19658   "!TARGET_64BIT"
19659   "movsw"
19660   [(set_attr "type" "str")
19661    (set_attr "memory" "both")
19662    (set_attr "mode" "HI")])
19664 (define_insn "*strmovhi_rex_1"
19665   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19666         (mem:HI (match_operand:DI 3 "register_operand" "1")))
19667    (set (match_operand:DI 0 "register_operand" "=D")
19668         (plus:DI (match_dup 2)
19669                  (const_int 2)))
19670    (set (match_operand:DI 1 "register_operand" "=S")
19671         (plus:DI (match_dup 3)
19672                  (const_int 2)))]
19673   "TARGET_64BIT"
19674   "movsw"
19675   [(set_attr "type" "str")
19676    (set_attr "memory" "both")
19677    (set_attr "mode" "HI")])
19679 (define_insn "*strmovqi_1"
19680   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19681         (mem:QI (match_operand:SI 3 "register_operand" "1")))
19682    (set (match_operand:SI 0 "register_operand" "=D")
19683         (plus:SI (match_dup 2)
19684                  (const_int 1)))
19685    (set (match_operand:SI 1 "register_operand" "=S")
19686         (plus:SI (match_dup 3)
19687                  (const_int 1)))]
19688   "!TARGET_64BIT"
19689   "movsb"
19690   [(set_attr "type" "str")
19691    (set_attr "memory" "both")
19692    (set_attr "mode" "QI")])
19694 (define_insn "*strmovqi_rex_1"
19695   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19696         (mem:QI (match_operand:DI 3 "register_operand" "1")))
19697    (set (match_operand:DI 0 "register_operand" "=D")
19698         (plus:DI (match_dup 2)
19699                  (const_int 1)))
19700    (set (match_operand:DI 1 "register_operand" "=S")
19701         (plus:DI (match_dup 3)
19702                  (const_int 1)))]
19703   "TARGET_64BIT"
19704   "movsb"
19705   [(set_attr "type" "str")
19706    (set_attr "memory" "both")
19707    (set_attr "prefix_rex" "0")
19708    (set_attr "mode" "QI")])
19710 (define_expand "rep_mov"
19711   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19712               (set (match_operand 0 "register_operand" "")
19713                    (match_operand 5 "" ""))
19714               (set (match_operand 2 "register_operand" "")
19715                    (match_operand 6 "" ""))
19716               (set (match_operand 1 "memory_operand" "")
19717                    (match_operand 3 "memory_operand" ""))
19718               (use (match_dup 4))])]
19719   ""
19720   "ix86_current_function_needs_cld = 1;")
19722 (define_insn "*rep_movdi_rex64"
19723   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19724    (set (match_operand:DI 0 "register_operand" "=D")
19725         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19726                             (const_int 3))
19727                  (match_operand:DI 3 "register_operand" "0")))
19728    (set (match_operand:DI 1 "register_operand" "=S")
19729         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19730                  (match_operand:DI 4 "register_operand" "1")))
19731    (set (mem:BLK (match_dup 3))
19732         (mem:BLK (match_dup 4)))
19733    (use (match_dup 5))]
19734   "TARGET_64BIT"
19735   "rep movsq"
19736   [(set_attr "type" "str")
19737    (set_attr "prefix_rep" "1")
19738    (set_attr "memory" "both")
19739    (set_attr "mode" "DI")])
19741 (define_insn "*rep_movsi"
19742   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19743    (set (match_operand:SI 0 "register_operand" "=D")
19744         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19745                             (const_int 2))
19746                  (match_operand:SI 3 "register_operand" "0")))
19747    (set (match_operand:SI 1 "register_operand" "=S")
19748         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19749                  (match_operand:SI 4 "register_operand" "1")))
19750    (set (mem:BLK (match_dup 3))
19751         (mem:BLK (match_dup 4)))
19752    (use (match_dup 5))]
19753   "!TARGET_64BIT"
19754   "rep movs{l|d}"
19755   [(set_attr "type" "str")
19756    (set_attr "prefix_rep" "1")
19757    (set_attr "memory" "both")
19758    (set_attr "mode" "SI")])
19760 (define_insn "*rep_movsi_rex64"
19761   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19762    (set (match_operand:DI 0 "register_operand" "=D")
19763         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19764                             (const_int 2))
19765                  (match_operand:DI 3 "register_operand" "0")))
19766    (set (match_operand:DI 1 "register_operand" "=S")
19767         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19768                  (match_operand:DI 4 "register_operand" "1")))
19769    (set (mem:BLK (match_dup 3))
19770         (mem:BLK (match_dup 4)))
19771    (use (match_dup 5))]
19772   "TARGET_64BIT"
19773   "rep movs{l|d}"
19774   [(set_attr "type" "str")
19775    (set_attr "prefix_rep" "1")
19776    (set_attr "memory" "both")
19777    (set_attr "mode" "SI")])
19779 (define_insn "*rep_movqi"
19780   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19781    (set (match_operand:SI 0 "register_operand" "=D")
19782         (plus:SI (match_operand:SI 3 "register_operand" "0")
19783                  (match_operand:SI 5 "register_operand" "2")))
19784    (set (match_operand:SI 1 "register_operand" "=S")
19785         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19786    (set (mem:BLK (match_dup 3))
19787         (mem:BLK (match_dup 4)))
19788    (use (match_dup 5))]
19789   "!TARGET_64BIT"
19790   "rep movsb"
19791   [(set_attr "type" "str")
19792    (set_attr "prefix_rep" "1")
19793    (set_attr "memory" "both")
19794    (set_attr "mode" "SI")])
19796 (define_insn "*rep_movqi_rex64"
19797   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19798    (set (match_operand:DI 0 "register_operand" "=D")
19799         (plus:DI (match_operand:DI 3 "register_operand" "0")
19800                  (match_operand:DI 5 "register_operand" "2")))
19801    (set (match_operand:DI 1 "register_operand" "=S")
19802         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19803    (set (mem:BLK (match_dup 3))
19804         (mem:BLK (match_dup 4)))
19805    (use (match_dup 5))]
19806   "TARGET_64BIT"
19807   "rep movsb"
19808   [(set_attr "type" "str")
19809    (set_attr "prefix_rep" "1")
19810    (set_attr "memory" "both")
19811    (set_attr "mode" "SI")])
19813 (define_expand "setmemsi"
19814    [(use (match_operand:BLK 0 "memory_operand" ""))
19815     (use (match_operand:SI 1 "nonmemory_operand" ""))
19816     (use (match_operand 2 "const_int_operand" ""))
19817     (use (match_operand 3 "const_int_operand" ""))
19818     (use (match_operand:SI 4 "const_int_operand" ""))
19819     (use (match_operand:SI 5 "const_int_operand" ""))]
19820   ""
19822  if (ix86_expand_setmem (operands[0], operands[1],
19823                          operands[2], operands[3],
19824                          operands[4], operands[5]))
19825    DONE;
19826  else
19827    FAIL;
19830 (define_expand "setmemdi"
19831    [(use (match_operand:BLK 0 "memory_operand" ""))
19832     (use (match_operand:DI 1 "nonmemory_operand" ""))
19833     (use (match_operand 2 "const_int_operand" ""))
19834     (use (match_operand 3 "const_int_operand" ""))
19835     (use (match_operand 4 "const_int_operand" ""))
19836     (use (match_operand 5 "const_int_operand" ""))]
19837   "TARGET_64BIT"
19839  if (ix86_expand_setmem (operands[0], operands[1],
19840                          operands[2], operands[3],
19841                          operands[4], operands[5]))
19842    DONE;
19843  else
19844    FAIL;
19847 ;; Most CPUs don't like single string operations
19848 ;; Handle this case here to simplify previous expander.
19850 (define_expand "strset"
19851   [(set (match_operand 1 "memory_operand" "")
19852         (match_operand 2 "register_operand" ""))
19853    (parallel [(set (match_operand 0 "register_operand" "")
19854                    (match_dup 3))
19855               (clobber (reg:CC FLAGS_REG))])]
19856   ""
19858   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19859     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19861   /* If .md ever supports :P for Pmode, this can be directly
19862      in the pattern above.  */
19863   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19864                               GEN_INT (GET_MODE_SIZE (GET_MODE
19865                                                       (operands[2]))));
19866   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19867     {
19868       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19869                                       operands[3]));
19870       DONE;
19871     }
19874 (define_expand "strset_singleop"
19875   [(parallel [(set (match_operand 1 "memory_operand" "")
19876                    (match_operand 2 "register_operand" ""))
19877               (set (match_operand 0 "register_operand" "")
19878                    (match_operand 3 "" ""))])]
19879   ""
19880   "ix86_current_function_needs_cld = 1;")
19882 (define_insn "*strsetdi_rex_1"
19883   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19884         (match_operand:DI 2 "register_operand" "a"))
19885    (set (match_operand:DI 0 "register_operand" "=D")
19886         (plus:DI (match_dup 1)
19887                  (const_int 8)))]
19888   "TARGET_64BIT"
19889   "stosq"
19890   [(set_attr "type" "str")
19891    (set_attr "memory" "store")
19892    (set_attr "mode" "DI")])
19894 (define_insn "*strsetsi_1"
19895   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19896         (match_operand:SI 2 "register_operand" "a"))
19897    (set (match_operand:SI 0 "register_operand" "=D")
19898         (plus:SI (match_dup 1)
19899                  (const_int 4)))]
19900   "!TARGET_64BIT"
19901   "stos{l|d}"
19902   [(set_attr "type" "str")
19903    (set_attr "memory" "store")
19904    (set_attr "mode" "SI")])
19906 (define_insn "*strsetsi_rex_1"
19907   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19908         (match_operand:SI 2 "register_operand" "a"))
19909    (set (match_operand:DI 0 "register_operand" "=D")
19910         (plus:DI (match_dup 1)
19911                  (const_int 4)))]
19912   "TARGET_64BIT"
19913   "stos{l|d}"
19914   [(set_attr "type" "str")
19915    (set_attr "memory" "store")
19916    (set_attr "mode" "SI")])
19918 (define_insn "*strsethi_1"
19919   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19920         (match_operand:HI 2 "register_operand" "a"))
19921    (set (match_operand:SI 0 "register_operand" "=D")
19922         (plus:SI (match_dup 1)
19923                  (const_int 2)))]
19924   "!TARGET_64BIT"
19925   "stosw"
19926   [(set_attr "type" "str")
19927    (set_attr "memory" "store")
19928    (set_attr "mode" "HI")])
19930 (define_insn "*strsethi_rex_1"
19931   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19932         (match_operand:HI 2 "register_operand" "a"))
19933    (set (match_operand:DI 0 "register_operand" "=D")
19934         (plus:DI (match_dup 1)
19935                  (const_int 2)))]
19936   "TARGET_64BIT"
19937   "stosw"
19938   [(set_attr "type" "str")
19939    (set_attr "memory" "store")
19940    (set_attr "mode" "HI")])
19942 (define_insn "*strsetqi_1"
19943   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19944         (match_operand:QI 2 "register_operand" "a"))
19945    (set (match_operand:SI 0 "register_operand" "=D")
19946         (plus:SI (match_dup 1)
19947                  (const_int 1)))]
19948   "!TARGET_64BIT"
19949   "stosb"
19950   [(set_attr "type" "str")
19951    (set_attr "memory" "store")
19952    (set_attr "mode" "QI")])
19954 (define_insn "*strsetqi_rex_1"
19955   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19956         (match_operand:QI 2 "register_operand" "a"))
19957    (set (match_operand:DI 0 "register_operand" "=D")
19958         (plus:DI (match_dup 1)
19959                  (const_int 1)))]
19960   "TARGET_64BIT"
19961   "stosb"
19962   [(set_attr "type" "str")
19963    (set_attr "memory" "store")
19964    (set_attr "prefix_rex" "0")
19965    (set_attr "mode" "QI")])
19967 (define_expand "rep_stos"
19968   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19969               (set (match_operand 0 "register_operand" "")
19970                    (match_operand 4 "" ""))
19971               (set (match_operand 2 "memory_operand" "") (const_int 0))
19972               (use (match_operand 3 "register_operand" ""))
19973               (use (match_dup 1))])]
19974   ""
19975   "ix86_current_function_needs_cld = 1;")
19977 (define_insn "*rep_stosdi_rex64"
19978   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19979    (set (match_operand:DI 0 "register_operand" "=D")
19980         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19981                             (const_int 3))
19982                  (match_operand:DI 3 "register_operand" "0")))
19983    (set (mem:BLK (match_dup 3))
19984         (const_int 0))
19985    (use (match_operand:DI 2 "register_operand" "a"))
19986    (use (match_dup 4))]
19987   "TARGET_64BIT"
19988   "rep stosq"
19989   [(set_attr "type" "str")
19990    (set_attr "prefix_rep" "1")
19991    (set_attr "memory" "store")
19992    (set_attr "mode" "DI")])
19994 (define_insn "*rep_stossi"
19995   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19996    (set (match_operand:SI 0 "register_operand" "=D")
19997         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19998                             (const_int 2))
19999                  (match_operand:SI 3 "register_operand" "0")))
20000    (set (mem:BLK (match_dup 3))
20001         (const_int 0))
20002    (use (match_operand:SI 2 "register_operand" "a"))
20003    (use (match_dup 4))]
20004   "!TARGET_64BIT"
20005   "rep stos{l|d}"
20006   [(set_attr "type" "str")
20007    (set_attr "prefix_rep" "1")
20008    (set_attr "memory" "store")
20009    (set_attr "mode" "SI")])
20011 (define_insn "*rep_stossi_rex64"
20012   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
20013    (set (match_operand:DI 0 "register_operand" "=D")
20014         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
20015                             (const_int 2))
20016                  (match_operand:DI 3 "register_operand" "0")))
20017    (set (mem:BLK (match_dup 3))
20018         (const_int 0))
20019    (use (match_operand:SI 2 "register_operand" "a"))
20020    (use (match_dup 4))]
20021   "TARGET_64BIT"
20022   "rep stos{l|d}"
20023   [(set_attr "type" "str")
20024    (set_attr "prefix_rep" "1")
20025    (set_attr "memory" "store")
20026    (set_attr "mode" "SI")])
20028 (define_insn "*rep_stosqi"
20029   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
20030    (set (match_operand:SI 0 "register_operand" "=D")
20031         (plus:SI (match_operand:SI 3 "register_operand" "0")
20032                  (match_operand:SI 4 "register_operand" "1")))
20033    (set (mem:BLK (match_dup 3))
20034         (const_int 0))
20035    (use (match_operand:QI 2 "register_operand" "a"))
20036    (use (match_dup 4))]
20037   "!TARGET_64BIT"
20038   "rep stosb"
20039   [(set_attr "type" "str")
20040    (set_attr "prefix_rep" "1")
20041    (set_attr "memory" "store")
20042    (set_attr "mode" "QI")])
20044 (define_insn "*rep_stosqi_rex64"
20045   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
20046    (set (match_operand:DI 0 "register_operand" "=D")
20047         (plus:DI (match_operand:DI 3 "register_operand" "0")
20048                  (match_operand:DI 4 "register_operand" "1")))
20049    (set (mem:BLK (match_dup 3))
20050         (const_int 0))
20051    (use (match_operand:QI 2 "register_operand" "a"))
20052    (use (match_dup 4))]
20053   "TARGET_64BIT"
20054   "rep stosb"
20055   [(set_attr "type" "str")
20056    (set_attr "prefix_rep" "1")
20057    (set_attr "memory" "store")
20058    (set_attr "prefix_rex" "0")
20059    (set_attr "mode" "QI")])
20061 (define_expand "cmpstrnsi"
20062   [(set (match_operand:SI 0 "register_operand" "")
20063         (compare:SI (match_operand:BLK 1 "general_operand" "")
20064                     (match_operand:BLK 2 "general_operand" "")))
20065    (use (match_operand 3 "general_operand" ""))
20066    (use (match_operand 4 "immediate_operand" ""))]
20067   ""
20069   rtx addr1, addr2, out, outlow, count, countreg, align;
20071   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
20072     FAIL;
20074   /* Can't use this if the user has appropriated esi or edi.  */
20075   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
20076     FAIL;
20078   out = operands[0];
20079   if (!REG_P (out))
20080     out = gen_reg_rtx (SImode);
20082   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
20083   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
20084   if (addr1 != XEXP (operands[1], 0))
20085     operands[1] = replace_equiv_address_nv (operands[1], addr1);
20086   if (addr2 != XEXP (operands[2], 0))
20087     operands[2] = replace_equiv_address_nv (operands[2], addr2);
20089   count = operands[3];
20090   countreg = ix86_zero_extend_to_Pmode (count);
20092   /* %%% Iff we are testing strict equality, we can use known alignment
20093      to good advantage.  This may be possible with combine, particularly
20094      once cc0 is dead.  */
20095   align = operands[4];
20097   if (CONST_INT_P (count))
20098     {
20099       if (INTVAL (count) == 0)
20100         {
20101           emit_move_insn (operands[0], const0_rtx);
20102           DONE;
20103         }
20104       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
20105                                      operands[1], operands[2]));
20106     }
20107   else
20108     {
20109       if (TARGET_64BIT)
20110         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
20111       else
20112         emit_insn (gen_cmpsi_1 (countreg, countreg));
20113       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
20114                                   operands[1], operands[2]));
20115     }
20117   outlow = gen_lowpart (QImode, out);
20118   emit_insn (gen_cmpintqi (outlow));
20119   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
20121   if (operands[0] != out)
20122     emit_move_insn (operands[0], out);
20124   DONE;
20127 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
20129 (define_expand "cmpintqi"
20130   [(set (match_dup 1)
20131         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20132    (set (match_dup 2)
20133         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20134    (parallel [(set (match_operand:QI 0 "register_operand" "")
20135                    (minus:QI (match_dup 1)
20136                              (match_dup 2)))
20137               (clobber (reg:CC FLAGS_REG))])]
20138   ""
20139   "operands[1] = gen_reg_rtx (QImode);
20140    operands[2] = gen_reg_rtx (QImode);")
20142 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
20143 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
20145 (define_expand "cmpstrnqi_nz_1"
20146   [(parallel [(set (reg:CC FLAGS_REG)
20147                    (compare:CC (match_operand 4 "memory_operand" "")
20148                                (match_operand 5 "memory_operand" "")))
20149               (use (match_operand 2 "register_operand" ""))
20150               (use (match_operand:SI 3 "immediate_operand" ""))
20151               (clobber (match_operand 0 "register_operand" ""))
20152               (clobber (match_operand 1 "register_operand" ""))
20153               (clobber (match_dup 2))])]
20154   ""
20155   "ix86_current_function_needs_cld = 1;")
20157 (define_insn "*cmpstrnqi_nz_1"
20158   [(set (reg:CC FLAGS_REG)
20159         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
20160                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
20161    (use (match_operand:SI 6 "register_operand" "2"))
20162    (use (match_operand:SI 3 "immediate_operand" "i"))
20163    (clobber (match_operand:SI 0 "register_operand" "=S"))
20164    (clobber (match_operand:SI 1 "register_operand" "=D"))
20165    (clobber (match_operand:SI 2 "register_operand" "=c"))]
20166   "!TARGET_64BIT"
20167   "repz cmpsb"
20168   [(set_attr "type" "str")
20169    (set_attr "mode" "QI")
20170    (set_attr "prefix_rep" "1")])
20172 (define_insn "*cmpstrnqi_nz_rex_1"
20173   [(set (reg:CC FLAGS_REG)
20174         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
20175                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
20176    (use (match_operand:DI 6 "register_operand" "2"))
20177    (use (match_operand:SI 3 "immediate_operand" "i"))
20178    (clobber (match_operand:DI 0 "register_operand" "=S"))
20179    (clobber (match_operand:DI 1 "register_operand" "=D"))
20180    (clobber (match_operand:DI 2 "register_operand" "=c"))]
20181   "TARGET_64BIT"
20182   "repz cmpsb"
20183   [(set_attr "type" "str")
20184    (set_attr "mode" "QI")
20185    (set_attr "prefix_rex" "0")
20186    (set_attr "prefix_rep" "1")])
20188 ;; The same, but the count is not known to not be zero.
20190 (define_expand "cmpstrnqi_1"
20191   [(parallel [(set (reg:CC FLAGS_REG)
20192                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
20193                                      (const_int 0))
20194                   (compare:CC (match_operand 4 "memory_operand" "")
20195                               (match_operand 5 "memory_operand" ""))
20196                   (const_int 0)))
20197               (use (match_operand:SI 3 "immediate_operand" ""))
20198               (use (reg:CC FLAGS_REG))
20199               (clobber (match_operand 0 "register_operand" ""))
20200               (clobber (match_operand 1 "register_operand" ""))
20201               (clobber (match_dup 2))])]
20202   ""
20203   "ix86_current_function_needs_cld = 1;")
20205 (define_insn "*cmpstrnqi_1"
20206   [(set (reg:CC FLAGS_REG)
20207         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
20208                              (const_int 0))
20209           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
20210                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
20211           (const_int 0)))
20212    (use (match_operand:SI 3 "immediate_operand" "i"))
20213    (use (reg:CC FLAGS_REG))
20214    (clobber (match_operand:SI 0 "register_operand" "=S"))
20215    (clobber (match_operand:SI 1 "register_operand" "=D"))
20216    (clobber (match_operand:SI 2 "register_operand" "=c"))]
20217   "!TARGET_64BIT"
20218   "repz cmpsb"
20219   [(set_attr "type" "str")
20220    (set_attr "mode" "QI")
20221    (set_attr "prefix_rep" "1")])
20223 (define_insn "*cmpstrnqi_rex_1"
20224   [(set (reg:CC FLAGS_REG)
20225         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
20226                              (const_int 0))
20227           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
20228                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
20229           (const_int 0)))
20230    (use (match_operand:SI 3 "immediate_operand" "i"))
20231    (use (reg:CC FLAGS_REG))
20232    (clobber (match_operand:DI 0 "register_operand" "=S"))
20233    (clobber (match_operand:DI 1 "register_operand" "=D"))
20234    (clobber (match_operand:DI 2 "register_operand" "=c"))]
20235   "TARGET_64BIT"
20236   "repz cmpsb"
20237   [(set_attr "type" "str")
20238    (set_attr "mode" "QI")
20239    (set_attr "prefix_rex" "0")
20240    (set_attr "prefix_rep" "1")])
20242 (define_expand "strlensi"
20243   [(set (match_operand:SI 0 "register_operand" "")
20244         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
20245                     (match_operand:QI 2 "immediate_operand" "")
20246                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
20247   ""
20249  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
20250    DONE;
20251  else
20252    FAIL;
20255 (define_expand "strlendi"
20256   [(set (match_operand:DI 0 "register_operand" "")
20257         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
20258                     (match_operand:QI 2 "immediate_operand" "")
20259                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
20260   ""
20262  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
20263    DONE;
20264  else
20265    FAIL;
20268 (define_expand "strlenqi_1"
20269   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
20270               (clobber (match_operand 1 "register_operand" ""))
20271               (clobber (reg:CC FLAGS_REG))])]
20272   ""
20273   "ix86_current_function_needs_cld = 1;")
20275 (define_insn "*strlenqi_1"
20276   [(set (match_operand:SI 0 "register_operand" "=&c")
20277         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
20278                     (match_operand:QI 2 "register_operand" "a")
20279                     (match_operand:SI 3 "immediate_operand" "i")
20280                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
20281    (clobber (match_operand:SI 1 "register_operand" "=D"))
20282    (clobber (reg:CC FLAGS_REG))]
20283   "!TARGET_64BIT"
20284   "repnz scasb"
20285   [(set_attr "type" "str")
20286    (set_attr "mode" "QI")
20287    (set_attr "prefix_rep" "1")])
20289 (define_insn "*strlenqi_rex_1"
20290   [(set (match_operand:DI 0 "register_operand" "=&c")
20291         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
20292                     (match_operand:QI 2 "register_operand" "a")
20293                     (match_operand:DI 3 "immediate_operand" "i")
20294                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
20295    (clobber (match_operand:DI 1 "register_operand" "=D"))
20296    (clobber (reg:CC FLAGS_REG))]
20297   "TARGET_64BIT"
20298   "repnz scasb"
20299   [(set_attr "type" "str")
20300    (set_attr "mode" "QI")
20301    (set_attr "prefix_rex" "0")
20302    (set_attr "prefix_rep" "1")])
20304 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
20305 ;; handled in combine, but it is not currently up to the task.
20306 ;; When used for their truth value, the cmpstrn* expanders generate
20307 ;; code like this:
20309 ;;   repz cmpsb
20310 ;;   seta       %al
20311 ;;   setb       %dl
20312 ;;   cmpb       %al, %dl
20313 ;;   jcc        label
20315 ;; The intermediate three instructions are unnecessary.
20317 ;; This one handles cmpstrn*_nz_1...
20318 (define_peephole2
20319   [(parallel[
20320      (set (reg:CC FLAGS_REG)
20321           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
20322                       (mem:BLK (match_operand 5 "register_operand" ""))))
20323      (use (match_operand 6 "register_operand" ""))
20324      (use (match_operand:SI 3 "immediate_operand" ""))
20325      (clobber (match_operand 0 "register_operand" ""))
20326      (clobber (match_operand 1 "register_operand" ""))
20327      (clobber (match_operand 2 "register_operand" ""))])
20328    (set (match_operand:QI 7 "register_operand" "")
20329         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20330    (set (match_operand:QI 8 "register_operand" "")
20331         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20332    (set (reg FLAGS_REG)
20333         (compare (match_dup 7) (match_dup 8)))
20334   ]
20335   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
20336   [(parallel[
20337      (set (reg:CC FLAGS_REG)
20338           (compare:CC (mem:BLK (match_dup 4))
20339                       (mem:BLK (match_dup 5))))
20340      (use (match_dup 6))
20341      (use (match_dup 3))
20342      (clobber (match_dup 0))
20343      (clobber (match_dup 1))
20344      (clobber (match_dup 2))])]
20345   "")
20347 ;; ...and this one handles cmpstrn*_1.
20348 (define_peephole2
20349   [(parallel[
20350      (set (reg:CC FLAGS_REG)
20351           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
20352                                (const_int 0))
20353             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
20354                         (mem:BLK (match_operand 5 "register_operand" "")))
20355             (const_int 0)))
20356      (use (match_operand:SI 3 "immediate_operand" ""))
20357      (use (reg:CC FLAGS_REG))
20358      (clobber (match_operand 0 "register_operand" ""))
20359      (clobber (match_operand 1 "register_operand" ""))
20360      (clobber (match_operand 2 "register_operand" ""))])
20361    (set (match_operand:QI 7 "register_operand" "")
20362         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20363    (set (match_operand:QI 8 "register_operand" "")
20364         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20365    (set (reg FLAGS_REG)
20366         (compare (match_dup 7) (match_dup 8)))
20367   ]
20368   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
20369   [(parallel[
20370      (set (reg:CC FLAGS_REG)
20371           (if_then_else:CC (ne (match_dup 6)
20372                                (const_int 0))
20373             (compare:CC (mem:BLK (match_dup 4))
20374                         (mem:BLK (match_dup 5)))
20375             (const_int 0)))
20376      (use (match_dup 3))
20377      (use (reg:CC FLAGS_REG))
20378      (clobber (match_dup 0))
20379      (clobber (match_dup 1))
20380      (clobber (match_dup 2))])]
20381   "")
20385 ;; Conditional move instructions.
20387 (define_expand "movdicc"
20388   [(set (match_operand:DI 0 "register_operand" "")
20389         (if_then_else:DI (match_operand 1 "comparison_operator" "")
20390                          (match_operand:DI 2 "general_operand" "")
20391                          (match_operand:DI 3 "general_operand" "")))]
20392   "TARGET_64BIT"
20393   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20395 (define_insn "x86_movdicc_0_m1_rex64"
20396   [(set (match_operand:DI 0 "register_operand" "=r")
20397         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
20398           (const_int -1)
20399           (const_int 0)))
20400    (clobber (reg:CC FLAGS_REG))]
20401   "TARGET_64BIT"
20402   "sbb{q}\t%0, %0"
20403   ; Since we don't have the proper number of operands for an alu insn,
20404   ; fill in all the blanks.
20405   [(set_attr "type" "alu")
20406    (set_attr "use_carry" "1")
20407    (set_attr "pent_pair" "pu")
20408    (set_attr "memory" "none")
20409    (set_attr "imm_disp" "false")
20410    (set_attr "mode" "DI")
20411    (set_attr "length_immediate" "0")])
20413 (define_insn "*x86_movdicc_0_m1_se"
20414   [(set (match_operand:DI 0 "register_operand" "=r")
20415         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
20416                          (const_int 1)
20417                          (const_int 0)))
20418    (clobber (reg:CC FLAGS_REG))]
20419   ""
20420   "sbb{q}\t%0, %0"
20421   [(set_attr "type" "alu")
20422    (set_attr "use_carry" "1")
20423    (set_attr "pent_pair" "pu")
20424    (set_attr "memory" "none")
20425    (set_attr "imm_disp" "false")
20426    (set_attr "mode" "DI")
20427    (set_attr "length_immediate" "0")])
20429 (define_insn "*movdicc_c_rex64"
20430   [(set (match_operand:DI 0 "register_operand" "=r,r")
20431         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
20432                                 [(reg FLAGS_REG) (const_int 0)])
20433                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
20434                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
20435   "TARGET_64BIT && TARGET_CMOVE
20436    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20437   "@
20438    cmov%O2%C1\t{%2, %0|%0, %2}
20439    cmov%O2%c1\t{%3, %0|%0, %3}"
20440   [(set_attr "type" "icmov")
20441    (set_attr "mode" "DI")])
20443 (define_expand "movsicc"
20444   [(set (match_operand:SI 0 "register_operand" "")
20445         (if_then_else:SI (match_operand 1 "comparison_operator" "")
20446                          (match_operand:SI 2 "general_operand" "")
20447                          (match_operand:SI 3 "general_operand" "")))]
20448   ""
20449   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20451 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
20452 ;; the register first winds up with `sbbl $0,reg', which is also weird.
20453 ;; So just document what we're doing explicitly.
20455 (define_insn "x86_movsicc_0_m1"
20456   [(set (match_operand:SI 0 "register_operand" "=r")
20457         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
20458           (const_int -1)
20459           (const_int 0)))
20460    (clobber (reg:CC FLAGS_REG))]
20461   ""
20462   "sbb{l}\t%0, %0"
20463   ; Since we don't have the proper number of operands for an alu insn,
20464   ; fill in all the blanks.
20465   [(set_attr "type" "alu")
20466    (set_attr "use_carry" "1")
20467    (set_attr "pent_pair" "pu")
20468    (set_attr "memory" "none")
20469    (set_attr "imm_disp" "false")
20470    (set_attr "mode" "SI")
20471    (set_attr "length_immediate" "0")])
20473 (define_insn "*x86_movsicc_0_m1_se"
20474   [(set (match_operand:SI 0 "register_operand" "=r")
20475         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
20476                          (const_int 1)
20477                          (const_int 0)))
20478    (clobber (reg:CC FLAGS_REG))]
20479   ""
20480   "sbb{l}\t%0, %0"
20481   [(set_attr "type" "alu")
20482    (set_attr "use_carry" "1")
20483    (set_attr "pent_pair" "pu")
20484    (set_attr "memory" "none")
20485    (set_attr "imm_disp" "false")
20486    (set_attr "mode" "SI")
20487    (set_attr "length_immediate" "0")])
20489 (define_insn "*movsicc_noc"
20490   [(set (match_operand:SI 0 "register_operand" "=r,r")
20491         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
20492                                 [(reg FLAGS_REG) (const_int 0)])
20493                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
20494                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
20495   "TARGET_CMOVE
20496    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20497   "@
20498    cmov%O2%C1\t{%2, %0|%0, %2}
20499    cmov%O2%c1\t{%3, %0|%0, %3}"
20500   [(set_attr "type" "icmov")
20501    (set_attr "mode" "SI")])
20503 (define_expand "movhicc"
20504   [(set (match_operand:HI 0 "register_operand" "")
20505         (if_then_else:HI (match_operand 1 "comparison_operator" "")
20506                          (match_operand:HI 2 "general_operand" "")
20507                          (match_operand:HI 3 "general_operand" "")))]
20508   "TARGET_HIMODE_MATH"
20509   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20511 (define_insn "*movhicc_noc"
20512   [(set (match_operand:HI 0 "register_operand" "=r,r")
20513         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
20514                                 [(reg FLAGS_REG) (const_int 0)])
20515                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
20516                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
20517   "TARGET_CMOVE
20518    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20519   "@
20520    cmov%O2%C1\t{%2, %0|%0, %2}
20521    cmov%O2%c1\t{%3, %0|%0, %3}"
20522   [(set_attr "type" "icmov")
20523    (set_attr "mode" "HI")])
20525 (define_expand "movqicc"
20526   [(set (match_operand:QI 0 "register_operand" "")
20527         (if_then_else:QI (match_operand 1 "comparison_operator" "")
20528                          (match_operand:QI 2 "general_operand" "")
20529                          (match_operand:QI 3 "general_operand" "")))]
20530   "TARGET_QIMODE_MATH"
20531   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20533 (define_insn_and_split "*movqicc_noc"
20534   [(set (match_operand:QI 0 "register_operand" "=r,r")
20535         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
20536                                 [(match_operand 4 "flags_reg_operand" "")
20537                                  (const_int 0)])
20538                       (match_operand:QI 2 "register_operand" "r,0")
20539                       (match_operand:QI 3 "register_operand" "0,r")))]
20540   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
20541   "#"
20542   "&& reload_completed"
20543   [(set (match_dup 0)
20544         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20545                       (match_dup 2)
20546                       (match_dup 3)))]
20547   "operands[0] = gen_lowpart (SImode, operands[0]);
20548    operands[2] = gen_lowpart (SImode, operands[2]);
20549    operands[3] = gen_lowpart (SImode, operands[3]);"
20550   [(set_attr "type" "icmov")
20551    (set_attr "mode" "SI")])
20553 (define_expand "mov<mode>cc"
20554   [(set (match_operand:X87MODEF 0 "register_operand" "")
20555         (if_then_else:X87MODEF
20556           (match_operand 1 "ix86_fp_comparison_operator" "")
20557           (match_operand:X87MODEF 2 "register_operand" "")
20558           (match_operand:X87MODEF 3 "register_operand" "")))]
20559   "(TARGET_80387 && TARGET_CMOVE)
20560    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20561   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
20563 (define_insn "*movsfcc_1_387"
20564   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
20565         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
20566                                 [(reg FLAGS_REG) (const_int 0)])
20567                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
20568                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
20569   "TARGET_80387 && TARGET_CMOVE
20570    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20571   "@
20572    fcmov%F1\t{%2, %0|%0, %2}
20573    fcmov%f1\t{%3, %0|%0, %3}
20574    cmov%O2%C1\t{%2, %0|%0, %2}
20575    cmov%O2%c1\t{%3, %0|%0, %3}"
20576   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20577    (set_attr "mode" "SF,SF,SI,SI")])
20579 (define_insn "*movdfcc_1"
20580   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
20581         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20582                                 [(reg FLAGS_REG) (const_int 0)])
20583                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20584                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20585   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20586    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20587   "@
20588    fcmov%F1\t{%2, %0|%0, %2}
20589    fcmov%f1\t{%3, %0|%0, %3}
20590    #
20591    #"
20592   [(set_attr "type" "fcmov,fcmov,multi,multi")
20593    (set_attr "mode" "DF")])
20595 (define_insn "*movdfcc_1_rex64"
20596   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
20597         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20598                                 [(reg FLAGS_REG) (const_int 0)])
20599                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20600                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20601   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20602    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20603   "@
20604    fcmov%F1\t{%2, %0|%0, %2}
20605    fcmov%f1\t{%3, %0|%0, %3}
20606    cmov%O2%C1\t{%2, %0|%0, %2}
20607    cmov%O2%c1\t{%3, %0|%0, %3}"
20608   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20609    (set_attr "mode" "DF")])
20611 (define_split
20612   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20613         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20614                                 [(match_operand 4 "flags_reg_operand" "")
20615                                  (const_int 0)])
20616                       (match_operand:DF 2 "nonimmediate_operand" "")
20617                       (match_operand:DF 3 "nonimmediate_operand" "")))]
20618   "!TARGET_64BIT && reload_completed"
20619   [(set (match_dup 2)
20620         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20621                       (match_dup 5)
20622                       (match_dup 6)))
20623    (set (match_dup 3)
20624         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20625                       (match_dup 7)
20626                       (match_dup 8)))]
20627   "split_di (&operands[2], 2, &operands[5], &operands[7]);
20628    split_di (&operands[0], 1, &operands[2], &operands[3]);")
20630 (define_insn "*movxfcc_1"
20631   [(set (match_operand:XF 0 "register_operand" "=f,f")
20632         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20633                                 [(reg FLAGS_REG) (const_int 0)])
20634                       (match_operand:XF 2 "register_operand" "f,0")
20635                       (match_operand:XF 3 "register_operand" "0,f")))]
20636   "TARGET_80387 && TARGET_CMOVE"
20637   "@
20638    fcmov%F1\t{%2, %0|%0, %2}
20639    fcmov%f1\t{%3, %0|%0, %3}"
20640   [(set_attr "type" "fcmov")
20641    (set_attr "mode" "XF")])
20643 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20644 ;; the scalar versions to have only XMM registers as operands.
20646 ;; SSE5 conditional move
20647 (define_insn "*sse5_pcmov_<mode>"
20648   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20649         (if_then_else:MODEF
20650           (match_operand:MODEF 1 "register_operand" "x,0")
20651           (match_operand:MODEF 2 "register_operand" "0,x")
20652           (match_operand:MODEF 3 "register_operand" "x,x")))]
20653   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20654   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20655   [(set_attr "type" "sse4arg")])
20657 ;; These versions of the min/max patterns are intentionally ignorant of
20658 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20659 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20660 ;; are undefined in this condition, we're certain this is correct.
20662 (define_insn "*avx_<code><mode>3"
20663   [(set (match_operand:MODEF 0 "register_operand" "=x")
20664         (smaxmin:MODEF
20665           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20666           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20667   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20668   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20669   [(set_attr "type" "sseadd")
20670    (set_attr "prefix" "vex")
20671    (set_attr "mode" "<MODE>")])
20673 (define_insn "<code><mode>3"
20674   [(set (match_operand:MODEF 0 "register_operand" "=x")
20675         (smaxmin:MODEF
20676           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20677           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20678   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20679   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20680   [(set_attr "type" "sseadd")
20681    (set_attr "mode" "<MODE>")])
20683 ;; These versions of the min/max patterns implement exactly the operations
20684 ;;   min = (op1 < op2 ? op1 : op2)
20685 ;;   max = (!(op1 < op2) ? op1 : op2)
20686 ;; Their operands are not commutative, and thus they may be used in the
20687 ;; presence of -0.0 and NaN.
20689 (define_insn "*avx_ieee_smin<mode>3"
20690   [(set (match_operand:MODEF 0 "register_operand" "=x")
20691         (unspec:MODEF
20692           [(match_operand:MODEF 1 "register_operand" "x")
20693            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20694          UNSPEC_IEEE_MIN))]
20695   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20696   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20697   [(set_attr "type" "sseadd")
20698    (set_attr "prefix" "vex")
20699    (set_attr "mode" "<MODE>")])
20701 (define_insn "*ieee_smin<mode>3"
20702   [(set (match_operand:MODEF 0 "register_operand" "=x")
20703         (unspec:MODEF
20704           [(match_operand:MODEF 1 "register_operand" "0")
20705            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20706          UNSPEC_IEEE_MIN))]
20707   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20708   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20709   [(set_attr "type" "sseadd")
20710    (set_attr "mode" "<MODE>")])
20712 (define_insn "*avx_ieee_smax<mode>3"
20713   [(set (match_operand:MODEF 0 "register_operand" "=x")
20714         (unspec:MODEF
20715           [(match_operand:MODEF 1 "register_operand" "0")
20716            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20717          UNSPEC_IEEE_MAX))]
20718   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20719   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20720   [(set_attr "type" "sseadd")
20721    (set_attr "prefix" "vex")
20722    (set_attr "mode" "<MODE>")])
20724 (define_insn "*ieee_smax<mode>3"
20725   [(set (match_operand:MODEF 0 "register_operand" "=x")
20726         (unspec:MODEF
20727           [(match_operand:MODEF 1 "register_operand" "0")
20728            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20729          UNSPEC_IEEE_MAX))]
20730   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20731   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20732   [(set_attr "type" "sseadd")
20733    (set_attr "mode" "<MODE>")])
20735 ;; Make two stack loads independent:
20736 ;;   fld aa              fld aa
20737 ;;   fld %st(0)     ->   fld bb
20738 ;;   fmul bb             fmul %st(1), %st
20740 ;; Actually we only match the last two instructions for simplicity.
20741 (define_peephole2
20742   [(set (match_operand 0 "fp_register_operand" "")
20743         (match_operand 1 "fp_register_operand" ""))
20744    (set (match_dup 0)
20745         (match_operator 2 "binary_fp_operator"
20746            [(match_dup 0)
20747             (match_operand 3 "memory_operand" "")]))]
20748   "REGNO (operands[0]) != REGNO (operands[1])"
20749   [(set (match_dup 0) (match_dup 3))
20750    (set (match_dup 0) (match_dup 4))]
20752   ;; The % modifier is not operational anymore in peephole2's, so we have to
20753   ;; swap the operands manually in the case of addition and multiplication.
20754   "if (COMMUTATIVE_ARITH_P (operands[2]))
20755      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20756                                  operands[0], operands[1]);
20757    else
20758      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20759                                  operands[1], operands[0]);")
20761 ;; Conditional addition patterns
20762 (define_expand "add<mode>cc"
20763   [(match_operand:SWI 0 "register_operand" "")
20764    (match_operand 1 "comparison_operator" "")
20765    (match_operand:SWI 2 "register_operand" "")
20766    (match_operand:SWI 3 "const_int_operand" "")]
20767   ""
20768   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20771 ;; Misc patterns (?)
20773 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20774 ;; Otherwise there will be nothing to keep
20776 ;; [(set (reg ebp) (reg esp))]
20777 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20778 ;;  (clobber (eflags)]
20779 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20781 ;; in proper program order.
20782 (define_insn "pro_epilogue_adjust_stack_1"
20783   [(set (match_operand:SI 0 "register_operand" "=r,r")
20784         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20785                  (match_operand:SI 2 "immediate_operand" "i,i")))
20786    (clobber (reg:CC FLAGS_REG))
20787    (clobber (mem:BLK (scratch)))]
20788   "!TARGET_64BIT"
20790   switch (get_attr_type (insn))
20791     {
20792     case TYPE_IMOV:
20793       return "mov{l}\t{%1, %0|%0, %1}";
20795     case TYPE_ALU:
20796       if (CONST_INT_P (operands[2])
20797           && (INTVAL (operands[2]) == 128
20798               || (INTVAL (operands[2]) < 0
20799                   && INTVAL (operands[2]) != -128)))
20800         {
20801           operands[2] = GEN_INT (-INTVAL (operands[2]));
20802           return "sub{l}\t{%2, %0|%0, %2}";
20803         }
20804       return "add{l}\t{%2, %0|%0, %2}";
20806     case TYPE_LEA:
20807       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20808       return "lea{l}\t{%a2, %0|%0, %a2}";
20810     default:
20811       gcc_unreachable ();
20812     }
20814   [(set (attr "type")
20815         (cond [(and (eq_attr "alternative" "0") 
20816                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20817                  (const_string "alu")
20818                (match_operand:SI 2 "const0_operand" "")
20819                  (const_string "imov")
20820               ]
20821               (const_string "lea")))
20822    (set (attr "length_immediate")
20823         (cond [(eq_attr "type" "imov")
20824                  (const_string "0")
20825                (and (eq_attr "type" "alu")
20826                     (match_operand 2 "const128_operand" ""))
20827                  (const_string "1")
20828               ]
20829               (const_string "*")))
20830    (set_attr "mode" "SI")])
20832 (define_insn "pro_epilogue_adjust_stack_rex64"
20833   [(set (match_operand:DI 0 "register_operand" "=r,r")
20834         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20835                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20836    (clobber (reg:CC FLAGS_REG))
20837    (clobber (mem:BLK (scratch)))]
20838   "TARGET_64BIT"
20840   switch (get_attr_type (insn))
20841     {
20842     case TYPE_IMOV:
20843       return "mov{q}\t{%1, %0|%0, %1}";
20845     case TYPE_ALU:
20846       if (CONST_INT_P (operands[2])
20847           /* Avoid overflows.  */
20848           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20849           && (INTVAL (operands[2]) == 128
20850               || (INTVAL (operands[2]) < 0
20851                   && INTVAL (operands[2]) != -128)))
20852         {
20853           operands[2] = GEN_INT (-INTVAL (operands[2]));
20854           return "sub{q}\t{%2, %0|%0, %2}";
20855         }
20856       return "add{q}\t{%2, %0|%0, %2}";
20858     case TYPE_LEA:
20859       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20860       return "lea{q}\t{%a2, %0|%0, %a2}";
20862     default:
20863       gcc_unreachable ();
20864     }
20866   [(set (attr "type")
20867         (cond [(and (eq_attr "alternative" "0")
20868                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20869                  (const_string "alu")
20870                (match_operand:DI 2 "const0_operand" "")
20871                  (const_string "imov")
20872               ]
20873               (const_string "lea")))
20874    (set (attr "length_immediate")
20875         (cond [(eq_attr "type" "imov")
20876                  (const_string "0")
20877                (and (eq_attr "type" "alu")
20878                     (match_operand 2 "const128_operand" ""))
20879                  (const_string "1")
20880               ]
20881               (const_string "*")))
20882    (set_attr "mode" "DI")])
20884 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20885   [(set (match_operand:DI 0 "register_operand" "=r,r")
20886         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20887                  (match_operand:DI 3 "immediate_operand" "i,i")))
20888    (use (match_operand:DI 2 "register_operand" "r,r"))
20889    (clobber (reg:CC FLAGS_REG))
20890    (clobber (mem:BLK (scratch)))]
20891   "TARGET_64BIT"
20893   switch (get_attr_type (insn))
20894     {
20895     case TYPE_ALU:
20896       return "add{q}\t{%2, %0|%0, %2}";
20898     case TYPE_LEA:
20899       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20900       return "lea{q}\t{%a2, %0|%0, %a2}";
20902     default:
20903       gcc_unreachable ();
20904     }
20906   [(set_attr "type" "alu,lea")
20907    (set_attr "mode" "DI")])
20909 (define_insn "allocate_stack_worker_32"
20910   [(set (match_operand:SI 0 "register_operand" "=a")
20911         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20912                             UNSPECV_STACK_PROBE))
20913    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20914    (clobber (reg:CC FLAGS_REG))]
20915   "!TARGET_64BIT && TARGET_STACK_PROBE"
20916   "call\t___chkstk"
20917   [(set_attr "type" "multi")
20918    (set_attr "length" "5")])
20920 (define_insn "allocate_stack_worker_64"
20921   [(set (match_operand:DI 0 "register_operand" "=a")
20922         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20923                             UNSPECV_STACK_PROBE))
20924    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20925    (clobber (reg:DI R10_REG))
20926    (clobber (reg:DI R11_REG))
20927    (clobber (reg:CC FLAGS_REG))]
20928   "TARGET_64BIT && TARGET_STACK_PROBE"
20929   "call\t___chkstk"
20930   [(set_attr "type" "multi")
20931    (set_attr "length" "5")])
20933 (define_expand "allocate_stack"
20934   [(match_operand 0 "register_operand" "")
20935    (match_operand 1 "general_operand" "")]
20936   "TARGET_STACK_PROBE"
20938   rtx x;
20940 #ifndef CHECK_STACK_LIMIT
20941 #define CHECK_STACK_LIMIT 0
20942 #endif
20944   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20945       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20946     {
20947       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20948                                stack_pointer_rtx, 0, OPTAB_DIRECT);
20949       if (x != stack_pointer_rtx)
20950         emit_move_insn (stack_pointer_rtx, x);
20951     }
20952   else
20953     {
20954       x = copy_to_mode_reg (Pmode, operands[1]);
20955       if (TARGET_64BIT)
20956         x = gen_allocate_stack_worker_64 (x, x);
20957       else
20958         x = gen_allocate_stack_worker_32 (x, x);
20959       emit_insn (x);
20960     }
20962   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20963   DONE;
20966 (define_expand "builtin_setjmp_receiver"
20967   [(label_ref (match_operand 0 "" ""))]
20968   "!TARGET_64BIT && flag_pic"
20970 #if TARGET_MACHO
20971   if (TARGET_MACHO)
20972     {
20973       rtx xops[3];
20974       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20975       rtx label_rtx = gen_label_rtx ();
20976       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20977       xops[0] = xops[1] = picreg;
20978       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20979       ix86_expand_binary_operator (MINUS, SImode, xops);
20980     }
20981   else
20982 #endif
20983     emit_insn (gen_set_got (pic_offset_table_rtx));
20984   DONE;
20987 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20989 (define_split
20990   [(set (match_operand 0 "register_operand" "")
20991         (match_operator 3 "promotable_binary_operator"
20992            [(match_operand 1 "register_operand" "")
20993             (match_operand 2 "aligned_operand" "")]))
20994    (clobber (reg:CC FLAGS_REG))]
20995   "! TARGET_PARTIAL_REG_STALL && reload_completed
20996    && ((GET_MODE (operands[0]) == HImode
20997         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20998             /* ??? next two lines just !satisfies_constraint_K (...) */
20999             || !CONST_INT_P (operands[2])
21000             || satisfies_constraint_K (operands[2])))
21001        || (GET_MODE (operands[0]) == QImode
21002            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
21003   [(parallel [(set (match_dup 0)
21004                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
21005               (clobber (reg:CC FLAGS_REG))])]
21006   "operands[0] = gen_lowpart (SImode, operands[0]);
21007    operands[1] = gen_lowpart (SImode, operands[1]);
21008    if (GET_CODE (operands[3]) != ASHIFT)
21009      operands[2] = gen_lowpart (SImode, operands[2]);
21010    PUT_MODE (operands[3], SImode);")
21012 ; Promote the QImode tests, as i386 has encoding of the AND
21013 ; instruction with 32-bit sign-extended immediate and thus the
21014 ; instruction size is unchanged, except in the %eax case for
21015 ; which it is increased by one byte, hence the ! optimize_size.
21016 (define_split
21017   [(set (match_operand 0 "flags_reg_operand" "")
21018         (match_operator 2 "compare_operator"
21019           [(and (match_operand 3 "aligned_operand" "")
21020                 (match_operand 4 "const_int_operand" ""))
21021            (const_int 0)]))
21022    (set (match_operand 1 "register_operand" "")
21023         (and (match_dup 3) (match_dup 4)))]
21024   "! TARGET_PARTIAL_REG_STALL && reload_completed
21025    && optimize_insn_for_speed_p ()
21026    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
21027        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
21028    /* Ensure that the operand will remain sign-extended immediate.  */
21029    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
21030   [(parallel [(set (match_dup 0)
21031                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
21032                                     (const_int 0)]))
21033               (set (match_dup 1)
21034                    (and:SI (match_dup 3) (match_dup 4)))])]
21036   operands[4]
21037     = gen_int_mode (INTVAL (operands[4])
21038                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
21039   operands[1] = gen_lowpart (SImode, operands[1]);
21040   operands[3] = gen_lowpart (SImode, operands[3]);
21043 ; Don't promote the QImode tests, as i386 doesn't have encoding of
21044 ; the TEST instruction with 32-bit sign-extended immediate and thus
21045 ; the instruction size would at least double, which is not what we
21046 ; want even with ! optimize_size.
21047 (define_split
21048   [(set (match_operand 0 "flags_reg_operand" "")
21049         (match_operator 1 "compare_operator"
21050           [(and (match_operand:HI 2 "aligned_operand" "")
21051                 (match_operand:HI 3 "const_int_operand" ""))
21052            (const_int 0)]))]
21053   "! TARGET_PARTIAL_REG_STALL && reload_completed
21054    && ! TARGET_FAST_PREFIX
21055    && optimize_insn_for_speed_p ()
21056    /* Ensure that the operand will remain sign-extended immediate.  */
21057    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
21058   [(set (match_dup 0)
21059         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
21060                          (const_int 0)]))]
21062   operands[3]
21063     = gen_int_mode (INTVAL (operands[3])
21064                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
21065   operands[2] = gen_lowpart (SImode, operands[2]);
21068 (define_split
21069   [(set (match_operand 0 "register_operand" "")
21070         (neg (match_operand 1 "register_operand" "")))
21071    (clobber (reg:CC FLAGS_REG))]
21072   "! TARGET_PARTIAL_REG_STALL && reload_completed
21073    && (GET_MODE (operands[0]) == HImode
21074        || (GET_MODE (operands[0]) == QImode
21075            && (TARGET_PROMOTE_QImode
21076                || optimize_insn_for_size_p ())))"
21077   [(parallel [(set (match_dup 0)
21078                    (neg:SI (match_dup 1)))
21079               (clobber (reg:CC FLAGS_REG))])]
21080   "operands[0] = gen_lowpart (SImode, operands[0]);
21081    operands[1] = gen_lowpart (SImode, operands[1]);")
21083 (define_split
21084   [(set (match_operand 0 "register_operand" "")
21085         (not (match_operand 1 "register_operand" "")))]
21086   "! TARGET_PARTIAL_REG_STALL && reload_completed
21087    && (GET_MODE (operands[0]) == HImode
21088        || (GET_MODE (operands[0]) == QImode
21089            && (TARGET_PROMOTE_QImode
21090                || optimize_insn_for_size_p ())))"
21091   [(set (match_dup 0)
21092         (not:SI (match_dup 1)))]
21093   "operands[0] = gen_lowpart (SImode, operands[0]);
21094    operands[1] = gen_lowpart (SImode, operands[1]);")
21096 (define_split
21097   [(set (match_operand 0 "register_operand" "")
21098         (if_then_else (match_operator 1 "comparison_operator"
21099                                 [(reg FLAGS_REG) (const_int 0)])
21100                       (match_operand 2 "register_operand" "")
21101                       (match_operand 3 "register_operand" "")))]
21102   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
21103    && (GET_MODE (operands[0]) == HImode
21104        || (GET_MODE (operands[0]) == QImode
21105            && (TARGET_PROMOTE_QImode
21106                || optimize_insn_for_size_p ())))"
21107   [(set (match_dup 0)
21108         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
21109   "operands[0] = gen_lowpart (SImode, operands[0]);
21110    operands[2] = gen_lowpart (SImode, operands[2]);
21111    operands[3] = gen_lowpart (SImode, operands[3]);")
21114 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
21115 ;; transform a complex memory operation into two memory to register operations.
21117 ;; Don't push memory operands
21118 (define_peephole2
21119   [(set (match_operand:SI 0 "push_operand" "")
21120         (match_operand:SI 1 "memory_operand" ""))
21121    (match_scratch:SI 2 "r")]
21122   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21123    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21124   [(set (match_dup 2) (match_dup 1))
21125    (set (match_dup 0) (match_dup 2))]
21126   "")
21128 (define_peephole2
21129   [(set (match_operand:DI 0 "push_operand" "")
21130         (match_operand:DI 1 "memory_operand" ""))
21131    (match_scratch:DI 2 "r")]
21132   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21133    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21134   [(set (match_dup 2) (match_dup 1))
21135    (set (match_dup 0) (match_dup 2))]
21136   "")
21138 ;; We need to handle SFmode only, because DFmode and XFmode is split to
21139 ;; SImode pushes.
21140 (define_peephole2
21141   [(set (match_operand:SF 0 "push_operand" "")
21142         (match_operand:SF 1 "memory_operand" ""))
21143    (match_scratch:SF 2 "r")]
21144   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21145    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21146   [(set (match_dup 2) (match_dup 1))
21147    (set (match_dup 0) (match_dup 2))]
21148   "")
21150 (define_peephole2
21151   [(set (match_operand:HI 0 "push_operand" "")
21152         (match_operand:HI 1 "memory_operand" ""))
21153    (match_scratch:HI 2 "r")]
21154   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21155    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21156   [(set (match_dup 2) (match_dup 1))
21157    (set (match_dup 0) (match_dup 2))]
21158   "")
21160 (define_peephole2
21161   [(set (match_operand:QI 0 "push_operand" "")
21162         (match_operand:QI 1 "memory_operand" ""))
21163    (match_scratch:QI 2 "q")]
21164   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21165    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21166   [(set (match_dup 2) (match_dup 1))
21167    (set (match_dup 0) (match_dup 2))]
21168   "")
21170 ;; Don't move an immediate directly to memory when the instruction
21171 ;; gets too big.
21172 (define_peephole2
21173   [(match_scratch:SI 1 "r")
21174    (set (match_operand:SI 0 "memory_operand" "")
21175         (const_int 0))]
21176   "optimize_insn_for_speed_p ()
21177    && ! TARGET_USE_MOV0
21178    && TARGET_SPLIT_LONG_MOVES
21179    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21180    && peep2_regno_dead_p (0, FLAGS_REG)"
21181   [(parallel [(set (match_dup 1) (const_int 0))
21182               (clobber (reg:CC FLAGS_REG))])
21183    (set (match_dup 0) (match_dup 1))]
21184   "")
21186 (define_peephole2
21187   [(match_scratch:HI 1 "r")
21188    (set (match_operand:HI 0 "memory_operand" "")
21189         (const_int 0))]
21190   "optimize_insn_for_speed_p ()
21191    && ! TARGET_USE_MOV0
21192    && TARGET_SPLIT_LONG_MOVES
21193    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21194    && peep2_regno_dead_p (0, FLAGS_REG)"
21195   [(parallel [(set (match_dup 2) (const_int 0))
21196               (clobber (reg:CC FLAGS_REG))])
21197    (set (match_dup 0) (match_dup 1))]
21198   "operands[2] = gen_lowpart (SImode, operands[1]);")
21200 (define_peephole2
21201   [(match_scratch:QI 1 "q")
21202    (set (match_operand:QI 0 "memory_operand" "")
21203         (const_int 0))]
21204   "optimize_insn_for_speed_p ()
21205    && ! TARGET_USE_MOV0
21206    && TARGET_SPLIT_LONG_MOVES
21207    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21208    && peep2_regno_dead_p (0, FLAGS_REG)"
21209   [(parallel [(set (match_dup 2) (const_int 0))
21210               (clobber (reg:CC FLAGS_REG))])
21211    (set (match_dup 0) (match_dup 1))]
21212   "operands[2] = gen_lowpart (SImode, operands[1]);")
21214 (define_peephole2
21215   [(match_scratch:SI 2 "r")
21216    (set (match_operand:SI 0 "memory_operand" "")
21217         (match_operand:SI 1 "immediate_operand" ""))]
21218   "optimize_insn_for_speed_p ()
21219    && TARGET_SPLIT_LONG_MOVES
21220    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21221   [(set (match_dup 2) (match_dup 1))
21222    (set (match_dup 0) (match_dup 2))]
21223   "")
21225 (define_peephole2
21226   [(match_scratch:HI 2 "r")
21227    (set (match_operand:HI 0 "memory_operand" "")
21228         (match_operand:HI 1 "immediate_operand" ""))]
21229   "optimize_insn_for_speed_p ()
21230    && TARGET_SPLIT_LONG_MOVES
21231    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21232   [(set (match_dup 2) (match_dup 1))
21233    (set (match_dup 0) (match_dup 2))]
21234   "")
21236 (define_peephole2
21237   [(match_scratch:QI 2 "q")
21238    (set (match_operand:QI 0 "memory_operand" "")
21239         (match_operand:QI 1 "immediate_operand" ""))]
21240   "optimize_insn_for_speed_p ()
21241    && TARGET_SPLIT_LONG_MOVES
21242    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21243   [(set (match_dup 2) (match_dup 1))
21244    (set (match_dup 0) (match_dup 2))]
21245   "")
21247 ;; Don't compare memory with zero, load and use a test instead.
21248 (define_peephole2
21249   [(set (match_operand 0 "flags_reg_operand" "")
21250         (match_operator 1 "compare_operator"
21251           [(match_operand:SI 2 "memory_operand" "")
21252            (const_int 0)]))
21253    (match_scratch:SI 3 "r")]
21254   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
21255   [(set (match_dup 3) (match_dup 2))
21256    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
21257   "")
21259 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
21260 ;; Don't split NOTs with a displacement operand, because resulting XOR
21261 ;; will not be pairable anyway.
21263 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
21264 ;; represented using a modRM byte.  The XOR replacement is long decoded,
21265 ;; so this split helps here as well.
21267 ;; Note: Can't do this as a regular split because we can't get proper
21268 ;; lifetime information then.
21270 (define_peephole2
21271   [(set (match_operand:SI 0 "nonimmediate_operand" "")
21272         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
21273   "optimize_insn_for_speed_p ()
21274    && ((TARGET_NOT_UNPAIRABLE
21275         && (!MEM_P (operands[0])
21276             || !memory_displacement_operand (operands[0], SImode)))
21277        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
21278    && peep2_regno_dead_p (0, FLAGS_REG)"
21279   [(parallel [(set (match_dup 0)
21280                    (xor:SI (match_dup 1) (const_int -1)))
21281               (clobber (reg:CC FLAGS_REG))])]
21282   "")
21284 (define_peephole2
21285   [(set (match_operand:HI 0 "nonimmediate_operand" "")
21286         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
21287   "optimize_insn_for_speed_p ()
21288    && ((TARGET_NOT_UNPAIRABLE
21289         && (!MEM_P (operands[0])
21290             || !memory_displacement_operand (operands[0], HImode)))
21291        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
21292    && peep2_regno_dead_p (0, FLAGS_REG)"
21293   [(parallel [(set (match_dup 0)
21294                    (xor:HI (match_dup 1) (const_int -1)))
21295               (clobber (reg:CC FLAGS_REG))])]
21296   "")
21298 (define_peephole2
21299   [(set (match_operand:QI 0 "nonimmediate_operand" "")
21300         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
21301   "optimize_insn_for_speed_p ()
21302    && ((TARGET_NOT_UNPAIRABLE
21303         && (!MEM_P (operands[0])
21304             || !memory_displacement_operand (operands[0], QImode)))
21305        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
21306    && peep2_regno_dead_p (0, FLAGS_REG)"
21307   [(parallel [(set (match_dup 0)
21308                    (xor:QI (match_dup 1) (const_int -1)))
21309               (clobber (reg:CC FLAGS_REG))])]
21310   "")
21312 ;; Non pairable "test imm, reg" instructions can be translated to
21313 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
21314 ;; byte opcode instead of two, have a short form for byte operands),
21315 ;; so do it for other CPUs as well.  Given that the value was dead,
21316 ;; this should not create any new dependencies.  Pass on the sub-word
21317 ;; versions if we're concerned about partial register stalls.
21319 (define_peephole2
21320   [(set (match_operand 0 "flags_reg_operand" "")
21321         (match_operator 1 "compare_operator"
21322           [(and:SI (match_operand:SI 2 "register_operand" "")
21323                    (match_operand:SI 3 "immediate_operand" ""))
21324            (const_int 0)]))]
21325   "ix86_match_ccmode (insn, CCNOmode)
21326    && (true_regnum (operands[2]) != AX_REG
21327        || satisfies_constraint_K (operands[3]))
21328    && peep2_reg_dead_p (1, operands[2])"
21329   [(parallel
21330      [(set (match_dup 0)
21331            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
21332                             (const_int 0)]))
21333       (set (match_dup 2)
21334            (and:SI (match_dup 2) (match_dup 3)))])]
21335   "")
21337 ;; We don't need to handle HImode case, because it will be promoted to SImode
21338 ;; on ! TARGET_PARTIAL_REG_STALL
21340 (define_peephole2
21341   [(set (match_operand 0 "flags_reg_operand" "")
21342         (match_operator 1 "compare_operator"
21343           [(and:QI (match_operand:QI 2 "register_operand" "")
21344                    (match_operand:QI 3 "immediate_operand" ""))
21345            (const_int 0)]))]
21346   "! TARGET_PARTIAL_REG_STALL
21347    && ix86_match_ccmode (insn, CCNOmode)
21348    && true_regnum (operands[2]) != AX_REG
21349    && peep2_reg_dead_p (1, operands[2])"
21350   [(parallel
21351      [(set (match_dup 0)
21352            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
21353                             (const_int 0)]))
21354       (set (match_dup 2)
21355            (and:QI (match_dup 2) (match_dup 3)))])]
21356   "")
21358 (define_peephole2
21359   [(set (match_operand 0 "flags_reg_operand" "")
21360         (match_operator 1 "compare_operator"
21361           [(and:SI
21362              (zero_extract:SI
21363                (match_operand 2 "ext_register_operand" "")
21364                (const_int 8)
21365                (const_int 8))
21366              (match_operand 3 "const_int_operand" ""))
21367            (const_int 0)]))]
21368   "! TARGET_PARTIAL_REG_STALL
21369    && ix86_match_ccmode (insn, CCNOmode)
21370    && true_regnum (operands[2]) != AX_REG
21371    && peep2_reg_dead_p (1, operands[2])"
21372   [(parallel [(set (match_dup 0)
21373                    (match_op_dup 1
21374                      [(and:SI
21375                         (zero_extract:SI
21376                           (match_dup 2)
21377                           (const_int 8)
21378                           (const_int 8))
21379                         (match_dup 3))
21380                       (const_int 0)]))
21381               (set (zero_extract:SI (match_dup 2)
21382                                     (const_int 8)
21383                                     (const_int 8))
21384                    (and:SI
21385                      (zero_extract:SI
21386                        (match_dup 2)
21387                        (const_int 8)
21388                        (const_int 8))
21389                      (match_dup 3)))])]
21390   "")
21392 ;; Don't do logical operations with memory inputs.
21393 (define_peephole2
21394   [(match_scratch:SI 2 "r")
21395    (parallel [(set (match_operand:SI 0 "register_operand" "")
21396                    (match_operator:SI 3 "arith_or_logical_operator"
21397                      [(match_dup 0)
21398                       (match_operand:SI 1 "memory_operand" "")]))
21399               (clobber (reg:CC FLAGS_REG))])]
21400   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
21401   [(set (match_dup 2) (match_dup 1))
21402    (parallel [(set (match_dup 0)
21403                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
21404               (clobber (reg:CC FLAGS_REG))])]
21405   "")
21407 (define_peephole2
21408   [(match_scratch:SI 2 "r")
21409    (parallel [(set (match_operand:SI 0 "register_operand" "")
21410                    (match_operator:SI 3 "arith_or_logical_operator"
21411                      [(match_operand:SI 1 "memory_operand" "")
21412                       (match_dup 0)]))
21413               (clobber (reg:CC FLAGS_REG))])]
21414   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
21415   [(set (match_dup 2) (match_dup 1))
21416    (parallel [(set (match_dup 0)
21417                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
21418               (clobber (reg:CC FLAGS_REG))])]
21419   "")
21421 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
21422 ;; refers to the destination of the load!
21424 (define_peephole2
21425   [(set (match_operand:SI 0 "register_operand" "")
21426         (match_operand:SI 1 "register_operand" ""))
21427    (parallel [(set (match_dup 0)
21428                    (match_operator:SI 3 "commutative_operator"
21429                      [(match_dup 0)
21430                       (match_operand:SI 2 "memory_operand" "")]))
21431               (clobber (reg:CC FLAGS_REG))])]
21432   "REGNO (operands[0]) != REGNO (operands[1])
21433    && GENERAL_REGNO_P (REGNO (operands[0]))
21434    && GENERAL_REGNO_P (REGNO (operands[1]))"
21435   [(set (match_dup 0) (match_dup 4))
21436    (parallel [(set (match_dup 0)
21437                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
21438               (clobber (reg:CC FLAGS_REG))])]
21439   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
21441 (define_peephole2
21442   [(set (match_operand 0 "register_operand" "")
21443         (match_operand 1 "register_operand" ""))
21444    (set (match_dup 0)
21445                    (match_operator 3 "commutative_operator"
21446                      [(match_dup 0)
21447                       (match_operand 2 "memory_operand" "")]))]
21448   "REGNO (operands[0]) != REGNO (operands[1])
21449    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
21450        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
21451   [(set (match_dup 0) (match_dup 2))
21452    (set (match_dup 0)
21453         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
21454   "")
21456 ; Don't do logical operations with memory outputs
21458 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
21459 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
21460 ; the same decoder scheduling characteristics as the original.
21462 (define_peephole2
21463   [(match_scratch:SI 2 "r")
21464    (parallel [(set (match_operand:SI 0 "memory_operand" "")
21465                    (match_operator:SI 3 "arith_or_logical_operator"
21466                      [(match_dup 0)
21467                       (match_operand:SI 1 "nonmemory_operand" "")]))
21468               (clobber (reg:CC FLAGS_REG))])]
21469   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
21470   [(set (match_dup 2) (match_dup 0))
21471    (parallel [(set (match_dup 2)
21472                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
21473               (clobber (reg:CC FLAGS_REG))])
21474    (set (match_dup 0) (match_dup 2))]
21475   "")
21477 (define_peephole2
21478   [(match_scratch:SI 2 "r")
21479    (parallel [(set (match_operand:SI 0 "memory_operand" "")
21480                    (match_operator:SI 3 "arith_or_logical_operator"
21481                      [(match_operand:SI 1 "nonmemory_operand" "")
21482                       (match_dup 0)]))
21483               (clobber (reg:CC FLAGS_REG))])]
21484   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
21485   [(set (match_dup 2) (match_dup 0))
21486    (parallel [(set (match_dup 2)
21487                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
21488               (clobber (reg:CC FLAGS_REG))])
21489    (set (match_dup 0) (match_dup 2))]
21490   "")
21492 ;; Attempt to always use XOR for zeroing registers.
21493 (define_peephole2
21494   [(set (match_operand 0 "register_operand" "")
21495         (match_operand 1 "const0_operand" ""))]
21496   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
21497    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21498    && GENERAL_REG_P (operands[0])
21499    && peep2_regno_dead_p (0, FLAGS_REG)"
21500   [(parallel [(set (match_dup 0) (const_int 0))
21501               (clobber (reg:CC FLAGS_REG))])]
21503   operands[0] = gen_lowpart (word_mode, operands[0]);
21506 (define_peephole2
21507   [(set (strict_low_part (match_operand 0 "register_operand" ""))
21508         (const_int 0))]
21509   "(GET_MODE (operands[0]) == QImode
21510     || GET_MODE (operands[0]) == HImode)
21511    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21512    && peep2_regno_dead_p (0, FLAGS_REG)"
21513   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
21514               (clobber (reg:CC FLAGS_REG))])])
21516 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
21517 (define_peephole2
21518   [(set (match_operand 0 "register_operand" "")
21519         (const_int -1))]
21520   "(GET_MODE (operands[0]) == HImode
21521     || GET_MODE (operands[0]) == SImode
21522     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
21523    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
21524    && peep2_regno_dead_p (0, FLAGS_REG)"
21525   [(parallel [(set (match_dup 0) (const_int -1))
21526               (clobber (reg:CC FLAGS_REG))])]
21527   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
21528                               operands[0]);")
21530 ;; Attempt to convert simple leas to adds. These can be created by
21531 ;; move expanders.
21532 (define_peephole2
21533   [(set (match_operand:SI 0 "register_operand" "")
21534         (plus:SI (match_dup 0)
21535                  (match_operand:SI 1 "nonmemory_operand" "")))]
21536   "peep2_regno_dead_p (0, FLAGS_REG)"
21537   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
21538               (clobber (reg:CC FLAGS_REG))])]
21539   "")
21541 (define_peephole2
21542   [(set (match_operand:SI 0 "register_operand" "")
21543         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
21544                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
21545   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
21546   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
21547               (clobber (reg:CC FLAGS_REG))])]
21548   "operands[2] = gen_lowpart (SImode, operands[2]);")
21550 (define_peephole2
21551   [(set (match_operand:DI 0 "register_operand" "")
21552         (plus:DI (match_dup 0)
21553                  (match_operand:DI 1 "x86_64_general_operand" "")))]
21554   "peep2_regno_dead_p (0, FLAGS_REG)"
21555   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
21556               (clobber (reg:CC FLAGS_REG))])]
21557   "")
21559 (define_peephole2
21560   [(set (match_operand:SI 0 "register_operand" "")
21561         (mult:SI (match_dup 0)
21562                  (match_operand:SI 1 "const_int_operand" "")))]
21563   "exact_log2 (INTVAL (operands[1])) >= 0
21564    && peep2_regno_dead_p (0, FLAGS_REG)"
21565   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21566               (clobber (reg:CC FLAGS_REG))])]
21567   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21569 (define_peephole2
21570   [(set (match_operand:DI 0 "register_operand" "")
21571         (mult:DI (match_dup 0)
21572                  (match_operand:DI 1 "const_int_operand" "")))]
21573   "exact_log2 (INTVAL (operands[1])) >= 0
21574    && peep2_regno_dead_p (0, FLAGS_REG)"
21575   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
21576               (clobber (reg:CC FLAGS_REG))])]
21577   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21579 (define_peephole2
21580   [(set (match_operand:SI 0 "register_operand" "")
21581         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
21582                    (match_operand:DI 2 "const_int_operand" "")) 0))]
21583   "exact_log2 (INTVAL (operands[2])) >= 0
21584    && REGNO (operands[0]) == REGNO (operands[1])
21585    && peep2_regno_dead_p (0, FLAGS_REG)"
21586   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21587               (clobber (reg:CC FLAGS_REG))])]
21588   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
21590 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
21591 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
21592 ;; many CPUs it is also faster, since special hardware to avoid esp
21593 ;; dependencies is present.
21595 ;; While some of these conversions may be done using splitters, we use peepholes
21596 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
21598 ;; Convert prologue esp subtractions to push.
21599 ;; We need register to push.  In order to keep verify_flow_info happy we have
21600 ;; two choices
21601 ;; - use scratch and clobber it in order to avoid dependencies
21602 ;; - use already live register
21603 ;; We can't use the second way right now, since there is no reliable way how to
21604 ;; verify that given register is live.  First choice will also most likely in
21605 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
21606 ;; call clobbered registers are dead.  We may want to use base pointer as an
21607 ;; alternative when no register is available later.
21609 (define_peephole2
21610   [(match_scratch:SI 0 "r")
21611    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21612               (clobber (reg:CC FLAGS_REG))
21613               (clobber (mem:BLK (scratch)))])]
21614   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21615   [(clobber (match_dup 0))
21616    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21617               (clobber (mem:BLK (scratch)))])])
21619 (define_peephole2
21620   [(match_scratch:SI 0 "r")
21621    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21622               (clobber (reg:CC FLAGS_REG))
21623               (clobber (mem:BLK (scratch)))])]
21624   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21625   [(clobber (match_dup 0))
21626    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21627    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21628               (clobber (mem:BLK (scratch)))])])
21630 ;; Convert esp subtractions to push.
21631 (define_peephole2
21632   [(match_scratch:SI 0 "r")
21633    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21634               (clobber (reg:CC FLAGS_REG))])]
21635   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21636   [(clobber (match_dup 0))
21637    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21639 (define_peephole2
21640   [(match_scratch:SI 0 "r")
21641    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21642               (clobber (reg:CC FLAGS_REG))])]
21643   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21644   [(clobber (match_dup 0))
21645    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21646    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21648 ;; Convert epilogue deallocator to pop.
21649 (define_peephole2
21650   [(match_scratch:SI 0 "r")
21651    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21652               (clobber (reg:CC FLAGS_REG))
21653               (clobber (mem:BLK (scratch)))])]
21654   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21655   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21656               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21657               (clobber (mem:BLK (scratch)))])]
21658   "")
21660 ;; Two pops case is tricky, since pop causes dependency on destination register.
21661 ;; We use two registers if available.
21662 (define_peephole2
21663   [(match_scratch:SI 0 "r")
21664    (match_scratch:SI 1 "r")
21665    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21666               (clobber (reg:CC FLAGS_REG))
21667               (clobber (mem:BLK (scratch)))])]
21668   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21669   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21670               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21671               (clobber (mem:BLK (scratch)))])
21672    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21673               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21674   "")
21676 (define_peephole2
21677   [(match_scratch:SI 0 "r")
21678    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21679               (clobber (reg:CC FLAGS_REG))
21680               (clobber (mem:BLK (scratch)))])]
21681   "optimize_insn_for_size_p ()"
21682   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21683               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21684               (clobber (mem:BLK (scratch)))])
21685    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21686               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21687   "")
21689 ;; Convert esp additions to pop.
21690 (define_peephole2
21691   [(match_scratch:SI 0 "r")
21692    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21693               (clobber (reg:CC FLAGS_REG))])]
21694   ""
21695   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21696               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21697   "")
21699 ;; Two pops case is tricky, since pop causes dependency on destination register.
21700 ;; We use two registers if available.
21701 (define_peephole2
21702   [(match_scratch:SI 0 "r")
21703    (match_scratch:SI 1 "r")
21704    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21705               (clobber (reg:CC FLAGS_REG))])]
21706   ""
21707   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21708               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21709    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21710               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21711   "")
21713 (define_peephole2
21714   [(match_scratch:SI 0 "r")
21715    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21716               (clobber (reg:CC FLAGS_REG))])]
21717   "optimize_insn_for_size_p ()"
21718   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21719               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21720    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21721               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21722   "")
21724 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21725 ;; required and register dies.  Similarly for 128 to -128.
21726 (define_peephole2
21727   [(set (match_operand 0 "flags_reg_operand" "")
21728         (match_operator 1 "compare_operator"
21729           [(match_operand 2 "register_operand" "")
21730            (match_operand 3 "const_int_operand" "")]))]
21731   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
21732      && incdec_operand (operands[3], GET_MODE (operands[3])))
21733     || (!TARGET_FUSE_CMP_AND_BRANCH
21734         && INTVAL (operands[3]) == 128))
21735    && ix86_match_ccmode (insn, CCGCmode)
21736    && peep2_reg_dead_p (1, operands[2])"
21737   [(parallel [(set (match_dup 0)
21738                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21739               (clobber (match_dup 2))])]
21740   "")
21742 (define_peephole2
21743   [(match_scratch:DI 0 "r")
21744    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21745               (clobber (reg:CC FLAGS_REG))
21746               (clobber (mem:BLK (scratch)))])]
21747   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21748   [(clobber (match_dup 0))
21749    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21750               (clobber (mem:BLK (scratch)))])])
21752 (define_peephole2
21753   [(match_scratch:DI 0 "r")
21754    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21755               (clobber (reg:CC FLAGS_REG))
21756               (clobber (mem:BLK (scratch)))])]
21757   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21758   [(clobber (match_dup 0))
21759    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21760    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21761               (clobber (mem:BLK (scratch)))])])
21763 ;; Convert esp subtractions to push.
21764 (define_peephole2
21765   [(match_scratch:DI 0 "r")
21766    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21767               (clobber (reg:CC FLAGS_REG))])]
21768   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21769   [(clobber (match_dup 0))
21770    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21772 (define_peephole2
21773   [(match_scratch:DI 0 "r")
21774    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21775               (clobber (reg:CC FLAGS_REG))])]
21776   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21777   [(clobber (match_dup 0))
21778    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21779    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21781 ;; Convert epilogue deallocator to pop.
21782 (define_peephole2
21783   [(match_scratch:DI 0 "r")
21784    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21785               (clobber (reg:CC FLAGS_REG))
21786               (clobber (mem:BLK (scratch)))])]
21787   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21788   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21789               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21790               (clobber (mem:BLK (scratch)))])]
21791   "")
21793 ;; Two pops case is tricky, since pop causes dependency on destination register.
21794 ;; We use two registers if available.
21795 (define_peephole2
21796   [(match_scratch:DI 0 "r")
21797    (match_scratch:DI 1 "r")
21798    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21799               (clobber (reg:CC FLAGS_REG))
21800               (clobber (mem:BLK (scratch)))])]
21801   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21802   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21803               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21804               (clobber (mem:BLK (scratch)))])
21805    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21806               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21807   "")
21809 (define_peephole2
21810   [(match_scratch:DI 0 "r")
21811    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21812               (clobber (reg:CC FLAGS_REG))
21813               (clobber (mem:BLK (scratch)))])]
21814   "optimize_insn_for_size_p ()"
21815   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21816               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21817               (clobber (mem:BLK (scratch)))])
21818    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21819               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21820   "")
21822 ;; Convert esp additions to pop.
21823 (define_peephole2
21824   [(match_scratch:DI 0 "r")
21825    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21826               (clobber (reg:CC FLAGS_REG))])]
21827   ""
21828   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21829               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21830   "")
21832 ;; Two pops case is tricky, since pop causes dependency on destination register.
21833 ;; We use two registers if available.
21834 (define_peephole2
21835   [(match_scratch:DI 0 "r")
21836    (match_scratch:DI 1 "r")
21837    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21838               (clobber (reg:CC FLAGS_REG))])]
21839   ""
21840   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21841               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21842    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21843               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21844   "")
21846 (define_peephole2
21847   [(match_scratch:DI 0 "r")
21848    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21849               (clobber (reg:CC FLAGS_REG))])]
21850   "optimize_insn_for_size_p ()"
21851   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21852               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21853    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21854               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21855   "")
21857 ;; Convert imul by three, five and nine into lea
21858 (define_peephole2
21859   [(parallel
21860     [(set (match_operand:SI 0 "register_operand" "")
21861           (mult:SI (match_operand:SI 1 "register_operand" "")
21862                    (match_operand:SI 2 "const_int_operand" "")))
21863      (clobber (reg:CC FLAGS_REG))])]
21864   "INTVAL (operands[2]) == 3
21865    || INTVAL (operands[2]) == 5
21866    || INTVAL (operands[2]) == 9"
21867   [(set (match_dup 0)
21868         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21869                  (match_dup 1)))]
21870   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21872 (define_peephole2
21873   [(parallel
21874     [(set (match_operand:SI 0 "register_operand" "")
21875           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21876                    (match_operand:SI 2 "const_int_operand" "")))
21877      (clobber (reg:CC FLAGS_REG))])]
21878   "optimize_insn_for_speed_p ()
21879    && (INTVAL (operands[2]) == 3
21880        || INTVAL (operands[2]) == 5
21881        || INTVAL (operands[2]) == 9)"
21882   [(set (match_dup 0) (match_dup 1))
21883    (set (match_dup 0)
21884         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21885                  (match_dup 0)))]
21886   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21888 (define_peephole2
21889   [(parallel
21890     [(set (match_operand:DI 0 "register_operand" "")
21891           (mult:DI (match_operand:DI 1 "register_operand" "")
21892                    (match_operand:DI 2 "const_int_operand" "")))
21893      (clobber (reg:CC FLAGS_REG))])]
21894   "TARGET_64BIT
21895    && (INTVAL (operands[2]) == 3
21896        || INTVAL (operands[2]) == 5
21897        || INTVAL (operands[2]) == 9)"
21898   [(set (match_dup 0)
21899         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21900                  (match_dup 1)))]
21901   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21903 (define_peephole2
21904   [(parallel
21905     [(set (match_operand:DI 0 "register_operand" "")
21906           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21907                    (match_operand:DI 2 "const_int_operand" "")))
21908      (clobber (reg:CC FLAGS_REG))])]
21909   "TARGET_64BIT
21910    && optimize_insn_for_speed_p ()
21911    && (INTVAL (operands[2]) == 3
21912        || INTVAL (operands[2]) == 5
21913        || INTVAL (operands[2]) == 9)"
21914   [(set (match_dup 0) (match_dup 1))
21915    (set (match_dup 0)
21916         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21917                  (match_dup 0)))]
21918   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21920 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21921 ;; imul $32bit_imm, reg, reg is direct decoded.
21922 (define_peephole2
21923   [(match_scratch:DI 3 "r")
21924    (parallel [(set (match_operand:DI 0 "register_operand" "")
21925                    (mult:DI (match_operand:DI 1 "memory_operand" "")
21926                             (match_operand:DI 2 "immediate_operand" "")))
21927               (clobber (reg:CC FLAGS_REG))])]
21928   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21929    && !satisfies_constraint_K (operands[2])"
21930   [(set (match_dup 3) (match_dup 1))
21931    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21932               (clobber (reg:CC FLAGS_REG))])]
21935 (define_peephole2
21936   [(match_scratch:SI 3 "r")
21937    (parallel [(set (match_operand:SI 0 "register_operand" "")
21938                    (mult:SI (match_operand:SI 1 "memory_operand" "")
21939                             (match_operand:SI 2 "immediate_operand" "")))
21940               (clobber (reg:CC FLAGS_REG))])]
21941   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21942    && !satisfies_constraint_K (operands[2])"
21943   [(set (match_dup 3) (match_dup 1))
21944    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21945               (clobber (reg:CC FLAGS_REG))])]
21948 (define_peephole2
21949   [(match_scratch:SI 3 "r")
21950    (parallel [(set (match_operand:DI 0 "register_operand" "")
21951                    (zero_extend:DI
21952                      (mult:SI (match_operand:SI 1 "memory_operand" "")
21953                               (match_operand:SI 2 "immediate_operand" ""))))
21954               (clobber (reg:CC FLAGS_REG))])]
21955   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21956    && !satisfies_constraint_K (operands[2])"
21957   [(set (match_dup 3) (match_dup 1))
21958    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21959               (clobber (reg:CC FLAGS_REG))])]
21962 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21963 ;; Convert it into imul reg, reg
21964 ;; It would be better to force assembler to encode instruction using long
21965 ;; immediate, but there is apparently no way to do so.
21966 (define_peephole2
21967   [(parallel [(set (match_operand:DI 0 "register_operand" "")
21968                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21969                             (match_operand:DI 2 "const_int_operand" "")))
21970               (clobber (reg:CC FLAGS_REG))])
21971    (match_scratch:DI 3 "r")]
21972   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21973    && satisfies_constraint_K (operands[2])"
21974   [(set (match_dup 3) (match_dup 2))
21975    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21976               (clobber (reg:CC FLAGS_REG))])]
21978   if (!rtx_equal_p (operands[0], operands[1]))
21979     emit_move_insn (operands[0], operands[1]);
21982 (define_peephole2
21983   [(parallel [(set (match_operand:SI 0 "register_operand" "")
21984                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21985                             (match_operand:SI 2 "const_int_operand" "")))
21986               (clobber (reg:CC FLAGS_REG))])
21987    (match_scratch:SI 3 "r")]
21988   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21989    && satisfies_constraint_K (operands[2])"
21990   [(set (match_dup 3) (match_dup 2))
21991    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21992               (clobber (reg:CC FLAGS_REG))])]
21994   if (!rtx_equal_p (operands[0], operands[1]))
21995     emit_move_insn (operands[0], operands[1]);
21998 (define_peephole2
21999   [(parallel [(set (match_operand:HI 0 "register_operand" "")
22000                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
22001                             (match_operand:HI 2 "immediate_operand" "")))
22002               (clobber (reg:CC FLAGS_REG))])
22003    (match_scratch:HI 3 "r")]
22004   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
22005   [(set (match_dup 3) (match_dup 2))
22006    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
22007               (clobber (reg:CC FLAGS_REG))])]
22009   if (!rtx_equal_p (operands[0], operands[1]))
22010     emit_move_insn (operands[0], operands[1]);
22013 ;; After splitting up read-modify operations, array accesses with memory
22014 ;; operands might end up in form:
22015 ;;  sall    $2, %eax
22016 ;;  movl    4(%esp), %edx
22017 ;;  addl    %edx, %eax
22018 ;; instead of pre-splitting:
22019 ;;  sall    $2, %eax
22020 ;;  addl    4(%esp), %eax
22021 ;; Turn it into:
22022 ;;  movl    4(%esp), %edx
22023 ;;  leal    (%edx,%eax,4), %eax
22025 (define_peephole2
22026   [(parallel [(set (match_operand 0 "register_operand" "")
22027                    (ashift (match_operand 1 "register_operand" "")
22028                            (match_operand 2 "const_int_operand" "")))
22029                (clobber (reg:CC FLAGS_REG))])
22030    (set (match_operand 3 "register_operand")
22031         (match_operand 4 "x86_64_general_operand" ""))
22032    (parallel [(set (match_operand 5 "register_operand" "")
22033                    (plus (match_operand 6 "register_operand" "")
22034                          (match_operand 7 "register_operand" "")))
22035                    (clobber (reg:CC FLAGS_REG))])]
22036   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
22037    /* Validate MODE for lea.  */
22038    && ((!TARGET_PARTIAL_REG_STALL
22039         && (GET_MODE (operands[0]) == QImode
22040             || GET_MODE (operands[0]) == HImode))
22041        || GET_MODE (operands[0]) == SImode
22042        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
22043    /* We reorder load and the shift.  */
22044    && !rtx_equal_p (operands[1], operands[3])
22045    && !reg_overlap_mentioned_p (operands[0], operands[4])
22046    /* Last PLUS must consist of operand 0 and 3.  */
22047    && !rtx_equal_p (operands[0], operands[3])
22048    && (rtx_equal_p (operands[3], operands[6])
22049        || rtx_equal_p (operands[3], operands[7]))
22050    && (rtx_equal_p (operands[0], operands[6])
22051        || rtx_equal_p (operands[0], operands[7]))
22052    /* The intermediate operand 0 must die or be same as output.  */
22053    && (rtx_equal_p (operands[0], operands[5])
22054        || peep2_reg_dead_p (3, operands[0]))"
22055   [(set (match_dup 3) (match_dup 4))
22056    (set (match_dup 0) (match_dup 1))]
22058   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
22059   int scale = 1 << INTVAL (operands[2]);
22060   rtx index = gen_lowpart (Pmode, operands[1]);
22061   rtx base = gen_lowpart (Pmode, operands[3]);
22062   rtx dest = gen_lowpart (mode, operands[5]);
22064   operands[1] = gen_rtx_PLUS (Pmode, base,
22065                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
22066   if (mode != Pmode)
22067     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
22068   operands[0] = dest;
22071 ;; Call-value patterns last so that the wildcard operand does not
22072 ;; disrupt insn-recog's switch tables.
22074 (define_insn "*call_value_pop_0"
22075   [(set (match_operand 0 "" "")
22076         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
22077               (match_operand:SI 2 "" "")))
22078    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
22079                             (match_operand:SI 3 "immediate_operand" "")))]
22080   "!TARGET_64BIT"
22082   if (SIBLING_CALL_P (insn))
22083     return "jmp\t%P1";
22084   else
22085     return "call\t%P1";
22087   [(set_attr "type" "callv")])
22089 (define_insn "*call_value_pop_1"
22090   [(set (match_operand 0 "" "")
22091         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
22092               (match_operand:SI 2 "" "")))
22093    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
22094                             (match_operand:SI 3 "immediate_operand" "i")))]
22095   "!TARGET_64BIT"
22097   if (constant_call_address_operand (operands[1], Pmode))
22098     {
22099       if (SIBLING_CALL_P (insn))
22100         return "jmp\t%P1";
22101       else
22102         return "call\t%P1";
22103     }
22104   if (SIBLING_CALL_P (insn))
22105     return "jmp\t%A1";
22106   else
22107     return "call\t%A1";
22109   [(set_attr "type" "callv")])
22111 (define_insn "*call_value_0"
22112   [(set (match_operand 0 "" "")
22113         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
22114               (match_operand:SI 2 "" "")))]
22115   "!TARGET_64BIT"
22117   if (SIBLING_CALL_P (insn))
22118     return "jmp\t%P1";
22119   else
22120     return "call\t%P1";
22122   [(set_attr "type" "callv")])
22124 (define_insn "*call_value_0_rex64"
22125   [(set (match_operand 0 "" "")
22126         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22127               (match_operand:DI 2 "const_int_operand" "")))]
22128   "TARGET_64BIT"
22130   if (SIBLING_CALL_P (insn))
22131     return "jmp\t%P1";
22132   else
22133     return "call\t%P1";
22135   [(set_attr "type" "callv")])
22137 (define_insn "*call_value_0_rex64_ms_sysv"
22138   [(set (match_operand 0 "" "")
22139         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22140               (match_operand:DI 2 "const_int_operand" "")))
22141    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
22142    (clobber (reg:TI XMM6_REG))
22143    (clobber (reg:TI XMM7_REG))
22144    (clobber (reg:TI XMM8_REG))
22145    (clobber (reg:TI XMM9_REG))
22146    (clobber (reg:TI XMM10_REG))
22147    (clobber (reg:TI XMM11_REG))
22148    (clobber (reg:TI XMM12_REG))
22149    (clobber (reg:TI XMM13_REG))
22150    (clobber (reg:TI XMM14_REG))
22151    (clobber (reg:TI XMM15_REG))
22152    (clobber (reg:DI SI_REG))
22153    (clobber (reg:DI DI_REG))]
22154   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22156   if (SIBLING_CALL_P (insn))
22157     return "jmp\t%P1";
22158   else
22159     return "call\t%P1";
22161   [(set_attr "type" "callv")])
22163 (define_insn "*call_value_1"
22164   [(set (match_operand 0 "" "")
22165         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
22166               (match_operand:SI 2 "" "")))]
22167   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
22169   if (constant_call_address_operand (operands[1], Pmode))
22170     return "call\t%P1";
22171   return "call\t%A1";
22173   [(set_attr "type" "callv")])
22175 (define_insn "*sibcall_value_1"
22176   [(set (match_operand 0 "" "")
22177         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
22178               (match_operand:SI 2 "" "")))]
22179   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
22180   "@
22181    jmp\t%P1
22182    jmp\t%A1"
22183   [(set_attr "type" "callv")])
22185 (define_insn "*call_value_1_rex64"
22186   [(set (match_operand 0 "" "")
22187         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
22188               (match_operand:DI 2 "" "")))]
22189   "!SIBLING_CALL_P (insn) && TARGET_64BIT
22190    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
22192   if (constant_call_address_operand (operands[1], Pmode))
22193     return "call\t%P1";
22194   return "call\t%A1";
22196   [(set_attr "type" "callv")])
22198 (define_insn "*call_value_1_rex64_ms_sysv"
22199   [(set (match_operand 0 "" "")
22200         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
22201               (match_operand:DI 2 "" "")))
22202    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
22203    (clobber (reg:TI 27))
22204    (clobber (reg:TI 28))
22205    (clobber (reg:TI 45))
22206    (clobber (reg:TI 46))
22207    (clobber (reg:TI 47))
22208    (clobber (reg:TI 48))
22209    (clobber (reg:TI 49))
22210    (clobber (reg:TI 50))
22211    (clobber (reg:TI 51))
22212    (clobber (reg:TI 52))
22213    (clobber (reg:DI SI_REG))
22214    (clobber (reg:DI DI_REG))]
22215   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22217   if (constant_call_address_operand (operands[1], Pmode))
22218     return "call\t%P1";
22219   return "call\t%A1";
22221   [(set_attr "type" "callv")])
22223 (define_insn "*call_value_1_rex64_large"
22224   [(set (match_operand 0 "" "")
22225         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
22226               (match_operand:DI 2 "" "")))]
22227   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22228   "call\t%A1"
22229   [(set_attr "type" "callv")])
22231 (define_insn "*sibcall_value_1_rex64"
22232   [(set (match_operand 0 "" "")
22233         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
22234               (match_operand:DI 2 "" "")))]
22235   "SIBLING_CALL_P (insn) && TARGET_64BIT"
22236   "@
22237    jmp\t%P1
22238    jmp\t%A1"
22239   [(set_attr "type" "callv")])
22241 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
22242 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
22243 ;; caught for use by garbage collectors and the like.  Using an insn that
22244 ;; maps to SIGILL makes it more likely the program will rightfully die.
22245 ;; Keeping with tradition, "6" is in honor of #UD.
22246 (define_insn "trap"
22247   [(trap_if (const_int 1) (const_int 6))]
22248   ""
22249   { return ASM_SHORT "0x0b0f"; }
22250   [(set_attr "length" "2")])
22252 (define_expand "sse_prologue_save"
22253   [(parallel [(set (match_operand:BLK 0 "" "")
22254                    (unspec:BLK [(reg:DI 21)
22255                                 (reg:DI 22)
22256                                 (reg:DI 23)
22257                                 (reg:DI 24)
22258                                 (reg:DI 25)
22259                                 (reg:DI 26)
22260                                 (reg:DI 27)
22261                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22262               (use (match_operand:DI 1 "register_operand" ""))
22263               (use (match_operand:DI 2 "immediate_operand" ""))
22264               (use (label_ref:DI (match_operand 3 "" "")))])]
22265   "TARGET_64BIT"
22266   "")
22268 (define_insn "*sse_prologue_save_insn"
22269   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22270                           (match_operand:DI 4 "const_int_operand" "n")))
22271         (unspec:BLK [(reg:DI 21)
22272                      (reg:DI 22)
22273                      (reg:DI 23)
22274                      (reg:DI 24)
22275                      (reg:DI 25)
22276                      (reg:DI 26)
22277                      (reg:DI 27)
22278                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22279    (use (match_operand:DI 1 "register_operand" "r"))
22280    (use (match_operand:DI 2 "const_int_operand" "i"))
22281    (use (label_ref:DI (match_operand 3 "" "X")))]
22282   "TARGET_64BIT
22283    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
22284    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22286   int i;
22287   operands[0] = gen_rtx_MEM (Pmode,
22288                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22289   /* VEX instruction with a REX prefix will #UD.  */
22290   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
22291     gcc_unreachable ();
22293   output_asm_insn ("jmp\t%A1", operands);
22294   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22295     {
22296       operands[4] = adjust_address (operands[0], DImode, i*16);
22297       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22298       PUT_MODE (operands[4], TImode);
22299       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22300         output_asm_insn ("rex", operands);
22301       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
22302     }
22303   (*targetm.asm_out.internal_label) (asm_out_file, "L",
22304                                      CODE_LABEL_NUMBER (operands[3]));
22305   return "";
22307   [(set_attr "type" "other")
22308    (set_attr "length_immediate" "0")
22309    (set_attr "length_address" "0")
22310    (set (attr "length")
22311      (if_then_else
22312        (eq (symbol_ref "TARGET_AVX") (const_int 0))
22313        (const_string "34")
22314        (const_string "42")))
22315    (set_attr "memory" "store")
22316    (set_attr "modrm" "0")
22317    (set_attr "prefix" "maybe_vex")
22318    (set_attr "mode" "DI")])
22320 (define_expand "prefetch"
22321   [(prefetch (match_operand 0 "address_operand" "")
22322              (match_operand:SI 1 "const_int_operand" "")
22323              (match_operand:SI 2 "const_int_operand" ""))]
22324   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22326   int rw = INTVAL (operands[1]);
22327   int locality = INTVAL (operands[2]);
22329   gcc_assert (rw == 0 || rw == 1);
22330   gcc_assert (locality >= 0 && locality <= 3);
22331   gcc_assert (GET_MODE (operands[0]) == Pmode
22332               || GET_MODE (operands[0]) == VOIDmode);
22334   /* Use 3dNOW prefetch in case we are asking for write prefetch not
22335      supported by SSE counterpart or the SSE prefetch is not available
22336      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
22337      of locality.  */
22338   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22339     operands[2] = GEN_INT (3);
22340   else
22341     operands[1] = const0_rtx;
22344 (define_insn "*prefetch_sse"
22345   [(prefetch (match_operand:SI 0 "address_operand" "p")
22346              (const_int 0)
22347              (match_operand:SI 1 "const_int_operand" ""))]
22348   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22350   static const char * const patterns[4] = {
22351    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22352   };
22354   int locality = INTVAL (operands[1]);
22355   gcc_assert (locality >= 0 && locality <= 3);
22357   return patterns[locality];
22359   [(set_attr "type" "sse")
22360    (set_attr "atom_sse_attr" "prefetch")
22361    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22362    (set_attr "memory" "none")])
22364 (define_insn "*prefetch_sse_rex"
22365   [(prefetch (match_operand:DI 0 "address_operand" "p")
22366              (const_int 0)
22367              (match_operand:SI 1 "const_int_operand" ""))]
22368   "TARGET_PREFETCH_SSE && TARGET_64BIT"
22370   static const char * const patterns[4] = {
22371    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22372   };
22374   int locality = INTVAL (operands[1]);
22375   gcc_assert (locality >= 0 && locality <= 3);
22377   return patterns[locality];
22379   [(set_attr "type" "sse")
22380    (set_attr "atom_sse_attr" "prefetch")
22381    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22382    (set_attr "memory" "none")])
22384 (define_insn "*prefetch_3dnow"
22385   [(prefetch (match_operand:SI 0 "address_operand" "p")
22386              (match_operand:SI 1 "const_int_operand" "n")
22387              (const_int 3))]
22388   "TARGET_3DNOW && !TARGET_64BIT"
22390   if (INTVAL (operands[1]) == 0)
22391     return "prefetch\t%a0";
22392   else
22393     return "prefetchw\t%a0";
22395   [(set_attr "type" "mmx")
22396    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22397    (set_attr "memory" "none")])
22399 (define_insn "*prefetch_3dnow_rex"
22400   [(prefetch (match_operand:DI 0 "address_operand" "p")
22401              (match_operand:SI 1 "const_int_operand" "n")
22402              (const_int 3))]
22403   "TARGET_3DNOW && TARGET_64BIT"
22405   if (INTVAL (operands[1]) == 0)
22406     return "prefetch\t%a0";
22407   else
22408     return "prefetchw\t%a0";
22410   [(set_attr "type" "mmx")
22411    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22412    (set_attr "memory" "none")])
22414 (define_expand "stack_protect_set"
22415   [(match_operand 0 "memory_operand" "")
22416    (match_operand 1 "memory_operand" "")]
22417   ""
22419 #ifdef TARGET_THREAD_SSP_OFFSET
22420   if (TARGET_64BIT)
22421     emit_insn (gen_stack_tls_protect_set_di (operands[0],
22422                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22423   else
22424     emit_insn (gen_stack_tls_protect_set_si (operands[0],
22425                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22426 #else
22427   if (TARGET_64BIT)
22428     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
22429   else
22430     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
22431 #endif
22432   DONE;
22435 (define_insn "stack_protect_set_si"
22436   [(set (match_operand:SI 0 "memory_operand" "=m")
22437         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
22438    (set (match_scratch:SI 2 "=&r") (const_int 0))
22439    (clobber (reg:CC FLAGS_REG))]
22440   ""
22441   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
22442   [(set_attr "type" "multi")])
22444 (define_insn "stack_protect_set_di"
22445   [(set (match_operand:DI 0 "memory_operand" "=m")
22446         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
22447    (set (match_scratch:DI 2 "=&r") (const_int 0))
22448    (clobber (reg:CC FLAGS_REG))]
22449   "TARGET_64BIT"
22450   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
22451   [(set_attr "type" "multi")])
22453 (define_insn "stack_tls_protect_set_si"
22454   [(set (match_operand:SI 0 "memory_operand" "=m")
22455         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
22456    (set (match_scratch:SI 2 "=&r") (const_int 0))
22457    (clobber (reg:CC FLAGS_REG))]
22458   ""
22459   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
22460   [(set_attr "type" "multi")])
22462 (define_insn "stack_tls_protect_set_di"
22463   [(set (match_operand:DI 0 "memory_operand" "=m")
22464         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
22465    (set (match_scratch:DI 2 "=&r") (const_int 0))
22466    (clobber (reg:CC FLAGS_REG))]
22467   "TARGET_64BIT"
22468   {
22469      /* The kernel uses a different segment register for performance reasons; a
22470         system call would not have to trash the userspace segment register,
22471         which would be expensive */
22472      if (ix86_cmodel != CM_KERNEL)
22473         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
22474      else
22475         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
22476   }
22477   [(set_attr "type" "multi")])
22479 (define_expand "stack_protect_test"
22480   [(match_operand 0 "memory_operand" "")
22481    (match_operand 1 "memory_operand" "")
22482    (match_operand 2 "" "")]
22483   ""
22485   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
22487 #ifdef TARGET_THREAD_SSP_OFFSET
22488   if (TARGET_64BIT)
22489     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
22490                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22491   else
22492     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
22493                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22494 #else
22495   if (TARGET_64BIT)
22496     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
22497   else
22498     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
22499 #endif
22501   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
22502                                   flags, const0_rtx, operands[2]));
22503   DONE;
22506 (define_insn "stack_protect_test_si"
22507   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22508         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22509                      (match_operand:SI 2 "memory_operand" "m")]
22510                     UNSPEC_SP_TEST))
22511    (clobber (match_scratch:SI 3 "=&r"))]
22512   ""
22513   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
22514   [(set_attr "type" "multi")])
22516 (define_insn "stack_protect_test_di"
22517   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22518         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22519                      (match_operand:DI 2 "memory_operand" "m")]
22520                     UNSPEC_SP_TEST))
22521    (clobber (match_scratch:DI 3 "=&r"))]
22522   "TARGET_64BIT"
22523   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
22524   [(set_attr "type" "multi")])
22526 (define_insn "stack_tls_protect_test_si"
22527   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22528         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22529                      (match_operand:SI 2 "const_int_operand" "i")]
22530                     UNSPEC_SP_TLS_TEST))
22531    (clobber (match_scratch:SI 3 "=r"))]
22532   ""
22533   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
22534   [(set_attr "type" "multi")])
22536 (define_insn "stack_tls_protect_test_di"
22537   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22538         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22539                      (match_operand:DI 2 "const_int_operand" "i")]
22540                     UNSPEC_SP_TLS_TEST))
22541    (clobber (match_scratch:DI 3 "=r"))]
22542   "TARGET_64BIT"
22543   {
22544      /* The kernel uses a different segment register for performance reasons; a
22545         system call would not have to trash the userspace segment register,
22546         which would be expensive */
22547      if (ix86_cmodel != CM_KERNEL)
22548         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
22549      else
22550         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
22551   }
22552   [(set_attr "type" "multi")])
22554 (define_mode_iterator CRC32MODE [QI HI SI])
22555 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
22556 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
22558 (define_insn "sse4_2_crc32<mode>"
22559   [(set (match_operand:SI 0 "register_operand" "=r")
22560         (unspec:SI
22561           [(match_operand:SI 1 "register_operand" "0")
22562            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
22563           UNSPEC_CRC32))]
22564   "TARGET_SSE4_2 || TARGET_CRC32"
22565   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
22566   [(set_attr "type" "sselog1")
22567    (set_attr "prefix_rep" "1")
22568    (set_attr "prefix_extra" "1")
22569    (set (attr "prefix_data16")
22570      (if_then_else (match_operand:HI 2 "" "")
22571        (const_string "1")
22572        (const_string "*")))
22573    (set (attr "prefix_rex")
22574      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
22575        (const_string "1")
22576        (const_string "*")))
22577    (set_attr "mode" "SI")])
22579 (define_insn "sse4_2_crc32di"
22580   [(set (match_operand:DI 0 "register_operand" "=r")
22581         (unspec:DI
22582           [(match_operand:DI 1 "register_operand" "0")
22583            (match_operand:DI 2 "nonimmediate_operand" "rm")]
22584           UNSPEC_CRC32))]
22585   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
22586   "crc32q\t{%2, %0|%0, %2}"
22587   [(set_attr "type" "sselog1")
22588    (set_attr "prefix_rep" "1")
22589    (set_attr "prefix_extra" "1")
22590    (set_attr "mode" "DI")])
22592 (define_expand "rdpmc"
22593   [(match_operand:DI 0 "register_operand" "")
22594    (match_operand:SI 1 "register_operand" "")]
22595   ""
22597   rtx reg = gen_reg_rtx (DImode);
22598   rtx si;
22600   /* Force operand 1 into ECX.  */
22601   rtx ecx = gen_rtx_REG (SImode, CX_REG);
22602   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
22603   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
22604                                 UNSPECV_RDPMC);
22606   if (TARGET_64BIT)
22607     {
22608       rtvec vec = rtvec_alloc (2);
22609       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22610       rtx upper = gen_reg_rtx (DImode);
22611       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
22612                                         gen_rtvec (1, const0_rtx),
22613                                         UNSPECV_RDPMC);
22614       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
22615       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
22616       emit_insn (load);
22617       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
22618                                    NULL, 1, OPTAB_DIRECT);
22619       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
22620                                  OPTAB_DIRECT);
22621     }
22622   else
22623     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
22624   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
22625   DONE;
22628 (define_insn "*rdpmc"
22629   [(set (match_operand:DI 0 "register_operand" "=A")
22630         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
22631                             UNSPECV_RDPMC))]
22632   "!TARGET_64BIT"
22633   "rdpmc"
22634   [(set_attr "type" "other")
22635    (set_attr "length" "2")])
22637 (define_insn "*rdpmc_rex64"
22638   [(set (match_operand:DI 0 "register_operand" "=a")
22639         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
22640                             UNSPECV_RDPMC))
22641   (set (match_operand:DI 1 "register_operand" "=d")
22642        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
22643   "TARGET_64BIT"
22644   "rdpmc"
22645   [(set_attr "type" "other")
22646    (set_attr "length" "2")])
22648 (define_expand "rdtsc"
22649   [(set (match_operand:DI 0 "register_operand" "")
22650         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
22651   ""
22653   if (TARGET_64BIT)
22654     {
22655       rtvec vec = rtvec_alloc (2);
22656       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22657       rtx upper = gen_reg_rtx (DImode);
22658       rtx lower = gen_reg_rtx (DImode);
22659       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
22660                                          gen_rtvec (1, const0_rtx),
22661                                          UNSPECV_RDTSC);
22662       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
22663       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
22664       emit_insn (load);
22665       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
22666                                    NULL, 1, OPTAB_DIRECT);
22667       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
22668                                    OPTAB_DIRECT);
22669       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
22670       DONE;
22671     }
22674 (define_insn "*rdtsc"
22675   [(set (match_operand:DI 0 "register_operand" "=A")
22676         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
22677   "!TARGET_64BIT"
22678   "rdtsc"
22679   [(set_attr "type" "other")
22680    (set_attr "length" "2")])
22682 (define_insn "*rdtsc_rex64"
22683   [(set (match_operand:DI 0 "register_operand" "=a")
22684         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
22685    (set (match_operand:DI 1 "register_operand" "=d")
22686         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
22687   "TARGET_64BIT"
22688   "rdtsc"
22689   [(set_attr "type" "other")
22690    (set_attr "length" "2")])
22692 (define_expand "rdtscp"
22693   [(match_operand:DI 0 "register_operand" "")
22694    (match_operand:SI 1 "memory_operand" "")]
22695   ""
22697   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
22698                                     gen_rtvec (1, const0_rtx),
22699                                     UNSPECV_RDTSCP);
22700   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
22701                                     gen_rtvec (1, const0_rtx),
22702                                     UNSPECV_RDTSCP);
22703   rtx reg = gen_reg_rtx (DImode);
22704   rtx tmp = gen_reg_rtx (SImode);
22706   if (TARGET_64BIT)
22707     {
22708       rtvec vec = rtvec_alloc (3);
22709       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22710       rtx upper = gen_reg_rtx (DImode);
22711       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
22712       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
22713       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
22714       emit_insn (load);
22715       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
22716                                    NULL, 1, OPTAB_DIRECT);
22717       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
22718                                  OPTAB_DIRECT);
22719     }
22720   else
22721     {
22722       rtvec vec = rtvec_alloc (2);
22723       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
22724       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
22725       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
22726       emit_insn (load);
22727     }
22728   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
22729   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
22730   DONE;
22733 (define_insn "*rdtscp"
22734   [(set (match_operand:DI 0 "register_operand" "=A")
22735         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22736    (set (match_operand:SI 1 "register_operand" "=c")
22737         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
22738   "!TARGET_64BIT"
22739   "rdtscp"
22740   [(set_attr "type" "other")
22741    (set_attr "length" "3")])
22743 (define_insn "*rdtscp_rex64"
22744   [(set (match_operand:DI 0 "register_operand" "=a")
22745         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22746    (set (match_operand:DI 1 "register_operand" "=d")
22747         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
22748    (set (match_operand:SI 2 "register_operand" "=c")
22749         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
22750   "TARGET_64BIT"
22751   "rdtscp"
22752   [(set_attr "type" "other")
22753    (set_attr "length" "3")])
22755 (include "mmx.md")
22756 (include "sse.md")
22757 (include "sync.md")