* config/i386/i386.md (maxmin_int): Rename code attribute from
[official-gcc/alias-decl.git] / gcc / config / i386 / i386.md
blob557bb3b14659e5b8ae46384ab65aa21346d2bdb6
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, 2010
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 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
35 ;;      otherwise nothing
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
43 ;;      delimiter.
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;;      %b0 would print %al if operands[0] is reg 0.
46 ;; w --  likewise, print the HImode name of the register.
47 ;; k --  likewise, print the SImode name of the register.
48 ;; q --  likewise, print the DImode name of the register.
49 ;; x --  likewise, print the V4SFmode name of the register.
50 ;; t --  likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; UNSPEC usage:
65 (define_constants
66   [; Relocation specifiers
67    (UNSPEC_GOT                  0)
68    (UNSPEC_GOTOFF               1)
69    (UNSPEC_GOTPCREL             2)
70    (UNSPEC_GOTTPOFF             3)
71    (UNSPEC_TPOFF                4)
72    (UNSPEC_NTPOFF               5)
73    (UNSPEC_DTPOFF               6)
74    (UNSPEC_GOTNTPOFF            7)
75    (UNSPEC_INDNTPOFF            8)
76    (UNSPEC_PLTOFF               9)
77    (UNSPEC_MACHOPIC_OFFSET      10)
79    ; Prologue support
80    (UNSPEC_STACK_ALLOC          11)
81    (UNSPEC_SET_GOT              12)
82    (UNSPEC_SSE_PROLOGUE_SAVE    13)
83    (UNSPEC_REG_SAVE             14)
84    (UNSPEC_DEF_CFA              15)
85    (UNSPEC_SET_RIP              16)
86    (UNSPEC_SET_GOT_OFFSET       17)
87    (UNSPEC_MEMORY_BLOCKAGE      18)
89    ; TLS support
90    (UNSPEC_TP                   20)
91    (UNSPEC_TLS_GD               21)
92    (UNSPEC_TLS_LD_BASE          22)
93    (UNSPEC_TLSDESC              23)
95    ; Other random patterns
96    (UNSPEC_SCAS                 30)
97    (UNSPEC_FNSTSW               31)
98    (UNSPEC_SAHF                 32)
99    (UNSPEC_FSTCW                33)
100    (UNSPEC_ADD_CARRY            34)
101    (UNSPEC_FLDCW                35)
102    (UNSPEC_REP                  36)
103    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
104    (UNSPEC_TRUNC_NOOP           39)
106    ; For SSE/MMX support:
107    (UNSPEC_FIX_NOTRUNC          40)
108    (UNSPEC_MASKMOV              41)
109    (UNSPEC_MOVMSK               42)
110    (UNSPEC_MOVNT                43)
111    (UNSPEC_MOVU                 44)
112    (UNSPEC_RCP                  45)
113    (UNSPEC_RSQRT                46)
114    (UNSPEC_SFENCE               47)
115    (UNSPEC_PFRCP                49)
116    (UNSPEC_PFRCPIT1             40)
117    (UNSPEC_PFRCPIT2             41)
118    (UNSPEC_PFRSQRT              42)
119    (UNSPEC_PFRSQIT1             43)
120    (UNSPEC_MFENCE               44)
121    (UNSPEC_LFENCE               45)
122    (UNSPEC_PSADBW               46)
123    (UNSPEC_LDDQU                47)
124    (UNSPEC_MS_TO_SYSV_CALL      48)
126    ; Generic math support
127    (UNSPEC_COPYSIGN             50)
128    (UNSPEC_IEEE_MIN             51)     ; not commutative
129    (UNSPEC_IEEE_MAX             52)     ; not commutative
131    ; x87 Floating point
132    (UNSPEC_SIN                  60)
133    (UNSPEC_COS                  61)
134    (UNSPEC_FPATAN               62)
135    (UNSPEC_FYL2X                63)
136    (UNSPEC_FYL2XP1              64)
137    (UNSPEC_FRNDINT              65)
138    (UNSPEC_FIST                 66)
139    (UNSPEC_F2XM1                67)
140    (UNSPEC_TAN                  68)
141    (UNSPEC_FXAM                 69)
143    ; x87 Rounding
144    (UNSPEC_FRNDINT_FLOOR        70)
145    (UNSPEC_FRNDINT_CEIL         71)
146    (UNSPEC_FRNDINT_TRUNC        72)
147    (UNSPEC_FRNDINT_MASK_PM      73)
148    (UNSPEC_FIST_FLOOR           74)
149    (UNSPEC_FIST_CEIL            75)
151    ; x87 Double output FP
152    (UNSPEC_SINCOS_COS           80)
153    (UNSPEC_SINCOS_SIN           81)
154    (UNSPEC_XTRACT_FRACT         84)
155    (UNSPEC_XTRACT_EXP           85)
156    (UNSPEC_FSCALE_FRACT         86)
157    (UNSPEC_FSCALE_EXP           87)
158    (UNSPEC_FPREM_F              88)
159    (UNSPEC_FPREM_U              89)
160    (UNSPEC_FPREM1_F             90)
161    (UNSPEC_FPREM1_U             91)
163    (UNSPEC_C2_FLAG              95)
164    (UNSPEC_FXAM_MEM             96)
166    ; SSP patterns
167    (UNSPEC_SP_SET               100)
168    (UNSPEC_SP_TEST              101)
169    (UNSPEC_SP_TLS_SET           102)
170    (UNSPEC_SP_TLS_TEST          103)
172    ; SSSE3
173    (UNSPEC_PSHUFB               120)
174    (UNSPEC_PSIGN                121)
175    (UNSPEC_PALIGNR              122)
177    ; For SSE4A support
178    (UNSPEC_EXTRQI               130)
179    (UNSPEC_EXTRQ                131)
180    (UNSPEC_INSERTQI             132)
181    (UNSPEC_INSERTQ              133)
183    ; For SSE4.1 support
184    (UNSPEC_BLENDV               134)
185    (UNSPEC_INSERTPS             135)
186    (UNSPEC_DP                   136)
187    (UNSPEC_MOVNTDQA             137)
188    (UNSPEC_MPSADBW              138)
189    (UNSPEC_PHMINPOSUW           139)
190    (UNSPEC_PTEST                140)
191    (UNSPEC_ROUND                141)
193    ; For SSE4.2 support
194    (UNSPEC_CRC32                143)
195    (UNSPEC_PCMPESTR             144)
196    (UNSPEC_PCMPISTR             145)
198    ; For FMA4 support
199    (UNSPEC_FMA4_INTRINSIC       150)
200    (UNSPEC_FMA4_FMADDSUB        151)
201    (UNSPEC_FMA4_FMSUBADD        152)
202    (UNSPEC_XOP_UNSIGNED_CMP     151)
203    (UNSPEC_XOP_TRUEFALSE        152)
204    (UNSPEC_XOP_PERMUTE          153)
205    (UNSPEC_FRCZ                 154)
207    ; For AES support
208    (UNSPEC_AESENC               159)
209    (UNSPEC_AESENCLAST           160)
210    (UNSPEC_AESDEC               161)
211    (UNSPEC_AESDECLAST           162)
212    (UNSPEC_AESIMC               163)
213    (UNSPEC_AESKEYGENASSIST      164)
215    ; For PCLMUL support
216    (UNSPEC_PCLMUL               165)
218    ; For AVX support
219    (UNSPEC_PCMP                 166)
220    (UNSPEC_VPERMIL              167)
221    (UNSPEC_VPERMIL2             168)
222    (UNSPEC_VPERMIL2F128         169)
223    (UNSPEC_MASKLOAD             170)
224    (UNSPEC_MASKSTORE            171)
225    (UNSPEC_CAST                 172)
226    (UNSPEC_VTESTP               173)
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    (UNSPECV_VSWAPMOV            21)
251    (UNSPECV_LLWP_INTRINSIC      22)
252    (UNSPECV_SLWP_INTRINSIC      23)
253    (UNSPECV_LWPVAL_INTRINSIC    24)
254    (UNSPECV_LWPINS_INTRINSIC    25)
255   ])
257 ;; Constants to represent pcomtrue/pcomfalse variants
258 (define_constants
259   [(PCOM_FALSE                  0)
260    (PCOM_TRUE                   1)
261    (COM_FALSE_S                 2)
262    (COM_FALSE_P                 3)
263    (COM_TRUE_S                  4)
264    (COM_TRUE_P                  5)
265   ])
267 ;; Constants used in the XOP pperm instruction
268 (define_constants
269   [(PPERM_SRC                   0x00)   /* copy source */
270    (PPERM_INVERT                0x20)   /* invert source */
271    (PPERM_REVERSE               0x40)   /* bit reverse source */
272    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
273    (PPERM_ZERO                  0x80)   /* all 0's */
274    (PPERM_ONES                  0xa0)   /* all 1's */
275    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
276    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
277    (PPERM_SRC1                  0x00)   /* use first source byte */
278    (PPERM_SRC2                  0x10)   /* use second source byte */
279    ])
281 ;; Registers by name.
282 (define_constants
283   [(AX_REG                       0)
284    (DX_REG                       1)
285    (CX_REG                       2)
286    (BX_REG                       3)
287    (SI_REG                       4)
288    (DI_REG                       5)
289    (BP_REG                       6)
290    (SP_REG                       7)
291    (ST0_REG                      8)
292    (ST1_REG                      9)
293    (ST2_REG                     10)
294    (ST3_REG                     11)
295    (ST4_REG                     12)
296    (ST5_REG                     13)
297    (ST6_REG                     14)
298    (ST7_REG                     15)
299    (FLAGS_REG                   17)
300    (FPSR_REG                    18)
301    (FPCR_REG                    19)
302    (XMM0_REG                    21)
303    (XMM1_REG                    22)
304    (XMM2_REG                    23)
305    (XMM3_REG                    24)
306    (XMM4_REG                    25)
307    (XMM5_REG                    26)
308    (XMM6_REG                    27)
309    (XMM7_REG                    28)
310    (MM0_REG                     29)
311    (MM1_REG                     30)
312    (MM2_REG                     31)
313    (MM3_REG                     32)
314    (MM4_REG                     33)
315    (MM5_REG                     34)
316    (MM6_REG                     35)
317    (MM7_REG                     36)
318    (R8_REG                      37)
319    (R9_REG                      38)
320    (R10_REG                     39)
321    (R11_REG                     40)
322    (R12_REG                     41)
323    (R13_REG                     42)
324    (XMM8_REG                    45)
325    (XMM9_REG                    46)
326    (XMM10_REG                   47)
327    (XMM11_REG                   48)
328    (XMM12_REG                   49)
329    (XMM13_REG                   50)
330    (XMM14_REG                   51)
331    (XMM15_REG                   52)
332   ])
334 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
335 ;; from i386.c.
337 ;; In C guard expressions, put expressions which may be compile-time
338 ;; constants first.  This allows for better optimization.  For
339 ;; example, write "TARGET_64BIT && reload_completed", not
340 ;; "reload_completed && TARGET_64BIT".
343 ;; Processor type.
344 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
345                     generic64,amdfam10"
346   (const (symbol_ref "ix86_schedule")))
348 ;; A basic instruction type.  Refinements due to arguments to be
349 ;; provided in other attributes.
350 (define_attr "type"
351   "other,multi,
352    alu,alu1,negnot,imov,imovx,lea,
353    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
354    icmp,test,ibr,setcc,icmov,
355    push,pop,call,callv,leave,
356    str,bitmanip,
357    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
358    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
359    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
360    ssemuladd,sse4arg,lwp,
361    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
362   (const_string "other"))
364 ;; Main data type used by the insn
365 (define_attr "mode"
366   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
367   (const_string "unknown"))
369 ;; The CPU unit operations uses.
370 (define_attr "unit" "integer,i387,sse,mmx,unknown"
371   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
372            (const_string "i387")
373          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
374                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
375                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
376            (const_string "sse")
377          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
378            (const_string "mmx")
379          (eq_attr "type" "other")
380            (const_string "unknown")]
381          (const_string "integer")))
383 ;; The (bounding maximum) length of an instruction immediate.
384 (define_attr "length_immediate" ""
385   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
386                           bitmanip")
387            (const_int 0)
388          (eq_attr "unit" "i387,sse,mmx")
389            (const_int 0)
390          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
391                           imul,icmp,push,pop")
392            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
393          (eq_attr "type" "imov,test")
394            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
395          (eq_attr "type" "call")
396            (if_then_else (match_operand 0 "constant_call_address_operand" "")
397              (const_int 4)
398              (const_int 0))
399          (eq_attr "type" "callv")
400            (if_then_else (match_operand 1 "constant_call_address_operand" "")
401              (const_int 4)
402              (const_int 0))
403          ;; We don't know the size before shorten_branches.  Expect
404          ;; the instruction to fit for better scheduling.
405          (eq_attr "type" "ibr")
406            (const_int 1)
407          ]
408          (symbol_ref "/* Update immediate_length and other attributes! */
409                       gcc_unreachable (),1")))
411 ;; The (bounding maximum) length of an instruction address.
412 (define_attr "length_address" ""
413   (cond [(eq_attr "type" "str,other,multi,fxch")
414            (const_int 0)
415          (and (eq_attr "type" "call")
416               (match_operand 0 "constant_call_address_operand" ""))
417              (const_int 0)
418          (and (eq_attr "type" "callv")
419               (match_operand 1 "constant_call_address_operand" ""))
420              (const_int 0)
421          ]
422          (symbol_ref "ix86_attr_length_address_default (insn)")))
424 ;; Set when length prefix is used.
425 (define_attr "prefix_data16" ""
426   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
427            (const_int 0)
428          (eq_attr "mode" "HI")
429            (const_int 1)
430          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
431            (const_int 1)
432         ]
433         (const_int 0)))
435 ;; Set when string REP prefix is used.
436 (define_attr "prefix_rep" ""
437   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
438            (const_int 0)
439          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
440            (const_int 1)
441         ]
442         (const_int 0)))
444 ;; Set when 0f opcode prefix is used.
445 (define_attr "prefix_0f" ""
446   (if_then_else
447     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
448          (eq_attr "unit" "sse,mmx"))
449     (const_int 1)
450     (const_int 0)))
452 ;; Set when REX opcode prefix is used.
453 (define_attr "prefix_rex" ""
454   (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
455            (const_int 0)
456          (and (eq_attr "mode" "DI")
457               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
458                    (eq_attr "unit" "!mmx")))
459            (const_int 1)
460          (and (eq_attr "mode" "QI")
461               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
462                   (const_int 0)))
463            (const_int 1)
464          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
465              (const_int 0))
466            (const_int 1)
467          (and (eq_attr "type" "imovx")
468               (match_operand:QI 1 "ext_QIreg_operand" ""))
469            (const_int 1)
470         ]
471         (const_int 0)))
473 ;; There are also additional prefixes in 3DNOW, SSSE3.
474 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
475 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
476 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
477 (define_attr "prefix_extra" ""
478   (cond [(eq_attr "type" "ssemuladd,sse4arg")
479            (const_int 2)
480          (eq_attr "type" "sseiadd1,ssecvt1")
481            (const_int 1)
482         ]
483         (const_int 0)))
485 ;; Prefix used: original, VEX or maybe VEX.
486 (define_attr "prefix" "orig,vex,maybe_vex"
487   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
488     (const_string "vex")
489     (const_string "orig")))
491 ;; VEX W bit is used.
492 (define_attr "prefix_vex_w" "" (const_int 0))
494 ;; The length of VEX prefix
495 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
496 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
497 ;; still prefix_0f 1, with prefix_extra 1.
498 (define_attr "length_vex" ""
499   (if_then_else (and (eq_attr "prefix_0f" "1")
500                      (eq_attr "prefix_extra" "0"))
501     (if_then_else (eq_attr "prefix_vex_w" "1")
502       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
503       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
504     (if_then_else (eq_attr "prefix_vex_w" "1")
505       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
506       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
508 ;; Set when modrm byte is used.
509 (define_attr "modrm" ""
510   (cond [(eq_attr "type" "str,leave")
511            (const_int 0)
512          (eq_attr "unit" "i387")
513            (const_int 0)
514          (and (eq_attr "type" "incdec")
515               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
516                    (ior (match_operand:SI 1 "register_operand" "")
517                         (match_operand:HI 1 "register_operand" ""))))
518            (const_int 0)
519          (and (eq_attr "type" "push")
520               (not (match_operand 1 "memory_operand" "")))
521            (const_int 0)
522          (and (eq_attr "type" "pop")
523               (not (match_operand 0 "memory_operand" "")))
524            (const_int 0)
525          (and (eq_attr "type" "imov")
526               (and (not (eq_attr "mode" "DI"))
527                    (ior (and (match_operand 0 "register_operand" "")
528                              (match_operand 1 "immediate_operand" ""))
529                         (ior (and (match_operand 0 "ax_reg_operand" "")
530                                   (match_operand 1 "memory_displacement_only_operand" ""))
531                              (and (match_operand 0 "memory_displacement_only_operand" "")
532                                   (match_operand 1 "ax_reg_operand" ""))))))
533            (const_int 0)
534          (and (eq_attr "type" "call")
535               (match_operand 0 "constant_call_address_operand" ""))
536              (const_int 0)
537          (and (eq_attr "type" "callv")
538               (match_operand 1 "constant_call_address_operand" ""))
539              (const_int 0)
540          (and (eq_attr "type" "alu,alu1,icmp,test")
541               (match_operand 0 "ax_reg_operand" ""))
542              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
543          ]
544          (const_int 1)))
546 ;; The (bounding maximum) length of an instruction in bytes.
547 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
548 ;; Later we may want to split them and compute proper length as for
549 ;; other insns.
550 (define_attr "length" ""
551   (cond [(eq_attr "type" "other,multi,fistp,frndint")
552            (const_int 16)
553          (eq_attr "type" "fcmp")
554            (const_int 4)
555          (eq_attr "unit" "i387")
556            (plus (const_int 2)
557                  (plus (attr "prefix_data16")
558                        (attr "length_address")))
559          (ior (eq_attr "prefix" "vex")
560               (and (eq_attr "prefix" "maybe_vex")
561                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
562            (plus (attr "length_vex")
563                  (plus (attr "length_immediate")
564                        (plus (attr "modrm")
565                              (attr "length_address"))))]
566          (plus (plus (attr "modrm")
567                      (plus (attr "prefix_0f")
568                            (plus (attr "prefix_rex")
569                                  (plus (attr "prefix_extra")
570                                        (const_int 1)))))
571                (plus (attr "prefix_rep")
572                      (plus (attr "prefix_data16")
573                            (plus (attr "length_immediate")
574                                  (attr "length_address")))))))
576 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
577 ;; `store' if there is a simple memory reference therein, or `unknown'
578 ;; if the instruction is complex.
580 (define_attr "memory" "none,load,store,both,unknown"
581   (cond [(eq_attr "type" "other,multi,str,lwp")
582            (const_string "unknown")
583          (eq_attr "type" "lea,fcmov,fpspc")
584            (const_string "none")
585          (eq_attr "type" "fistp,leave")
586            (const_string "both")
587          (eq_attr "type" "frndint")
588            (const_string "load")
589          (eq_attr "type" "push")
590            (if_then_else (match_operand 1 "memory_operand" "")
591              (const_string "both")
592              (const_string "store"))
593          (eq_attr "type" "pop")
594            (if_then_else (match_operand 0 "memory_operand" "")
595              (const_string "both")
596              (const_string "load"))
597          (eq_attr "type" "setcc")
598            (if_then_else (match_operand 0 "memory_operand" "")
599              (const_string "store")
600              (const_string "none"))
601          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
602            (if_then_else (ior (match_operand 0 "memory_operand" "")
603                               (match_operand 1 "memory_operand" ""))
604              (const_string "load")
605              (const_string "none"))
606          (eq_attr "type" "ibr")
607            (if_then_else (match_operand 0 "memory_operand" "")
608              (const_string "load")
609              (const_string "none"))
610          (eq_attr "type" "call")
611            (if_then_else (match_operand 0 "constant_call_address_operand" "")
612              (const_string "none")
613              (const_string "load"))
614          (eq_attr "type" "callv")
615            (if_then_else (match_operand 1 "constant_call_address_operand" "")
616              (const_string "none")
617              (const_string "load"))
618          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
619               (match_operand 1 "memory_operand" ""))
620            (const_string "both")
621          (and (match_operand 0 "memory_operand" "")
622               (match_operand 1 "memory_operand" ""))
623            (const_string "both")
624          (match_operand 0 "memory_operand" "")
625            (const_string "store")
626          (match_operand 1 "memory_operand" "")
627            (const_string "load")
628          (and (eq_attr "type"
629                  "!alu1,negnot,ishift1,
630                    imov,imovx,icmp,test,bitmanip,
631                    fmov,fcmp,fsgn,
632                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
633                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
634               (match_operand 2 "memory_operand" ""))
635            (const_string "load")
636          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
637               (match_operand 3 "memory_operand" ""))
638            (const_string "load")
639         ]
640         (const_string "none")))
642 ;; Indicates if an instruction has both an immediate and a displacement.
644 (define_attr "imm_disp" "false,true,unknown"
645   (cond [(eq_attr "type" "other,multi")
646            (const_string "unknown")
647          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
648               (and (match_operand 0 "memory_displacement_operand" "")
649                    (match_operand 1 "immediate_operand" "")))
650            (const_string "true")
651          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
652               (and (match_operand 0 "memory_displacement_operand" "")
653                    (match_operand 2 "immediate_operand" "")))
654            (const_string "true")
655         ]
656         (const_string "false")))
658 ;; Indicates if an FP operation has an integer source.
660 (define_attr "fp_int_src" "false,true"
661   (const_string "false"))
663 ;; Defines rounding mode of an FP operation.
665 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
666   (const_string "any"))
668 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
669 (define_attr "use_carry" "0,1" (const_string "0"))
671 ;; Define attribute to indicate unaligned ssemov insns
672 (define_attr "movu" "0,1" (const_string "0"))
674 ;; Describe a user's asm statement.
675 (define_asm_attributes
676   [(set_attr "length" "128")
677    (set_attr "type" "multi")])
679 ;; All integer comparison codes.
680 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
682 ;; All floating-point comparison codes.
683 (define_code_iterator fp_cond [unordered ordered
684                                uneq unge ungt unle unlt ltgt])
686 (define_code_iterator plusminus [plus minus])
688 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
690 ;; Base name for define_insn
691 (define_code_attr plusminus_insn
692   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
693    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
695 ;; Base name for insn mnemonic.
696 (define_code_attr plusminus_mnemonic
697   [(plus "add") (ss_plus "adds") (us_plus "addus")
698    (minus "sub") (ss_minus "subs") (us_minus "subus")])
699 (define_code_attr plusminus_carry_mnemonic
700   [(plus "adc") (minus "sbb")])
702 ;; Mark commutative operators as such in constraints.
703 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
704                         (minus "") (ss_minus "") (us_minus "")])
706 ;; Mapping of signed max and min
707 (define_code_iterator smaxmin [smax smin])
709 ;; Mapping of unsigned max and min
710 (define_code_iterator umaxmin [umax umin])
712 ;; Mapping of signed/unsigned max and min
713 (define_code_iterator maxmin [smax smin umax umin])
715 ;; Base name for integer and FP insn mnemonic
716 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
717                               (umax "maxu") (umin "minu")])
718 (define_code_attr maxmin_float [(smax "max") (smin "min")])
720 ;; Mapping of logic operators
721 (define_code_iterator any_logic [and ior xor])
722 (define_code_iterator any_or [ior xor])
724 ;; Base name for insn mnemonic.
725 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
727 ;; Mapping of shift-right operators
728 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
730 ;; Base name for define_insn
731 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
733 ;; Base name for insn mnemonic.
734 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
736 ;; Mapping of rotate operators
737 (define_code_iterator any_rotate [rotate rotatert])
739 ;; Base name for define_insn
740 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
742 ;; Base name for insn mnemonic.
743 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
745 ;; Mapping of abs neg operators
746 (define_code_iterator absneg [abs neg])
748 ;; Base name for x87 insn mnemonic.
749 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
751 ;; Used in signed and unsigned widening multiplications.
752 (define_code_iterator any_extend [sign_extend zero_extend])
754 ;; Various insn prefixes for signed and unsigned operations.
755 (define_code_attr u [(sign_extend "") (zero_extend "u")
756                      (div "") (udiv "u")])
757 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
759 ;; Used in signed and unsigned divisions.
760 (define_code_iterator any_div [div udiv])
762 ;; Instruction prefix for signed and unsigned operations.
763 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
764                              (div "i") (udiv "")])
766 ;; All single word integer modes.
767 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
769 ;; Single word integer modes without DImode.
770 (define_mode_iterator SWI124 [QI HI SI])
772 ;; Single word integer modes without QImode.
773 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
775 ;; Single word integer modes without QImode and HImode.
776 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
778 ;; All math-dependant single and double word integer modes.
779 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
780                              (HI "TARGET_HIMODE_MATH")
781                              SI DI (TI "TARGET_64BIT")])
783 ;; Math-dependant single word integer modes.
784 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
785                             (HI "TARGET_HIMODE_MATH")
786                             SI (DI "TARGET_64BIT")])
788 ;; Math-dependant single word integer modes without DImode.
789 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
790                                (HI "TARGET_HIMODE_MATH")
791                                SI])
793 ;; Math-dependant single word integer modes without QImode.
794 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
795                                SI (DI "TARGET_64BIT")])
797 ;; Double word integer modes.
798 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
799                            (TI "TARGET_64BIT")])
801 ;; Double word integer modes as mode attribute.
802 (define_mode_attr DWI [(SI "DI") (DI "TI")])
803 (define_mode_attr dwi [(SI "di") (DI "ti")])
805 ;; Half mode for double word integer modes.
806 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
807                             (DI "TARGET_64BIT")])
809 ;; Instruction suffix for integer modes.
810 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
812 ;; Register class for integer modes.
813 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
815 ;; Immediate operand constraint for integer modes.
816 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
818 ;; General operand constraint for word modes.
819 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
821 ;; Immediate operand constraint for double integer modes.
822 (define_mode_attr di [(SI "iF") (DI "e")])
824 ;; Immediate operand constraint for shifts.
825 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
827 ;; General operand predicate for integer modes.
828 (define_mode_attr general_operand
829         [(QI "general_operand")
830          (HI "general_operand")
831          (SI "general_operand")
832          (DI "x86_64_general_operand")
833          (TI "x86_64_general_operand")])
835 ;; General sign/zero extend operand predicate for integer modes.
836 (define_mode_attr general_szext_operand
837         [(QI "general_operand")
838          (HI "general_operand")
839          (SI "general_operand")
840          (DI "x86_64_szext_general_operand")])
842 ;; Operand predicate for shifts.
843 (define_mode_attr shift_operand
844         [(QI "nonimmediate_operand")
845          (HI "nonimmediate_operand")
846          (SI "nonimmediate_operand")
847          (DI "shiftdi_operand")
848          (TI "register_operand")])
850 ;; Operand predicate for shift argument.
851 (define_mode_attr shift_immediate_operand
852         [(QI "const_1_to_31_operand")
853          (HI "const_1_to_31_operand")
854          (SI "const_1_to_31_operand")
855          (DI "const_1_to_63_operand")])
857 ;; Input operand predicate for arithmetic left shifts.
858 (define_mode_attr ashl_input_operand
859         [(QI "nonimmediate_operand")
860          (HI "nonimmediate_operand")
861          (SI "nonimmediate_operand")
862          (DI "ashldi_input_operand")
863          (TI "reg_or_pm1_operand")])
865 ;; SSE and x87 SFmode and DFmode floating point modes
866 (define_mode_iterator MODEF [SF DF])
868 ;; All x87 floating point modes
869 (define_mode_iterator X87MODEF [SF DF XF])
871 ;; All integer modes handled by x87 fisttp operator.
872 (define_mode_iterator X87MODEI [HI SI DI])
874 ;; All integer modes handled by integer x87 operators.
875 (define_mode_iterator X87MODEI12 [HI SI])
877 ;; All integer modes handled by SSE cvtts?2si* operators.
878 (define_mode_iterator SSEMODEI24 [SI DI])
880 ;; SSE asm suffix for floating point modes
881 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
883 ;; SSE vector mode corresponding to a scalar mode
884 (define_mode_attr ssevecmode
885   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
887 ;; Instruction suffix for REX 64bit operators.
888 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
890 ;; This mode iterator allows :P to be used for patterns that operate on
891 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
892 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
894 ;; Scheduling descriptions
896 (include "pentium.md")
897 (include "ppro.md")
898 (include "k6.md")
899 (include "athlon.md")
900 (include "geode.md")
901 (include "atom.md")
904 ;; Operand and operator predicates and constraints
906 (include "predicates.md")
907 (include "constraints.md")
910 ;; Compare and branch/compare and store instructions.
912 (define_expand "cbranch<mode>4"
913   [(set (reg:CC FLAGS_REG)
914         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
915                     (match_operand:SDWIM 2 "<general_operand>" "")))
916    (set (pc) (if_then_else
917                (match_operator 0 "comparison_operator"
918                 [(reg:CC FLAGS_REG) (const_int 0)])
919                (label_ref (match_operand 3 "" ""))
920                (pc)))]
921   ""
923   if (MEM_P (operands[1]) && MEM_P (operands[2]))
924     operands[1] = force_reg (<MODE>mode, operands[1]);
925   ix86_compare_op0 = operands[1];
926   ix86_compare_op1 = operands[2];
927   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
928   DONE;
931 (define_expand "cstore<mode>4"
932   [(set (reg:CC FLAGS_REG)
933         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
934                     (match_operand:SWIM 3 "<general_operand>" "")))
935    (set (match_operand:QI 0 "register_operand" "")
936         (match_operator 1 "comparison_operator"
937           [(reg:CC FLAGS_REG) (const_int 0)]))]
938   ""
940   if (MEM_P (operands[2]) && MEM_P (operands[3]))
941     operands[2] = force_reg (<MODE>mode, operands[2]);
942   ix86_compare_op0 = operands[2];
943   ix86_compare_op1 = operands[3];
944   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
945   DONE;
948 (define_expand "cmp<mode>_1"
949   [(set (reg:CC FLAGS_REG)
950         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
951                     (match_operand:SWI48 1 "<general_operand>" "")))]
952   ""
953   "")
955 (define_insn "*cmp<mode>_ccno_1"
956   [(set (reg FLAGS_REG)
957         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
958                  (match_operand:SWI 1 "const0_operand" "")))]
959   "ix86_match_ccmode (insn, CCNOmode)"
960   "@
961    test{<imodesuffix>}\t%0, %0
962    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
963   [(set_attr "type" "test,icmp")
964    (set_attr "length_immediate" "0,1")
965    (set_attr "mode" "<MODE>")])
967 (define_insn "*cmp<mode>_1"
968   [(set (reg FLAGS_REG)
969         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
970                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
971   "ix86_match_ccmode (insn, CCmode)"
972   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
973   [(set_attr "type" "icmp")
974    (set_attr "mode" "<MODE>")])
976 (define_insn "*cmp<mode>_minus_1"
977   [(set (reg FLAGS_REG)
978         (compare
979           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
980                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
981           (const_int 0)))]
982   "ix86_match_ccmode (insn, CCGOCmode)"
983   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
984   [(set_attr "type" "icmp")
985    (set_attr "mode" "<MODE>")])
987 (define_insn "*cmpqi_ext_1"
988   [(set (reg FLAGS_REG)
989         (compare
990           (match_operand:QI 0 "general_operand" "Qm")
991           (subreg:QI
992             (zero_extract:SI
993               (match_operand 1 "ext_register_operand" "Q")
994               (const_int 8)
995               (const_int 8)) 0)))]
996   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
997   "cmp{b}\t{%h1, %0|%0, %h1}"
998   [(set_attr "type" "icmp")
999    (set_attr "mode" "QI")])
1001 (define_insn "*cmpqi_ext_1_rex64"
1002   [(set (reg FLAGS_REG)
1003         (compare
1004           (match_operand:QI 0 "register_operand" "Q")
1005           (subreg:QI
1006             (zero_extract:SI
1007               (match_operand 1 "ext_register_operand" "Q")
1008               (const_int 8)
1009               (const_int 8)) 0)))]
1010   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1011   "cmp{b}\t{%h1, %0|%0, %h1}"
1012   [(set_attr "type" "icmp")
1013    (set_attr "mode" "QI")])
1015 (define_insn "*cmpqi_ext_2"
1016   [(set (reg FLAGS_REG)
1017         (compare
1018           (subreg:QI
1019             (zero_extract:SI
1020               (match_operand 0 "ext_register_operand" "Q")
1021               (const_int 8)
1022               (const_int 8)) 0)
1023           (match_operand:QI 1 "const0_operand" "")))]
1024   "ix86_match_ccmode (insn, CCNOmode)"
1025   "test{b}\t%h0, %h0"
1026   [(set_attr "type" "test")
1027    (set_attr "length_immediate" "0")
1028    (set_attr "mode" "QI")])
1030 (define_expand "cmpqi_ext_3"
1031   [(set (reg:CC FLAGS_REG)
1032         (compare:CC
1033           (subreg:QI
1034             (zero_extract:SI
1035               (match_operand 0 "ext_register_operand" "")
1036               (const_int 8)
1037               (const_int 8)) 0)
1038           (match_operand:QI 1 "immediate_operand" "")))]
1039   ""
1040   "")
1042 (define_insn "*cmpqi_ext_3_insn"
1043   [(set (reg FLAGS_REG)
1044         (compare
1045           (subreg:QI
1046             (zero_extract:SI
1047               (match_operand 0 "ext_register_operand" "Q")
1048               (const_int 8)
1049               (const_int 8)) 0)
1050           (match_operand:QI 1 "general_operand" "Qmn")))]
1051   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1052   "cmp{b}\t{%1, %h0|%h0, %1}"
1053   [(set_attr "type" "icmp")
1054    (set_attr "modrm" "1")
1055    (set_attr "mode" "QI")])
1057 (define_insn "*cmpqi_ext_3_insn_rex64"
1058   [(set (reg FLAGS_REG)
1059         (compare
1060           (subreg:QI
1061             (zero_extract:SI
1062               (match_operand 0 "ext_register_operand" "Q")
1063               (const_int 8)
1064               (const_int 8)) 0)
1065           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1066   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1067   "cmp{b}\t{%1, %h0|%h0, %1}"
1068   [(set_attr "type" "icmp")
1069    (set_attr "modrm" "1")
1070    (set_attr "mode" "QI")])
1072 (define_insn "*cmpqi_ext_4"
1073   [(set (reg FLAGS_REG)
1074         (compare
1075           (subreg:QI
1076             (zero_extract:SI
1077               (match_operand 0 "ext_register_operand" "Q")
1078               (const_int 8)
1079               (const_int 8)) 0)
1080           (subreg:QI
1081             (zero_extract:SI
1082               (match_operand 1 "ext_register_operand" "Q")
1083               (const_int 8)
1084               (const_int 8)) 0)))]
1085   "ix86_match_ccmode (insn, CCmode)"
1086   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1087   [(set_attr "type" "icmp")
1088    (set_attr "mode" "QI")])
1090 ;; These implement float point compares.
1091 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1092 ;; which would allow mix and match FP modes on the compares.  Which is what
1093 ;; the old patterns did, but with many more of them.
1095 (define_expand "cbranchxf4"
1096   [(set (reg:CC FLAGS_REG)
1097         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1098                     (match_operand:XF 2 "nonmemory_operand" "")))
1099    (set (pc) (if_then_else
1100               (match_operator 0 "ix86_fp_comparison_operator"
1101                [(reg:CC FLAGS_REG)
1102                 (const_int 0)])
1103               (label_ref (match_operand 3 "" ""))
1104               (pc)))]
1105   "TARGET_80387"
1107   ix86_compare_op0 = operands[1];
1108   ix86_compare_op1 = operands[2];
1109   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1110   DONE;
1113 (define_expand "cstorexf4"
1114   [(set (reg:CC FLAGS_REG)
1115         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1116                     (match_operand:XF 3 "nonmemory_operand" "")))
1117    (set (match_operand:QI 0 "register_operand" "")
1118               (match_operator 1 "ix86_fp_comparison_operator"
1119                [(reg:CC FLAGS_REG)
1120                 (const_int 0)]))]
1121   "TARGET_80387"
1123   ix86_compare_op0 = operands[2];
1124   ix86_compare_op1 = operands[3];
1125   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1126   DONE;
1129 (define_expand "cbranch<mode>4"
1130   [(set (reg:CC FLAGS_REG)
1131         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1132                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1133    (set (pc) (if_then_else
1134               (match_operator 0 "ix86_fp_comparison_operator"
1135                [(reg:CC FLAGS_REG)
1136                 (const_int 0)])
1137               (label_ref (match_operand 3 "" ""))
1138               (pc)))]
1139   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1141   ix86_compare_op0 = operands[1];
1142   ix86_compare_op1 = operands[2];
1143   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1144   DONE;
1147 (define_expand "cstore<mode>4"
1148   [(set (reg:CC FLAGS_REG)
1149         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1150                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1151    (set (match_operand:QI 0 "register_operand" "")
1152               (match_operator 1 "ix86_fp_comparison_operator"
1153                [(reg:CC FLAGS_REG)
1154                 (const_int 0)]))]
1155   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1157   ix86_compare_op0 = operands[2];
1158   ix86_compare_op1 = operands[3];
1159   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1160   DONE;
1163 (define_expand "cbranchcc4"
1164   [(set (pc) (if_then_else
1165               (match_operator 0 "comparison_operator"
1166                [(match_operand 1 "flags_reg_operand" "")
1167                 (match_operand 2 "const0_operand" "")])
1168               (label_ref (match_operand 3 "" ""))
1169               (pc)))]
1170   ""
1172   ix86_compare_op0 = operands[1];
1173   ix86_compare_op1 = operands[2];
1174   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1175   DONE;
1178 (define_expand "cstorecc4"
1179   [(set (match_operand:QI 0 "register_operand" "")
1180               (match_operator 1 "comparison_operator"
1181                [(match_operand 2 "flags_reg_operand" "")
1182                 (match_operand 3 "const0_operand" "")]))]
1183   ""
1185   ix86_compare_op0 = operands[2];
1186   ix86_compare_op1 = operands[3];
1187   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1188   DONE;
1192 ;; FP compares, step 1:
1193 ;; Set the FP condition codes.
1195 ;; CCFPmode     compare with exceptions
1196 ;; CCFPUmode    compare with no exceptions
1198 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1199 ;; used to manage the reg stack popping would not be preserved.
1201 (define_insn "*cmpfp_0"
1202   [(set (match_operand:HI 0 "register_operand" "=a")
1203         (unspec:HI
1204           [(compare:CCFP
1205              (match_operand 1 "register_operand" "f")
1206              (match_operand 2 "const0_operand" ""))]
1207         UNSPEC_FNSTSW))]
1208   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1209    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1210   "* return output_fp_compare (insn, operands, 0, 0);"
1211   [(set_attr "type" "multi")
1212    (set_attr "unit" "i387")
1213    (set (attr "mode")
1214      (cond [(match_operand:SF 1 "" "")
1215               (const_string "SF")
1216             (match_operand:DF 1 "" "")
1217               (const_string "DF")
1218            ]
1219            (const_string "XF")))])
1221 (define_insn_and_split "*cmpfp_0_cc"
1222   [(set (reg:CCFP FLAGS_REG)
1223         (compare:CCFP
1224           (match_operand 1 "register_operand" "f")
1225           (match_operand 2 "const0_operand" "")))
1226    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1227   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1228    && TARGET_SAHF && !TARGET_CMOVE
1229    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1230   "#"
1231   "&& reload_completed"
1232   [(set (match_dup 0)
1233         (unspec:HI
1234           [(compare:CCFP (match_dup 1)(match_dup 2))]
1235         UNSPEC_FNSTSW))
1236    (set (reg:CC FLAGS_REG)
1237         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1238   ""
1239   [(set_attr "type" "multi")
1240    (set_attr "unit" "i387")
1241    (set (attr "mode")
1242      (cond [(match_operand:SF 1 "" "")
1243               (const_string "SF")
1244             (match_operand:DF 1 "" "")
1245               (const_string "DF")
1246            ]
1247            (const_string "XF")))])
1249 (define_insn "*cmpfp_xf"
1250   [(set (match_operand:HI 0 "register_operand" "=a")
1251         (unspec:HI
1252           [(compare:CCFP
1253              (match_operand:XF 1 "register_operand" "f")
1254              (match_operand:XF 2 "register_operand" "f"))]
1255           UNSPEC_FNSTSW))]
1256   "TARGET_80387"
1257   "* return output_fp_compare (insn, operands, 0, 0);"
1258   [(set_attr "type" "multi")
1259    (set_attr "unit" "i387")
1260    (set_attr "mode" "XF")])
1262 (define_insn_and_split "*cmpfp_xf_cc"
1263   [(set (reg:CCFP FLAGS_REG)
1264         (compare:CCFP
1265           (match_operand:XF 1 "register_operand" "f")
1266           (match_operand:XF 2 "register_operand" "f")))
1267    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1268   "TARGET_80387
1269    && TARGET_SAHF && !TARGET_CMOVE"
1270   "#"
1271   "&& reload_completed"
1272   [(set (match_dup 0)
1273         (unspec:HI
1274           [(compare:CCFP (match_dup 1)(match_dup 2))]
1275         UNSPEC_FNSTSW))
1276    (set (reg:CC FLAGS_REG)
1277         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1278   ""
1279   [(set_attr "type" "multi")
1280    (set_attr "unit" "i387")
1281    (set_attr "mode" "XF")])
1283 (define_insn "*cmpfp_<mode>"
1284   [(set (match_operand:HI 0 "register_operand" "=a")
1285         (unspec:HI
1286           [(compare:CCFP
1287              (match_operand:MODEF 1 "register_operand" "f")
1288              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1289           UNSPEC_FNSTSW))]
1290   "TARGET_80387"
1291   "* return output_fp_compare (insn, operands, 0, 0);"
1292   [(set_attr "type" "multi")
1293    (set_attr "unit" "i387")
1294    (set_attr "mode" "<MODE>")])
1296 (define_insn_and_split "*cmpfp_<mode>_cc"
1297   [(set (reg:CCFP FLAGS_REG)
1298         (compare:CCFP
1299           (match_operand:MODEF 1 "register_operand" "f")
1300           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1301    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1302   "TARGET_80387
1303    && TARGET_SAHF && !TARGET_CMOVE"
1304   "#"
1305   "&& reload_completed"
1306   [(set (match_dup 0)
1307         (unspec:HI
1308           [(compare:CCFP (match_dup 1)(match_dup 2))]
1309         UNSPEC_FNSTSW))
1310    (set (reg:CC FLAGS_REG)
1311         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1312   ""
1313   [(set_attr "type" "multi")
1314    (set_attr "unit" "i387")
1315    (set_attr "mode" "<MODE>")])
1317 (define_insn "*cmpfp_u"
1318   [(set (match_operand:HI 0 "register_operand" "=a")
1319         (unspec:HI
1320           [(compare:CCFPU
1321              (match_operand 1 "register_operand" "f")
1322              (match_operand 2 "register_operand" "f"))]
1323           UNSPEC_FNSTSW))]
1324   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1325    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1326   "* return output_fp_compare (insn, operands, 0, 1);"
1327   [(set_attr "type" "multi")
1328    (set_attr "unit" "i387")
1329    (set (attr "mode")
1330      (cond [(match_operand:SF 1 "" "")
1331               (const_string "SF")
1332             (match_operand:DF 1 "" "")
1333               (const_string "DF")
1334            ]
1335            (const_string "XF")))])
1337 (define_insn_and_split "*cmpfp_u_cc"
1338   [(set (reg:CCFPU FLAGS_REG)
1339         (compare:CCFPU
1340           (match_operand 1 "register_operand" "f")
1341           (match_operand 2 "register_operand" "f")))
1342    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1343   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1344    && TARGET_SAHF && !TARGET_CMOVE
1345    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1346   "#"
1347   "&& reload_completed"
1348   [(set (match_dup 0)
1349         (unspec:HI
1350           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1351         UNSPEC_FNSTSW))
1352    (set (reg:CC FLAGS_REG)
1353         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1354   ""
1355   [(set_attr "type" "multi")
1356    (set_attr "unit" "i387")
1357    (set (attr "mode")
1358      (cond [(match_operand:SF 1 "" "")
1359               (const_string "SF")
1360             (match_operand:DF 1 "" "")
1361               (const_string "DF")
1362            ]
1363            (const_string "XF")))])
1365 (define_insn "*cmpfp_<mode>"
1366   [(set (match_operand:HI 0 "register_operand" "=a")
1367         (unspec:HI
1368           [(compare:CCFP
1369              (match_operand 1 "register_operand" "f")
1370              (match_operator 3 "float_operator"
1371                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1372           UNSPEC_FNSTSW))]
1373   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1374    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1375    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1376   "* return output_fp_compare (insn, operands, 0, 0);"
1377   [(set_attr "type" "multi")
1378    (set_attr "unit" "i387")
1379    (set_attr "fp_int_src" "true")
1380    (set_attr "mode" "<MODE>")])
1382 (define_insn_and_split "*cmpfp_<mode>_cc"
1383   [(set (reg:CCFP FLAGS_REG)
1384         (compare:CCFP
1385           (match_operand 1 "register_operand" "f")
1386           (match_operator 3 "float_operator"
1387             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1388    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1389   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1390    && TARGET_SAHF && !TARGET_CMOVE
1391    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1392    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1393   "#"
1394   "&& reload_completed"
1395   [(set (match_dup 0)
1396         (unspec:HI
1397           [(compare:CCFP
1398              (match_dup 1)
1399              (match_op_dup 3 [(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 "fp_int_src" "true")
1407    (set_attr "mode" "<MODE>")])
1409 ;; FP compares, step 2
1410 ;; Move the fpsw to ax.
1412 (define_insn "x86_fnstsw_1"
1413   [(set (match_operand:HI 0 "register_operand" "=a")
1414         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1415   "TARGET_80387"
1416   "fnstsw\t%0"
1417   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1418    (set_attr "mode" "SI")
1419    (set_attr "unit" "i387")])
1421 ;; FP compares, step 3
1422 ;; Get ax into flags, general case.
1424 (define_insn "x86_sahf_1"
1425   [(set (reg:CC FLAGS_REG)
1426         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1427                    UNSPEC_SAHF))]
1428   "TARGET_SAHF"
1430 #ifdef HAVE_AS_IX86_SAHF
1431   return "sahf";
1432 #else
1433   return ASM_BYTE "0x9e";
1434 #endif
1436   [(set_attr "length" "1")
1437    (set_attr "athlon_decode" "vector")
1438    (set_attr "amdfam10_decode" "direct")
1439    (set_attr "mode" "SI")])
1441 ;; Pentium Pro can do steps 1 through 3 in one go.
1442 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1443 (define_insn "*cmpfp_i_mixed"
1444   [(set (reg:CCFP FLAGS_REG)
1445         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1446                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1447   "TARGET_MIX_SSE_I387
1448    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1449    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1450   "* return output_fp_compare (insn, operands, 1, 0);"
1451   [(set_attr "type" "fcmp,ssecomi")
1452    (set_attr "prefix" "orig,maybe_vex")
1453    (set (attr "mode")
1454      (if_then_else (match_operand:SF 1 "" "")
1455         (const_string "SF")
1456         (const_string "DF")))
1457    (set (attr "prefix_rep")
1458         (if_then_else (eq_attr "type" "ssecomi")
1459                       (const_string "0")
1460                       (const_string "*")))
1461    (set (attr "prefix_data16")
1462         (cond [(eq_attr "type" "fcmp")
1463                  (const_string "*")
1464                (eq_attr "mode" "DF")
1465                  (const_string "1")
1466               ]
1467               (const_string "0")))
1468    (set_attr "athlon_decode" "vector")
1469    (set_attr "amdfam10_decode" "direct")])
1471 (define_insn "*cmpfp_i_sse"
1472   [(set (reg:CCFP FLAGS_REG)
1473         (compare:CCFP (match_operand 0 "register_operand" "x")
1474                       (match_operand 1 "nonimmediate_operand" "xm")))]
1475   "TARGET_SSE_MATH
1476    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1477    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1478   "* return output_fp_compare (insn, operands, 1, 0);"
1479   [(set_attr "type" "ssecomi")
1480    (set_attr "prefix" "maybe_vex")
1481    (set (attr "mode")
1482      (if_then_else (match_operand:SF 1 "" "")
1483         (const_string "SF")
1484         (const_string "DF")))
1485    (set_attr "prefix_rep" "0")
1486    (set (attr "prefix_data16")
1487         (if_then_else (eq_attr "mode" "DF")
1488                       (const_string "1")
1489                       (const_string "0")))
1490    (set_attr "athlon_decode" "vector")
1491    (set_attr "amdfam10_decode" "direct")])
1493 (define_insn "*cmpfp_i_i387"
1494   [(set (reg:CCFP FLAGS_REG)
1495         (compare:CCFP (match_operand 0 "register_operand" "f")
1496                       (match_operand 1 "register_operand" "f")))]
1497   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1498    && TARGET_CMOVE
1499    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1500    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1501   "* return output_fp_compare (insn, operands, 1, 0);"
1502   [(set_attr "type" "fcmp")
1503    (set (attr "mode")
1504      (cond [(match_operand:SF 1 "" "")
1505               (const_string "SF")
1506             (match_operand:DF 1 "" "")
1507               (const_string "DF")
1508            ]
1509            (const_string "XF")))
1510    (set_attr "athlon_decode" "vector")
1511    (set_attr "amdfam10_decode" "direct")])
1513 (define_insn "*cmpfp_iu_mixed"
1514   [(set (reg:CCFPU FLAGS_REG)
1515         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1516                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1517   "TARGET_MIX_SSE_I387
1518    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1519    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1520   "* return output_fp_compare (insn, operands, 1, 1);"
1521   [(set_attr "type" "fcmp,ssecomi")
1522    (set_attr "prefix" "orig,maybe_vex")
1523    (set (attr "mode")
1524      (if_then_else (match_operand:SF 1 "" "")
1525         (const_string "SF")
1526         (const_string "DF")))
1527    (set (attr "prefix_rep")
1528         (if_then_else (eq_attr "type" "ssecomi")
1529                       (const_string "0")
1530                       (const_string "*")))
1531    (set (attr "prefix_data16")
1532         (cond [(eq_attr "type" "fcmp")
1533                  (const_string "*")
1534                (eq_attr "mode" "DF")
1535                  (const_string "1")
1536               ]
1537               (const_string "0")))
1538    (set_attr "athlon_decode" "vector")
1539    (set_attr "amdfam10_decode" "direct")])
1541 (define_insn "*cmpfp_iu_sse"
1542   [(set (reg:CCFPU FLAGS_REG)
1543         (compare:CCFPU (match_operand 0 "register_operand" "x")
1544                        (match_operand 1 "nonimmediate_operand" "xm")))]
1545   "TARGET_SSE_MATH
1546    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1547    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1548   "* return output_fp_compare (insn, operands, 1, 1);"
1549   [(set_attr "type" "ssecomi")
1550    (set_attr "prefix" "maybe_vex")
1551    (set (attr "mode")
1552      (if_then_else (match_operand:SF 1 "" "")
1553         (const_string "SF")
1554         (const_string "DF")))
1555    (set_attr "prefix_rep" "0")
1556    (set (attr "prefix_data16")
1557         (if_then_else (eq_attr "mode" "DF")
1558                       (const_string "1")
1559                       (const_string "0")))
1560    (set_attr "athlon_decode" "vector")
1561    (set_attr "amdfam10_decode" "direct")])
1563 (define_insn "*cmpfp_iu_387"
1564   [(set (reg:CCFPU FLAGS_REG)
1565         (compare:CCFPU (match_operand 0 "register_operand" "f")
1566                        (match_operand 1 "register_operand" "f")))]
1567   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1568    && TARGET_CMOVE
1569    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1570    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1571   "* return output_fp_compare (insn, operands, 1, 1);"
1572   [(set_attr "type" "fcmp")
1573    (set (attr "mode")
1574      (cond [(match_operand:SF 1 "" "")
1575               (const_string "SF")
1576             (match_operand:DF 1 "" "")
1577               (const_string "DF")
1578            ]
1579            (const_string "XF")))
1580    (set_attr "athlon_decode" "vector")
1581    (set_attr "amdfam10_decode" "direct")])
1583 ;; Move instructions.
1585 ;; General case of fullword move.
1587 (define_expand "movsi"
1588   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1589         (match_operand:SI 1 "general_operand" ""))]
1590   ""
1591   "ix86_expand_move (SImode, operands); DONE;")
1593 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1594 ;; general_operand.
1596 ;; %%% We don't use a post-inc memory reference because x86 is not a
1597 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1598 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1599 ;; targets without our curiosities, and it is just as easy to represent
1600 ;; this differently.
1602 (define_insn "*pushsi2"
1603   [(set (match_operand:SI 0 "push_operand" "=<")
1604         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1605   "!TARGET_64BIT"
1606   "push{l}\t%1"
1607   [(set_attr "type" "push")
1608    (set_attr "mode" "SI")])
1610 ;; For 64BIT abi we always round up to 8 bytes.
1611 (define_insn "*pushsi2_rex64"
1612   [(set (match_operand:SI 0 "push_operand" "=X")
1613         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1614   "TARGET_64BIT"
1615   "push{q}\t%q1"
1616   [(set_attr "type" "push")
1617    (set_attr "mode" "SI")])
1619 (define_insn "*pushsi2_prologue"
1620   [(set (match_operand:SI 0 "push_operand" "=<")
1621         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1622    (clobber (mem:BLK (scratch)))]
1623   "!TARGET_64BIT"
1624   "push{l}\t%1"
1625   [(set_attr "type" "push")
1626    (set_attr "mode" "SI")])
1628 (define_insn "*popsi1_epilogue"
1629   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1630         (mem:SI (reg:SI SP_REG)))
1631    (set (reg:SI SP_REG)
1632         (plus:SI (reg:SI SP_REG) (const_int 4)))
1633    (clobber (mem:BLK (scratch)))]
1634   "!TARGET_64BIT"
1635   "pop{l}\t%0"
1636   [(set_attr "type" "pop")
1637    (set_attr "mode" "SI")])
1639 (define_insn "popsi1"
1640   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1641         (mem:SI (reg:SI SP_REG)))
1642    (set (reg:SI SP_REG)
1643         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1644   "!TARGET_64BIT"
1645   "pop{l}\t%0"
1646   [(set_attr "type" "pop")
1647    (set_attr "mode" "SI")])
1649 (define_insn "*movsi_xor"
1650   [(set (match_operand:SI 0 "register_operand" "=r")
1651         (match_operand:SI 1 "const0_operand" ""))
1652    (clobber (reg:CC FLAGS_REG))]
1653   "reload_completed"
1654   "xor{l}\t%0, %0"
1655   [(set_attr "type" "alu1")
1656    (set_attr "mode" "SI")
1657    (set_attr "length_immediate" "0")])
1659 (define_insn "*movsi_or"
1660   [(set (match_operand:SI 0 "register_operand" "=r")
1661         (match_operand:SI 1 "immediate_operand" "i"))
1662    (clobber (reg:CC FLAGS_REG))]
1663   "reload_completed
1664    && operands[1] == constm1_rtx"
1666   operands[1] = constm1_rtx;
1667   return "or{l}\t{%1, %0|%0, %1}";
1669   [(set_attr "type" "alu1")
1670    (set_attr "mode" "SI")
1671    (set_attr "length_immediate" "1")])
1673 (define_insn "*movsi_1"
1674   [(set (match_operand:SI 0 "nonimmediate_operand"
1675                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1676         (match_operand:SI 1 "general_operand"
1677                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1678   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1680   switch (get_attr_type (insn))
1681     {
1682     case TYPE_SSELOG1:
1683       if (get_attr_mode (insn) == MODE_TI)
1684         return "%vpxor\t%0, %d0";
1685       return "%vxorps\t%0, %d0";
1687     case TYPE_SSEMOV:
1688       switch (get_attr_mode (insn))
1689         {
1690         case MODE_TI:
1691           return "%vmovdqa\t{%1, %0|%0, %1}";
1692         case MODE_V4SF:
1693           return "%vmovaps\t{%1, %0|%0, %1}";
1694         case MODE_SI:
1695           return "%vmovd\t{%1, %0|%0, %1}";
1696         case MODE_SF:
1697           return "%vmovss\t{%1, %0|%0, %1}";
1698         default:
1699           gcc_unreachable ();
1700         }
1702     case TYPE_MMX:
1703       return "pxor\t%0, %0";
1705     case TYPE_MMXMOV:
1706       if (get_attr_mode (insn) == MODE_DI)
1707         return "movq\t{%1, %0|%0, %1}";
1708       return "movd\t{%1, %0|%0, %1}";
1710     case TYPE_LEA:
1711       return "lea{l}\t{%1, %0|%0, %1}";
1713     default:
1714       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1715       return "mov{l}\t{%1, %0|%0, %1}";
1716     }
1718   [(set (attr "type")
1719      (cond [(eq_attr "alternative" "2")
1720               (const_string "mmx")
1721             (eq_attr "alternative" "3,4,5")
1722               (const_string "mmxmov")
1723             (eq_attr "alternative" "6")
1724               (const_string "sselog1")
1725             (eq_attr "alternative" "7,8,9,10,11")
1726               (const_string "ssemov")
1727             (match_operand:DI 1 "pic_32bit_operand" "")
1728               (const_string "lea")
1729            ]
1730            (const_string "imov")))
1731    (set (attr "prefix")
1732      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1733        (const_string "orig")
1734        (const_string "maybe_vex")))
1735    (set (attr "prefix_data16")
1736      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1737        (const_string "1")
1738        (const_string "*")))
1739    (set (attr "mode")
1740      (cond [(eq_attr "alternative" "2,3")
1741               (const_string "DI")
1742             (eq_attr "alternative" "6,7")
1743               (if_then_else
1744                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1745                 (const_string "V4SF")
1746                 (const_string "TI"))
1747             (and (eq_attr "alternative" "8,9,10,11")
1748                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1749               (const_string "SF")
1750            ]
1751            (const_string "SI")))])
1753 ;; Stores and loads of ax to arbitrary constant address.
1754 ;; We fake an second form of instruction to force reload to load address
1755 ;; into register when rax is not available
1756 (define_insn "*movabssi_1_rex64"
1757   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1758         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1759   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1760   "@
1761    movabs{l}\t{%1, %P0|%P0, %1}
1762    mov{l}\t{%1, %a0|%a0, %1}"
1763   [(set_attr "type" "imov")
1764    (set_attr "modrm" "0,*")
1765    (set_attr "length_address" "8,0")
1766    (set_attr "length_immediate" "0,*")
1767    (set_attr "memory" "store")
1768    (set_attr "mode" "SI")])
1770 (define_insn "*movabssi_2_rex64"
1771   [(set (match_operand:SI 0 "register_operand" "=a,r")
1772         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1773   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1774   "@
1775    movabs{l}\t{%P1, %0|%0, %P1}
1776    mov{l}\t{%a1, %0|%0, %a1}"
1777   [(set_attr "type" "imov")
1778    (set_attr "modrm" "0,*")
1779    (set_attr "length_address" "8,0")
1780    (set_attr "length_immediate" "0")
1781    (set_attr "memory" "load")
1782    (set_attr "mode" "SI")])
1784 (define_insn "*swapsi"
1785   [(set (match_operand:SI 0 "register_operand" "+r")
1786         (match_operand:SI 1 "register_operand" "+r"))
1787    (set (match_dup 1)
1788         (match_dup 0))]
1789   ""
1790   "xchg{l}\t%1, %0"
1791   [(set_attr "type" "imov")
1792    (set_attr "mode" "SI")
1793    (set_attr "pent_pair" "np")
1794    (set_attr "athlon_decode" "vector")
1795    (set_attr "amdfam10_decode" "double")])
1797 (define_expand "movhi"
1798   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1799         (match_operand:HI 1 "general_operand" ""))]
1800   ""
1801   "ix86_expand_move (HImode, operands); DONE;")
1803 (define_insn "*pushhi2"
1804   [(set (match_operand:HI 0 "push_operand" "=X")
1805         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1806   "!TARGET_64BIT"
1807   "push{l}\t%k1"
1808   [(set_attr "type" "push")
1809    (set_attr "mode" "SI")])
1811 ;; For 64BIT abi we always round up to 8 bytes.
1812 (define_insn "*pushhi2_rex64"
1813   [(set (match_operand:HI 0 "push_operand" "=X")
1814         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1815   "TARGET_64BIT"
1816   "push{q}\t%q1"
1817   [(set_attr "type" "push")
1818    (set_attr "mode" "DI")])
1820 (define_insn "*movhi_1"
1821   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1822         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1823   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1825   switch (get_attr_type (insn))
1826     {
1827     case TYPE_IMOVX:
1828       /* movzwl is faster than movw on p2 due to partial word stalls,
1829          though not as fast as an aligned movl.  */
1830       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1831     default:
1832       if (get_attr_mode (insn) == MODE_SI)
1833         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1834       else
1835         return "mov{w}\t{%1, %0|%0, %1}";
1836     }
1838   [(set (attr "type")
1839      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1840               (const_string "imov")
1841             (and (eq_attr "alternative" "0")
1842                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1843                           (const_int 0))
1844                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1845                           (const_int 0))))
1846               (const_string "imov")
1847             (and (eq_attr "alternative" "1,2")
1848                  (match_operand:HI 1 "aligned_operand" ""))
1849               (const_string "imov")
1850             (and (ne (symbol_ref "TARGET_MOVX")
1851                      (const_int 0))
1852                  (eq_attr "alternative" "0,2"))
1853               (const_string "imovx")
1854            ]
1855            (const_string "imov")))
1856     (set (attr "mode")
1857       (cond [(eq_attr "type" "imovx")
1858                (const_string "SI")
1859              (and (eq_attr "alternative" "1,2")
1860                   (match_operand:HI 1 "aligned_operand" ""))
1861                (const_string "SI")
1862              (and (eq_attr "alternative" "0")
1863                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1864                            (const_int 0))
1865                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1866                            (const_int 0))))
1867                (const_string "SI")
1868             ]
1869             (const_string "HI")))])
1871 ;; Stores and loads of ax to arbitrary constant address.
1872 ;; We fake an second form of instruction to force reload to load address
1873 ;; into register when rax is not available
1874 (define_insn "*movabshi_1_rex64"
1875   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1876         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1877   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1878   "@
1879    movabs{w}\t{%1, %P0|%P0, %1}
1880    mov{w}\t{%1, %a0|%a0, %1}"
1881   [(set_attr "type" "imov")
1882    (set_attr "modrm" "0,*")
1883    (set_attr "length_address" "8,0")
1884    (set_attr "length_immediate" "0,*")
1885    (set_attr "memory" "store")
1886    (set_attr "mode" "HI")])
1888 (define_insn "*movabshi_2_rex64"
1889   [(set (match_operand:HI 0 "register_operand" "=a,r")
1890         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1891   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1892   "@
1893    movabs{w}\t{%P1, %0|%0, %P1}
1894    mov{w}\t{%a1, %0|%0, %a1}"
1895   [(set_attr "type" "imov")
1896    (set_attr "modrm" "0,*")
1897    (set_attr "length_address" "8,0")
1898    (set_attr "length_immediate" "0")
1899    (set_attr "memory" "load")
1900    (set_attr "mode" "HI")])
1902 (define_insn "*swaphi_1"
1903   [(set (match_operand:HI 0 "register_operand" "+r")
1904         (match_operand:HI 1 "register_operand" "+r"))
1905    (set (match_dup 1)
1906         (match_dup 0))]
1907   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1908   "xchg{l}\t%k1, %k0"
1909   [(set_attr "type" "imov")
1910    (set_attr "mode" "SI")
1911    (set_attr "pent_pair" "np")
1912    (set_attr "athlon_decode" "vector")
1913    (set_attr "amdfam10_decode" "double")])
1915 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1916 (define_insn "*swaphi_2"
1917   [(set (match_operand:HI 0 "register_operand" "+r")
1918         (match_operand:HI 1 "register_operand" "+r"))
1919    (set (match_dup 1)
1920         (match_dup 0))]
1921   "TARGET_PARTIAL_REG_STALL"
1922   "xchg{w}\t%1, %0"
1923   [(set_attr "type" "imov")
1924    (set_attr "mode" "HI")
1925    (set_attr "pent_pair" "np")
1926    (set_attr "athlon_decode" "vector")])
1928 (define_expand "movstricthi"
1929   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1930         (match_operand:HI 1 "general_operand" ""))]
1931   ""
1933   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1934     FAIL;
1935   /* Don't generate memory->memory moves, go through a register */
1936   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1937     operands[1] = force_reg (HImode, operands[1]);
1940 (define_insn "*movstricthi_1"
1941   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1942         (match_operand:HI 1 "general_operand" "rn,m"))]
1943   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1944    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1945   "mov{w}\t{%1, %0|%0, %1}"
1946   [(set_attr "type" "imov")
1947    (set_attr "mode" "HI")])
1949 (define_insn "*movstricthi_xor"
1950   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1951         (match_operand:HI 1 "const0_operand" ""))
1952    (clobber (reg:CC FLAGS_REG))]
1953   "reload_completed"
1954   "xor{w}\t%0, %0"
1955   [(set_attr "type" "alu1")
1956    (set_attr "mode" "HI")
1957    (set_attr "length_immediate" "0")])
1959 (define_expand "movqi"
1960   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1961         (match_operand:QI 1 "general_operand" ""))]
1962   ""
1963   "ix86_expand_move (QImode, operands); DONE;")
1965 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1966 ;; "push a byte".  But actually we use pushl, which has the effect
1967 ;; of rounding the amount pushed up to a word.
1969 (define_insn "*pushqi2"
1970   [(set (match_operand:QI 0 "push_operand" "=X")
1971         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1972   "!TARGET_64BIT"
1973   "push{l}\t%k1"
1974   [(set_attr "type" "push")
1975    (set_attr "mode" "SI")])
1977 ;; For 64BIT abi we always round up to 8 bytes.
1978 (define_insn "*pushqi2_rex64"
1979   [(set (match_operand:QI 0 "push_operand" "=X")
1980         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1981   "TARGET_64BIT"
1982   "push{q}\t%q1"
1983   [(set_attr "type" "push")
1984    (set_attr "mode" "DI")])
1986 ;; Situation is quite tricky about when to choose full sized (SImode) move
1987 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1988 ;; partial register dependency machines (such as AMD Athlon), where QImode
1989 ;; moves issue extra dependency and for partial register stalls machines
1990 ;; that don't use QImode patterns (and QImode move cause stall on the next
1991 ;; instruction).
1993 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1994 ;; register stall machines with, where we use QImode instructions, since
1995 ;; partial register stall can be caused there.  Then we use movzx.
1996 (define_insn "*movqi_1"
1997   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1998         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1999   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2001   switch (get_attr_type (insn))
2002     {
2003     case TYPE_IMOVX:
2004       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2005       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2006     default:
2007       if (get_attr_mode (insn) == MODE_SI)
2008         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2009       else
2010         return "mov{b}\t{%1, %0|%0, %1}";
2011     }
2013   [(set (attr "type")
2014      (cond [(and (eq_attr "alternative" "5")
2015                  (not (match_operand:QI 1 "aligned_operand" "")))
2016               (const_string "imovx")
2017             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2018               (const_string "imov")
2019             (and (eq_attr "alternative" "3")
2020                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2021                           (const_int 0))
2022                       (eq (symbol_ref "TARGET_QIMODE_MATH")
2023                           (const_int 0))))
2024               (const_string "imov")
2025             (eq_attr "alternative" "3,5")
2026               (const_string "imovx")
2027             (and (ne (symbol_ref "TARGET_MOVX")
2028                      (const_int 0))
2029                  (eq_attr "alternative" "2"))
2030               (const_string "imovx")
2031            ]
2032            (const_string "imov")))
2033    (set (attr "mode")
2034       (cond [(eq_attr "alternative" "3,4,5")
2035                (const_string "SI")
2036              (eq_attr "alternative" "6")
2037                (const_string "QI")
2038              (eq_attr "type" "imovx")
2039                (const_string "SI")
2040              (and (eq_attr "type" "imov")
2041                   (and (eq_attr "alternative" "0,1")
2042                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2043                                 (const_int 0))
2044                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2045                                      (const_int 0))
2046                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2047                                      (const_int 0))))))
2048                (const_string "SI")
2049              ;; Avoid partial register stalls when not using QImode arithmetic
2050              (and (eq_attr "type" "imov")
2051                   (and (eq_attr "alternative" "0,1")
2052                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2053                                 (const_int 0))
2054                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2055                                 (const_int 0)))))
2056                (const_string "SI")
2057            ]
2058            (const_string "QI")))])
2060 (define_insn "*swapqi_1"
2061   [(set (match_operand:QI 0 "register_operand" "+r")
2062         (match_operand:QI 1 "register_operand" "+r"))
2063    (set (match_dup 1)
2064         (match_dup 0))]
2065   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2066   "xchg{l}\t%k1, %k0"
2067   [(set_attr "type" "imov")
2068    (set_attr "mode" "SI")
2069    (set_attr "pent_pair" "np")
2070    (set_attr "athlon_decode" "vector")
2071    (set_attr "amdfam10_decode" "vector")])
2073 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2074 (define_insn "*swapqi_2"
2075   [(set (match_operand:QI 0 "register_operand" "+q")
2076         (match_operand:QI 1 "register_operand" "+q"))
2077    (set (match_dup 1)
2078         (match_dup 0))]
2079   "TARGET_PARTIAL_REG_STALL"
2080   "xchg{b}\t%1, %0"
2081   [(set_attr "type" "imov")
2082    (set_attr "mode" "QI")
2083    (set_attr "pent_pair" "np")
2084    (set_attr "athlon_decode" "vector")])
2086 (define_expand "movstrictqi"
2087   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2088         (match_operand:QI 1 "general_operand" ""))]
2089   ""
2091   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2092     FAIL;
2093   /* Don't generate memory->memory moves, go through a register.  */
2094   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2095     operands[1] = force_reg (QImode, operands[1]);
2098 (define_insn "*movstrictqi_1"
2099   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2100         (match_operand:QI 1 "general_operand" "*qn,m"))]
2101   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2102    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2103   "mov{b}\t{%1, %0|%0, %1}"
2104   [(set_attr "type" "imov")
2105    (set_attr "mode" "QI")])
2107 (define_insn "*movstrictqi_xor"
2108   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2109         (match_operand:QI 1 "const0_operand" ""))
2110    (clobber (reg:CC FLAGS_REG))]
2111   "reload_completed"
2112   "xor{b}\t%0, %0"
2113   [(set_attr "type" "alu1")
2114    (set_attr "mode" "QI")
2115    (set_attr "length_immediate" "0")])
2117 (define_insn "*movsi_extv_1"
2118   [(set (match_operand:SI 0 "register_operand" "=R")
2119         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2120                          (const_int 8)
2121                          (const_int 8)))]
2122   ""
2123   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2124   [(set_attr "type" "imovx")
2125    (set_attr "mode" "SI")])
2127 (define_insn "*movhi_extv_1"
2128   [(set (match_operand:HI 0 "register_operand" "=R")
2129         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2130                          (const_int 8)
2131                          (const_int 8)))]
2132   ""
2133   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2134   [(set_attr "type" "imovx")
2135    (set_attr "mode" "SI")])
2137 (define_insn "*movqi_extv_1"
2138   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2139         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2140                          (const_int 8)
2141                          (const_int 8)))]
2142   "!TARGET_64BIT"
2144   switch (get_attr_type (insn))
2145     {
2146     case TYPE_IMOVX:
2147       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2148     default:
2149       return "mov{b}\t{%h1, %0|%0, %h1}";
2150     }
2152   [(set (attr "type")
2153      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2154                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2155                              (ne (symbol_ref "TARGET_MOVX")
2156                                  (const_int 0))))
2157         (const_string "imovx")
2158         (const_string "imov")))
2159    (set (attr "mode")
2160      (if_then_else (eq_attr "type" "imovx")
2161         (const_string "SI")
2162         (const_string "QI")))])
2164 (define_insn "*movqi_extv_1_rex64"
2165   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2166         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2167                          (const_int 8)
2168                          (const_int 8)))]
2169   "TARGET_64BIT"
2171   switch (get_attr_type (insn))
2172     {
2173     case TYPE_IMOVX:
2174       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2175     default:
2176       return "mov{b}\t{%h1, %0|%0, %h1}";
2177     }
2179   [(set (attr "type")
2180      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2181                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2182                              (ne (symbol_ref "TARGET_MOVX")
2183                                  (const_int 0))))
2184         (const_string "imovx")
2185         (const_string "imov")))
2186    (set (attr "mode")
2187      (if_then_else (eq_attr "type" "imovx")
2188         (const_string "SI")
2189         (const_string "QI")))])
2191 ;; Stores and loads of ax to arbitrary constant address.
2192 ;; We fake an second form of instruction to force reload to load address
2193 ;; into register when rax is not available
2194 (define_insn "*movabsqi_1_rex64"
2195   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2196         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2197   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2198   "@
2199    movabs{b}\t{%1, %P0|%P0, %1}
2200    mov{b}\t{%1, %a0|%a0, %1}"
2201   [(set_attr "type" "imov")
2202    (set_attr "modrm" "0,*")
2203    (set_attr "length_address" "8,0")
2204    (set_attr "length_immediate" "0,*")
2205    (set_attr "memory" "store")
2206    (set_attr "mode" "QI")])
2208 (define_insn "*movabsqi_2_rex64"
2209   [(set (match_operand:QI 0 "register_operand" "=a,r")
2210         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2211   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2212   "@
2213    movabs{b}\t{%P1, %0|%0, %P1}
2214    mov{b}\t{%a1, %0|%0, %a1}"
2215   [(set_attr "type" "imov")
2216    (set_attr "modrm" "0,*")
2217    (set_attr "length_address" "8,0")
2218    (set_attr "length_immediate" "0")
2219    (set_attr "memory" "load")
2220    (set_attr "mode" "QI")])
2222 (define_insn "*movdi_extzv_1"
2223   [(set (match_operand:DI 0 "register_operand" "=R")
2224         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2225                          (const_int 8)
2226                          (const_int 8)))]
2227   "TARGET_64BIT"
2228   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2229   [(set_attr "type" "imovx")
2230    (set_attr "mode" "SI")])
2232 (define_insn "*movsi_extzv_1"
2233   [(set (match_operand:SI 0 "register_operand" "=R")
2234         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2235                          (const_int 8)
2236                          (const_int 8)))]
2237   ""
2238   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2239   [(set_attr "type" "imovx")
2240    (set_attr "mode" "SI")])
2242 (define_insn "*movqi_extzv_2"
2243   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2244         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2245                                     (const_int 8)
2246                                     (const_int 8)) 0))]
2247   "!TARGET_64BIT"
2249   switch (get_attr_type (insn))
2250     {
2251     case TYPE_IMOVX:
2252       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2253     default:
2254       return "mov{b}\t{%h1, %0|%0, %h1}";
2255     }
2257   [(set (attr "type")
2258      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2259                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2260                              (ne (symbol_ref "TARGET_MOVX")
2261                                  (const_int 0))))
2262         (const_string "imovx")
2263         (const_string "imov")))
2264    (set (attr "mode")
2265      (if_then_else (eq_attr "type" "imovx")
2266         (const_string "SI")
2267         (const_string "QI")))])
2269 (define_insn "*movqi_extzv_2_rex64"
2270   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2271         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2272                                     (const_int 8)
2273                                     (const_int 8)) 0))]
2274   "TARGET_64BIT"
2276   switch (get_attr_type (insn))
2277     {
2278     case TYPE_IMOVX:
2279       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2280     default:
2281       return "mov{b}\t{%h1, %0|%0, %h1}";
2282     }
2284   [(set (attr "type")
2285      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2286                         (ne (symbol_ref "TARGET_MOVX")
2287                             (const_int 0)))
2288         (const_string "imovx")
2289         (const_string "imov")))
2290    (set (attr "mode")
2291      (if_then_else (eq_attr "type" "imovx")
2292         (const_string "SI")
2293         (const_string "QI")))])
2295 (define_insn "movsi_insv_1"
2296   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2297                          (const_int 8)
2298                          (const_int 8))
2299         (match_operand:SI 1 "general_operand" "Qmn"))]
2300   "!TARGET_64BIT"
2301   "mov{b}\t{%b1, %h0|%h0, %b1}"
2302   [(set_attr "type" "imov")
2303    (set_attr "mode" "QI")])
2305 (define_insn "*movsi_insv_1_rex64"
2306   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2307                          (const_int 8)
2308                          (const_int 8))
2309         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2310   "TARGET_64BIT"
2311   "mov{b}\t{%b1, %h0|%h0, %b1}"
2312   [(set_attr "type" "imov")
2313    (set_attr "mode" "QI")])
2315 (define_insn "movdi_insv_1_rex64"
2316   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2317                          (const_int 8)
2318                          (const_int 8))
2319         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2320   "TARGET_64BIT"
2321   "mov{b}\t{%b1, %h0|%h0, %b1}"
2322   [(set_attr "type" "imov")
2323    (set_attr "mode" "QI")])
2325 (define_insn "*movqi_insv_2"
2326   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2327                          (const_int 8)
2328                          (const_int 8))
2329         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2330                      (const_int 8)))]
2331   ""
2332   "mov{b}\t{%h1, %h0|%h0, %h1}"
2333   [(set_attr "type" "imov")
2334    (set_attr "mode" "QI")])
2336 (define_expand "movdi"
2337   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2338         (match_operand:DI 1 "general_operand" ""))]
2339   ""
2340   "ix86_expand_move (DImode, operands); DONE;")
2342 (define_insn "*pushdi"
2343   [(set (match_operand:DI 0 "push_operand" "=<")
2344         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2345   "!TARGET_64BIT"
2346   "#")
2348 (define_insn "*pushdi2_rex64"
2349   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2350         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2351   "TARGET_64BIT"
2352   "@
2353    push{q}\t%1
2354    #"
2355   [(set_attr "type" "push,multi")
2356    (set_attr "mode" "DI")])
2358 ;; Convert impossible pushes of immediate to existing instructions.
2359 ;; First try to get scratch register and go through it.  In case this
2360 ;; fails, push sign extended lower part first and then overwrite
2361 ;; upper part by 32bit move.
2362 (define_peephole2
2363   [(match_scratch:DI 2 "r")
2364    (set (match_operand:DI 0 "push_operand" "")
2365         (match_operand:DI 1 "immediate_operand" ""))]
2366   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2367    && !x86_64_immediate_operand (operands[1], DImode)"
2368   [(set (match_dup 2) (match_dup 1))
2369    (set (match_dup 0) (match_dup 2))]
2370   "")
2372 ;; We need to define this as both peepholer and splitter for case
2373 ;; peephole2 pass is not run.
2374 ;; "&& 1" is needed to keep it from matching the previous pattern.
2375 (define_peephole2
2376   [(set (match_operand:DI 0 "push_operand" "")
2377         (match_operand:DI 1 "immediate_operand" ""))]
2378   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2379    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2380   [(set (match_dup 0) (match_dup 1))
2381    (set (match_dup 2) (match_dup 3))]
2382   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2383    operands[1] = gen_lowpart (DImode, operands[2]);
2384    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2385                                                     GEN_INT (4)));
2386   ")
2388 (define_split
2389   [(set (match_operand:DI 0 "push_operand" "")
2390         (match_operand:DI 1 "immediate_operand" ""))]
2391   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2392                     ? epilogue_completed : reload_completed)
2393    && !symbolic_operand (operands[1], DImode)
2394    && !x86_64_immediate_operand (operands[1], DImode)"
2395   [(set (match_dup 0) (match_dup 1))
2396    (set (match_dup 2) (match_dup 3))]
2397   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2398    operands[1] = gen_lowpart (DImode, operands[2]);
2399    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2400                                                     GEN_INT (4)));
2401   ")
2403 (define_insn "*pushdi2_prologue_rex64"
2404   [(set (match_operand:DI 0 "push_operand" "=<")
2405         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2406    (clobber (mem:BLK (scratch)))]
2407   "TARGET_64BIT"
2408   "push{q}\t%1"
2409   [(set_attr "type" "push")
2410    (set_attr "mode" "DI")])
2412 (define_insn "*popdi1_epilogue_rex64"
2413   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2414         (mem:DI (reg:DI SP_REG)))
2415    (set (reg:DI SP_REG)
2416         (plus:DI (reg:DI SP_REG) (const_int 8)))
2417    (clobber (mem:BLK (scratch)))]
2418   "TARGET_64BIT"
2419   "pop{q}\t%0"
2420   [(set_attr "type" "pop")
2421    (set_attr "mode" "DI")])
2423 (define_insn "popdi1"
2424   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2425         (mem:DI (reg:DI SP_REG)))
2426    (set (reg:DI SP_REG)
2427         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2428   "TARGET_64BIT"
2429   "pop{q}\t%0"
2430   [(set_attr "type" "pop")
2431    (set_attr "mode" "DI")])
2433 (define_insn "*movdi_xor_rex64"
2434   [(set (match_operand:DI 0 "register_operand" "=r")
2435         (match_operand:DI 1 "const0_operand" ""))
2436    (clobber (reg:CC FLAGS_REG))]
2437   "TARGET_64BIT
2438    && reload_completed"
2439   "xor{l}\t%k0, %k0";
2440   [(set_attr "type" "alu1")
2441    (set_attr "mode" "SI")
2442    (set_attr "length_immediate" "0")])
2444 (define_insn "*movdi_or_rex64"
2445   [(set (match_operand:DI 0 "register_operand" "=r")
2446         (match_operand:DI 1 "const_int_operand" "i"))
2447    (clobber (reg:CC FLAGS_REG))]
2448   "TARGET_64BIT
2449    && reload_completed
2450    && operands[1] == constm1_rtx"
2452   operands[1] = constm1_rtx;
2453   return "or{q}\t{%1, %0|%0, %1}";
2455   [(set_attr "type" "alu1")
2456    (set_attr "mode" "DI")
2457    (set_attr "length_immediate" "1")])
2459 (define_insn "*movdi_2"
2460   [(set (match_operand:DI 0 "nonimmediate_operand"
2461                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2462         (match_operand:DI 1 "general_operand"
2463                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2464   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2465   "@
2466    #
2467    #
2468    pxor\t%0, %0
2469    movq\t{%1, %0|%0, %1}
2470    movq\t{%1, %0|%0, %1}
2471    %vpxor\t%0, %d0
2472    %vmovq\t{%1, %0|%0, %1}
2473    %vmovdqa\t{%1, %0|%0, %1}
2474    %vmovq\t{%1, %0|%0, %1}
2475    xorps\t%0, %0
2476    movlps\t{%1, %0|%0, %1}
2477    movaps\t{%1, %0|%0, %1}
2478    movlps\t{%1, %0|%0, %1}"
2479   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2480    (set (attr "prefix")
2481      (if_then_else (eq_attr "alternative" "5,6,7,8")
2482        (const_string "vex")
2483        (const_string "orig")))
2484    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2486 (define_split
2487   [(set (match_operand:DI 0 "push_operand" "")
2488         (match_operand:DI 1 "general_operand" ""))]
2489   "!TARGET_64BIT && reload_completed
2490    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2491   [(const_int 0)]
2492   "ix86_split_long_move (operands); DONE;")
2494 ;; %%% This multiword shite has got to go.
2495 (define_split
2496   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2497         (match_operand:DI 1 "general_operand" ""))]
2498   "!TARGET_64BIT && reload_completed
2499    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2500    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2501   [(const_int 0)]
2502   "ix86_split_long_move (operands); DONE;")
2504 (define_insn "*movdi_1_rex64"
2505   [(set (match_operand:DI 0 "nonimmediate_operand"
2506           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2507         (match_operand:DI 1 "general_operand"
2508           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2509   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2511   switch (get_attr_type (insn))
2512     {
2513     case TYPE_SSECVT:
2514       if (SSE_REG_P (operands[0]))
2515         return "movq2dq\t{%1, %0|%0, %1}";
2516       else
2517         return "movdq2q\t{%1, %0|%0, %1}";
2519     case TYPE_SSEMOV:
2520       if (TARGET_AVX)
2521         {
2522           if (get_attr_mode (insn) == MODE_TI)
2523             return "vmovdqa\t{%1, %0|%0, %1}";
2524           else
2525             return "vmovq\t{%1, %0|%0, %1}";
2526         }
2528       if (get_attr_mode (insn) == MODE_TI)
2529         return "movdqa\t{%1, %0|%0, %1}";
2530       /* FALLTHRU */
2532     case TYPE_MMXMOV:
2533       /* Moves from and into integer register is done using movd
2534          opcode with REX prefix.  */
2535       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2536         return "movd\t{%1, %0|%0, %1}";
2537       return "movq\t{%1, %0|%0, %1}";
2539     case TYPE_SSELOG1:
2540       return "%vpxor\t%0, %d0";
2542     case TYPE_MMX:
2543       return "pxor\t%0, %0";
2545     case TYPE_MULTI:
2546       return "#";
2548     case TYPE_LEA:
2549       return "lea{q}\t{%a1, %0|%0, %a1}";
2551     default:
2552       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2553       if (get_attr_mode (insn) == MODE_SI)
2554         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2555       else if (which_alternative == 2)
2556         return "movabs{q}\t{%1, %0|%0, %1}";
2557       else
2558         return "mov{q}\t{%1, %0|%0, %1}";
2559     }
2561   [(set (attr "type")
2562      (cond [(eq_attr "alternative" "5")
2563               (const_string "mmx")
2564             (eq_attr "alternative" "6,7,8,9,10")
2565               (const_string "mmxmov")
2566             (eq_attr "alternative" "11")
2567               (const_string "sselog1")
2568             (eq_attr "alternative" "12,13,14,15,16")
2569               (const_string "ssemov")
2570             (eq_attr "alternative" "17,18")
2571               (const_string "ssecvt")
2572             (eq_attr "alternative" "4")
2573               (const_string "multi")
2574             (match_operand:DI 1 "pic_32bit_operand" "")
2575               (const_string "lea")
2576            ]
2577            (const_string "imov")))
2578    (set (attr "modrm")
2579      (if_then_else
2580        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2581          (const_string "0")
2582          (const_string "*")))
2583    (set (attr "length_immediate")
2584      (if_then_else
2585        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2586          (const_string "8")
2587          (const_string "*")))
2588    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2589    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2590    (set (attr "prefix")
2591      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2592        (const_string "maybe_vex")
2593        (const_string "orig")))
2594    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2596 ;; Stores and loads of ax to arbitrary constant address.
2597 ;; We fake an second form of instruction to force reload to load address
2598 ;; into register when rax is not available
2599 (define_insn "*movabsdi_1_rex64"
2600   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2601         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2602   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2603   "@
2604    movabs{q}\t{%1, %P0|%P0, %1}
2605    mov{q}\t{%1, %a0|%a0, %1}"
2606   [(set_attr "type" "imov")
2607    (set_attr "modrm" "0,*")
2608    (set_attr "length_address" "8,0")
2609    (set_attr "length_immediate" "0,*")
2610    (set_attr "memory" "store")
2611    (set_attr "mode" "DI")])
2613 (define_insn "*movabsdi_2_rex64"
2614   [(set (match_operand:DI 0 "register_operand" "=a,r")
2615         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2616   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2617   "@
2618    movabs{q}\t{%P1, %0|%0, %P1}
2619    mov{q}\t{%a1, %0|%0, %a1}"
2620   [(set_attr "type" "imov")
2621    (set_attr "modrm" "0,*")
2622    (set_attr "length_address" "8,0")
2623    (set_attr "length_immediate" "0")
2624    (set_attr "memory" "load")
2625    (set_attr "mode" "DI")])
2627 ;; Convert impossible stores of immediate to existing instructions.
2628 ;; First try to get scratch register and go through it.  In case this
2629 ;; fails, move by 32bit parts.
2630 (define_peephole2
2631   [(match_scratch:DI 2 "r")
2632    (set (match_operand:DI 0 "memory_operand" "")
2633         (match_operand:DI 1 "immediate_operand" ""))]
2634   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2635    && !x86_64_immediate_operand (operands[1], DImode)"
2636   [(set (match_dup 2) (match_dup 1))
2637    (set (match_dup 0) (match_dup 2))]
2638   "")
2640 ;; We need to define this as both peepholer and splitter for case
2641 ;; peephole2 pass is not run.
2642 ;; "&& 1" is needed to keep it from matching the previous pattern.
2643 (define_peephole2
2644   [(set (match_operand:DI 0 "memory_operand" "")
2645         (match_operand:DI 1 "immediate_operand" ""))]
2646   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2647    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2648   [(set (match_dup 2) (match_dup 3))
2649    (set (match_dup 4) (match_dup 5))]
2650   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2652 (define_split
2653   [(set (match_operand:DI 0 "memory_operand" "")
2654         (match_operand:DI 1 "immediate_operand" ""))]
2655   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2656                     ? epilogue_completed : reload_completed)
2657    && !symbolic_operand (operands[1], DImode)
2658    && !x86_64_immediate_operand (operands[1], DImode)"
2659   [(set (match_dup 2) (match_dup 3))
2660    (set (match_dup 4) (match_dup 5))]
2661   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2663 (define_insn "*swapdi_rex64"
2664   [(set (match_operand:DI 0 "register_operand" "+r")
2665         (match_operand:DI 1 "register_operand" "+r"))
2666    (set (match_dup 1)
2667         (match_dup 0))]
2668   "TARGET_64BIT"
2669   "xchg{q}\t%1, %0"
2670   [(set_attr "type" "imov")
2671    (set_attr "mode" "DI")
2672    (set_attr "pent_pair" "np")
2673    (set_attr "athlon_decode" "vector")
2674    (set_attr "amdfam10_decode" "double")])
2676 (define_expand "movoi"
2677   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2678         (match_operand:OI 1 "general_operand" ""))]
2679   "TARGET_AVX"
2680   "ix86_expand_move (OImode, operands); DONE;")
2682 (define_insn "*movoi_internal"
2683   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2684         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2685   "TARGET_AVX
2686    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2688   switch (which_alternative)
2689     {
2690     case 0:
2691       return "vxorps\t%0, %0, %0";
2692     case 1:
2693     case 2:
2694       if (misaligned_operand (operands[0], OImode)
2695           || misaligned_operand (operands[1], OImode))
2696         return "vmovdqu\t{%1, %0|%0, %1}";
2697       else
2698         return "vmovdqa\t{%1, %0|%0, %1}";
2699     default:
2700       gcc_unreachable ();
2701     }
2703   [(set_attr "type" "sselog1,ssemov,ssemov")
2704    (set_attr "prefix" "vex")
2705    (set_attr "mode" "OI")])
2707 (define_expand "movti"
2708   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2709         (match_operand:TI 1 "nonimmediate_operand" ""))]
2710   "TARGET_SSE || TARGET_64BIT"
2712   if (TARGET_64BIT)
2713     ix86_expand_move (TImode, operands);
2714   else if (push_operand (operands[0], TImode))
2715     ix86_expand_push (TImode, operands[1]);
2716   else
2717     ix86_expand_vector_move (TImode, operands);
2718   DONE;
2721 (define_insn "*movti_internal"
2722   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2723         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2724   "TARGET_SSE && !TARGET_64BIT
2725    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2727   switch (which_alternative)
2728     {
2729     case 0:
2730       if (get_attr_mode (insn) == MODE_V4SF)
2731         return "%vxorps\t%0, %d0";
2732       else
2733         return "%vpxor\t%0, %d0";
2734     case 1:
2735     case 2:
2736       /* TDmode values are passed as TImode on the stack.  Moving them
2737          to stack may result in unaligned memory access.  */
2738       if (misaligned_operand (operands[0], TImode)
2739           || misaligned_operand (operands[1], TImode))
2740         {
2741           if (get_attr_mode (insn) == MODE_V4SF)
2742             return "%vmovups\t{%1, %0|%0, %1}";
2743          else
2744            return "%vmovdqu\t{%1, %0|%0, %1}";
2745         }
2746       else
2747         {
2748           if (get_attr_mode (insn) == MODE_V4SF)
2749             return "%vmovaps\t{%1, %0|%0, %1}";
2750          else
2751            return "%vmovdqa\t{%1, %0|%0, %1}";
2752         }
2753     default:
2754       gcc_unreachable ();
2755     }
2757   [(set_attr "type" "sselog1,ssemov,ssemov")
2758    (set_attr "prefix" "maybe_vex")
2759    (set (attr "mode")
2760         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2761                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2762                  (const_string "V4SF")
2763                (and (eq_attr "alternative" "2")
2764                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2765                         (const_int 0)))
2766                  (const_string "V4SF")]
2767               (const_string "TI")))])
2769 (define_insn "*movti_rex64"
2770   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2771         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2772   "TARGET_64BIT
2773    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2775   switch (which_alternative)
2776     {
2777     case 0:
2778     case 1:
2779       return "#";
2780     case 2:
2781       if (get_attr_mode (insn) == MODE_V4SF)
2782         return "%vxorps\t%0, %d0";
2783       else
2784         return "%vpxor\t%0, %d0";
2785     case 3:
2786     case 4:
2787       /* TDmode values are passed as TImode on the stack.  Moving them
2788          to stack may result in unaligned memory access.  */
2789       if (misaligned_operand (operands[0], TImode)
2790           || misaligned_operand (operands[1], TImode))
2791         {
2792           if (get_attr_mode (insn) == MODE_V4SF)
2793             return "%vmovups\t{%1, %0|%0, %1}";
2794          else
2795            return "%vmovdqu\t{%1, %0|%0, %1}";
2796         }
2797       else
2798         {
2799           if (get_attr_mode (insn) == MODE_V4SF)
2800             return "%vmovaps\t{%1, %0|%0, %1}";
2801          else
2802            return "%vmovdqa\t{%1, %0|%0, %1}";
2803         }
2804     default:
2805       gcc_unreachable ();
2806     }
2808   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2809    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2810    (set (attr "mode")
2811         (cond [(eq_attr "alternative" "2,3")
2812                  (if_then_else
2813                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2814                        (const_int 0))
2815                    (const_string "V4SF")
2816                    (const_string "TI"))
2817                (eq_attr "alternative" "4")
2818                  (if_then_else
2819                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2820                             (const_int 0))
2821                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2822                             (const_int 0)))
2823                    (const_string "V4SF")
2824                    (const_string "TI"))]
2825                (const_string "DI")))])
2827 (define_split
2828   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2829         (match_operand:TI 1 "general_operand" ""))]
2830   "reload_completed && !SSE_REG_P (operands[0])
2831    && !SSE_REG_P (operands[1])"
2832   [(const_int 0)]
2833   "ix86_split_long_move (operands); DONE;")
2835 ;; This expands to what emit_move_complex would generate if we didn't
2836 ;; have a movti pattern.  Having this avoids problems with reload on
2837 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2838 ;; to have around all the time.
2839 (define_expand "movcdi"
2840   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2841         (match_operand:CDI 1 "general_operand" ""))]
2842   ""
2844   if (push_operand (operands[0], CDImode))
2845     emit_move_complex_push (CDImode, operands[0], operands[1]);
2846   else
2847     emit_move_complex_parts (operands[0], operands[1]);
2848   DONE;
2851 (define_expand "movsf"
2852   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2853         (match_operand:SF 1 "general_operand" ""))]
2854   ""
2855   "ix86_expand_move (SFmode, operands); DONE;")
2857 (define_insn "*pushsf"
2858   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2859         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2860   "!TARGET_64BIT"
2862   /* Anything else should be already split before reg-stack.  */
2863   gcc_assert (which_alternative == 1);
2864   return "push{l}\t%1";
2866   [(set_attr "type" "multi,push,multi")
2867    (set_attr "unit" "i387,*,*")
2868    (set_attr "mode" "SF,SI,SF")])
2870 (define_insn "*pushsf_rex64"
2871   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2872         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2873   "TARGET_64BIT"
2875   /* Anything else should be already split before reg-stack.  */
2876   gcc_assert (which_alternative == 1);
2877   return "push{q}\t%q1";
2879   [(set_attr "type" "multi,push,multi")
2880    (set_attr "unit" "i387,*,*")
2881    (set_attr "mode" "SF,DI,SF")])
2883 (define_split
2884   [(set (match_operand:SF 0 "push_operand" "")
2885         (match_operand:SF 1 "memory_operand" ""))]
2886   "reload_completed
2887    && MEM_P (operands[1])
2888    && (operands[2] = find_constant_src (insn))"
2889   [(set (match_dup 0)
2890         (match_dup 2))])
2892 ;; %%% Kill this when call knows how to work this out.
2893 (define_split
2894   [(set (match_operand:SF 0 "push_operand" "")
2895         (match_operand:SF 1 "any_fp_register_operand" ""))]
2896   "!TARGET_64BIT"
2897   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2898    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2900 (define_split
2901   [(set (match_operand:SF 0 "push_operand" "")
2902         (match_operand:SF 1 "any_fp_register_operand" ""))]
2903   "TARGET_64BIT"
2904   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2905    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2907 (define_insn "*movsf_1"
2908   [(set (match_operand:SF 0 "nonimmediate_operand"
2909           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2910         (match_operand:SF 1 "general_operand"
2911           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2912   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2913    && (reload_in_progress || reload_completed
2914        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2915        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2916            && standard_80387_constant_p (operands[1]))
2917        || GET_CODE (operands[1]) != CONST_DOUBLE
2918        || memory_operand (operands[0], SFmode))"
2920   switch (which_alternative)
2921     {
2922     case 0:
2923     case 1:
2924       return output_387_reg_move (insn, operands);
2926     case 2:
2927       return standard_80387_constant_opcode (operands[1]);
2929     case 3:
2930     case 4:
2931       return "mov{l}\t{%1, %0|%0, %1}";
2932     case 5:
2933       if (get_attr_mode (insn) == MODE_TI)
2934         return "%vpxor\t%0, %d0";
2935       else
2936         return "%vxorps\t%0, %d0";
2937     case 6:
2938       if (get_attr_mode (insn) == MODE_V4SF)
2939         return "%vmovaps\t{%1, %0|%0, %1}";
2940       else
2941         return "%vmovss\t{%1, %d0|%d0, %1}";
2942     case 7:
2943       if (TARGET_AVX)
2944         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2945                                    : "vmovss\t{%1, %0|%0, %1}";
2946       else
2947         return "movss\t{%1, %0|%0, %1}";
2948     case 8:
2949       return "%vmovss\t{%1, %0|%0, %1}";
2951     case 9: case 10: case 14: case 15:
2952       return "movd\t{%1, %0|%0, %1}";
2953     case 12: case 13:
2954       return "%vmovd\t{%1, %0|%0, %1}";
2956     case 11:
2957       return "movq\t{%1, %0|%0, %1}";
2959     default:
2960       gcc_unreachable ();
2961     }
2963   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2964    (set (attr "prefix")
2965      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2966        (const_string "maybe_vex")
2967        (const_string "orig")))
2968    (set (attr "mode")
2969         (cond [(eq_attr "alternative" "3,4,9,10")
2970                  (const_string "SI")
2971                (eq_attr "alternative" "5")
2972                  (if_then_else
2973                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2974                                  (const_int 0))
2975                              (ne (symbol_ref "TARGET_SSE2")
2976                                  (const_int 0)))
2977                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2978                             (const_int 0)))
2979                    (const_string "TI")
2980                    (const_string "V4SF"))
2981                /* For architectures resolving dependencies on
2982                   whole SSE registers use APS move to break dependency
2983                   chains, otherwise use short move to avoid extra work.
2985                   Do the same for architectures resolving dependencies on
2986                   the parts.  While in DF mode it is better to always handle
2987                   just register parts, the SF mode is different due to lack
2988                   of instructions to load just part of the register.  It is
2989                   better to maintain the whole registers in single format
2990                   to avoid problems on using packed logical operations.  */
2991                (eq_attr "alternative" "6")
2992                  (if_then_else
2993                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2994                             (const_int 0))
2995                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2996                             (const_int 0)))
2997                    (const_string "V4SF")
2998                    (const_string "SF"))
2999                (eq_attr "alternative" "11")
3000                  (const_string "DI")]
3001                (const_string "SF")))])
3003 (define_insn "*swapsf"
3004   [(set (match_operand:SF 0 "fp_register_operand" "+f")
3005         (match_operand:SF 1 "fp_register_operand" "+f"))
3006    (set (match_dup 1)
3007         (match_dup 0))]
3008   "reload_completed || TARGET_80387"
3010   if (STACK_TOP_P (operands[0]))
3011     return "fxch\t%1";
3012   else
3013     return "fxch\t%0";
3015   [(set_attr "type" "fxch")
3016    (set_attr "mode" "SF")])
3018 (define_expand "movdf"
3019   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3020         (match_operand:DF 1 "general_operand" ""))]
3021   ""
3022   "ix86_expand_move (DFmode, operands); DONE;")
3024 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3025 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3026 ;; On the average, pushdf using integers can be still shorter.  Allow this
3027 ;; pattern for optimize_size too.
3029 (define_insn "*pushdf_nointeger"
3030   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3031         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3032   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3034   /* This insn should be already split before reg-stack.  */
3035   gcc_unreachable ();
3037   [(set_attr "type" "multi")
3038    (set_attr "unit" "i387,*,*,*")
3039    (set_attr "mode" "DF,SI,SI,DF")])
3041 (define_insn "*pushdf_integer"
3042   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3043         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3044   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3046   /* This insn should be already split before reg-stack.  */
3047   gcc_unreachable ();
3049   [(set_attr "type" "multi")
3050    (set_attr "unit" "i387,*,*")
3051    (set_attr "mode" "DF,SI,DF")])
3053 ;; %%% Kill this when call knows how to work this out.
3054 (define_split
3055   [(set (match_operand:DF 0 "push_operand" "")
3056         (match_operand:DF 1 "any_fp_register_operand" ""))]
3057   "reload_completed"
3058   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3059    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3060   "")
3062 (define_split
3063   [(set (match_operand:DF 0 "push_operand" "")
3064         (match_operand:DF 1 "general_operand" ""))]
3065   "reload_completed"
3066   [(const_int 0)]
3067   "ix86_split_long_move (operands); DONE;")
3069 ;; Moving is usually shorter when only FP registers are used. This separate
3070 ;; movdf pattern avoids the use of integer registers for FP operations
3071 ;; when optimizing for size.
3073 (define_insn "*movdf_nointeger"
3074   [(set (match_operand:DF 0 "nonimmediate_operand"
3075                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3076         (match_operand:DF 1 "general_operand"
3077                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3078   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3079    && ((optimize_function_for_size_p (cfun)
3080        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3081    && (reload_in_progress || reload_completed
3082        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3083        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3084            && optimize_function_for_size_p (cfun)
3085            && !memory_operand (operands[0], DFmode)
3086            && standard_80387_constant_p (operands[1]))
3087        || GET_CODE (operands[1]) != CONST_DOUBLE
3088        || ((optimize_function_for_size_p (cfun)
3089             || !TARGET_MEMORY_MISMATCH_STALL
3090             || reload_in_progress || reload_completed)
3091            && memory_operand (operands[0], DFmode)))"
3093   switch (which_alternative)
3094     {
3095     case 0:
3096     case 1:
3097       return output_387_reg_move (insn, operands);
3099     case 2:
3100       return standard_80387_constant_opcode (operands[1]);
3102     case 3:
3103     case 4:
3104       return "#";
3105     case 5:
3106       switch (get_attr_mode (insn))
3107         {
3108         case MODE_V4SF:
3109           return "%vxorps\t%0, %d0";
3110         case MODE_V2DF:
3111           return "%vxorpd\t%0, %d0";
3112         case MODE_TI:
3113           return "%vpxor\t%0, %d0";
3114         default:
3115           gcc_unreachable ();
3116         }
3117     case 6:
3118     case 7:
3119     case 8:
3120       switch (get_attr_mode (insn))
3121         {
3122         case MODE_V4SF:
3123           return "%vmovaps\t{%1, %0|%0, %1}";
3124         case MODE_V2DF:
3125           return "%vmovapd\t{%1, %0|%0, %1}";
3126         case MODE_TI:
3127           return "%vmovdqa\t{%1, %0|%0, %1}";
3128         case MODE_DI:
3129           return "%vmovq\t{%1, %0|%0, %1}";
3130         case MODE_DF:
3131           if (TARGET_AVX)
3132             {
3133               if (REG_P (operands[0]) && REG_P (operands[1]))
3134                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3135               else
3136                 return "vmovsd\t{%1, %0|%0, %1}";
3137             }
3138           else
3139             return "movsd\t{%1, %0|%0, %1}";
3140         case MODE_V1DF:
3141           if (TARGET_AVX)
3142             {
3143               if (REG_P (operands[0]))
3144                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3145               else
3146                 return "vmovlpd\t{%1, %0|%0, %1}";
3147             }
3148           else
3149             return "movlpd\t{%1, %0|%0, %1}";
3150         case MODE_V2SF:
3151           if (TARGET_AVX)
3152             {
3153               if (REG_P (operands[0]))
3154                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3155               else
3156                 return "vmovlps\t{%1, %0|%0, %1}";
3157             }
3158           else
3159             return "movlps\t{%1, %0|%0, %1}";
3160         default:
3161           gcc_unreachable ();
3162         }
3164     default:
3165       gcc_unreachable ();
3166     }
3168   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3169    (set (attr "prefix")
3170      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3171        (const_string "orig")
3172        (const_string "maybe_vex")))
3173    (set (attr "prefix_data16")
3174      (if_then_else (eq_attr "mode" "V1DF")
3175        (const_string "1")
3176        (const_string "*")))
3177    (set (attr "mode")
3178         (cond [(eq_attr "alternative" "0,1,2")
3179                  (const_string "DF")
3180                (eq_attr "alternative" "3,4")
3181                  (const_string "SI")
3183                /* For SSE1, we have many fewer alternatives.  */
3184                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3185                  (cond [(eq_attr "alternative" "5,6")
3186                           (const_string "V4SF")
3187                        ]
3188                    (const_string "V2SF"))
3190                /* xorps is one byte shorter.  */
3191                (eq_attr "alternative" "5")
3192                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3193                             (const_int 0))
3194                           (const_string "V4SF")
3195                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3196                             (const_int 0))
3197                           (const_string "TI")
3198                        ]
3199                        (const_string "V2DF"))
3201                /* For architectures resolving dependencies on
3202                   whole SSE registers use APD move to break dependency
3203                   chains, otherwise use short move to avoid extra work.
3205                   movaps encodes one byte shorter.  */
3206                (eq_attr "alternative" "6")
3207                  (cond
3208                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3209                         (const_int 0))
3210                       (const_string "V4SF")
3211                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3212                         (const_int 0))
3213                       (const_string "V2DF")
3214                    ]
3215                    (const_string "DF"))
3216                /* For architectures resolving dependencies on register
3217                   parts we may avoid extra work to zero out upper part
3218                   of register.  */
3219                (eq_attr "alternative" "7")
3220                  (if_then_else
3221                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3222                        (const_int 0))
3223                    (const_string "V1DF")
3224                    (const_string "DF"))
3225               ]
3226               (const_string "DF")))])
3228 (define_insn "*movdf_integer_rex64"
3229   [(set (match_operand:DF 0 "nonimmediate_operand"
3230                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3231         (match_operand:DF 1 "general_operand"
3232                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3233   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3234    && (reload_in_progress || reload_completed
3235        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3236        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3237            && optimize_function_for_size_p (cfun)
3238            && standard_80387_constant_p (operands[1]))
3239        || GET_CODE (operands[1]) != CONST_DOUBLE
3240        || memory_operand (operands[0], DFmode))"
3242   switch (which_alternative)
3243     {
3244     case 0:
3245     case 1:
3246       return output_387_reg_move (insn, operands);
3248     case 2:
3249       return standard_80387_constant_opcode (operands[1]);
3251     case 3:
3252     case 4:
3253       return "#";
3255     case 5:
3256       switch (get_attr_mode (insn))
3257         {
3258         case MODE_V4SF:
3259           return "%vxorps\t%0, %d0";
3260         case MODE_V2DF:
3261           return "%vxorpd\t%0, %d0";
3262         case MODE_TI:
3263           return "%vpxor\t%0, %d0";
3264         default:
3265           gcc_unreachable ();
3266         }
3267     case 6:
3268     case 7:
3269     case 8:
3270       switch (get_attr_mode (insn))
3271         {
3272         case MODE_V4SF:
3273           return "%vmovaps\t{%1, %0|%0, %1}";
3274         case MODE_V2DF:
3275           return "%vmovapd\t{%1, %0|%0, %1}";
3276         case MODE_TI:
3277           return "%vmovdqa\t{%1, %0|%0, %1}";
3278         case MODE_DI:
3279           return "%vmovq\t{%1, %0|%0, %1}";
3280         case MODE_DF:
3281           if (TARGET_AVX)
3282             {
3283               if (REG_P (operands[0]) && REG_P (operands[1]))
3284                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3285               else
3286                 return "vmovsd\t{%1, %0|%0, %1}";
3287             }
3288           else
3289             return "movsd\t{%1, %0|%0, %1}";
3290         case MODE_V1DF:
3291           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3292         case MODE_V2SF:
3293           return "%vmovlps\t{%1, %d0|%d0, %1}";
3294         default:
3295           gcc_unreachable ();
3296         }
3298     case 9:
3299     case 10:
3300     return "%vmovd\t{%1, %0|%0, %1}";
3302     default:
3303       gcc_unreachable();
3304     }
3306   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3307    (set (attr "prefix")
3308      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3309        (const_string "orig")
3310        (const_string "maybe_vex")))
3311    (set (attr "prefix_data16")
3312      (if_then_else (eq_attr "mode" "V1DF")
3313        (const_string "1")
3314        (const_string "*")))
3315    (set (attr "mode")
3316         (cond [(eq_attr "alternative" "0,1,2")
3317                  (const_string "DF")
3318                (eq_attr "alternative" "3,4,9,10")
3319                  (const_string "DI")
3321                /* For SSE1, we have many fewer alternatives.  */
3322                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3323                  (cond [(eq_attr "alternative" "5,6")
3324                           (const_string "V4SF")
3325                        ]
3326                    (const_string "V2SF"))
3328                /* xorps is one byte shorter.  */
3329                (eq_attr "alternative" "5")
3330                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3331                             (const_int 0))
3332                           (const_string "V4SF")
3333                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3334                             (const_int 0))
3335                           (const_string "TI")
3336                        ]
3337                        (const_string "V2DF"))
3339                /* For architectures resolving dependencies on
3340                   whole SSE registers use APD move to break dependency
3341                   chains, otherwise use short move to avoid extra work.
3343                   movaps encodes one byte shorter.  */
3344                (eq_attr "alternative" "6")
3345                  (cond
3346                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3347                         (const_int 0))
3348                       (const_string "V4SF")
3349                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3350                         (const_int 0))
3351                       (const_string "V2DF")
3352                    ]
3353                    (const_string "DF"))
3354                /* For architectures resolving dependencies on register
3355                   parts we may avoid extra work to zero out upper part
3356                   of register.  */
3357                (eq_attr "alternative" "7")
3358                  (if_then_else
3359                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3360                        (const_int 0))
3361                    (const_string "V1DF")
3362                    (const_string "DF"))
3363               ]
3364               (const_string "DF")))])
3366 (define_insn "*movdf_integer"
3367   [(set (match_operand:DF 0 "nonimmediate_operand"
3368                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3369         (match_operand:DF 1 "general_operand"
3370                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3371   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3372    && optimize_function_for_speed_p (cfun)
3373    && TARGET_INTEGER_DFMODE_MOVES
3374    && (reload_in_progress || reload_completed
3375        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3376        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3377            && optimize_function_for_size_p (cfun)
3378            && standard_80387_constant_p (operands[1]))
3379        || GET_CODE (operands[1]) != CONST_DOUBLE
3380        || memory_operand (operands[0], DFmode))"
3382   switch (which_alternative)
3383     {
3384     case 0:
3385     case 1:
3386       return output_387_reg_move (insn, operands);
3388     case 2:
3389       return standard_80387_constant_opcode (operands[1]);
3391     case 3:
3392     case 4:
3393       return "#";
3395     case 5:
3396       switch (get_attr_mode (insn))
3397         {
3398         case MODE_V4SF:
3399           return "xorps\t%0, %0";
3400         case MODE_V2DF:
3401           return "xorpd\t%0, %0";
3402         case MODE_TI:
3403           return "pxor\t%0, %0";
3404         default:
3405           gcc_unreachable ();
3406         }
3407     case 6:
3408     case 7:
3409     case 8:
3410       switch (get_attr_mode (insn))
3411         {
3412         case MODE_V4SF:
3413           return "movaps\t{%1, %0|%0, %1}";
3414         case MODE_V2DF:
3415           return "movapd\t{%1, %0|%0, %1}";
3416         case MODE_TI:
3417           return "movdqa\t{%1, %0|%0, %1}";
3418         case MODE_DI:
3419           return "movq\t{%1, %0|%0, %1}";
3420         case MODE_DF:
3421           return "movsd\t{%1, %0|%0, %1}";
3422         case MODE_V1DF:
3423           return "movlpd\t{%1, %0|%0, %1}";
3424         case MODE_V2SF:
3425           return "movlps\t{%1, %0|%0, %1}";
3426         default:
3427           gcc_unreachable ();
3428         }
3430     default:
3431       gcc_unreachable();
3432     }
3434   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3435    (set (attr "prefix_data16")
3436      (if_then_else (eq_attr "mode" "V1DF")
3437        (const_string "1")
3438        (const_string "*")))
3439    (set (attr "mode")
3440         (cond [(eq_attr "alternative" "0,1,2")
3441                  (const_string "DF")
3442                (eq_attr "alternative" "3,4")
3443                  (const_string "SI")
3445                /* For SSE1, we have many fewer alternatives.  */
3446                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3447                  (cond [(eq_attr "alternative" "5,6")
3448                           (const_string "V4SF")
3449                        ]
3450                    (const_string "V2SF"))
3452                /* xorps is one byte shorter.  */
3453                (eq_attr "alternative" "5")
3454                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3455                             (const_int 0))
3456                           (const_string "V4SF")
3457                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3458                             (const_int 0))
3459                           (const_string "TI")
3460                        ]
3461                        (const_string "V2DF"))
3463                /* For architectures resolving dependencies on
3464                   whole SSE registers use APD move to break dependency
3465                   chains, otherwise use short move to avoid extra work.
3467                   movaps encodes one byte shorter.  */
3468                (eq_attr "alternative" "6")
3469                  (cond
3470                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3471                         (const_int 0))
3472                       (const_string "V4SF")
3473                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3474                         (const_int 0))
3475                       (const_string "V2DF")
3476                    ]
3477                    (const_string "DF"))
3478                /* For architectures resolving dependencies on register
3479                   parts we may avoid extra work to zero out upper part
3480                   of register.  */
3481                (eq_attr "alternative" "7")
3482                  (if_then_else
3483                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3484                        (const_int 0))
3485                    (const_string "V1DF")
3486                    (const_string "DF"))
3487               ]
3488               (const_string "DF")))])
3490 (define_split
3491   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3492         (match_operand:DF 1 "general_operand" ""))]
3493   "reload_completed
3494    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3495    && ! (ANY_FP_REG_P (operands[0]) ||
3496          (GET_CODE (operands[0]) == SUBREG
3497           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3498    && ! (ANY_FP_REG_P (operands[1]) ||
3499          (GET_CODE (operands[1]) == SUBREG
3500           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3501   [(const_int 0)]
3502   "ix86_split_long_move (operands); DONE;")
3504 (define_insn "*swapdf"
3505   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3506         (match_operand:DF 1 "fp_register_operand" "+f"))
3507    (set (match_dup 1)
3508         (match_dup 0))]
3509   "reload_completed || TARGET_80387"
3511   if (STACK_TOP_P (operands[0]))
3512     return "fxch\t%1";
3513   else
3514     return "fxch\t%0";
3516   [(set_attr "type" "fxch")
3517    (set_attr "mode" "DF")])
3519 (define_expand "movxf"
3520   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3521         (match_operand:XF 1 "general_operand" ""))]
3522   ""
3523   "ix86_expand_move (XFmode, operands); DONE;")
3525 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3526 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3527 ;; Pushing using integer instructions is longer except for constants
3528 ;; and direct memory references.
3529 ;; (assuming that any given constant is pushed only once, but this ought to be
3530 ;;  handled elsewhere).
3532 (define_insn "*pushxf_nointeger"
3533   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3534         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3535   "optimize_function_for_size_p (cfun)"
3537   /* This insn should be already split before reg-stack.  */
3538   gcc_unreachable ();
3540   [(set_attr "type" "multi")
3541    (set_attr "unit" "i387,*,*")
3542    (set_attr "mode" "XF,SI,SI")])
3544 (define_insn "*pushxf_integer"
3545   [(set (match_operand:XF 0 "push_operand" "=<,<")
3546         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3547   "optimize_function_for_speed_p (cfun)"
3549   /* This insn should be already split before reg-stack.  */
3550   gcc_unreachable ();
3552   [(set_attr "type" "multi")
3553    (set_attr "unit" "i387,*")
3554    (set_attr "mode" "XF,SI")])
3556 (define_split
3557   [(set (match_operand 0 "push_operand" "")
3558         (match_operand 1 "general_operand" ""))]
3559   "reload_completed
3560    && (GET_MODE (operands[0]) == XFmode
3561        || GET_MODE (operands[0]) == DFmode)
3562    && !ANY_FP_REG_P (operands[1])"
3563   [(const_int 0)]
3564   "ix86_split_long_move (operands); DONE;")
3566 (define_split
3567   [(set (match_operand:XF 0 "push_operand" "")
3568         (match_operand:XF 1 "any_fp_register_operand" ""))]
3569   ""
3570   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3571    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3572   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3574 ;; Do not use integer registers when optimizing for size
3575 (define_insn "*movxf_nointeger"
3576   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3577         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3578   "optimize_function_for_size_p (cfun)
3579    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3580    && (reload_in_progress || reload_completed
3581        || standard_80387_constant_p (operands[1])
3582        || GET_CODE (operands[1]) != CONST_DOUBLE
3583        || memory_operand (operands[0], XFmode))"
3585   switch (which_alternative)
3586     {
3587     case 0:
3588     case 1:
3589       return output_387_reg_move (insn, operands);
3591     case 2:
3592       return standard_80387_constant_opcode (operands[1]);
3594     case 3: case 4:
3595       return "#";
3596     default:
3597       gcc_unreachable ();
3598     }
3600   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3601    (set_attr "mode" "XF,XF,XF,SI,SI")])
3603 (define_insn "*movxf_integer"
3604   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3605         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3606   "optimize_function_for_speed_p (cfun)
3607    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3608    && (reload_in_progress || reload_completed
3609        || GET_CODE (operands[1]) != CONST_DOUBLE
3610        || memory_operand (operands[0], XFmode))"
3612   switch (which_alternative)
3613     {
3614     case 0:
3615     case 1:
3616       return output_387_reg_move (insn, operands);
3618     case 2:
3619       return standard_80387_constant_opcode (operands[1]);
3621     case 3: case 4:
3622       return "#";
3624     default:
3625       gcc_unreachable ();
3626     }
3628   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3629    (set_attr "mode" "XF,XF,XF,SI,SI")])
3631 (define_expand "movtf"
3632   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3633         (match_operand:TF 1 "nonimmediate_operand" ""))]
3634   "TARGET_SSE2"
3636   ix86_expand_move (TFmode, operands);
3637   DONE;
3640 (define_insn "*movtf_internal"
3641   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3642         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3643   "TARGET_SSE2
3644    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3646   switch (which_alternative)
3647     {
3648     case 0:
3649     case 1:
3650       if (get_attr_mode (insn) == MODE_V4SF)
3651         return "%vmovaps\t{%1, %0|%0, %1}";
3652       else
3653         return "%vmovdqa\t{%1, %0|%0, %1}";
3654     case 2:
3655       if (get_attr_mode (insn) == MODE_V4SF)
3656         return "%vxorps\t%0, %d0";
3657       else
3658         return "%vpxor\t%0, %d0";
3659     case 3:
3660     case 4:
3661         return "#";
3662     default:
3663       gcc_unreachable ();
3664     }
3666   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3667    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3668    (set (attr "mode")
3669         (cond [(eq_attr "alternative" "0,2")
3670                  (if_then_else
3671                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3672                        (const_int 0))
3673                    (const_string "V4SF")
3674                    (const_string "TI"))
3675                (eq_attr "alternative" "1")
3676                  (if_then_else
3677                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3678                             (const_int 0))
3679                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3680                             (const_int 0)))
3681                    (const_string "V4SF")
3682                    (const_string "TI"))]
3683                (const_string "DI")))])
3685 (define_insn "*pushtf_sse"
3686   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3687         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3688   "TARGET_SSE2"
3690   /* This insn should be already split before reg-stack.  */
3691   gcc_unreachable ();
3693   [(set_attr "type" "multi")
3694    (set_attr "unit" "sse,*,*")
3695    (set_attr "mode" "TF,SI,SI")])
3697 (define_split
3698   [(set (match_operand:TF 0 "push_operand" "")
3699         (match_operand:TF 1 "general_operand" ""))]
3700   "TARGET_SSE2 && reload_completed
3701    && !SSE_REG_P (operands[1])"
3702   [(const_int 0)]
3703   "ix86_split_long_move (operands); DONE;")
3705 (define_split
3706   [(set (match_operand:TF 0 "push_operand" "")
3707         (match_operand:TF 1 "any_fp_register_operand" ""))]
3708   "TARGET_SSE2"
3709   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3710    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3711   "")
3713 (define_split
3714   [(set (match_operand 0 "nonimmediate_operand" "")
3715         (match_operand 1 "general_operand" ""))]
3716   "reload_completed
3717    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3718    && GET_MODE (operands[0]) == XFmode
3719    && ! (ANY_FP_REG_P (operands[0]) ||
3720          (GET_CODE (operands[0]) == SUBREG
3721           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3722    && ! (ANY_FP_REG_P (operands[1]) ||
3723          (GET_CODE (operands[1]) == SUBREG
3724           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3725   [(const_int 0)]
3726   "ix86_split_long_move (operands); DONE;")
3728 (define_split
3729   [(set (match_operand 0 "register_operand" "")
3730         (match_operand 1 "memory_operand" ""))]
3731   "reload_completed
3732    && MEM_P (operands[1])
3733    && (GET_MODE (operands[0]) == TFmode
3734        || GET_MODE (operands[0]) == XFmode
3735        || GET_MODE (operands[0]) == SFmode
3736        || GET_MODE (operands[0]) == DFmode)
3737    && (operands[2] = find_constant_src (insn))"
3738   [(set (match_dup 0) (match_dup 2))]
3740   rtx c = operands[2];
3741   rtx r = operands[0];
3743   if (GET_CODE (r) == SUBREG)
3744     r = SUBREG_REG (r);
3746   if (SSE_REG_P (r))
3747     {
3748       if (!standard_sse_constant_p (c))
3749         FAIL;
3750     }
3751   else if (FP_REG_P (r))
3752     {
3753       if (!standard_80387_constant_p (c))
3754         FAIL;
3755     }
3756   else if (MMX_REG_P (r))
3757     FAIL;
3760 (define_split
3761   [(set (match_operand 0 "register_operand" "")
3762         (float_extend (match_operand 1 "memory_operand" "")))]
3763   "reload_completed
3764    && MEM_P (operands[1])
3765    && (GET_MODE (operands[0]) == TFmode
3766        || GET_MODE (operands[0]) == XFmode
3767        || GET_MODE (operands[0]) == SFmode
3768        || GET_MODE (operands[0]) == DFmode)
3769    && (operands[2] = find_constant_src (insn))"
3770   [(set (match_dup 0) (match_dup 2))]
3772   rtx c = operands[2];
3773   rtx r = operands[0];
3775   if (GET_CODE (r) == SUBREG)
3776     r = SUBREG_REG (r);
3778   if (SSE_REG_P (r))
3779     {
3780       if (!standard_sse_constant_p (c))
3781         FAIL;
3782     }
3783   else if (FP_REG_P (r))
3784     {
3785       if (!standard_80387_constant_p (c))
3786         FAIL;
3787     }
3788   else if (MMX_REG_P (r))
3789     FAIL;
3792 (define_insn "swapxf"
3793   [(set (match_operand:XF 0 "register_operand" "+f")
3794         (match_operand:XF 1 "register_operand" "+f"))
3795    (set (match_dup 1)
3796         (match_dup 0))]
3797   "TARGET_80387"
3799   if (STACK_TOP_P (operands[0]))
3800     return "fxch\t%1";
3801   else
3802     return "fxch\t%0";
3804   [(set_attr "type" "fxch")
3805    (set_attr "mode" "XF")])
3807 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3808 (define_split
3809   [(set (match_operand:X87MODEF 0 "register_operand" "")
3810         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3811   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3812    && (standard_80387_constant_p (operands[1]) == 8
3813        || standard_80387_constant_p (operands[1]) == 9)"
3814   [(set (match_dup 0)(match_dup 1))
3815    (set (match_dup 0)
3816         (neg:X87MODEF (match_dup 0)))]
3818   REAL_VALUE_TYPE r;
3820   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3821   if (real_isnegzero (&r))
3822     operands[1] = CONST0_RTX (<MODE>mode);
3823   else
3824     operands[1] = CONST1_RTX (<MODE>mode);
3827 (define_split
3828   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3829         (match_operand:TF 1 "general_operand" ""))]
3830   "reload_completed
3831    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3832   [(const_int 0)]
3833   "ix86_split_long_move (operands); DONE;")
3835 ;; Zero extension instructions
3837 (define_expand "zero_extendhisi2"
3838   [(set (match_operand:SI 0 "register_operand" "")
3839      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3840   ""
3842   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3843     {
3844       operands[1] = force_reg (HImode, operands[1]);
3845       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3846       DONE;
3847     }
3850 (define_insn "zero_extendhisi2_and"
3851   [(set (match_operand:SI 0 "register_operand" "=r")
3852      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3853    (clobber (reg:CC FLAGS_REG))]
3854   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3855   "#"
3856   [(set_attr "type" "alu1")
3857    (set_attr "mode" "SI")])
3859 (define_split
3860   [(set (match_operand:SI 0 "register_operand" "")
3861         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3862    (clobber (reg:CC FLAGS_REG))]
3863   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3864    && optimize_function_for_speed_p (cfun)"
3865   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3866               (clobber (reg:CC FLAGS_REG))])]
3867   "")
3869 (define_insn "*zero_extendhisi2_movzwl"
3870   [(set (match_operand:SI 0 "register_operand" "=r")
3871      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3872   "!TARGET_ZERO_EXTEND_WITH_AND
3873    || optimize_function_for_size_p (cfun)"
3874   "movz{wl|x}\t{%1, %0|%0, %1}"
3875   [(set_attr "type" "imovx")
3876    (set_attr "mode" "SI")])
3878 (define_expand "zero_extendqihi2"
3879   [(parallel
3880     [(set (match_operand:HI 0 "register_operand" "")
3881        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3882      (clobber (reg:CC FLAGS_REG))])]
3883   ""
3884   "")
3886 (define_insn "*zero_extendqihi2_and"
3887   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3888      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3889    (clobber (reg:CC FLAGS_REG))]
3890   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3891   "#"
3892   [(set_attr "type" "alu1")
3893    (set_attr "mode" "HI")])
3895 (define_insn "*zero_extendqihi2_movzbw_and"
3896   [(set (match_operand:HI 0 "register_operand" "=r,r")
3897      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3898    (clobber (reg:CC FLAGS_REG))]
3899   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3900   "#"
3901   [(set_attr "type" "imovx,alu1")
3902    (set_attr "mode" "HI")])
3904 ; zero extend to SImode here to avoid partial register stalls
3905 (define_insn "*zero_extendqihi2_movzbl"
3906   [(set (match_operand:HI 0 "register_operand" "=r")
3907      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3908   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3909    && reload_completed"
3910   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3911   [(set_attr "type" "imovx")
3912    (set_attr "mode" "SI")])
3914 ;; For the movzbw case strip only the clobber
3915 (define_split
3916   [(set (match_operand:HI 0 "register_operand" "")
3917         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3918    (clobber (reg:CC FLAGS_REG))]
3919   "reload_completed
3920    && (!TARGET_ZERO_EXTEND_WITH_AND
3921        || optimize_function_for_size_p (cfun))
3922    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3923   [(set (match_operand:HI 0 "register_operand" "")
3924         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3926 ;; When source and destination does not overlap, clear destination
3927 ;; first and then do the movb
3928 (define_split
3929   [(set (match_operand:HI 0 "register_operand" "")
3930         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3931    (clobber (reg:CC FLAGS_REG))]
3932   "reload_completed
3933    && ANY_QI_REG_P (operands[0])
3934    && (TARGET_ZERO_EXTEND_WITH_AND
3935        && optimize_function_for_speed_p (cfun))
3936    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3937   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3939   operands[2] = gen_lowpart (QImode, operands[0]);
3940   ix86_expand_clear (operands[0]);
3943 ;; Rest is handled by single and.
3944 (define_split
3945   [(set (match_operand:HI 0 "register_operand" "")
3946         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3947    (clobber (reg:CC FLAGS_REG))]
3948   "reload_completed
3949    && true_regnum (operands[0]) == true_regnum (operands[1])"
3950   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3951               (clobber (reg:CC FLAGS_REG))])]
3952   "")
3954 (define_expand "zero_extendqisi2"
3955   [(parallel
3956     [(set (match_operand:SI 0 "register_operand" "")
3957        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3958      (clobber (reg:CC FLAGS_REG))])]
3959   ""
3960   "")
3962 (define_insn "*zero_extendqisi2_and"
3963   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3964      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3965    (clobber (reg:CC FLAGS_REG))]
3966   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3967   "#"
3968   [(set_attr "type" "alu1")
3969    (set_attr "mode" "SI")])
3971 (define_insn "*zero_extendqisi2_movzbl_and"
3972   [(set (match_operand:SI 0 "register_operand" "=r,r")
3973      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3974    (clobber (reg:CC FLAGS_REG))]
3975   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3976   "#"
3977   [(set_attr "type" "imovx,alu1")
3978    (set_attr "mode" "SI")])
3980 (define_insn "*zero_extendqisi2_movzbl"
3981   [(set (match_operand:SI 0 "register_operand" "=r")
3982      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3983   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3984    && reload_completed"
3985   "movz{bl|x}\t{%1, %0|%0, %1}"
3986   [(set_attr "type" "imovx")
3987    (set_attr "mode" "SI")])
3989 ;; For the movzbl case strip only the clobber
3990 (define_split
3991   [(set (match_operand:SI 0 "register_operand" "")
3992         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3993    (clobber (reg:CC FLAGS_REG))]
3994   "reload_completed
3995    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3996    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3997   [(set (match_dup 0)
3998         (zero_extend:SI (match_dup 1)))])
4000 ;; When source and destination does not overlap, clear destination
4001 ;; first and then do the movb
4002 (define_split
4003   [(set (match_operand:SI 0 "register_operand" "")
4004         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4005    (clobber (reg:CC FLAGS_REG))]
4006   "reload_completed
4007    && ANY_QI_REG_P (operands[0])
4008    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4009    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4010    && !reg_overlap_mentioned_p (operands[0], operands[1])"
4011   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
4013   operands[2] = gen_lowpart (QImode, operands[0]);
4014   ix86_expand_clear (operands[0]);
4017 ;; Rest is handled by single and.
4018 (define_split
4019   [(set (match_operand:SI 0 "register_operand" "")
4020         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4021    (clobber (reg:CC FLAGS_REG))]
4022   "reload_completed
4023    && true_regnum (operands[0]) == true_regnum (operands[1])"
4024   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4025               (clobber (reg:CC FLAGS_REG))])]
4026   "")
4028 ;; %%% Kill me once multi-word ops are sane.
4029 (define_expand "zero_extendsidi2"
4030   [(set (match_operand:DI 0 "register_operand" "")
4031      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4032   ""
4034   if (!TARGET_64BIT)
4035     {
4036       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4037       DONE;
4038     }
4041 (define_insn "zero_extendsidi2_32"
4042   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4043         (zero_extend:DI
4044          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
4045    (clobber (reg:CC FLAGS_REG))]
4046   "!TARGET_64BIT"
4047   "@
4048    #
4049    #
4050    #
4051    movd\t{%1, %0|%0, %1}
4052    movd\t{%1, %0|%0, %1}
4053    %vmovd\t{%1, %0|%0, %1}
4054    %vmovd\t{%1, %0|%0, %1}"
4055   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4056    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4057    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4059 (define_insn "zero_extendsidi2_rex64"
4060   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4061      (zero_extend:DI
4062        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4063   "TARGET_64BIT"
4064   "@
4065    mov\t{%k1, %k0|%k0, %k1}
4066    #
4067    movd\t{%1, %0|%0, %1}
4068    movd\t{%1, %0|%0, %1}
4069    %vmovd\t{%1, %0|%0, %1}
4070    %vmovd\t{%1, %0|%0, %1}"
4071   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4072    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4073    (set_attr "prefix_0f" "0,*,*,*,*,*")
4074    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4076 (define_split
4077   [(set (match_operand:DI 0 "memory_operand" "")
4078      (zero_extend:DI (match_dup 0)))]
4079   "TARGET_64BIT"
4080   [(set (match_dup 4) (const_int 0))]
4081   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4083 (define_split
4084   [(set (match_operand:DI 0 "register_operand" "")
4085         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4086    (clobber (reg:CC FLAGS_REG))]
4087   "!TARGET_64BIT && reload_completed
4088    && true_regnum (operands[0]) == true_regnum (operands[1])"
4089   [(set (match_dup 4) (const_int 0))]
4090   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4092 (define_split
4093   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4094         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4095    (clobber (reg:CC FLAGS_REG))]
4096   "!TARGET_64BIT && reload_completed
4097    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4098   [(set (match_dup 3) (match_dup 1))
4099    (set (match_dup 4) (const_int 0))]
4100   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4102 (define_insn "zero_extendhidi2"
4103   [(set (match_operand:DI 0 "register_operand" "=r")
4104      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4105   "TARGET_64BIT"
4106   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4107   [(set_attr "type" "imovx")
4108    (set_attr "mode" "SI")])
4110 (define_insn "zero_extendqidi2"
4111   [(set (match_operand:DI 0 "register_operand" "=r")
4112      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4113   "TARGET_64BIT"
4114   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4115   [(set_attr "type" "imovx")
4116    (set_attr "mode" "SI")])
4118 ;; Sign extension instructions
4120 (define_expand "extendsidi2"
4121   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4122                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4123               (clobber (reg:CC FLAGS_REG))
4124               (clobber (match_scratch:SI 2 ""))])]
4125   ""
4127   if (TARGET_64BIT)
4128     {
4129       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4130       DONE;
4131     }
4134 (define_insn "*extendsidi2_1"
4135   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4136         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4137    (clobber (reg:CC FLAGS_REG))
4138    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4139   "!TARGET_64BIT"
4140   "#")
4142 (define_insn "extendsidi2_rex64"
4143   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4144         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4145   "TARGET_64BIT"
4146   "@
4147    {cltq|cdqe}
4148    movs{lq|x}\t{%1, %0|%0, %1}"
4149   [(set_attr "type" "imovx")
4150    (set_attr "mode" "DI")
4151    (set_attr "prefix_0f" "0")
4152    (set_attr "modrm" "0,1")])
4154 (define_insn "extendhidi2"
4155   [(set (match_operand:DI 0 "register_operand" "=r")
4156         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4157   "TARGET_64BIT"
4158   "movs{wq|x}\t{%1, %0|%0, %1}"
4159   [(set_attr "type" "imovx")
4160    (set_attr "mode" "DI")])
4162 (define_insn "extendqidi2"
4163   [(set (match_operand:DI 0 "register_operand" "=r")
4164         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4165   "TARGET_64BIT"
4166   "movs{bq|x}\t{%1, %0|%0, %1}"
4167    [(set_attr "type" "imovx")
4168     (set_attr "mode" "DI")])
4170 ;; Extend to memory case when source register does die.
4171 (define_split
4172   [(set (match_operand:DI 0 "memory_operand" "")
4173         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4174    (clobber (reg:CC FLAGS_REG))
4175    (clobber (match_operand:SI 2 "register_operand" ""))]
4176   "(reload_completed
4177     && dead_or_set_p (insn, operands[1])
4178     && !reg_mentioned_p (operands[1], operands[0]))"
4179   [(set (match_dup 3) (match_dup 1))
4180    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4181               (clobber (reg:CC FLAGS_REG))])
4182    (set (match_dup 4) (match_dup 1))]
4183   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4185 ;; Extend to memory case when source register does not die.
4186 (define_split
4187   [(set (match_operand:DI 0 "memory_operand" "")
4188         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4189    (clobber (reg:CC FLAGS_REG))
4190    (clobber (match_operand:SI 2 "register_operand" ""))]
4191   "reload_completed"
4192   [(const_int 0)]
4194   split_di (&operands[0], 1, &operands[3], &operands[4]);
4196   emit_move_insn (operands[3], operands[1]);
4198   /* Generate a cltd if possible and doing so it profitable.  */
4199   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4200       && true_regnum (operands[1]) == AX_REG
4201       && true_regnum (operands[2]) == DX_REG)
4202     {
4203       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
4204     }
4205   else
4206     {
4207       emit_move_insn (operands[2], operands[1]);
4208       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
4209     }
4210   emit_move_insn (operands[4], operands[2]);
4211   DONE;
4214 ;; Extend to register case.  Optimize case where source and destination
4215 ;; registers match and cases where we can use cltd.
4216 (define_split
4217   [(set (match_operand:DI 0 "register_operand" "")
4218         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4219    (clobber (reg:CC FLAGS_REG))
4220    (clobber (match_scratch:SI 2 ""))]
4221   "reload_completed"
4222   [(const_int 0)]
4224   split_di (&operands[0], 1, &operands[3], &operands[4]);
4226   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4227     emit_move_insn (operands[3], operands[1]);
4229   /* Generate a cltd if possible and doing so it profitable.  */
4230   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4231       && true_regnum (operands[3]) == AX_REG
4232       && true_regnum (operands[4]) == DX_REG)
4233     {
4234       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
4235       DONE;
4236     }
4238   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4239     emit_move_insn (operands[4], operands[1]);
4241   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
4242   DONE;
4245 (define_insn "extendhisi2"
4246   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4247         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4248   ""
4250   switch (get_attr_prefix_0f (insn))
4251     {
4252     case 0:
4253       return "{cwtl|cwde}";
4254     default:
4255       return "movs{wl|x}\t{%1, %0|%0, %1}";
4256     }
4258   [(set_attr "type" "imovx")
4259    (set_attr "mode" "SI")
4260    (set (attr "prefix_0f")
4261      ;; movsx is short decodable while cwtl is vector decoded.
4262      (if_then_else (and (eq_attr "cpu" "!k6")
4263                         (eq_attr "alternative" "0"))
4264         (const_string "0")
4265         (const_string "1")))
4266    (set (attr "modrm")
4267      (if_then_else (eq_attr "prefix_0f" "0")
4268         (const_string "0")
4269         (const_string "1")))])
4271 (define_insn "*extendhisi2_zext"
4272   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4273         (zero_extend:DI
4274           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4275   "TARGET_64BIT"
4277   switch (get_attr_prefix_0f (insn))
4278     {
4279     case 0:
4280       return "{cwtl|cwde}";
4281     default:
4282       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4283     }
4285   [(set_attr "type" "imovx")
4286    (set_attr "mode" "SI")
4287    (set (attr "prefix_0f")
4288      ;; movsx is short decodable while cwtl is vector decoded.
4289      (if_then_else (and (eq_attr "cpu" "!k6")
4290                         (eq_attr "alternative" "0"))
4291         (const_string "0")
4292         (const_string "1")))
4293    (set (attr "modrm")
4294      (if_then_else (eq_attr "prefix_0f" "0")
4295         (const_string "0")
4296         (const_string "1")))])
4298 (define_insn "extendqihi2"
4299   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4300         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4301   ""
4303   switch (get_attr_prefix_0f (insn))
4304     {
4305     case 0:
4306       return "{cbtw|cbw}";
4307     default:
4308       return "movs{bw|x}\t{%1, %0|%0, %1}";
4309     }
4311   [(set_attr "type" "imovx")
4312    (set_attr "mode" "HI")
4313    (set (attr "prefix_0f")
4314      ;; movsx is short decodable while cwtl is vector decoded.
4315      (if_then_else (and (eq_attr "cpu" "!k6")
4316                         (eq_attr "alternative" "0"))
4317         (const_string "0")
4318         (const_string "1")))
4319    (set (attr "modrm")
4320      (if_then_else (eq_attr "prefix_0f" "0")
4321         (const_string "0")
4322         (const_string "1")))])
4324 (define_insn "extendqisi2"
4325   [(set (match_operand:SI 0 "register_operand" "=r")
4326         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4327   ""
4328   "movs{bl|x}\t{%1, %0|%0, %1}"
4329    [(set_attr "type" "imovx")
4330     (set_attr "mode" "SI")])
4332 (define_insn "*extendqisi2_zext"
4333   [(set (match_operand:DI 0 "register_operand" "=r")
4334         (zero_extend:DI
4335           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4336   "TARGET_64BIT"
4337   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4338    [(set_attr "type" "imovx")
4339     (set_attr "mode" "SI")])
4341 ;; Conversions between float and double.
4343 ;; These are all no-ops in the model used for the 80387.  So just
4344 ;; emit moves.
4346 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4347 (define_insn "*dummy_extendsfdf2"
4348   [(set (match_operand:DF 0 "push_operand" "=<")
4349         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4350   "0"
4351   "#")
4353 (define_split
4354   [(set (match_operand:DF 0 "push_operand" "")
4355         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4356   ""
4357   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4358    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4360 (define_insn "*dummy_extendsfxf2"
4361   [(set (match_operand:XF 0 "push_operand" "=<")
4362         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4363   "0"
4364   "#")
4366 (define_split
4367   [(set (match_operand:XF 0 "push_operand" "")
4368         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4369   ""
4370   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4371    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4372   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4374 (define_split
4375   [(set (match_operand:XF 0 "push_operand" "")
4376         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4377   ""
4378   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4379    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4380   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4382 (define_expand "extendsfdf2"
4383   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4384         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4385   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4387   /* ??? Needed for compress_float_constant since all fp constants
4388      are LEGITIMATE_CONSTANT_P.  */
4389   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4390     {
4391       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4392           && standard_80387_constant_p (operands[1]) > 0)
4393         {
4394           operands[1] = simplify_const_unary_operation
4395             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4396           emit_move_insn_1 (operands[0], operands[1]);
4397           DONE;
4398         }
4399       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4400     }
4403 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4404    cvtss2sd:
4405       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4406       cvtps2pd xmm2,xmm1
4407    We do the conversion post reload to avoid producing of 128bit spills
4408    that might lead to ICE on 32bit target.  The sequence unlikely combine
4409    anyway.  */
4410 (define_split
4411   [(set (match_operand:DF 0 "register_operand" "")
4412         (float_extend:DF
4413           (match_operand:SF 1 "nonimmediate_operand" "")))]
4414   "TARGET_USE_VECTOR_FP_CONVERTS
4415    && optimize_insn_for_speed_p ()
4416    && reload_completed && SSE_REG_P (operands[0])"
4417    [(set (match_dup 2)
4418          (float_extend:V2DF
4419            (vec_select:V2SF
4420              (match_dup 3)
4421              (parallel [(const_int 0) (const_int 1)]))))]
4423   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4424   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4425   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4426      Try to avoid move when unpacking can be done in source.  */
4427   if (REG_P (operands[1]))
4428     {
4429       /* If it is unsafe to overwrite upper half of source, we need
4430          to move to destination and unpack there.  */
4431       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4432            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4433           && true_regnum (operands[0]) != true_regnum (operands[1]))
4434         {
4435           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4436           emit_move_insn (tmp, operands[1]);
4437         }
4438       else
4439         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4440       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4441                                              operands[3]));
4442     }
4443   else
4444     emit_insn (gen_vec_setv4sf_0 (operands[3],
4445                                   CONST0_RTX (V4SFmode), operands[1]));
4448 (define_insn "*extendsfdf2_mixed"
4449   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4450         (float_extend:DF
4451           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4452   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4454   switch (which_alternative)
4455     {
4456     case 0:
4457     case 1:
4458       return output_387_reg_move (insn, operands);
4460     case 2:
4461       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4463     default:
4464       gcc_unreachable ();
4465     }
4467   [(set_attr "type" "fmov,fmov,ssecvt")
4468    (set_attr "prefix" "orig,orig,maybe_vex")
4469    (set_attr "mode" "SF,XF,DF")])
4471 (define_insn "*extendsfdf2_sse"
4472   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4473         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4474   "TARGET_SSE2 && TARGET_SSE_MATH"
4475   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4476   [(set_attr "type" "ssecvt")
4477    (set_attr "prefix" "maybe_vex")
4478    (set_attr "mode" "DF")])
4480 (define_insn "*extendsfdf2_i387"
4481   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4482         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4483   "TARGET_80387"
4484   "* return output_387_reg_move (insn, operands);"
4485   [(set_attr "type" "fmov")
4486    (set_attr "mode" "SF,XF")])
4488 (define_expand "extend<mode>xf2"
4489   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4490         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4491   "TARGET_80387"
4493   /* ??? Needed for compress_float_constant since all fp constants
4494      are LEGITIMATE_CONSTANT_P.  */
4495   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4496     {
4497       if (standard_80387_constant_p (operands[1]) > 0)
4498         {
4499           operands[1] = simplify_const_unary_operation
4500             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4501           emit_move_insn_1 (operands[0], operands[1]);
4502           DONE;
4503         }
4504       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4505     }
4508 (define_insn "*extend<mode>xf2_i387"
4509   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4510         (float_extend:XF
4511           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4512   "TARGET_80387"
4513   "* return output_387_reg_move (insn, operands);"
4514   [(set_attr "type" "fmov")
4515    (set_attr "mode" "<MODE>,XF")])
4517 ;; %%% This seems bad bad news.
4518 ;; This cannot output into an f-reg because there is no way to be sure
4519 ;; of truncating in that case.  Otherwise this is just like a simple move
4520 ;; insn.  So we pretend we can output to a reg in order to get better
4521 ;; register preferencing, but we really use a stack slot.
4523 ;; Conversion from DFmode to SFmode.
4525 (define_expand "truncdfsf2"
4526   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4527         (float_truncate:SF
4528           (match_operand:DF 1 "nonimmediate_operand" "")))]
4529   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4531   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4532     ;
4533   else if (flag_unsafe_math_optimizations)
4534     ;
4535   else
4536     {
4537       enum ix86_stack_slot slot = (virtuals_instantiated
4538                                    ? SLOT_TEMP
4539                                    : SLOT_VIRTUAL);
4540       rtx temp = assign_386_stack_local (SFmode, slot);
4541       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4542       DONE;
4543     }
4546 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4547    cvtsd2ss:
4548       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4549       cvtpd2ps xmm2,xmm1
4550    We do the conversion post reload to avoid producing of 128bit spills
4551    that might lead to ICE on 32bit target.  The sequence unlikely combine
4552    anyway.  */
4553 (define_split
4554   [(set (match_operand:SF 0 "register_operand" "")
4555         (float_truncate:SF
4556           (match_operand:DF 1 "nonimmediate_operand" "")))]
4557   "TARGET_USE_VECTOR_FP_CONVERTS
4558    && optimize_insn_for_speed_p ()
4559    && reload_completed && SSE_REG_P (operands[0])"
4560    [(set (match_dup 2)
4561          (vec_concat:V4SF
4562            (float_truncate:V2SF
4563              (match_dup 4))
4564            (match_dup 3)))]
4566   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4567   operands[3] = CONST0_RTX (V2SFmode);
4568   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4569   /* Use movsd for loading from memory, unpcklpd for registers.
4570      Try to avoid move when unpacking can be done in source, or SSE3
4571      movddup is available.  */
4572   if (REG_P (operands[1]))
4573     {
4574       if (!TARGET_SSE3
4575           && true_regnum (operands[0]) != true_regnum (operands[1])
4576           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4577               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4578         {
4579           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4580           emit_move_insn (tmp, operands[1]);
4581           operands[1] = tmp;
4582         }
4583       else if (!TARGET_SSE3)
4584         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4585       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4586     }
4587   else
4588     emit_insn (gen_sse2_loadlpd (operands[4],
4589                                  CONST0_RTX (V2DFmode), operands[1]));
4592 (define_expand "truncdfsf2_with_temp"
4593   [(parallel [(set (match_operand:SF 0 "" "")
4594                    (float_truncate:SF (match_operand:DF 1 "" "")))
4595               (clobber (match_operand:SF 2 "" ""))])]
4596   "")
4598 (define_insn "*truncdfsf_fast_mixed"
4599   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4600         (float_truncate:SF
4601           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4602   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4604   switch (which_alternative)
4605     {
4606     case 0:
4607       return output_387_reg_move (insn, operands);
4608     case 1:
4609       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4610     default:
4611       gcc_unreachable ();
4612     }
4614   [(set_attr "type" "fmov,ssecvt")
4615    (set_attr "prefix" "orig,maybe_vex")
4616    (set_attr "mode" "SF")])
4618 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4619 ;; because nothing we do here is unsafe.
4620 (define_insn "*truncdfsf_fast_sse"
4621   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4622         (float_truncate:SF
4623           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4624   "TARGET_SSE2 && TARGET_SSE_MATH"
4625   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4626   [(set_attr "type" "ssecvt")
4627    (set_attr "prefix" "maybe_vex")
4628    (set_attr "mode" "SF")])
4630 (define_insn "*truncdfsf_fast_i387"
4631   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4632         (float_truncate:SF
4633           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4634   "TARGET_80387 && flag_unsafe_math_optimizations"
4635   "* return output_387_reg_move (insn, operands);"
4636   [(set_attr "type" "fmov")
4637    (set_attr "mode" "SF")])
4639 (define_insn "*truncdfsf_mixed"
4640   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4641         (float_truncate:SF
4642           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4643    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4644   "TARGET_MIX_SSE_I387"
4646   switch (which_alternative)
4647     {
4648     case 0:
4649       return output_387_reg_move (insn, operands);
4650     case 1:
4651       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4653     default:
4654       return "#";
4655     }
4657   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4658    (set_attr "unit" "*,*,i387,i387,i387")
4659    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4660    (set_attr "mode" "SF")])
4662 (define_insn "*truncdfsf_i387"
4663   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4664         (float_truncate:SF
4665           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4666    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4667   "TARGET_80387"
4669   switch (which_alternative)
4670     {
4671     case 0:
4672       return output_387_reg_move (insn, operands);
4674     default:
4675       return "#";
4676     }
4678   [(set_attr "type" "fmov,multi,multi,multi")
4679    (set_attr "unit" "*,i387,i387,i387")
4680    (set_attr "mode" "SF")])
4682 (define_insn "*truncdfsf2_i387_1"
4683   [(set (match_operand:SF 0 "memory_operand" "=m")
4684         (float_truncate:SF
4685           (match_operand:DF 1 "register_operand" "f")))]
4686   "TARGET_80387
4687    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4688    && !TARGET_MIX_SSE_I387"
4689   "* return output_387_reg_move (insn, operands);"
4690   [(set_attr "type" "fmov")
4691    (set_attr "mode" "SF")])
4693 (define_split
4694   [(set (match_operand:SF 0 "register_operand" "")
4695         (float_truncate:SF
4696          (match_operand:DF 1 "fp_register_operand" "")))
4697    (clobber (match_operand 2 "" ""))]
4698   "reload_completed"
4699   [(set (match_dup 2) (match_dup 1))
4700    (set (match_dup 0) (match_dup 2))]
4702   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4705 ;; Conversion from XFmode to {SF,DF}mode
4707 (define_expand "truncxf<mode>2"
4708   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4709                    (float_truncate:MODEF
4710                      (match_operand:XF 1 "register_operand" "")))
4711               (clobber (match_dup 2))])]
4712   "TARGET_80387"
4714   if (flag_unsafe_math_optimizations)
4715     {
4716       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4717       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4718       if (reg != operands[0])
4719         emit_move_insn (operands[0], reg);
4720       DONE;
4721     }
4722   else
4723     {
4724      enum ix86_stack_slot slot = (virtuals_instantiated
4725                                   ? SLOT_TEMP
4726                                   : SLOT_VIRTUAL);
4727       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4728     }
4731 (define_insn "*truncxfsf2_mixed"
4732   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4733         (float_truncate:SF
4734           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4735    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4736   "TARGET_80387"
4738   gcc_assert (!which_alternative);
4739   return output_387_reg_move (insn, operands);
4741   [(set_attr "type" "fmov,multi,multi,multi")
4742    (set_attr "unit" "*,i387,i387,i387")
4743    (set_attr "mode" "SF")])
4745 (define_insn "*truncxfdf2_mixed"
4746   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4747         (float_truncate:DF
4748           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4749    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4750   "TARGET_80387"
4752   gcc_assert (!which_alternative);
4753   return output_387_reg_move (insn, operands);
4755   [(set_attr "type" "fmov,multi,multi,multi")
4756    (set_attr "unit" "*,i387,i387,i387")
4757    (set_attr "mode" "DF")])
4759 (define_insn "truncxf<mode>2_i387_noop"
4760   [(set (match_operand:MODEF 0 "register_operand" "=f")
4761         (float_truncate:MODEF
4762           (match_operand:XF 1 "register_operand" "f")))]
4763   "TARGET_80387 && flag_unsafe_math_optimizations"
4764   "* return output_387_reg_move (insn, operands);"
4765   [(set_attr "type" "fmov")
4766    (set_attr "mode" "<MODE>")])
4768 (define_insn "*truncxf<mode>2_i387"
4769   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4770         (float_truncate:MODEF
4771           (match_operand:XF 1 "register_operand" "f")))]
4772   "TARGET_80387"
4773   "* return output_387_reg_move (insn, operands);"
4774   [(set_attr "type" "fmov")
4775    (set_attr "mode" "<MODE>")])
4777 (define_split
4778   [(set (match_operand:MODEF 0 "register_operand" "")
4779         (float_truncate:MODEF
4780           (match_operand:XF 1 "register_operand" "")))
4781    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4782   "TARGET_80387 && reload_completed"
4783   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4784    (set (match_dup 0) (match_dup 2))]
4785   "")
4787 (define_split
4788   [(set (match_operand:MODEF 0 "memory_operand" "")
4789         (float_truncate:MODEF
4790           (match_operand:XF 1 "register_operand" "")))
4791    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4792   "TARGET_80387"
4793   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4794   "")
4796 ;; Signed conversion to DImode.
4798 (define_expand "fix_truncxfdi2"
4799   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4800                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4801               (clobber (reg:CC FLAGS_REG))])]
4802   "TARGET_80387"
4804   if (TARGET_FISTTP)
4805    {
4806      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4807      DONE;
4808    }
4811 (define_expand "fix_trunc<mode>di2"
4812   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4813                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4814               (clobber (reg:CC FLAGS_REG))])]
4815   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4817   if (TARGET_FISTTP
4818       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4819    {
4820      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4821      DONE;
4822    }
4823   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4824    {
4825      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4826      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4827      if (out != operands[0])
4828         emit_move_insn (operands[0], out);
4829      DONE;
4830    }
4833 ;; Signed conversion to SImode.
4835 (define_expand "fix_truncxfsi2"
4836   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4837                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4838               (clobber (reg:CC FLAGS_REG))])]
4839   "TARGET_80387"
4841   if (TARGET_FISTTP)
4842    {
4843      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4844      DONE;
4845    }
4848 (define_expand "fix_trunc<mode>si2"
4849   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4850                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4851               (clobber (reg:CC FLAGS_REG))])]
4852   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4854   if (TARGET_FISTTP
4855       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4856    {
4857      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4858      DONE;
4859    }
4860   if (SSE_FLOAT_MODE_P (<MODE>mode))
4861    {
4862      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4863      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4864      if (out != operands[0])
4865         emit_move_insn (operands[0], out);
4866      DONE;
4867    }
4870 ;; Signed conversion to HImode.
4872 (define_expand "fix_trunc<mode>hi2"
4873   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4874                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4875               (clobber (reg:CC FLAGS_REG))])]
4876   "TARGET_80387
4877    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4879   if (TARGET_FISTTP)
4880    {
4881      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4882      DONE;
4883    }
4886 ;; Unsigned conversion to SImode.
4888 (define_expand "fixuns_trunc<mode>si2"
4889   [(parallel
4890     [(set (match_operand:SI 0 "register_operand" "")
4891           (unsigned_fix:SI
4892             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4893      (use (match_dup 2))
4894      (clobber (match_scratch:<ssevecmode> 3 ""))
4895      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4896   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4898   enum machine_mode mode = <MODE>mode;
4899   enum machine_mode vecmode = <ssevecmode>mode;
4900   REAL_VALUE_TYPE TWO31r;
4901   rtx two31;
4903   if (optimize_insn_for_size_p ())
4904     FAIL;
4906   real_ldexp (&TWO31r, &dconst1, 31);
4907   two31 = const_double_from_real_value (TWO31r, mode);
4908   two31 = ix86_build_const_vector (mode, true, two31);
4909   operands[2] = force_reg (vecmode, two31);
4912 (define_insn_and_split "*fixuns_trunc<mode>_1"
4913   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4914         (unsigned_fix:SI
4915           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4916    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4917    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4918    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4919   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4920    && optimize_function_for_speed_p (cfun)"
4921   "#"
4922   "&& reload_completed"
4923   [(const_int 0)]
4925   ix86_split_convert_uns_si_sse (operands);
4926   DONE;
4929 ;; Unsigned conversion to HImode.
4930 ;; Without these patterns, we'll try the unsigned SI conversion which
4931 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4933 (define_expand "fixuns_trunc<mode>hi2"
4934   [(set (match_dup 2)
4935         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4936    (set (match_operand:HI 0 "nonimmediate_operand" "")
4937         (subreg:HI (match_dup 2) 0))]
4938   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4939   "operands[2] = gen_reg_rtx (SImode);")
4941 ;; When SSE is available, it is always faster to use it!
4942 (define_insn "fix_trunc<mode>di_sse"
4943   [(set (match_operand:DI 0 "register_operand" "=r,r")
4944         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4945   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4946    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4947   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4948   [(set_attr "type" "sseicvt")
4949    (set_attr "prefix" "maybe_vex")
4950    (set_attr "prefix_rex" "1")
4951    (set_attr "mode" "<MODE>")
4952    (set_attr "athlon_decode" "double,vector")
4953    (set_attr "amdfam10_decode" "double,double")])
4955 (define_insn "fix_trunc<mode>si_sse"
4956   [(set (match_operand:SI 0 "register_operand" "=r,r")
4957         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4958   "SSE_FLOAT_MODE_P (<MODE>mode)
4959    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4960   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4961   [(set_attr "type" "sseicvt")
4962    (set_attr "prefix" "maybe_vex")
4963    (set_attr "mode" "<MODE>")
4964    (set_attr "athlon_decode" "double,vector")
4965    (set_attr "amdfam10_decode" "double,double")])
4967 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4968 (define_peephole2
4969   [(set (match_operand:MODEF 0 "register_operand" "")
4970         (match_operand:MODEF 1 "memory_operand" ""))
4971    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4972         (fix:SSEMODEI24 (match_dup 0)))]
4973   "TARGET_SHORTEN_X87_SSE
4974    && peep2_reg_dead_p (2, operands[0])"
4975   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4976   "")
4978 ;; Avoid vector decoded forms of the instruction.
4979 (define_peephole2
4980   [(match_scratch:DF 2 "Y2")
4981    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4982         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4983   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4984   [(set (match_dup 2) (match_dup 1))
4985    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4986   "")
4988 (define_peephole2
4989   [(match_scratch:SF 2 "x")
4990    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4991         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4992   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4993   [(set (match_dup 2) (match_dup 1))
4994    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4995   "")
4997 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4998   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4999         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5000   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5001    && TARGET_FISTTP
5002    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5003          && (TARGET_64BIT || <MODE>mode != DImode))
5004         && TARGET_SSE_MATH)
5005    && can_create_pseudo_p ()"
5006   "#"
5007   "&& 1"
5008   [(const_int 0)]
5010   if (memory_operand (operands[0], VOIDmode))
5011     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5012   else
5013     {
5014       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5015       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5016                                                             operands[1],
5017                                                             operands[2]));
5018     }
5019   DONE;
5021   [(set_attr "type" "fisttp")
5022    (set_attr "mode" "<MODE>")])
5024 (define_insn "fix_trunc<mode>_i387_fisttp"
5025   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5026         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5027    (clobber (match_scratch:XF 2 "=&1f"))]
5028   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5029    && TARGET_FISTTP
5030    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5031          && (TARGET_64BIT || <MODE>mode != DImode))
5032         && TARGET_SSE_MATH)"
5033   "* return output_fix_trunc (insn, operands, 1);"
5034   [(set_attr "type" "fisttp")
5035    (set_attr "mode" "<MODE>")])
5037 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5038   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5039         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5040    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5041    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5042   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5043    && TARGET_FISTTP
5044    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5045         && (TARGET_64BIT || <MODE>mode != DImode))
5046         && TARGET_SSE_MATH)"
5047   "#"
5048   [(set_attr "type" "fisttp")
5049    (set_attr "mode" "<MODE>")])
5051 (define_split
5052   [(set (match_operand:X87MODEI 0 "register_operand" "")
5053         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5054    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5055    (clobber (match_scratch 3 ""))]
5056   "reload_completed"
5057   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5058               (clobber (match_dup 3))])
5059    (set (match_dup 0) (match_dup 2))]
5060   "")
5062 (define_split
5063   [(set (match_operand:X87MODEI 0 "memory_operand" "")
5064         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5065    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5066    (clobber (match_scratch 3 ""))]
5067   "reload_completed"
5068   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5069               (clobber (match_dup 3))])]
5070   "")
5072 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5073 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5074 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5075 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5076 ;; function in i386.c.
5077 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5078   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5079         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5080    (clobber (reg:CC FLAGS_REG))]
5081   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5082    && !TARGET_FISTTP
5083    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5084          && (TARGET_64BIT || <MODE>mode != DImode))
5085    && can_create_pseudo_p ()"
5086   "#"
5087   "&& 1"
5088   [(const_int 0)]
5090   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5092   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5093   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5094   if (memory_operand (operands[0], VOIDmode))
5095     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5096                                          operands[2], operands[3]));
5097   else
5098     {
5099       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5100       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5101                                                      operands[2], operands[3],
5102                                                      operands[4]));
5103     }
5104   DONE;
5106   [(set_attr "type" "fistp")
5107    (set_attr "i387_cw" "trunc")
5108    (set_attr "mode" "<MODE>")])
5110 (define_insn "fix_truncdi_i387"
5111   [(set (match_operand:DI 0 "memory_operand" "=m")
5112         (fix:DI (match_operand 1 "register_operand" "f")))
5113    (use (match_operand:HI 2 "memory_operand" "m"))
5114    (use (match_operand:HI 3 "memory_operand" "m"))
5115    (clobber (match_scratch:XF 4 "=&1f"))]
5116   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5117    && !TARGET_FISTTP
5118    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5119   "* return output_fix_trunc (insn, operands, 0);"
5120   [(set_attr "type" "fistp")
5121    (set_attr "i387_cw" "trunc")
5122    (set_attr "mode" "DI")])
5124 (define_insn "fix_truncdi_i387_with_temp"
5125   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5126         (fix:DI (match_operand 1 "register_operand" "f,f")))
5127    (use (match_operand:HI 2 "memory_operand" "m,m"))
5128    (use (match_operand:HI 3 "memory_operand" "m,m"))
5129    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5130    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5131   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5132    && !TARGET_FISTTP
5133    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5134   "#"
5135   [(set_attr "type" "fistp")
5136    (set_attr "i387_cw" "trunc")
5137    (set_attr "mode" "DI")])
5139 (define_split
5140   [(set (match_operand:DI 0 "register_operand" "")
5141         (fix:DI (match_operand 1 "register_operand" "")))
5142    (use (match_operand:HI 2 "memory_operand" ""))
5143    (use (match_operand:HI 3 "memory_operand" ""))
5144    (clobber (match_operand:DI 4 "memory_operand" ""))
5145    (clobber (match_scratch 5 ""))]
5146   "reload_completed"
5147   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5148               (use (match_dup 2))
5149               (use (match_dup 3))
5150               (clobber (match_dup 5))])
5151    (set (match_dup 0) (match_dup 4))]
5152   "")
5154 (define_split
5155   [(set (match_operand:DI 0 "memory_operand" "")
5156         (fix:DI (match_operand 1 "register_operand" "")))
5157    (use (match_operand:HI 2 "memory_operand" ""))
5158    (use (match_operand:HI 3 "memory_operand" ""))
5159    (clobber (match_operand:DI 4 "memory_operand" ""))
5160    (clobber (match_scratch 5 ""))]
5161   "reload_completed"
5162   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5163               (use (match_dup 2))
5164               (use (match_dup 3))
5165               (clobber (match_dup 5))])]
5166   "")
5168 (define_insn "fix_trunc<mode>_i387"
5169   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5170         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5171    (use (match_operand:HI 2 "memory_operand" "m"))
5172    (use (match_operand:HI 3 "memory_operand" "m"))]
5173   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5174    && !TARGET_FISTTP
5175    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5176   "* return output_fix_trunc (insn, operands, 0);"
5177   [(set_attr "type" "fistp")
5178    (set_attr "i387_cw" "trunc")
5179    (set_attr "mode" "<MODE>")])
5181 (define_insn "fix_trunc<mode>_i387_with_temp"
5182   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5183         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5184    (use (match_operand:HI 2 "memory_operand" "m,m"))
5185    (use (match_operand:HI 3 "memory_operand" "m,m"))
5186    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5187   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5188    && !TARGET_FISTTP
5189    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5190   "#"
5191   [(set_attr "type" "fistp")
5192    (set_attr "i387_cw" "trunc")
5193    (set_attr "mode" "<MODE>")])
5195 (define_split
5196   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5197         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5198    (use (match_operand:HI 2 "memory_operand" ""))
5199    (use (match_operand:HI 3 "memory_operand" ""))
5200    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5201   "reload_completed"
5202   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5203               (use (match_dup 2))
5204               (use (match_dup 3))])
5205    (set (match_dup 0) (match_dup 4))]
5206   "")
5208 (define_split
5209   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5210         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5211    (use (match_operand:HI 2 "memory_operand" ""))
5212    (use (match_operand:HI 3 "memory_operand" ""))
5213    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5214   "reload_completed"
5215   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5216               (use (match_dup 2))
5217               (use (match_dup 3))])]
5218   "")
5220 (define_insn "x86_fnstcw_1"
5221   [(set (match_operand:HI 0 "memory_operand" "=m")
5222         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5223   "TARGET_80387"
5224   "fnstcw\t%0"
5225   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5226    (set_attr "mode" "HI")
5227    (set_attr "unit" "i387")])
5229 (define_insn "x86_fldcw_1"
5230   [(set (reg:HI FPCR_REG)
5231         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5232   "TARGET_80387"
5233   "fldcw\t%0"
5234   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5235    (set_attr "mode" "HI")
5236    (set_attr "unit" "i387")
5237    (set_attr "athlon_decode" "vector")
5238    (set_attr "amdfam10_decode" "vector")])
5240 ;; Conversion between fixed point and floating point.
5242 ;; Even though we only accept memory inputs, the backend _really_
5243 ;; wants to be able to do this between registers.
5245 (define_expand "floathi<mode>2"
5246   [(set (match_operand:X87MODEF 0 "register_operand" "")
5247         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5248   "TARGET_80387
5249    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5250        || TARGET_MIX_SSE_I387)"
5251   "")
5253 ;; Pre-reload splitter to add memory clobber to the pattern.
5254 (define_insn_and_split "*floathi<mode>2_1"
5255   [(set (match_operand:X87MODEF 0 "register_operand" "")
5256         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5257   "TARGET_80387
5258    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5259        || TARGET_MIX_SSE_I387)
5260    && can_create_pseudo_p ()"
5261   "#"
5262   "&& 1"
5263   [(parallel [(set (match_dup 0)
5264               (float:X87MODEF (match_dup 1)))
5265    (clobber (match_dup 2))])]
5266   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5268 (define_insn "*floathi<mode>2_i387_with_temp"
5269   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5270         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5271   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5272   "TARGET_80387
5273    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5274        || TARGET_MIX_SSE_I387)"
5275   "#"
5276   [(set_attr "type" "fmov,multi")
5277    (set_attr "mode" "<MODE>")
5278    (set_attr "unit" "*,i387")
5279    (set_attr "fp_int_src" "true")])
5281 (define_insn "*floathi<mode>2_i387"
5282   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5283         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5284   "TARGET_80387
5285    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5286        || TARGET_MIX_SSE_I387)"
5287   "fild%Z1\t%1"
5288   [(set_attr "type" "fmov")
5289    (set_attr "mode" "<MODE>")
5290    (set_attr "fp_int_src" "true")])
5292 (define_split
5293   [(set (match_operand:X87MODEF 0 "register_operand" "")
5294         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5295    (clobber (match_operand:HI 2 "memory_operand" ""))]
5296   "TARGET_80387
5297    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5298        || TARGET_MIX_SSE_I387)
5299    && reload_completed"
5300   [(set (match_dup 2) (match_dup 1))
5301    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5302   "")
5304 (define_split
5305   [(set (match_operand:X87MODEF 0 "register_operand" "")
5306         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5307    (clobber (match_operand:HI 2 "memory_operand" ""))]
5308    "TARGET_80387
5309     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5310         || TARGET_MIX_SSE_I387)
5311     && reload_completed"
5312   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5313   "")
5315 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5316   [(set (match_operand:X87MODEF 0 "register_operand" "")
5317         (float:X87MODEF
5318           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5319   "TARGET_80387
5320    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5321        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5323   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5324         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5325       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5326     {
5327       rtx reg = gen_reg_rtx (XFmode);
5328       rtx insn;
5330       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5332       if (<X87MODEF:MODE>mode == SFmode)
5333         insn = gen_truncxfsf2 (operands[0], reg);
5334       else if (<X87MODEF:MODE>mode == DFmode)
5335         insn = gen_truncxfdf2 (operands[0], reg);
5336       else
5337         gcc_unreachable ();
5339       emit_insn (insn);
5340       DONE;
5341     }
5344 ;; Pre-reload splitter to add memory clobber to the pattern.
5345 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5346   [(set (match_operand:X87MODEF 0 "register_operand" "")
5347         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5348   "((TARGET_80387
5349      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5350      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5351            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5352          || TARGET_MIX_SSE_I387))
5353     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5354         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5355         && ((<SSEMODEI24:MODE>mode == SImode
5356              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5357              && optimize_function_for_speed_p (cfun)
5358              && flag_trapping_math)
5359             || !(TARGET_INTER_UNIT_CONVERSIONS
5360                  || optimize_function_for_size_p (cfun)))))
5361    && can_create_pseudo_p ()"
5362   "#"
5363   "&& 1"
5364   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5365               (clobber (match_dup 2))])]
5367   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5369   /* Avoid store forwarding (partial memory) stall penalty
5370      by passing DImode value through XMM registers.  */
5371   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5372       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5373       && optimize_function_for_speed_p (cfun))
5374     {
5375       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5376                                                             operands[1],
5377                                                             operands[2]));
5378       DONE;
5379     }
5382 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5383   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5384         (float:MODEF
5385           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5386    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5387   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5388    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5389   "#"
5390   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5391    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5392    (set_attr "unit" "*,i387,*,*,*")
5393    (set_attr "athlon_decode" "*,*,double,direct,double")
5394    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5395    (set_attr "fp_int_src" "true")])
5397 (define_insn "*floatsi<mode>2_vector_mixed"
5398   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5399         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5400   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5401    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5402   "@
5403    fild%Z1\t%1
5404    #"
5405   [(set_attr "type" "fmov,sseicvt")
5406    (set_attr "mode" "<MODE>,<ssevecmode>")
5407    (set_attr "unit" "i387,*")
5408    (set_attr "athlon_decode" "*,direct")
5409    (set_attr "amdfam10_decode" "*,double")
5410    (set_attr "fp_int_src" "true")])
5412 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5413   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5414         (float:MODEF
5415           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5416   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5417   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5418    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5419   "#"
5420   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5421    (set_attr "mode" "<MODEF:MODE>")
5422    (set_attr "unit" "*,i387,*,*")
5423    (set_attr "athlon_decode" "*,*,double,direct")
5424    (set_attr "amdfam10_decode" "*,*,vector,double")
5425    (set_attr "fp_int_src" "true")])
5427 (define_split
5428   [(set (match_operand:MODEF 0 "register_operand" "")
5429         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5430    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5431   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5432    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5433    && TARGET_INTER_UNIT_CONVERSIONS
5434    && reload_completed
5435    && (SSE_REG_P (operands[0])
5436        || (GET_CODE (operands[0]) == SUBREG
5437            && SSE_REG_P (operands[0])))"
5438   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5439   "")
5441 (define_split
5442   [(set (match_operand:MODEF 0 "register_operand" "")
5443         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5444    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5445   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5446    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5447    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5448    && reload_completed
5449    && (SSE_REG_P (operands[0])
5450        || (GET_CODE (operands[0]) == SUBREG
5451            && SSE_REG_P (operands[0])))"
5452   [(set (match_dup 2) (match_dup 1))
5453    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5454   "")
5456 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5457   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5458         (float:MODEF
5459           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5460   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5461    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5462    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5463   "@
5464    fild%Z1\t%1
5465    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5466    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5467   [(set_attr "type" "fmov,sseicvt,sseicvt")
5468    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5469    (set_attr "mode" "<MODEF:MODE>")
5470    (set (attr "prefix_rex")
5471      (if_then_else
5472        (and (eq_attr "prefix" "maybe_vex")
5473             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5474        (const_string "1")
5475        (const_string "*")))
5476    (set_attr "unit" "i387,*,*")
5477    (set_attr "athlon_decode" "*,double,direct")
5478    (set_attr "amdfam10_decode" "*,vector,double")
5479    (set_attr "fp_int_src" "true")])
5481 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5482   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5483         (float:MODEF
5484           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5485   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5486    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5487    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5488   "@
5489    fild%Z1\t%1
5490    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5491   [(set_attr "type" "fmov,sseicvt")
5492    (set_attr "prefix" "orig,maybe_vex")
5493    (set_attr "mode" "<MODEF:MODE>")
5494    (set (attr "prefix_rex")
5495      (if_then_else
5496        (and (eq_attr "prefix" "maybe_vex")
5497             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5498        (const_string "1")
5499        (const_string "*")))
5500    (set_attr "athlon_decode" "*,direct")
5501    (set_attr "amdfam10_decode" "*,double")
5502    (set_attr "fp_int_src" "true")])
5504 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5505   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5506         (float:MODEF
5507           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5508    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5509   "TARGET_SSE2 && TARGET_SSE_MATH
5510    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5511   "#"
5512   [(set_attr "type" "sseicvt")
5513    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5514    (set_attr "athlon_decode" "double,direct,double")
5515    (set_attr "amdfam10_decode" "vector,double,double")
5516    (set_attr "fp_int_src" "true")])
5518 (define_insn "*floatsi<mode>2_vector_sse"
5519   [(set (match_operand:MODEF 0 "register_operand" "=x")
5520         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5521   "TARGET_SSE2 && TARGET_SSE_MATH
5522    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5523   "#"
5524   [(set_attr "type" "sseicvt")
5525    (set_attr "mode" "<MODE>")
5526    (set_attr "athlon_decode" "direct")
5527    (set_attr "amdfam10_decode" "double")
5528    (set_attr "fp_int_src" "true")])
5530 (define_split
5531   [(set (match_operand:MODEF 0 "register_operand" "")
5532         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5533    (clobber (match_operand:SI 2 "memory_operand" ""))]
5534   "TARGET_SSE2 && TARGET_SSE_MATH
5535    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5536    && reload_completed
5537    && (SSE_REG_P (operands[0])
5538        || (GET_CODE (operands[0]) == SUBREG
5539            && SSE_REG_P (operands[0])))"
5540   [(const_int 0)]
5542   rtx op1 = operands[1];
5544   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5545                                      <MODE>mode, 0);
5546   if (GET_CODE (op1) == SUBREG)
5547     op1 = SUBREG_REG (op1);
5549   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5550     {
5551       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5552       emit_insn (gen_sse2_loadld (operands[4],
5553                                   CONST0_RTX (V4SImode), operands[1]));
5554     }
5555   /* We can ignore possible trapping value in the
5556      high part of SSE register for non-trapping math. */
5557   else if (SSE_REG_P (op1) && !flag_trapping_math)
5558     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5559   else
5560     {
5561       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5562       emit_move_insn (operands[2], operands[1]);
5563       emit_insn (gen_sse2_loadld (operands[4],
5564                                   CONST0_RTX (V4SImode), operands[2]));
5565     }
5566   emit_insn
5567     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5568   DONE;
5571 (define_split
5572   [(set (match_operand:MODEF 0 "register_operand" "")
5573         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5574    (clobber (match_operand:SI 2 "memory_operand" ""))]
5575   "TARGET_SSE2 && TARGET_SSE_MATH
5576    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5577    && reload_completed
5578    && (SSE_REG_P (operands[0])
5579        || (GET_CODE (operands[0]) == SUBREG
5580            && SSE_REG_P (operands[0])))"
5581   [(const_int 0)]
5583   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5584                                      <MODE>mode, 0);
5585   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5587   emit_insn (gen_sse2_loadld (operands[4],
5588                               CONST0_RTX (V4SImode), operands[1]));
5589   emit_insn
5590     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5591   DONE;
5594 (define_split
5595   [(set (match_operand:MODEF 0 "register_operand" "")
5596         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5597   "TARGET_SSE2 && TARGET_SSE_MATH
5598    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5599    && reload_completed
5600    && (SSE_REG_P (operands[0])
5601        || (GET_CODE (operands[0]) == SUBREG
5602            && SSE_REG_P (operands[0])))"
5603   [(const_int 0)]
5605   rtx op1 = operands[1];
5607   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5608                                      <MODE>mode, 0);
5609   if (GET_CODE (op1) == SUBREG)
5610     op1 = SUBREG_REG (op1);
5612   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5613     {
5614       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5615       emit_insn (gen_sse2_loadld (operands[4],
5616                                   CONST0_RTX (V4SImode), operands[1]));
5617     }
5618   /* We can ignore possible trapping value in the
5619      high part of SSE register for non-trapping math. */
5620   else if (SSE_REG_P (op1) && !flag_trapping_math)
5621     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5622   else
5623     gcc_unreachable ();
5624   emit_insn
5625     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5626   DONE;
5629 (define_split
5630   [(set (match_operand:MODEF 0 "register_operand" "")
5631         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5632   "TARGET_SSE2 && TARGET_SSE_MATH
5633    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5634    && reload_completed
5635    && (SSE_REG_P (operands[0])
5636        || (GET_CODE (operands[0]) == SUBREG
5637            && SSE_REG_P (operands[0])))"
5638   [(const_int 0)]
5640   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5641                                      <MODE>mode, 0);
5642   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5644   emit_insn (gen_sse2_loadld (operands[4],
5645                               CONST0_RTX (V4SImode), operands[1]));
5646   emit_insn
5647     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5648   DONE;
5651 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5652   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5653         (float:MODEF
5654           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5655   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5656   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5657    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5658   "#"
5659   [(set_attr "type" "sseicvt")
5660    (set_attr "mode" "<MODEF:MODE>")
5661    (set_attr "athlon_decode" "double,direct")
5662    (set_attr "amdfam10_decode" "vector,double")
5663    (set_attr "fp_int_src" "true")])
5665 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5666   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5667         (float:MODEF
5668           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5669   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5670    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5671    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5672   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5673   [(set_attr "type" "sseicvt")
5674    (set_attr "prefix" "maybe_vex")
5675    (set_attr "mode" "<MODEF:MODE>")
5676    (set (attr "prefix_rex")
5677      (if_then_else
5678        (and (eq_attr "prefix" "maybe_vex")
5679             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5680        (const_string "1")
5681        (const_string "*")))
5682    (set_attr "athlon_decode" "double,direct")
5683    (set_attr "amdfam10_decode" "vector,double")
5684    (set_attr "fp_int_src" "true")])
5686 (define_split
5687   [(set (match_operand:MODEF 0 "register_operand" "")
5688         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5689    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5690   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5691    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5692    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5693    && reload_completed
5694    && (SSE_REG_P (operands[0])
5695        || (GET_CODE (operands[0]) == SUBREG
5696            && SSE_REG_P (operands[0])))"
5697   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5698   "")
5700 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5701   [(set (match_operand:MODEF 0 "register_operand" "=x")
5702         (float:MODEF
5703           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5704   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5705    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5706    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5707   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5708   [(set_attr "type" "sseicvt")
5709    (set_attr "prefix" "maybe_vex")
5710    (set_attr "mode" "<MODEF:MODE>")
5711    (set (attr "prefix_rex")
5712      (if_then_else
5713        (and (eq_attr "prefix" "maybe_vex")
5714             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5715        (const_string "1")
5716        (const_string "*")))
5717    (set_attr "athlon_decode" "direct")
5718    (set_attr "amdfam10_decode" "double")
5719    (set_attr "fp_int_src" "true")])
5721 (define_split
5722   [(set (match_operand:MODEF 0 "register_operand" "")
5723         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5724    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5725   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5726    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5727    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5728    && reload_completed
5729    && (SSE_REG_P (operands[0])
5730        || (GET_CODE (operands[0]) == SUBREG
5731            && SSE_REG_P (operands[0])))"
5732   [(set (match_dup 2) (match_dup 1))
5733    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5734   "")
5736 (define_split
5737   [(set (match_operand:MODEF 0 "register_operand" "")
5738         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5739    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5740   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5741    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5742    && reload_completed
5743    && (SSE_REG_P (operands[0])
5744        || (GET_CODE (operands[0]) == SUBREG
5745            && SSE_REG_P (operands[0])))"
5746   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5747   "")
5749 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5750   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5751         (float:X87MODEF
5752           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5753   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5754   "TARGET_80387
5755    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5756   "@
5757    fild%Z1\t%1
5758    #"
5759   [(set_attr "type" "fmov,multi")
5760    (set_attr "mode" "<X87MODEF:MODE>")
5761    (set_attr "unit" "*,i387")
5762    (set_attr "fp_int_src" "true")])
5764 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5765   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5766         (float:X87MODEF
5767           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5768   "TARGET_80387
5769    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5770   "fild%Z1\t%1"
5771   [(set_attr "type" "fmov")
5772    (set_attr "mode" "<X87MODEF:MODE>")
5773    (set_attr "fp_int_src" "true")])
5775 (define_split
5776   [(set (match_operand:X87MODEF 0 "register_operand" "")
5777         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5778    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5779   "TARGET_80387
5780    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5781    && reload_completed
5782    && FP_REG_P (operands[0])"
5783   [(set (match_dup 2) (match_dup 1))
5784    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5785   "")
5787 (define_split
5788   [(set (match_operand:X87MODEF 0 "register_operand" "")
5789         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5790    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5791   "TARGET_80387
5792    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5793    && reload_completed
5794    && FP_REG_P (operands[0])"
5795   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5796   "")
5798 ;; Avoid store forwarding (partial memory) stall penalty
5799 ;; by passing DImode value through XMM registers.  */
5801 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5802   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5803         (float:X87MODEF
5804           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5805    (clobber (match_scratch:V4SI 3 "=X,x"))
5806    (clobber (match_scratch:V4SI 4 "=X,x"))
5807    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5808   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5809    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5810    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5811   "#"
5812   [(set_attr "type" "multi")
5813    (set_attr "mode" "<X87MODEF:MODE>")
5814    (set_attr "unit" "i387")
5815    (set_attr "fp_int_src" "true")])
5817 (define_split
5818   [(set (match_operand:X87MODEF 0 "register_operand" "")
5819         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5820    (clobber (match_scratch:V4SI 3 ""))
5821    (clobber (match_scratch:V4SI 4 ""))
5822    (clobber (match_operand:DI 2 "memory_operand" ""))]
5823   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5824    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5825    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5826    && reload_completed
5827    && FP_REG_P (operands[0])"
5828   [(set (match_dup 2) (match_dup 3))
5829    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5831   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5832      Assemble the 64-bit DImode value in an xmm register.  */
5833   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5834                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5835   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5836                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5837   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5838                                          operands[4]));
5840   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5843 (define_split
5844   [(set (match_operand:X87MODEF 0 "register_operand" "")
5845         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5846    (clobber (match_scratch:V4SI 3 ""))
5847    (clobber (match_scratch:V4SI 4 ""))
5848    (clobber (match_operand:DI 2 "memory_operand" ""))]
5849   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5850    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5851    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5852    && reload_completed
5853    && FP_REG_P (operands[0])"
5854   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5855   "")
5857 ;; Avoid store forwarding (partial memory) stall penalty by extending
5858 ;; SImode value to DImode through XMM register instead of pushing two
5859 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5860 ;; targets benefit from this optimization. Also note that fild
5861 ;; loads from memory only.
5863 (define_insn "*floatunssi<mode>2_1"
5864   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5865         (unsigned_float:X87MODEF
5866           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5867    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5868    (clobber (match_scratch:SI 3 "=X,x"))]
5869   "!TARGET_64BIT
5870    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5871    && TARGET_SSE"
5872   "#"
5873   [(set_attr "type" "multi")
5874    (set_attr "mode" "<MODE>")])
5876 (define_split
5877   [(set (match_operand:X87MODEF 0 "register_operand" "")
5878         (unsigned_float:X87MODEF
5879           (match_operand:SI 1 "register_operand" "")))
5880    (clobber (match_operand:DI 2 "memory_operand" ""))
5881    (clobber (match_scratch:SI 3 ""))]
5882   "!TARGET_64BIT
5883    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5884    && TARGET_SSE
5885    && reload_completed"
5886   [(set (match_dup 2) (match_dup 1))
5887    (set (match_dup 0)
5888         (float:X87MODEF (match_dup 2)))]
5889   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5891 (define_split
5892   [(set (match_operand:X87MODEF 0 "register_operand" "")
5893         (unsigned_float:X87MODEF
5894           (match_operand:SI 1 "memory_operand" "")))
5895    (clobber (match_operand:DI 2 "memory_operand" ""))
5896    (clobber (match_scratch:SI 3 ""))]
5897   "!TARGET_64BIT
5898    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5899    && TARGET_SSE
5900    && reload_completed"
5901   [(set (match_dup 2) (match_dup 3))
5902    (set (match_dup 0)
5903         (float:X87MODEF (match_dup 2)))]
5905   emit_move_insn (operands[3], operands[1]);
5906   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5909 (define_expand "floatunssi<mode>2"
5910   [(parallel
5911      [(set (match_operand:X87MODEF 0 "register_operand" "")
5912            (unsigned_float:X87MODEF
5913              (match_operand:SI 1 "nonimmediate_operand" "")))
5914       (clobber (match_dup 2))
5915       (clobber (match_scratch:SI 3 ""))])]
5916   "!TARGET_64BIT
5917    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5918         && TARGET_SSE)
5919        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5921   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5922     {
5923       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5924       DONE;
5925     }
5926   else
5927     {
5928       enum ix86_stack_slot slot = (virtuals_instantiated
5929                                    ? SLOT_TEMP
5930                                    : SLOT_VIRTUAL);
5931       operands[2] = assign_386_stack_local (DImode, slot);
5932     }
5935 (define_expand "floatunsdisf2"
5936   [(use (match_operand:SF 0 "register_operand" ""))
5937    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5938   "TARGET_64BIT && TARGET_SSE_MATH"
5939   "x86_emit_floatuns (operands); DONE;")
5941 (define_expand "floatunsdidf2"
5942   [(use (match_operand:DF 0 "register_operand" ""))
5943    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5944   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5945    && TARGET_SSE2 && TARGET_SSE_MATH"
5947   if (TARGET_64BIT)
5948     x86_emit_floatuns (operands);
5949   else
5950     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5951   DONE;
5954 ;; Add instructions
5956 (define_expand "add<mode>3"
5957   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5958         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5959                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5960   ""
5961   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5963 (define_insn_and_split "*add<dwi>3_doubleword"
5964   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5965         (plus:<DWI>
5966           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5967           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5968    (clobber (reg:CC FLAGS_REG))]
5969   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5970   "#"
5971   "reload_completed"
5972   [(parallel [(set (reg:CC FLAGS_REG)
5973                    (unspec:CC [(match_dup 1) (match_dup 2)]
5974                               UNSPEC_ADD_CARRY))
5975               (set (match_dup 0)
5976                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5977    (parallel [(set (match_dup 3)
5978                    (plus:DWIH
5979                      (match_dup 4)
5980                      (plus:DWIH
5981                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5982                        (match_dup 5))))
5983               (clobber (reg:CC FLAGS_REG))])]
5984   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5986 (define_insn "*add<mode>3_cc"
5987   [(set (reg:CC FLAGS_REG)
5988         (unspec:CC
5989           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5990            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5991           UNSPEC_ADD_CARRY))
5992    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5993         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5994   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5995   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5996   [(set_attr "type" "alu")
5997    (set_attr "mode" "<MODE>")])
5999 (define_insn "addqi3_cc"
6000   [(set (reg:CC FLAGS_REG)
6001         (unspec:CC
6002           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6003            (match_operand:QI 2 "general_operand" "qn,qm")]
6004           UNSPEC_ADD_CARRY))
6005    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6006         (plus:QI (match_dup 1) (match_dup 2)))]
6007   "ix86_binary_operator_ok (PLUS, QImode, operands)"
6008   "add{b}\t{%2, %0|%0, %2}"
6009   [(set_attr "type" "alu")
6010    (set_attr "mode" "QI")])
6012 (define_insn "*lea_1"
6013   [(set (match_operand:DWIH 0 "register_operand" "=r")
6014         (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
6015   ""
6016   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
6017   [(set_attr "type" "lea")
6018    (set_attr "mode" "<MODE>")])
6020 (define_insn "*lea_2"
6021   [(set (match_operand:SI 0 "register_operand" "=r")
6022         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6023   "TARGET_64BIT"
6024   "lea{l}\t{%a1, %0|%0, %a1}"
6025   [(set_attr "type" "lea")
6026    (set_attr "mode" "SI")])
6028 (define_insn "*lea_2_zext"
6029   [(set (match_operand:DI 0 "register_operand" "=r")
6030         (zero_extend:DI
6031           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6032   "TARGET_64BIT"
6033   "lea{l}\t{%a1, %k0|%k0, %a1}"
6034   [(set_attr "type" "lea")
6035    (set_attr "mode" "SI")])
6037 (define_insn "*add<mode>_1"
6038   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6039         (plus:SWI48
6040           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6041           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6042    (clobber (reg:CC FLAGS_REG))]
6043   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6045   switch (get_attr_type (insn))
6046     {
6047     case TYPE_LEA:
6048       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6049       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6051     case TYPE_INCDEC:
6052       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6053       if (operands[2] == const1_rtx)
6054         return "inc{<imodesuffix>}\t%0";
6055       else
6056         {
6057           gcc_assert (operands[2] == constm1_rtx);
6058           return "dec{<imodesuffix>}\t%0";
6059         }
6061     default:
6062       /* Use add as much as possible to replace lea for AGU optimization. */
6063       if (which_alternative == 2 && TARGET_OPT_AGU)
6064         return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6065         
6066       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6067       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6068         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6070       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6071     }
6073   [(set (attr "type")
6074      (cond [(and (eq_attr "alternative" "2") 
6075                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6076               (const_string "lea")
6077             (eq_attr "alternative" "3")
6078               (const_string "lea")
6079             ; Current assemblers are broken and do not allow @GOTOFF in
6080             ; ought but a memory context.
6081             (match_operand:SWI48 2 "pic_symbolic_operand" "")
6082               (const_string "lea")
6083             (match_operand:SWI48 2 "incdec_operand" "")
6084               (const_string "incdec")
6085            ]
6086            (const_string "alu")))
6087    (set (attr "length_immediate")
6088       (if_then_else
6089         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6090         (const_string "1")
6091         (const_string "*")))
6092    (set_attr "mode" "<MODE>")])
6094 ;; It may seem that nonimmediate operand is proper one for operand 1.
6095 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6096 ;; we take care in ix86_binary_operator_ok to not allow two memory
6097 ;; operands so proper swapping will be done in reload.  This allow
6098 ;; patterns constructed from addsi_1 to match.
6100 (define_insn "*addsi_1_zext"
6101   [(set (match_operand:DI 0 "register_operand" "=r,r")
6102         (zero_extend:DI
6103           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6104                    (match_operand:SI 2 "general_operand" "g,li"))))
6105    (clobber (reg:CC FLAGS_REG))]
6106   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6108   switch (get_attr_type (insn))
6109     {
6110     case TYPE_LEA:
6111       operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6112       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6114     case TYPE_INCDEC:
6115       if (operands[2] == const1_rtx)
6116         return "inc{l}\t%k0";
6117       else
6118         {
6119           gcc_assert (operands[2] == constm1_rtx);
6120           return "dec{l}\t%k0";
6121         }
6123     default:
6124       if (x86_maybe_negate_const_int (&operands[2], SImode))
6125         return "sub{l}\t{%2, %k0|%k0, %2}";
6127       return "add{l}\t{%2, %k0|%k0, %2}";
6128     }
6130   [(set (attr "type")
6131      (cond [(eq_attr "alternative" "1")
6132               (const_string "lea")
6133             ; Current assemblers are broken and do not allow @GOTOFF in
6134             ; ought but a memory context.
6135             (match_operand:SI 2 "pic_symbolic_operand" "")
6136               (const_string "lea")
6137             (match_operand:SI 2 "incdec_operand" "")
6138               (const_string "incdec")
6139            ]
6140            (const_string "alu")))
6141    (set (attr "length_immediate")
6142       (if_then_else
6143         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6144         (const_string "1")
6145         (const_string "*")))
6146    (set_attr "mode" "SI")])
6148 (define_insn "*addhi_1"
6149   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6150         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6151                  (match_operand:HI 2 "general_operand" "rn,rm")))
6152    (clobber (reg:CC FLAGS_REG))]
6153   "TARGET_PARTIAL_REG_STALL
6154    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6156   switch (get_attr_type (insn))
6157     {
6158     case TYPE_INCDEC:
6159       if (operands[2] == const1_rtx)
6160         return "inc{w}\t%0";
6161       else
6162         {
6163           gcc_assert (operands[2] == constm1_rtx);
6164           return "dec{w}\t%0";
6165         }
6167     default:
6168       if (x86_maybe_negate_const_int (&operands[2], HImode))
6169         return "sub{w}\t{%2, %0|%0, %2}";
6171       return "add{w}\t{%2, %0|%0, %2}";
6172     }
6174   [(set (attr "type")
6175      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6176         (const_string "incdec")
6177         (const_string "alu")))
6178    (set (attr "length_immediate")
6179       (if_then_else
6180         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6181         (const_string "1")
6182         (const_string "*")))
6183    (set_attr "mode" "HI")])
6185 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6186 ;; type optimizations enabled by define-splits.  This is not important
6187 ;; for PII, and in fact harmful because of partial register stalls.
6189 (define_insn "*addhi_1_lea"
6190   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6191         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6192                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6193    (clobber (reg:CC FLAGS_REG))]
6194   "!TARGET_PARTIAL_REG_STALL
6195    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6197   switch (get_attr_type (insn))
6198     {
6199     case TYPE_LEA:
6200       return "#";
6201     case TYPE_INCDEC:
6202       if (operands[2] == const1_rtx)
6203         return "inc{w}\t%0";
6204       else
6205         {
6206           gcc_assert (operands[2] == constm1_rtx);
6207           return "dec{w}\t%0";
6208         }
6210     default:
6211       if (x86_maybe_negate_const_int (&operands[2], HImode))
6212         return "sub{w}\t{%2, %0|%0, %2}";
6214       return "add{w}\t{%2, %0|%0, %2}";
6215     }
6217   [(set (attr "type")
6218      (if_then_else (eq_attr "alternative" "2")
6219         (const_string "lea")
6220         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6221            (const_string "incdec")
6222            (const_string "alu"))))
6223    (set (attr "length_immediate")
6224       (if_then_else
6225         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6226         (const_string "1")
6227         (const_string "*")))
6228    (set_attr "mode" "HI,HI,SI")])
6230 (define_insn "*addqi_1"
6231   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6232         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6233                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6234    (clobber (reg:CC FLAGS_REG))]
6235   "TARGET_PARTIAL_REG_STALL
6236    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6238   int widen = (which_alternative == 2);
6239   switch (get_attr_type (insn))
6240     {
6241     case TYPE_INCDEC:
6242       if (operands[2] == const1_rtx)
6243         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6244       else
6245         {
6246           gcc_assert (operands[2] == constm1_rtx);
6247           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6248         }
6250     default:
6251       if (x86_maybe_negate_const_int (&operands[2], QImode))
6252         {
6253           if (widen)
6254             return "sub{l}\t{%2, %k0|%k0, %2}";
6255           else
6256             return "sub{b}\t{%2, %0|%0, %2}";
6257         }
6258       if (widen)
6259         return "add{l}\t{%k2, %k0|%k0, %k2}";
6260       else
6261         return "add{b}\t{%2, %0|%0, %2}";
6262     }
6264   [(set (attr "type")
6265      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6266         (const_string "incdec")
6267         (const_string "alu")))
6268    (set (attr "length_immediate")
6269       (if_then_else
6270         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6271         (const_string "1")
6272         (const_string "*")))
6273    (set_attr "mode" "QI,QI,SI")])
6275 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6276 (define_insn "*addqi_1_lea"
6277   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6278         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6279                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6280    (clobber (reg:CC FLAGS_REG))]
6281   "!TARGET_PARTIAL_REG_STALL
6282    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6284   int widen = (which_alternative == 2);
6285   switch (get_attr_type (insn))
6286     {
6287     case TYPE_LEA:
6288       return "#";
6289     case TYPE_INCDEC:
6290       if (operands[2] == const1_rtx)
6291         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6292       else
6293         {
6294           gcc_assert (operands[2] == constm1_rtx);
6295           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6296         }
6298     default:
6299       if (x86_maybe_negate_const_int (&operands[2], QImode))
6300         {
6301           if (widen)
6302             return "sub{l}\t{%2, %k0|%k0, %2}";
6303           else
6304             return "sub{b}\t{%2, %0|%0, %2}";
6305         }
6306       if (widen)
6307         return "add{l}\t{%k2, %k0|%k0, %k2}";
6308       else
6309         return "add{b}\t{%2, %0|%0, %2}";
6310     }
6312   [(set (attr "type")
6313      (if_then_else (eq_attr "alternative" "3")
6314         (const_string "lea")
6315         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6316            (const_string "incdec")
6317            (const_string "alu"))))
6318    (set (attr "length_immediate")
6319       (if_then_else
6320         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6321         (const_string "1")
6322         (const_string "*")))
6323    (set_attr "mode" "QI,QI,SI,SI")])
6325 (define_insn "*addqi_1_slp"
6326   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6327         (plus:QI (match_dup 0)
6328                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6329    (clobber (reg:CC FLAGS_REG))]
6330   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6331    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6333   switch (get_attr_type (insn))
6334     {
6335     case TYPE_INCDEC:
6336       if (operands[1] == const1_rtx)
6337         return "inc{b}\t%0";
6338       else
6339         {
6340           gcc_assert (operands[1] == constm1_rtx);
6341           return "dec{b}\t%0";
6342         }
6344     default:
6345       if (x86_maybe_negate_const_int (&operands[1], QImode))
6346         return "sub{b}\t{%1, %0|%0, %1}";
6348       return "add{b}\t{%1, %0|%0, %1}";
6349     }
6351   [(set (attr "type")
6352      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6353         (const_string "incdec")
6354         (const_string "alu1")))
6355    (set (attr "memory")
6356      (if_then_else (match_operand 1 "memory_operand" "")
6357         (const_string "load")
6358         (const_string "none")))
6359    (set_attr "mode" "QI")])
6361 (define_insn "*add<mode>_2"
6362   [(set (reg FLAGS_REG)
6363         (compare
6364           (plus:SWI48
6365             (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6366             (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6367           (const_int 0)))
6368    (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6369         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6370   "ix86_match_ccmode (insn, CCGOCmode)
6371    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6372    /* Current assemblers are broken and do not allow @GOTOFF in
6373       ought but a memory context.  */
6374    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6376   switch (get_attr_type (insn))
6377     {
6378     case TYPE_INCDEC:
6379       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6380       if (operands[2] == const1_rtx)
6381         return "inc{<imodesuffix>}\t%0";
6382       else
6383         {
6384           gcc_assert (operands[2] == constm1_rtx);
6385           return "dec{<imodesuffix>}\t%0";
6386         }
6388     default:
6389       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6390       /* ???? In DImode, we ought to handle there the 32bit case too
6391          - do we need new constraint?  */
6392       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6393         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6395       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6396     }
6398   [(set (attr "type")
6399      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6400         (const_string "incdec")
6401         (const_string "alu")))
6402    (set (attr "length_immediate")
6403       (if_then_else
6404         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6405         (const_string "1")
6406         (const_string "*")))
6407    (set_attr "mode" "<MODE>")])
6409 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6410 (define_insn "*addsi_2_zext"
6411   [(set (reg FLAGS_REG)
6412         (compare
6413           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6414                    (match_operand:SI 2 "general_operand" "g"))
6415           (const_int 0)))
6416    (set (match_operand:DI 0 "register_operand" "=r")
6417         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6418   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6419    && ix86_binary_operator_ok (PLUS, SImode, operands)
6420    /* Current assemblers are broken and do not allow @GOTOFF in
6421       ought but a memory context.  */
6422    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6424   switch (get_attr_type (insn))
6425     {
6426     case TYPE_INCDEC:
6427       if (operands[2] == const1_rtx)
6428         return "inc{l}\t%k0";
6429       else
6430         {
6431           gcc_assert (operands[2] == constm1_rtx);
6432           return "dec{l}\t%k0";
6433         }
6435     default:
6436       if (x86_maybe_negate_const_int (&operands[2], SImode))
6437         return "sub{l}\t{%2, %k0|%k0, %2}";
6439       return "add{l}\t{%2, %k0|%k0, %2}";
6440     }
6442   [(set (attr "type")
6443      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6444         (const_string "incdec")
6445         (const_string "alu")))
6446    (set (attr "length_immediate")
6447       (if_then_else
6448         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6449         (const_string "1")
6450         (const_string "*")))
6451    (set_attr "mode" "SI")])
6453 (define_insn "*addhi_2"
6454   [(set (reg FLAGS_REG)
6455         (compare
6456           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6457                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6458           (const_int 0)))
6459    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6460         (plus:HI (match_dup 1) (match_dup 2)))]
6461   "ix86_match_ccmode (insn, CCGOCmode)
6462    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6464   switch (get_attr_type (insn))
6465     {
6466     case TYPE_INCDEC:
6467       if (operands[2] == const1_rtx)
6468         return "inc{w}\t%0";
6469       else
6470         {
6471           gcc_assert (operands[2] == constm1_rtx);
6472           return "dec{w}\t%0";
6473         }
6475     default:
6476       if (x86_maybe_negate_const_int (&operands[2], HImode))
6477         return "sub{w}\t{%2, %0|%0, %2}";
6479       return "add{w}\t{%2, %0|%0, %2}";
6480     }
6482   [(set (attr "type")
6483      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6484         (const_string "incdec")
6485         (const_string "alu")))
6486    (set (attr "length_immediate")
6487       (if_then_else
6488         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6489         (const_string "1")
6490         (const_string "*")))
6491    (set_attr "mode" "HI")])
6493 (define_insn "*addqi_2"
6494   [(set (reg FLAGS_REG)
6495         (compare
6496           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6497                    (match_operand:QI 2 "general_operand" "qmn,qn"))
6498           (const_int 0)))
6499    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6500         (plus:QI (match_dup 1) (match_dup 2)))]
6501   "ix86_match_ccmode (insn, CCGOCmode)
6502    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6504   switch (get_attr_type (insn))
6505     {
6506     case TYPE_INCDEC:
6507       if (operands[2] == const1_rtx)
6508         return "inc{b}\t%0";
6509       else
6510         {
6511           gcc_assert (operands[2] == constm1_rtx
6512                       || (CONST_INT_P (operands[2])
6513                           && INTVAL (operands[2]) == 255));
6514           return "dec{b}\t%0";
6515         }
6517     default:
6518       if (x86_maybe_negate_const_int (&operands[2], QImode))
6519         return "sub{b}\t{%2, %0|%0, %2}";
6521       return "add{b}\t{%2, %0|%0, %2}";
6522     }
6524   [(set (attr "type")
6525      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6526         (const_string "incdec")
6527         (const_string "alu")))
6528    (set_attr "mode" "QI")])
6530 (define_insn "*add<mode>_3"
6531   [(set (reg FLAGS_REG)
6532         (compare
6533           (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6534           (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6535    (clobber (match_scratch:SWI48 0 "=r"))]
6536   "ix86_match_ccmode (insn, CCZmode)
6537    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6538    /* Current assemblers are broken and do not allow @GOTOFF in
6539       ought but a memory context.  */
6540    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6542   switch (get_attr_type (insn))
6543     {
6544     case TYPE_INCDEC:
6545       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6546       if (operands[2] == const1_rtx)
6547         return "inc{<imodesuffix>}\t%0";
6548       else
6549         {
6550           gcc_assert (operands[2] == constm1_rtx);
6551           return "dec{<imodesuffix>}\t%0";
6552         }
6554     default:
6555       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6556       /* ???? In DImode, we ought to handle there the 32bit case too
6557          - do we need new constraint?  */
6558       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6559         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6561       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6562     }
6564   [(set (attr "type")
6565      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6566         (const_string "incdec")
6567         (const_string "alu")))
6568    (set (attr "length_immediate")
6569       (if_then_else
6570         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6571         (const_string "1")
6572         (const_string "*")))
6573    (set_attr "mode" "<MODE>")])
6575 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6576 (define_insn "*addsi_3_zext"
6577   [(set (reg FLAGS_REG)
6578         (compare
6579           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6580           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6581    (set (match_operand:DI 0 "register_operand" "=r")
6582         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6583   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6584    && ix86_binary_operator_ok (PLUS, SImode, operands)
6585    /* Current assemblers are broken and do not allow @GOTOFF in
6586       ought but a memory context.  */
6587    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6589   switch (get_attr_type (insn))
6590     {
6591     case TYPE_INCDEC:
6592       if (operands[2] == const1_rtx)
6593         return "inc{l}\t%k0";
6594       else
6595         {
6596           gcc_assert (operands[2] == constm1_rtx);
6597           return "dec{l}\t%k0";
6598         }
6600     default:
6601       if (x86_maybe_negate_const_int (&operands[2], SImode))
6602         return "sub{l}\t{%2, %k0|%k0, %2}";
6604       return "add{l}\t{%2, %k0|%k0, %2}";
6605     }
6607   [(set (attr "type")
6608      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6609         (const_string "incdec")
6610         (const_string "alu")))
6611    (set (attr "length_immediate")
6612       (if_then_else
6613         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6614         (const_string "1")
6615         (const_string "*")))
6616    (set_attr "mode" "SI")])
6618 (define_insn "*addhi_3"
6619   [(set (reg FLAGS_REG)
6620         (compare
6621           (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6622           (match_operand:HI 1 "nonimmediate_operand" "%0")))
6623    (clobber (match_scratch:HI 0 "=r"))]
6624   "ix86_match_ccmode (insn, CCZmode)
6625    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6627   switch (get_attr_type (insn))
6628     {
6629     case TYPE_INCDEC:
6630       if (operands[2] == const1_rtx)
6631         return "inc{w}\t%0";
6632       else
6633         {
6634           gcc_assert (operands[2] == constm1_rtx);
6635           return "dec{w}\t%0";
6636         }
6638     default:
6639       if (x86_maybe_negate_const_int (&operands[2], HImode))
6640         return "sub{w}\t{%2, %0|%0, %2}";
6642       return "add{w}\t{%2, %0|%0, %2}";
6643     }
6645   [(set (attr "type")
6646      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6647         (const_string "incdec")
6648         (const_string "alu")))
6649    (set (attr "length_immediate")
6650       (if_then_else
6651         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6652         (const_string "1")
6653         (const_string "*")))
6654    (set_attr "mode" "HI")])
6656 (define_insn "*addqi_3"
6657   [(set (reg FLAGS_REG)
6658         (compare
6659           (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6660           (match_operand:QI 1 "nonimmediate_operand" "%0")))
6661    (clobber (match_scratch:QI 0 "=q"))]
6662   "ix86_match_ccmode (insn, CCZmode)
6663    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6665   switch (get_attr_type (insn))
6666     {
6667     case TYPE_INCDEC:
6668       if (operands[2] == const1_rtx)
6669         return "inc{b}\t%0";
6670       else
6671         {
6672           gcc_assert (operands[2] == constm1_rtx
6673                       || (CONST_INT_P (operands[2])
6674                           && INTVAL (operands[2]) == 255));
6675           return "dec{b}\t%0";
6676         }
6678     default:
6679       if (x86_maybe_negate_const_int (&operands[2], QImode))
6680         return "sub{b}\t{%2, %0|%0, %2}";
6682       return "add{b}\t{%2, %0|%0, %2}";
6683     }
6685   [(set (attr "type")
6686      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6687         (const_string "incdec")
6688         (const_string "alu")))
6689    (set_attr "mode" "QI")])
6691 ; For comparisons against 1, -1 and 128, we may generate better code
6692 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6693 ; is matched then.  We can't accept general immediate, because for
6694 ; case of overflows,  the result is messed up.
6695 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6696 ; only for comparisons not depending on it.
6698 (define_insn "*adddi_4"
6699   [(set (reg FLAGS_REG)
6700         (compare
6701           (match_operand:DI 1 "nonimmediate_operand" "0")
6702           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6703    (clobber (match_scratch:DI 0 "=rm"))]
6704   "TARGET_64BIT
6705    && ix86_match_ccmode (insn, CCGCmode)"
6707   switch (get_attr_type (insn))
6708     {
6709     case TYPE_INCDEC:
6710       if (operands[2] == constm1_rtx)
6711         return "inc{q}\t%0";
6712       else
6713         {
6714           gcc_assert (operands[2] == const1_rtx);
6715           return "dec{q}\t%0";
6716         }
6718     default:
6719       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6720       if (x86_maybe_negate_const_int (&operands[2], DImode))
6721         return "add{q}\t{%2, %0|%0, %2}";
6723       return "sub{q}\t{%2, %0|%0, %2}";
6724     }
6726   [(set (attr "type")
6727      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6728         (const_string "incdec")
6729         (const_string "alu")))
6730    (set (attr "length_immediate")
6731       (if_then_else
6732         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6733         (const_string "1")
6734         (const_string "*")))
6735    (set_attr "mode" "DI")])
6737 ; For comparisons against 1, -1 and 128, we may generate better code
6738 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6739 ; is matched then.  We can't accept general immediate, because for
6740 ; case of overflows,  the result is messed up.
6741 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6742 ; only for comparisons not depending on it.
6744 (define_insn "*addsi_4"
6745   [(set (reg FLAGS_REG)
6746         (compare
6747           (match_operand:SI 1 "nonimmediate_operand" "0")
6748           (match_operand:SI 2 "const_int_operand" "n")))
6749    (clobber (match_scratch:SI 0 "=rm"))]
6750   "ix86_match_ccmode (insn, CCGCmode)"
6752   switch (get_attr_type (insn))
6753     {
6754     case TYPE_INCDEC:
6755       if (operands[2] == constm1_rtx)
6756         return "inc{l}\t%0";
6757       else
6758         {
6759           gcc_assert (operands[2] == const1_rtx);
6760           return "dec{l}\t%0";
6761         }
6763     default:
6764       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6765       if (x86_maybe_negate_const_int (&operands[2], SImode))
6766         return "add{l}\t{%2, %0|%0, %2}";
6768       return "sub{l}\t{%2, %0|%0, %2}";
6769     }
6771   [(set (attr "type")
6772      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6773         (const_string "incdec")
6774         (const_string "alu")))
6775    (set (attr "length_immediate")
6776       (if_then_else
6777         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6778         (const_string "1")
6779         (const_string "*")))
6780    (set_attr "mode" "SI")])
6782 ; See comments above addsi_4 for details.
6784 (define_insn "*addhi_4"
6785   [(set (reg FLAGS_REG)
6786         (compare
6787           (match_operand:HI 1 "nonimmediate_operand" "0")
6788           (match_operand:HI 2 "const_int_operand" "n")))
6789    (clobber (match_scratch:HI 0 "=rm"))]
6790   "ix86_match_ccmode (insn, CCGCmode)"
6792   switch (get_attr_type (insn))
6793     {
6794     case TYPE_INCDEC:
6795       if (operands[2] == constm1_rtx)
6796         return "inc{w}\t%0";
6797       else
6798         {
6799           gcc_assert (operands[2] == const1_rtx);
6800           return "dec{w}\t%0";
6801         }
6803     default:
6804       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6805       if (x86_maybe_negate_const_int (&operands[2], HImode))
6806         return "add{w}\t{%2, %0|%0, %2}";
6808       return "sub{w}\t{%2, %0|%0, %2}";
6809     }
6811   [(set (attr "type")
6812      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6813         (const_string "incdec")
6814         (const_string "alu")))
6815    (set (attr "length_immediate")
6816       (if_then_else
6817         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6818         (const_string "1")
6819         (const_string "*")))
6820    (set_attr "mode" "HI")])
6822 ; See comments above addsi_4 for details.
6824 (define_insn "*addqi_4"
6825   [(set (reg FLAGS_REG)
6826         (compare
6827           (match_operand:QI 1 "nonimmediate_operand" "0")
6828           (match_operand:QI 2 "const_int_operand" "n")))
6829    (clobber (match_scratch:QI 0 "=qm"))]
6830   "ix86_match_ccmode (insn, CCGCmode)"
6832   switch (get_attr_type (insn))
6833     {
6834     case TYPE_INCDEC:
6835       if (operands[2] == constm1_rtx
6836           || (CONST_INT_P (operands[2])
6837               && INTVAL (operands[2]) == 255))
6838         return "inc{b}\t%0";
6839       else
6840         {
6841           gcc_assert (operands[2] == const1_rtx);
6842           return "dec{b}\t%0";
6843         }
6845     default:
6846       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6847       if (x86_maybe_negate_const_int (&operands[2], QImode))
6848         return "add{b}\t{%2, %0|%0, %2}";
6850       return "sub{b}\t{%2, %0|%0, %2}";
6851     }
6853   [(set (attr "type")
6854      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6855         (const_string "incdec")
6856         (const_string "alu")))
6857    (set_attr "mode" "QI")])
6859 (define_insn "*add<mode>_5"
6860   [(set (reg FLAGS_REG)
6861         (compare
6862           (plus:SWI48
6863             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6864             (match_operand:SWI48 2 "<general_operand>" "<g>"))
6865           (const_int 0)))
6866    (clobber (match_scratch:SWI48 0 "=r"))]
6867   "ix86_match_ccmode (insn, CCGOCmode)
6868    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6869    /* Current assemblers are broken and do not allow @GOTOFF in
6870       ought but a memory context.  */
6871    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6873   switch (get_attr_type (insn))
6874     {
6875     case TYPE_INCDEC:
6876       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6877       if (operands[2] == const1_rtx)
6878         return "inc{<imodesuffix>}\t%0";
6879       else
6880         {
6881           gcc_assert (operands[2] == constm1_rtx);
6882           return "dec{<imodesuffix>}\t%0";
6883         }
6885     default:
6886       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6887       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6888         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6890       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6891     }
6893   [(set (attr "type")
6894      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6895         (const_string "incdec")
6896         (const_string "alu")))
6897    (set (attr "length_immediate")
6898       (if_then_else
6899         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6900         (const_string "1")
6901         (const_string "*")))
6902    (set_attr "mode" "<MODE>")])
6904 (define_insn "*addhi_5"
6905   [(set (reg FLAGS_REG)
6906         (compare
6907           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6908                    (match_operand:HI 2 "general_operand" "rmn"))
6909           (const_int 0)))
6910    (clobber (match_scratch:HI 0 "=r"))]
6911   "ix86_match_ccmode (insn, CCGOCmode)
6912    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6914   switch (get_attr_type (insn))
6915     {
6916     case TYPE_INCDEC:
6917       if (operands[2] == const1_rtx)
6918         return "inc{w}\t%0";
6919       else
6920         {
6921           gcc_assert (operands[2] == constm1_rtx);
6922           return "dec{w}\t%0";
6923         }
6925     default:
6926       if (x86_maybe_negate_const_int (&operands[2], HImode))
6927         return "sub{w}\t{%2, %0|%0, %2}";
6929       return "add{w}\t{%2, %0|%0, %2}";
6930     }
6932   [(set (attr "type")
6933      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6934         (const_string "incdec")
6935         (const_string "alu")))
6936    (set (attr "length_immediate")
6937       (if_then_else
6938         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6939         (const_string "1")
6940         (const_string "*")))
6941    (set_attr "mode" "HI")])
6943 (define_insn "*addqi_5"
6944   [(set (reg FLAGS_REG)
6945         (compare
6946           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6947                    (match_operand:QI 2 "general_operand" "qmn"))
6948           (const_int 0)))
6949    (clobber (match_scratch:QI 0 "=q"))]
6950   "ix86_match_ccmode (insn, CCGOCmode)
6951    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6953   switch (get_attr_type (insn))
6954     {
6955     case TYPE_INCDEC:
6956       if (operands[2] == const1_rtx)
6957         return "inc{b}\t%0";
6958       else
6959         {
6960           gcc_assert (operands[2] == constm1_rtx
6961                       || (CONST_INT_P (operands[2])
6962                           && INTVAL (operands[2]) == 255));
6963           return "dec{b}\t%0";
6964         }
6966     default:
6967       if (x86_maybe_negate_const_int (&operands[2], QImode))
6968         return "sub{b}\t{%2, %0|%0, %2}";
6970       return "add{b}\t{%2, %0|%0, %2}";
6971     }
6973   [(set (attr "type")
6974      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6975         (const_string "incdec")
6976         (const_string "alu")))
6977    (set_attr "mode" "QI")])
6979 (define_insn "*addqi_ext_1_rex64"
6980   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6981                          (const_int 8)
6982                          (const_int 8))
6983         (plus:SI
6984           (zero_extract:SI
6985             (match_operand 1 "ext_register_operand" "0")
6986             (const_int 8)
6987             (const_int 8))
6988           (match_operand:QI 2 "nonmemory_operand" "Qn")))
6989    (clobber (reg:CC FLAGS_REG))]
6990   "TARGET_64BIT"
6992   switch (get_attr_type (insn))
6993     {
6994     case TYPE_INCDEC:
6995       if (operands[2] == const1_rtx)
6996         return "inc{b}\t%h0";
6997       else
6998         {
6999           gcc_assert (operands[2] == constm1_rtx
7000                       || (CONST_INT_P (operands[2])
7001                           && INTVAL (operands[2]) == 255));
7002           return "dec{b}\t%h0";
7003         }
7005     default:
7006       return "add{b}\t{%2, %h0|%h0, %2}";
7007     }
7009   [(set (attr "type")
7010      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7011         (const_string "incdec")
7012         (const_string "alu")))
7013    (set_attr "modrm" "1")
7014    (set_attr "mode" "QI")])
7016 (define_insn "addqi_ext_1"
7017   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7018                          (const_int 8)
7019                          (const_int 8))
7020         (plus:SI
7021           (zero_extract:SI
7022             (match_operand 1 "ext_register_operand" "0")
7023             (const_int 8)
7024             (const_int 8))
7025           (match_operand:QI 2 "general_operand" "Qmn")))
7026    (clobber (reg:CC FLAGS_REG))]
7027   "!TARGET_64BIT"
7029   switch (get_attr_type (insn))
7030     {
7031     case TYPE_INCDEC:
7032       if (operands[2] == const1_rtx)
7033         return "inc{b}\t%h0";
7034       else
7035         {
7036           gcc_assert (operands[2] == constm1_rtx
7037                       || (CONST_INT_P (operands[2])
7038                           && INTVAL (operands[2]) == 255));
7039           return "dec{b}\t%h0";
7040         }
7042     default:
7043       return "add{b}\t{%2, %h0|%h0, %2}";
7044     }
7046   [(set (attr "type")
7047      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7048         (const_string "incdec")
7049         (const_string "alu")))
7050    (set_attr "modrm" "1")
7051    (set_attr "mode" "QI")])
7053 (define_insn "*addqi_ext_2"
7054   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7055                          (const_int 8)
7056                          (const_int 8))
7057         (plus:SI
7058           (zero_extract:SI
7059             (match_operand 1 "ext_register_operand" "%0")
7060             (const_int 8)
7061             (const_int 8))
7062           (zero_extract:SI
7063             (match_operand 2 "ext_register_operand" "Q")
7064             (const_int 8)
7065             (const_int 8))))
7066    (clobber (reg:CC FLAGS_REG))]
7067   ""
7068   "add{b}\t{%h2, %h0|%h0, %h2}"
7069   [(set_attr "type" "alu")
7070    (set_attr "mode" "QI")])
7072 ;; The lea patterns for non-Pmodes needs to be matched by
7073 ;; several insns converted to real lea by splitters.
7075 (define_insn_and_split "*lea_general_1"
7076   [(set (match_operand 0 "register_operand" "=r")
7077         (plus (plus (match_operand 1 "index_register_operand" "l")
7078                     (match_operand 2 "register_operand" "r"))
7079               (match_operand 3 "immediate_operand" "i")))]
7080   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7081     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7082    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7083    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7084    && GET_MODE (operands[0]) == GET_MODE (operands[2])
7085    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7086        || GET_MODE (operands[3]) == VOIDmode)"
7087   "#"
7088   "&& reload_completed"
7089   [(const_int 0)]
7091   rtx pat;
7092   operands[0] = gen_lowpart (SImode, operands[0]);
7093   operands[1] = gen_lowpart (Pmode, operands[1]);
7094   operands[2] = gen_lowpart (Pmode, operands[2]);
7095   operands[3] = gen_lowpart (Pmode, operands[3]);
7096   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7097                       operands[3]);
7098   if (Pmode != SImode)
7099     pat = gen_rtx_SUBREG (SImode, pat, 0);
7100   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7101   DONE;
7103   [(set_attr "type" "lea")
7104    (set_attr "mode" "SI")])
7106 (define_insn_and_split "*lea_general_1_zext"
7107   [(set (match_operand:DI 0 "register_operand" "=r")
7108         (zero_extend:DI
7109           (plus:SI (plus:SI
7110                      (match_operand:SI 1 "index_register_operand" "l")
7111                      (match_operand:SI 2 "register_operand" "r"))
7112                    (match_operand:SI 3 "immediate_operand" "i"))))]
7113   "TARGET_64BIT"
7114   "#"
7115   "&& reload_completed"
7116   [(set (match_dup 0)
7117         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7118                                                      (match_dup 2))
7119                                             (match_dup 3)) 0)))]
7121   operands[1] = gen_lowpart (Pmode, operands[1]);
7122   operands[2] = gen_lowpart (Pmode, operands[2]);
7123   operands[3] = gen_lowpart (Pmode, operands[3]);
7125   [(set_attr "type" "lea")
7126    (set_attr "mode" "SI")])
7128 (define_insn_and_split "*lea_general_2"
7129   [(set (match_operand 0 "register_operand" "=r")
7130         (plus (mult (match_operand 1 "index_register_operand" "l")
7131                     (match_operand 2 "const248_operand" "i"))
7132               (match_operand 3 "nonmemory_operand" "ri")))]
7133   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7134     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7135    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7136    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7137    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7138        || GET_MODE (operands[3]) == VOIDmode)"
7139   "#"
7140   "&& reload_completed"
7141   [(const_int 0)]
7143   rtx pat;
7144   operands[0] = gen_lowpart (SImode, operands[0]);
7145   operands[1] = gen_lowpart (Pmode, operands[1]);
7146   operands[3] = gen_lowpart (Pmode, operands[3]);
7147   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7148                       operands[3]);
7149   if (Pmode != SImode)
7150     pat = gen_rtx_SUBREG (SImode, pat, 0);
7151   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7152   DONE;
7154   [(set_attr "type" "lea")
7155    (set_attr "mode" "SI")])
7157 (define_insn_and_split "*lea_general_2_zext"
7158   [(set (match_operand:DI 0 "register_operand" "=r")
7159         (zero_extend:DI
7160           (plus:SI (mult:SI
7161                      (match_operand:SI 1 "index_register_operand" "l")
7162                      (match_operand:SI 2 "const248_operand" "n"))
7163                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7164   "TARGET_64BIT"
7165   "#"
7166   "&& reload_completed"
7167   [(set (match_dup 0)
7168         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7169                                                      (match_dup 2))
7170                                             (match_dup 3)) 0)))]
7172   operands[1] = gen_lowpart (Pmode, operands[1]);
7173   operands[3] = gen_lowpart (Pmode, operands[3]);
7175   [(set_attr "type" "lea")
7176    (set_attr "mode" "SI")])
7178 (define_insn_and_split "*lea_general_3"
7179   [(set (match_operand 0 "register_operand" "=r")
7180         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7181                           (match_operand 2 "const248_operand" "i"))
7182                     (match_operand 3 "register_operand" "r"))
7183               (match_operand 4 "immediate_operand" "i")))]
7184   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7185     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7186    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7187    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7188    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7189   "#"
7190   "&& reload_completed"
7191   [(const_int 0)]
7193   rtx pat;
7194   operands[0] = gen_lowpart (SImode, operands[0]);
7195   operands[1] = gen_lowpart (Pmode, operands[1]);
7196   operands[3] = gen_lowpart (Pmode, operands[3]);
7197   operands[4] = gen_lowpart (Pmode, operands[4]);
7198   pat = gen_rtx_PLUS (Pmode,
7199                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7200                                                          operands[2]),
7201                                     operands[3]),
7202                       operands[4]);
7203   if (Pmode != SImode)
7204     pat = gen_rtx_SUBREG (SImode, pat, 0);
7205   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7206   DONE;
7208   [(set_attr "type" "lea")
7209    (set_attr "mode" "SI")])
7211 (define_insn_and_split "*lea_general_3_zext"
7212   [(set (match_operand:DI 0 "register_operand" "=r")
7213         (zero_extend:DI
7214           (plus:SI (plus:SI
7215                      (mult:SI
7216                        (match_operand:SI 1 "index_register_operand" "l")
7217                        (match_operand:SI 2 "const248_operand" "n"))
7218                      (match_operand:SI 3 "register_operand" "r"))
7219                    (match_operand:SI 4 "immediate_operand" "i"))))]
7220   "TARGET_64BIT"
7221   "#"
7222   "&& reload_completed"
7223   [(set (match_dup 0)
7224         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7225                                                               (match_dup 2))
7226                                                      (match_dup 3))
7227                                             (match_dup 4)) 0)))]
7229   operands[1] = gen_lowpart (Pmode, operands[1]);
7230   operands[3] = gen_lowpart (Pmode, operands[3]);
7231   operands[4] = gen_lowpart (Pmode, operands[4]);
7233   [(set_attr "type" "lea")
7234    (set_attr "mode" "SI")])
7236 ;; Convert lea to the lea pattern to avoid flags dependency.
7237 (define_split
7238   [(set (match_operand:DI 0 "register_operand" "")
7239         (plus:DI (match_operand:DI 1 "register_operand" "")
7240                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7241    (clobber (reg:CC FLAGS_REG))]
7242   "TARGET_64BIT && reload_completed 
7243    && ix86_lea_for_add_ok (PLUS, insn, operands)"
7244   [(set (match_dup 0)
7245         (plus:DI (match_dup 1)
7246                  (match_dup 2)))]
7247   "")
7249 ;; Convert lea to the lea pattern to avoid flags dependency.
7250 (define_split
7251   [(set (match_operand 0 "register_operand" "")
7252         (plus (match_operand 1 "register_operand" "")
7253               (match_operand 2 "nonmemory_operand" "")))
7254    (clobber (reg:CC FLAGS_REG))]
7255   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
7256   [(const_int 0)]
7258   rtx pat;
7259   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7260      may confuse gen_lowpart.  */
7261   if (GET_MODE (operands[0]) != Pmode)
7262     {
7263       operands[1] = gen_lowpart (Pmode, operands[1]);
7264       operands[2] = gen_lowpart (Pmode, operands[2]);
7265     }
7266   operands[0] = gen_lowpart (SImode, operands[0]);
7267   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7268   if (Pmode != SImode)
7269     pat = gen_rtx_SUBREG (SImode, pat, 0);
7270   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7271   DONE;
7274 ;; Convert lea to the lea pattern to avoid flags dependency.
7275 (define_split
7276   [(set (match_operand:DI 0 "register_operand" "")
7277         (zero_extend:DI
7278           (plus:SI (match_operand:SI 1 "register_operand" "")
7279                    (match_operand:SI 2 "nonmemory_operand" ""))))
7280    (clobber (reg:CC FLAGS_REG))]
7281   "TARGET_64BIT && reload_completed
7282    && true_regnum (operands[0]) != true_regnum (operands[1])"
7283   [(set (match_dup 0)
7284         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7286   operands[1] = gen_lowpart (Pmode, operands[1]);
7287   operands[2] = gen_lowpart (Pmode, operands[2]);
7290 ;; Subtract instructions
7292 (define_expand "sub<mode>3"
7293   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7294         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7295                      (match_operand:SDWIM 2 "<general_operand>" "")))]
7296   ""
7297   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7299 (define_insn_and_split "*sub<dwi>3_doubleword"
7300   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7301         (minus:<DWI>
7302           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7303           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7304    (clobber (reg:CC FLAGS_REG))]
7305   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7306   "#"
7307   "reload_completed"
7308   [(parallel [(set (reg:CC FLAGS_REG)
7309                    (compare:CC (match_dup 1) (match_dup 2)))
7310               (set (match_dup 0)
7311                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7312    (parallel [(set (match_dup 3)
7313                    (minus:DWIH
7314                      (match_dup 4)
7315                      (plus:DWIH
7316                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7317                        (match_dup 5))))
7318               (clobber (reg:CC FLAGS_REG))])]
7319   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7321 (define_insn "*sub<mode>_1"
7322   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7323         (minus:SWI
7324           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7325           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7326    (clobber (reg:CC FLAGS_REG))]
7327   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7328   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7329   [(set_attr "type" "alu")
7330    (set_attr "mode" "<MODE>")])
7332 (define_insn "*subsi_1_zext"
7333   [(set (match_operand:DI 0 "register_operand" "=r")
7334         (zero_extend:DI
7335           (minus:SI (match_operand:SI 1 "register_operand" "0")
7336                     (match_operand:SI 2 "general_operand" "g"))))
7337    (clobber (reg:CC FLAGS_REG))]
7338   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7339   "sub{l}\t{%2, %k0|%k0, %2}"
7340   [(set_attr "type" "alu")
7341    (set_attr "mode" "SI")])
7343 (define_insn "*subqi_1_slp"
7344   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7345         (minus:QI (match_dup 0)
7346                   (match_operand:QI 1 "general_operand" "qn,qm")))
7347    (clobber (reg:CC FLAGS_REG))]
7348   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7349    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7350   "sub{b}\t{%1, %0|%0, %1}"
7351   [(set_attr "type" "alu1")
7352    (set_attr "mode" "QI")])
7354 (define_insn "*sub<mode>_2"
7355   [(set (reg FLAGS_REG)
7356         (compare
7357           (minus:SWI
7358             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7359             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7360           (const_int 0)))
7361    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7362         (minus:SWI (match_dup 1) (match_dup 2)))]
7363   "ix86_match_ccmode (insn, CCGOCmode)
7364    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7365   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7366   [(set_attr "type" "alu")
7367    (set_attr "mode" "<MODE>")])
7369 (define_insn "*subsi_2_zext"
7370   [(set (reg FLAGS_REG)
7371         (compare
7372           (minus:SI (match_operand:SI 1 "register_operand" "0")
7373                     (match_operand:SI 2 "general_operand" "g"))
7374           (const_int 0)))
7375    (set (match_operand:DI 0 "register_operand" "=r")
7376         (zero_extend:DI
7377           (minus:SI (match_dup 1)
7378                     (match_dup 2))))]
7379   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7380    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7381   "sub{l}\t{%2, %k0|%k0, %2}"
7382   [(set_attr "type" "alu")
7383    (set_attr "mode" "SI")])
7385 (define_insn "*sub<mode>_3"
7386   [(set (reg FLAGS_REG)
7387         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7388                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7389    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7390         (minus:SWI (match_dup 1) (match_dup 2)))]
7391   "ix86_match_ccmode (insn, CCmode)
7392    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7393   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7394   [(set_attr "type" "alu")
7395    (set_attr "mode" "<MODE>")])
7397 (define_insn "*subsi_3_zext"
7398   [(set (reg FLAGS_REG)
7399         (compare (match_operand:SI 1 "register_operand" "0")
7400                  (match_operand:SI 2 "general_operand" "g")))
7401    (set (match_operand:DI 0 "register_operand" "=r")
7402         (zero_extend:DI
7403           (minus:SI (match_dup 1)
7404                     (match_dup 2))))]
7405   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7406    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7407   "sub{l}\t{%2, %1|%1, %2}"
7408   [(set_attr "type" "alu")
7409    (set_attr "mode" "SI")])
7411 ;; Add with carry and subtract with borrow
7413 (define_expand "<plusminus_insn><mode>3_carry"
7414   [(parallel
7415     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7416           (plusminus:SWI
7417             (match_operand:SWI 1 "nonimmediate_operand" "")
7418             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7419                        [(match_operand 3 "flags_reg_operand" "")
7420                         (const_int 0)])
7421                       (match_operand:SWI 2 "<general_operand>" ""))))
7422      (clobber (reg:CC FLAGS_REG))])]
7423   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7424   "")
7426 (define_insn "*<plusminus_insn><mode>3_carry"
7427   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7428         (plusminus:SWI
7429           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7430           (plus:SWI
7431             (match_operator 3 "ix86_carry_flag_operator"
7432              [(reg FLAGS_REG) (const_int 0)])
7433             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7434    (clobber (reg:CC FLAGS_REG))]
7435   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7436   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7437   [(set_attr "type" "alu")
7438    (set_attr "use_carry" "1")
7439    (set_attr "pent_pair" "pu")
7440    (set_attr "mode" "<MODE>")])
7442 (define_insn "*addsi3_carry_zext"
7443   [(set (match_operand:DI 0 "register_operand" "=r")
7444         (zero_extend:DI
7445           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7446                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7447                              [(reg FLAGS_REG) (const_int 0)])
7448                             (match_operand:SI 2 "general_operand" "g")))))
7449    (clobber (reg:CC FLAGS_REG))]
7450   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7451   "adc{l}\t{%2, %k0|%k0, %2}"
7452   [(set_attr "type" "alu")
7453    (set_attr "use_carry" "1")
7454    (set_attr "pent_pair" "pu")
7455    (set_attr "mode" "SI")])
7457 (define_insn "*subsi3_carry_zext"
7458   [(set (match_operand:DI 0 "register_operand" "=r")
7459         (zero_extend:DI
7460           (minus:SI (match_operand:SI 1 "register_operand" "0")
7461                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7462                               [(reg FLAGS_REG) (const_int 0)])
7463                              (match_operand:SI 2 "general_operand" "g")))))
7464    (clobber (reg:CC FLAGS_REG))]
7465   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7466   "sbb{l}\t{%2, %k0|%k0, %2}"
7467   [(set_attr "type" "alu")
7468    (set_attr "pent_pair" "pu")
7469    (set_attr "mode" "SI")])
7471 ;; Overflow setting add and subtract instructions
7473 (define_insn "*add<mode>3_cconly_overflow"
7474   [(set (reg:CCC FLAGS_REG)
7475         (compare:CCC
7476           (plus:SWI
7477             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7478             (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7479           (match_dup 1)))
7480    (clobber (match_scratch:SWI 0 "=<r>"))]
7481   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7482   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7483   [(set_attr "type" "alu")
7484    (set_attr "mode" "<MODE>")])
7486 (define_insn "*sub<mode>3_cconly_overflow"
7487   [(set (reg:CCC FLAGS_REG)
7488         (compare:CCC
7489           (minus:SWI
7490             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7491             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7492           (match_dup 0)))]
7493   ""
7494   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7495   [(set_attr "type" "icmp")
7496    (set_attr "mode" "<MODE>")])
7498 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7499   [(set (reg:CCC FLAGS_REG)
7500         (compare:CCC
7501             (plusminus:SWI
7502                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7503                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7504             (match_dup 1)))
7505    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7506         (plusminus:SWI (match_dup 1) (match_dup 2)))]
7507   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7508   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7509   [(set_attr "type" "alu")
7510    (set_attr "mode" "<MODE>")])
7512 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7513   [(set (reg:CCC FLAGS_REG)
7514         (compare:CCC
7515           (plusminus:SI
7516             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7517             (match_operand:SI 2 "general_operand" "g"))
7518           (match_dup 1)))
7519    (set (match_operand:DI 0 "register_operand" "=r")
7520         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7521   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7522   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7523   [(set_attr "type" "alu")
7524    (set_attr "mode" "SI")])
7526 ;; The patterns that match these are at the end of this file.
7528 (define_expand "<plusminus_insn>xf3"
7529   [(set (match_operand:XF 0 "register_operand" "")
7530         (plusminus:XF
7531           (match_operand:XF 1 "register_operand" "")
7532           (match_operand:XF 2 "register_operand" "")))]
7533   "TARGET_80387"
7534   "")
7536 (define_expand "<plusminus_insn><mode>3"
7537   [(set (match_operand:MODEF 0 "register_operand" "")
7538         (plusminus:MODEF
7539           (match_operand:MODEF 1 "register_operand" "")
7540           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7541   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7542     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7543   "")
7545 ;; Multiply instructions
7547 (define_expand "mul<mode>3"
7548   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7549                    (mult:SWIM248
7550                      (match_operand:SWIM248 1 "register_operand" "")
7551                      (match_operand:SWIM248 2 "<general_operand>" "")))
7552               (clobber (reg:CC FLAGS_REG))])]
7553   ""
7554   "")
7556 (define_expand "mulqi3"
7557   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7558                    (mult:QI
7559                      (match_operand:QI 1 "register_operand" "")
7560                      (match_operand:QI 2 "nonimmediate_operand" "")))
7561               (clobber (reg:CC FLAGS_REG))])]
7562   "TARGET_QIMODE_MATH"
7563   "")
7565 ;; On AMDFAM10
7566 ;; IMUL reg32/64, reg32/64, imm8        Direct
7567 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7568 ;; IMUL reg32/64, reg32/64, imm32       Direct
7569 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7570 ;; IMUL reg32/64, reg32/64              Direct
7571 ;; IMUL reg32/64, mem32/64              Direct
7573 (define_insn "*mul<mode>3_1"
7574   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7575         (mult:SWI48
7576           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7577           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7578    (clobber (reg:CC FLAGS_REG))]
7579   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7580   "@
7581    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7582    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7583    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7584   [(set_attr "type" "imul")
7585    (set_attr "prefix_0f" "0,0,1")
7586    (set (attr "athlon_decode")
7587         (cond [(eq_attr "cpu" "athlon")
7588                   (const_string "vector")
7589                (eq_attr "alternative" "1")
7590                   (const_string "vector")
7591                (and (eq_attr "alternative" "2")
7592                     (match_operand 1 "memory_operand" ""))
7593                   (const_string "vector")]
7594               (const_string "direct")))
7595    (set (attr "amdfam10_decode")
7596         (cond [(and (eq_attr "alternative" "0,1")
7597                     (match_operand 1 "memory_operand" ""))
7598                   (const_string "vector")]
7599               (const_string "direct")))
7600    (set_attr "mode" "<MODE>")])
7602 (define_insn "*mulsi3_1_zext"
7603   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7604         (zero_extend:DI
7605           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7606                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7607    (clobber (reg:CC FLAGS_REG))]
7608   "TARGET_64BIT
7609    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7610   "@
7611    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7612    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7613    imul{l}\t{%2, %k0|%k0, %2}"
7614   [(set_attr "type" "imul")
7615    (set_attr "prefix_0f" "0,0,1")
7616    (set (attr "athlon_decode")
7617         (cond [(eq_attr "cpu" "athlon")
7618                   (const_string "vector")
7619                (eq_attr "alternative" "1")
7620                   (const_string "vector")
7621                (and (eq_attr "alternative" "2")
7622                     (match_operand 1 "memory_operand" ""))
7623                   (const_string "vector")]
7624               (const_string "direct")))
7625    (set (attr "amdfam10_decode")
7626         (cond [(and (eq_attr "alternative" "0,1")
7627                     (match_operand 1 "memory_operand" ""))
7628                   (const_string "vector")]
7629               (const_string "direct")))
7630    (set_attr "mode" "SI")])
7632 ;; On AMDFAM10
7633 ;; IMUL reg16, reg16, imm8      VectorPath
7634 ;; IMUL reg16, mem16, imm8      VectorPath
7635 ;; IMUL reg16, reg16, imm16     VectorPath
7636 ;; IMUL reg16, mem16, imm16     VectorPath
7637 ;; IMUL reg16, reg16            Direct
7638 ;; IMUL reg16, mem16            Direct
7640 (define_insn "*mulhi3_1"
7641   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7642         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7643                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7644    (clobber (reg:CC FLAGS_REG))]
7645   "TARGET_HIMODE_MATH
7646    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7647   "@
7648    imul{w}\t{%2, %1, %0|%0, %1, %2}
7649    imul{w}\t{%2, %1, %0|%0, %1, %2}
7650    imul{w}\t{%2, %0|%0, %2}"
7651   [(set_attr "type" "imul")
7652    (set_attr "prefix_0f" "0,0,1")
7653    (set (attr "athlon_decode")
7654         (cond [(eq_attr "cpu" "athlon")
7655                   (const_string "vector")
7656                (eq_attr "alternative" "1,2")
7657                   (const_string "vector")]
7658               (const_string "direct")))
7659    (set (attr "amdfam10_decode")
7660         (cond [(eq_attr "alternative" "0,1")
7661                   (const_string "vector")]
7662               (const_string "direct")))
7663    (set_attr "mode" "HI")])
7665 ;;On AMDFAM10
7666 ;; MUL reg8     Direct
7667 ;; MUL mem8     Direct
7669 (define_insn "*mulqi3_1"
7670   [(set (match_operand:QI 0 "register_operand" "=a")
7671         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7672                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7673    (clobber (reg:CC FLAGS_REG))]
7674   "TARGET_QIMODE_MATH
7675    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7676   "mul{b}\t%2"
7677   [(set_attr "type" "imul")
7678    (set_attr "length_immediate" "0")
7679    (set (attr "athlon_decode")
7680      (if_then_else (eq_attr "cpu" "athlon")
7681         (const_string "vector")
7682         (const_string "direct")))
7683    (set_attr "amdfam10_decode" "direct")
7684    (set_attr "mode" "QI")])
7686 (define_expand "<u>mul<mode><dwi>3"
7687   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7688                    (mult:<DWI>
7689                      (any_extend:<DWI>
7690                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7691                      (any_extend:<DWI>
7692                        (match_operand:DWIH 2 "register_operand" ""))))
7693               (clobber (reg:CC FLAGS_REG))])]
7694   ""
7695   "")
7697 (define_expand "<u>mulqihi3"
7698   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7699                    (mult:HI
7700                      (any_extend:HI
7701                        (match_operand:QI 1 "nonimmediate_operand" ""))
7702                      (any_extend:HI
7703                        (match_operand:QI 2 "register_operand" ""))))
7704               (clobber (reg:CC FLAGS_REG))])]
7705   "TARGET_QIMODE_MATH"
7706   "")
7708 (define_insn "*<u>mul<mode><dwi>3_1"
7709   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7710         (mult:<DWI>
7711           (any_extend:<DWI>
7712             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7713           (any_extend:<DWI>
7714             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7715    (clobber (reg:CC FLAGS_REG))]
7716   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7717   "<sgnprefix>mul{<imodesuffix>}\t%2"
7718   [(set_attr "type" "imul")
7719    (set_attr "length_immediate" "0")
7720    (set (attr "athlon_decode")
7721      (if_then_else (eq_attr "cpu" "athlon")
7722         (const_string "vector")
7723         (const_string "double")))
7724    (set_attr "amdfam10_decode" "double")
7725    (set_attr "mode" "<MODE>")])
7727 (define_insn "*<u>mulqihi3_1"
7728   [(set (match_operand:HI 0 "register_operand" "=a")
7729         (mult:HI
7730           (any_extend:HI
7731             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7732           (any_extend:HI
7733             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7734    (clobber (reg:CC FLAGS_REG))]
7735   "TARGET_QIMODE_MATH
7736    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7737   "<sgnprefix>mul{b}\t%2"
7738   [(set_attr "type" "imul")
7739    (set_attr "length_immediate" "0")
7740    (set (attr "athlon_decode")
7741      (if_then_else (eq_attr "cpu" "athlon")
7742         (const_string "vector")
7743         (const_string "direct")))
7744    (set_attr "amdfam10_decode" "direct")
7745    (set_attr "mode" "QI")])
7747 (define_expand "<s>mul<mode>3_highpart"
7748   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7749                    (truncate:SWI48
7750                      (lshiftrt:<DWI>
7751                        (mult:<DWI>
7752                          (any_extend:<DWI>
7753                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7754                          (any_extend:<DWI>
7755                            (match_operand:SWI48 2 "register_operand" "")))
7756                        (match_dup 4))))
7757               (clobber (match_scratch:SWI48 3 ""))
7758               (clobber (reg:CC FLAGS_REG))])]
7759   ""
7760   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7762 (define_insn "*<s>muldi3_highpart_1"
7763   [(set (match_operand:DI 0 "register_operand" "=d")
7764         (truncate:DI
7765           (lshiftrt:TI
7766             (mult:TI
7767               (any_extend:TI
7768                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7769               (any_extend:TI
7770                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7771             (const_int 64))))
7772    (clobber (match_scratch:DI 3 "=1"))
7773    (clobber (reg:CC FLAGS_REG))]
7774   "TARGET_64BIT
7775    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7776   "<sgnprefix>mul{q}\t%2"
7777   [(set_attr "type" "imul")
7778    (set_attr "length_immediate" "0")
7779    (set (attr "athlon_decode")
7780      (if_then_else (eq_attr "cpu" "athlon")
7781         (const_string "vector")
7782         (const_string "double")))
7783    (set_attr "amdfam10_decode" "double")
7784    (set_attr "mode" "DI")])
7786 (define_insn "*<s>mulsi3_highpart_1"
7787   [(set (match_operand:SI 0 "register_operand" "=d")
7788         (truncate:SI
7789           (lshiftrt:DI
7790             (mult:DI
7791               (any_extend:DI
7792                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7793               (any_extend:DI
7794                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7795             (const_int 32))))
7796    (clobber (match_scratch:SI 3 "=1"))
7797    (clobber (reg:CC FLAGS_REG))]
7798   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7799   "<sgnprefix>mul{l}\t%2"
7800   [(set_attr "type" "imul")
7801    (set_attr "length_immediate" "0")
7802    (set (attr "athlon_decode")
7803      (if_then_else (eq_attr "cpu" "athlon")
7804         (const_string "vector")
7805         (const_string "double")))
7806    (set_attr "amdfam10_decode" "double")
7807    (set_attr "mode" "SI")])
7809 (define_insn "*<s>mulsi3_highpart_zext"
7810   [(set (match_operand:DI 0 "register_operand" "=d")
7811         (zero_extend:DI (truncate:SI
7812           (lshiftrt:DI
7813             (mult:DI (any_extend:DI
7814                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7815                      (any_extend:DI
7816                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7817             (const_int 32)))))
7818    (clobber (match_scratch:SI 3 "=1"))
7819    (clobber (reg:CC FLAGS_REG))]
7820   "TARGET_64BIT
7821    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7822   "<sgnprefix>mul{l}\t%2"
7823   [(set_attr "type" "imul")
7824    (set_attr "length_immediate" "0")
7825    (set (attr "athlon_decode")
7826      (if_then_else (eq_attr "cpu" "athlon")
7827         (const_string "vector")
7828         (const_string "double")))
7829    (set_attr "amdfam10_decode" "double")
7830    (set_attr "mode" "SI")])
7832 ;; The patterns that match these are at the end of this file.
7834 (define_expand "mulxf3"
7835   [(set (match_operand:XF 0 "register_operand" "")
7836         (mult:XF (match_operand:XF 1 "register_operand" "")
7837                  (match_operand:XF 2 "register_operand" "")))]
7838   "TARGET_80387"
7839   "")
7841 (define_expand "mul<mode>3"
7842   [(set (match_operand:MODEF 0 "register_operand" "")
7843         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7844                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7845   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7846     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7847   "")
7849 ;; Divide instructions
7851 (define_insn "<u>divqi3"
7852   [(set (match_operand:QI 0 "register_operand" "=a")
7853         (any_div:QI
7854           (match_operand:HI 1 "register_operand" "0")
7855           (match_operand:QI 2 "nonimmediate_operand" "qm")))
7856    (clobber (reg:CC FLAGS_REG))]
7857   "TARGET_QIMODE_MATH"
7858   "<sgnprefix>div{b}\t%2"
7859   [(set_attr "type" "idiv")
7860    (set_attr "mode" "QI")])
7862 ;; The patterns that match these are at the end of this file.
7864 (define_expand "divxf3"
7865   [(set (match_operand:XF 0 "register_operand" "")
7866         (div:XF (match_operand:XF 1 "register_operand" "")
7867                 (match_operand:XF 2 "register_operand" "")))]
7868   "TARGET_80387"
7869   "")
7871 (define_expand "divdf3"
7872   [(set (match_operand:DF 0 "register_operand" "")
7873         (div:DF (match_operand:DF 1 "register_operand" "")
7874                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7875    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7876     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7877    "")
7879 (define_expand "divsf3"
7880   [(set (match_operand:SF 0 "register_operand" "")
7881         (div:SF (match_operand:SF 1 "register_operand" "")
7882                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7883   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7884     || TARGET_SSE_MATH"
7886   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7887       && flag_finite_math_only && !flag_trapping_math
7888       && flag_unsafe_math_optimizations)
7889     {
7890       ix86_emit_swdivsf (operands[0], operands[1],
7891                          operands[2], SFmode);
7892       DONE;
7893     }
7896 ;; Divmod instructions.
7898 (define_expand "divmod<mode>4"
7899   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7900                    (div:SWIM248
7901                      (match_operand:SWIM248 1 "register_operand" "")
7902                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7903               (set (match_operand:SWIM248 3 "register_operand" "")
7904                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
7905               (clobber (reg:CC FLAGS_REG))])]
7906   ""
7907   "")
7909 (define_insn_and_split "*divmod<mode>4"
7910   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7911         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7912                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7913    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7914         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7915    (clobber (reg:CC FLAGS_REG))]
7916   ""
7917   "#"
7918   "&& reload_completed"
7919   [(parallel [(set (match_dup 1)
7920                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7921               (clobber (reg:CC FLAGS_REG))])
7922    (parallel [(set (match_dup 0)
7923                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7924               (set (match_dup 1)
7925                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7926               (use (match_dup 1))
7927               (clobber (reg:CC FLAGS_REG))])]
7929   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
7931   if (<MODE>mode != HImode
7932       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7933     operands[4] = operands[2];
7934   else
7935     {
7936       /* Avoid use of cltd in favor of a mov+shift.  */
7937       emit_move_insn (operands[1], operands[2]);
7938       operands[4] = operands[1];
7939     }
7941   [(set_attr "type" "multi")
7942    (set_attr "mode" "<MODE>")])
7944 (define_insn "*divmod<mode>4_noext"
7945   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7946         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7947                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7948    (set (match_operand:SWIM248 1 "register_operand" "=d")
7949         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7950    (use (match_operand:SWIM248 4 "register_operand" "1"))
7951    (clobber (reg:CC FLAGS_REG))]
7952   ""
7953   "idiv{<imodesuffix>}\t%3"
7954   [(set_attr "type" "idiv")
7955    (set_attr "mode" "<MODE>")])
7957 (define_expand "udivmod<mode>4"
7958   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7959                    (udiv:SWIM248
7960                      (match_operand:SWIM248 1 "register_operand" "")
7961                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7962               (set (match_operand:SWIM248 3 "register_operand" "")
7963                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7964               (clobber (reg:CC FLAGS_REG))])]
7965   ""
7966   "")
7968 (define_insn_and_split "*udivmod<mode>4"
7969   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7970         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7971                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7972    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7973         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7974    (clobber (reg:CC FLAGS_REG))]
7975   ""
7976   "#"
7977   "&& reload_completed"
7978   [(set (match_dup 1) (const_int 0))
7979    (parallel [(set (match_dup 0)
7980                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7981               (set (match_dup 1)
7982                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7983               (use (match_dup 1))
7984               (clobber (reg:CC FLAGS_REG))])]
7985   ""
7986   [(set_attr "type" "multi")
7987    (set_attr "mode" "<MODE>")])
7989 (define_insn "*udivmod<mode>4_noext"
7990   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7991         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7992                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7993    (set (match_operand:SWIM248 1 "register_operand" "=d")
7994         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7995    (use (match_operand:SWIM248 4 "register_operand" "1"))
7996    (clobber (reg:CC FLAGS_REG))]
7997   ""
7998   "div{<imodesuffix>}\t%3"
7999   [(set_attr "type" "idiv")
8000    (set_attr "mode" "<MODE>")])
8002 ;; We cannot use div/idiv for double division, because it causes
8003 ;; "division by zero" on the overflow and that's not what we expect
8004 ;; from truncate.  Because true (non truncating) double division is
8005 ;; never generated, we can't create this insn anyway.
8007 ;(define_insn ""
8008 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8009 ;       (truncate:SI
8010 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8011 ;                  (zero_extend:DI
8012 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8013 ;   (set (match_operand:SI 3 "register_operand" "=d")
8014 ;       (truncate:SI
8015 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8016 ;   (clobber (reg:CC FLAGS_REG))]
8017 ;  ""
8018 ;  "div{l}\t{%2, %0|%0, %2}"
8019 ;  [(set_attr "type" "idiv")])
8021 ;;- Logical AND instructions
8023 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8024 ;; Note that this excludes ah.
8026 (define_expand "testsi_ccno_1"
8027   [(set (reg:CCNO FLAGS_REG)
8028         (compare:CCNO
8029           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8030                   (match_operand:SI 1 "nonmemory_operand" ""))
8031           (const_int 0)))]
8032   ""
8033   "")
8035 (define_expand "testqi_ccz_1"
8036   [(set (reg:CCZ FLAGS_REG)
8037         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8038                              (match_operand:QI 1 "nonmemory_operand" ""))
8039                  (const_int 0)))]
8040   ""
8041   "")
8043 (define_insn "*testdi_1"
8044   [(set (reg FLAGS_REG)
8045         (compare
8046          (and:DI
8047           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8048           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8049          (const_int 0)))]
8050   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8051    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8052   "@
8053    test{l}\t{%k1, %k0|%k0, %k1}
8054    test{l}\t{%k1, %k0|%k0, %k1}
8055    test{q}\t{%1, %0|%0, %1}
8056    test{q}\t{%1, %0|%0, %1}
8057    test{q}\t{%1, %0|%0, %1}"
8058   [(set_attr "type" "test")
8059    (set_attr "modrm" "0,1,0,1,1")
8060    (set_attr "mode" "SI,SI,DI,DI,DI")])
8062 (define_insn "*testqi_1_maybe_si"
8063   [(set (reg FLAGS_REG)
8064         (compare
8065           (and:QI
8066             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8067             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8068           (const_int 0)))]
8069    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8070     && ix86_match_ccmode (insn,
8071                          CONST_INT_P (operands[1])
8072                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8074   if (which_alternative == 3)
8075     {
8076       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8077         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8078       return "test{l}\t{%1, %k0|%k0, %1}";
8079     }
8080   return "test{b}\t{%1, %0|%0, %1}";
8082   [(set_attr "type" "test")
8083    (set_attr "modrm" "0,1,1,1")
8084    (set_attr "mode" "QI,QI,QI,SI")
8085    (set_attr "pent_pair" "uv,np,uv,np")])
8087 (define_insn "*test<mode>_1"
8088   [(set (reg FLAGS_REG)
8089         (compare
8090          (and:SWI124
8091           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8092           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8093          (const_int 0)))]
8094   "ix86_match_ccmode (insn, CCNOmode)
8095    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8096   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8097   [(set_attr "type" "test")
8098    (set_attr "modrm" "0,1,1")
8099    (set_attr "mode" "<MODE>")
8100    (set_attr "pent_pair" "uv,np,uv")])
8102 (define_expand "testqi_ext_ccno_0"
8103   [(set (reg:CCNO FLAGS_REG)
8104         (compare:CCNO
8105           (and:SI
8106             (zero_extract:SI
8107               (match_operand 0 "ext_register_operand" "")
8108               (const_int 8)
8109               (const_int 8))
8110             (match_operand 1 "const_int_operand" ""))
8111           (const_int 0)))]
8112   ""
8113   "")
8115 (define_insn "*testqi_ext_0"
8116   [(set (reg FLAGS_REG)
8117         (compare
8118           (and:SI
8119             (zero_extract:SI
8120               (match_operand 0 "ext_register_operand" "Q")
8121               (const_int 8)
8122               (const_int 8))
8123             (match_operand 1 "const_int_operand" "n"))
8124           (const_int 0)))]
8125   "ix86_match_ccmode (insn, CCNOmode)"
8126   "test{b}\t{%1, %h0|%h0, %1}"
8127   [(set_attr "type" "test")
8128    (set_attr "mode" "QI")
8129    (set_attr "length_immediate" "1")
8130    (set_attr "modrm" "1")
8131    (set_attr "pent_pair" "np")])
8133 (define_insn "*testqi_ext_1_rex64"
8134   [(set (reg FLAGS_REG)
8135         (compare
8136           (and:SI
8137             (zero_extract:SI
8138               (match_operand 0 "ext_register_operand" "Q")
8139               (const_int 8)
8140               (const_int 8))
8141             (zero_extend:SI
8142               (match_operand:QI 1 "register_operand" "Q")))
8143           (const_int 0)))]
8144   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8145   "test{b}\t{%1, %h0|%h0, %1}"
8146   [(set_attr "type" "test")
8147    (set_attr "mode" "QI")])
8149 (define_insn "*testqi_ext_1"
8150   [(set (reg FLAGS_REG)
8151         (compare
8152           (and:SI
8153             (zero_extract:SI
8154               (match_operand 0 "ext_register_operand" "Q")
8155               (const_int 8)
8156               (const_int 8))
8157             (zero_extend:SI
8158               (match_operand:QI 1 "general_operand" "Qm")))
8159           (const_int 0)))]
8160   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8161   "test{b}\t{%1, %h0|%h0, %1}"
8162   [(set_attr "type" "test")
8163    (set_attr "mode" "QI")])
8165 (define_insn "*testqi_ext_2"
8166   [(set (reg FLAGS_REG)
8167         (compare
8168           (and:SI
8169             (zero_extract:SI
8170               (match_operand 0 "ext_register_operand" "Q")
8171               (const_int 8)
8172               (const_int 8))
8173             (zero_extract:SI
8174               (match_operand 1 "ext_register_operand" "Q")
8175               (const_int 8)
8176               (const_int 8)))
8177           (const_int 0)))]
8178   "ix86_match_ccmode (insn, CCNOmode)"
8179   "test{b}\t{%h1, %h0|%h0, %h1}"
8180   [(set_attr "type" "test")
8181    (set_attr "mode" "QI")])
8183 (define_insn "*testqi_ext_3_rex64"
8184   [(set (reg FLAGS_REG)
8185         (compare (zero_extract:DI
8186                    (match_operand 0 "nonimmediate_operand" "rm")
8187                    (match_operand:DI 1 "const_int_operand" "")
8188                    (match_operand:DI 2 "const_int_operand" ""))
8189                  (const_int 0)))]
8190   "TARGET_64BIT
8191    && ix86_match_ccmode (insn, CCNOmode)
8192    && INTVAL (operands[1]) > 0
8193    && INTVAL (operands[2]) >= 0
8194    /* Ensure that resulting mask is zero or sign extended operand.  */
8195    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8196        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8197            && INTVAL (operands[1]) > 32))
8198    && (GET_MODE (operands[0]) == SImode
8199        || GET_MODE (operands[0]) == DImode
8200        || GET_MODE (operands[0]) == HImode
8201        || GET_MODE (operands[0]) == QImode)"
8202   "#")
8204 ;; Combine likes to form bit extractions for some tests.  Humor it.
8205 (define_insn "*testqi_ext_3"
8206   [(set (reg FLAGS_REG)
8207         (compare (zero_extract:SI
8208                    (match_operand 0 "nonimmediate_operand" "rm")
8209                    (match_operand:SI 1 "const_int_operand" "")
8210                    (match_operand:SI 2 "const_int_operand" ""))
8211                  (const_int 0)))]
8212   "ix86_match_ccmode (insn, CCNOmode)
8213    && INTVAL (operands[1]) > 0
8214    && INTVAL (operands[2]) >= 0
8215    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8216    && (GET_MODE (operands[0]) == SImode
8217        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8218        || GET_MODE (operands[0]) == HImode
8219        || GET_MODE (operands[0]) == QImode)"
8220   "#")
8222 (define_split
8223   [(set (match_operand 0 "flags_reg_operand" "")
8224         (match_operator 1 "compare_operator"
8225           [(zero_extract
8226              (match_operand 2 "nonimmediate_operand" "")
8227              (match_operand 3 "const_int_operand" "")
8228              (match_operand 4 "const_int_operand" ""))
8229            (const_int 0)]))]
8230   "ix86_match_ccmode (insn, CCNOmode)"
8231   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8233   rtx val = operands[2];
8234   HOST_WIDE_INT len = INTVAL (operands[3]);
8235   HOST_WIDE_INT pos = INTVAL (operands[4]);
8236   HOST_WIDE_INT mask;
8237   enum machine_mode mode, submode;
8239   mode = GET_MODE (val);
8240   if (MEM_P (val))
8241     {
8242       /* ??? Combine likes to put non-volatile mem extractions in QImode
8243          no matter the size of the test.  So find a mode that works.  */
8244       if (! MEM_VOLATILE_P (val))
8245         {
8246           mode = smallest_mode_for_size (pos + len, MODE_INT);
8247           val = adjust_address (val, mode, 0);
8248         }
8249     }
8250   else if (GET_CODE (val) == SUBREG
8251            && (submode = GET_MODE (SUBREG_REG (val)),
8252                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8253            && pos + len <= GET_MODE_BITSIZE (submode)
8254            && GET_MODE_CLASS (submode) == MODE_INT)
8255     {
8256       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8257       mode = submode;
8258       val = SUBREG_REG (val);
8259     }
8260   else if (mode == HImode && pos + len <= 8)
8261     {
8262       /* Small HImode tests can be converted to QImode.  */
8263       mode = QImode;
8264       val = gen_lowpart (QImode, val);
8265     }
8267   if (len == HOST_BITS_PER_WIDE_INT)
8268     mask = -1;
8269   else
8270     mask = ((HOST_WIDE_INT)1 << len) - 1;
8271   mask <<= pos;
8273   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8276 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8277 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8278 ;; this is relatively important trick.
8279 ;; Do the conversion only post-reload to avoid limiting of the register class
8280 ;; to QI regs.
8281 (define_split
8282   [(set (match_operand 0 "flags_reg_operand" "")
8283         (match_operator 1 "compare_operator"
8284           [(and (match_operand 2 "register_operand" "")
8285                 (match_operand 3 "const_int_operand" ""))
8286            (const_int 0)]))]
8287    "reload_completed
8288     && QI_REG_P (operands[2])
8289     && GET_MODE (operands[2]) != QImode
8290     && ((ix86_match_ccmode (insn, CCZmode)
8291          && !(INTVAL (operands[3]) & ~(255 << 8)))
8292         || (ix86_match_ccmode (insn, CCNOmode)
8293             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8294   [(set (match_dup 0)
8295         (match_op_dup 1
8296           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8297                    (match_dup 3))
8298            (const_int 0)]))]
8299   "operands[2] = gen_lowpart (SImode, operands[2]);
8300    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8302 (define_split
8303   [(set (match_operand 0 "flags_reg_operand" "")
8304         (match_operator 1 "compare_operator"
8305           [(and (match_operand 2 "nonimmediate_operand" "")
8306                 (match_operand 3 "const_int_operand" ""))
8307            (const_int 0)]))]
8308    "reload_completed
8309     && GET_MODE (operands[2]) != QImode
8310     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8311     && ((ix86_match_ccmode (insn, CCZmode)
8312          && !(INTVAL (operands[3]) & ~255))
8313         || (ix86_match_ccmode (insn, CCNOmode)
8314             && !(INTVAL (operands[3]) & ~127)))"
8315   [(set (match_dup 0)
8316         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8317                          (const_int 0)]))]
8318   "operands[2] = gen_lowpart (QImode, operands[2]);
8319    operands[3] = gen_lowpart (QImode, operands[3]);")
8321 ;; %%% This used to optimize known byte-wide and operations to memory,
8322 ;; and sometimes to QImode registers.  If this is considered useful,
8323 ;; it should be done with splitters.
8325 (define_expand "and<mode>3"
8326   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8327         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8328                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8329   ""
8330   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8332 (define_insn "*anddi_1"
8333   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8334         (and:DI
8335          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8336          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8337    (clobber (reg:CC FLAGS_REG))]
8338   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8340   switch (get_attr_type (insn))
8341     {
8342     case TYPE_IMOVX:
8343       {
8344         enum machine_mode mode;
8346         gcc_assert (CONST_INT_P (operands[2]));
8347         if (INTVAL (operands[2]) == 0xff)
8348           mode = QImode;
8349         else
8350           {
8351             gcc_assert (INTVAL (operands[2]) == 0xffff);
8352             mode = HImode;
8353           }
8355         operands[1] = gen_lowpart (mode, operands[1]);
8356         if (mode == QImode)
8357           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8358         else
8359           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8360       }
8362     default:
8363       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8364       if (get_attr_mode (insn) == MODE_SI)
8365         return "and{l}\t{%k2, %k0|%k0, %k2}";
8366       else
8367         return "and{q}\t{%2, %0|%0, %2}";
8368     }
8370   [(set_attr "type" "alu,alu,alu,imovx")
8371    (set_attr "length_immediate" "*,*,*,0")
8372    (set (attr "prefix_rex")
8373      (if_then_else
8374        (and (eq_attr "type" "imovx")
8375             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8376                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8377        (const_string "1")
8378        (const_string "*")))
8379    (set_attr "mode" "SI,DI,DI,SI")])
8381 (define_insn "*andsi_1"
8382   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8383         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8384                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8385    (clobber (reg:CC FLAGS_REG))]
8386   "ix86_binary_operator_ok (AND, SImode, operands)"
8388   switch (get_attr_type (insn))
8389     {
8390     case TYPE_IMOVX:
8391       {
8392         enum machine_mode mode;
8394         gcc_assert (CONST_INT_P (operands[2]));
8395         if (INTVAL (operands[2]) == 0xff)
8396           mode = QImode;
8397         else
8398           {
8399             gcc_assert (INTVAL (operands[2]) == 0xffff);
8400             mode = HImode;
8401           }
8403         operands[1] = gen_lowpart (mode, operands[1]);
8404         if (mode == QImode)
8405           return "movz{bl|x}\t{%1, %0|%0, %1}";
8406         else
8407           return "movz{wl|x}\t{%1, %0|%0, %1}";
8408       }
8410     default:
8411       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8412       return "and{l}\t{%2, %0|%0, %2}";
8413     }
8415   [(set_attr "type" "alu,alu,imovx")
8416    (set (attr "prefix_rex")
8417      (if_then_else
8418        (and (eq_attr "type" "imovx")
8419             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8420                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8421        (const_string "1")
8422        (const_string "*")))
8423    (set_attr "length_immediate" "*,*,0")
8424    (set_attr "mode" "SI")])
8426 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8427 (define_insn "*andsi_1_zext"
8428   [(set (match_operand:DI 0 "register_operand" "=r")
8429         (zero_extend:DI
8430           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8431                   (match_operand:SI 2 "general_operand" "g"))))
8432    (clobber (reg:CC FLAGS_REG))]
8433   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8434   "and{l}\t{%2, %k0|%k0, %2}"
8435   [(set_attr "type" "alu")
8436    (set_attr "mode" "SI")])
8438 (define_insn "*andhi_1"
8439   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8440         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8441                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8442    (clobber (reg:CC FLAGS_REG))]
8443   "ix86_binary_operator_ok (AND, HImode, operands)"
8445   switch (get_attr_type (insn))
8446     {
8447     case TYPE_IMOVX:
8448       gcc_assert (CONST_INT_P (operands[2]));
8449       gcc_assert (INTVAL (operands[2]) == 0xff);
8450       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8452     default:
8453       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8455       return "and{w}\t{%2, %0|%0, %2}";
8456     }
8458   [(set_attr "type" "alu,alu,imovx")
8459    (set_attr "length_immediate" "*,*,0")
8460    (set (attr "prefix_rex")
8461      (if_then_else
8462        (and (eq_attr "type" "imovx")
8463             (match_operand 1 "ext_QIreg_nomode_operand" ""))
8464        (const_string "1")
8465        (const_string "*")))
8466    (set_attr "mode" "HI,HI,SI")])
8468 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8469 (define_insn "*andqi_1"
8470   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8471         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8472                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8473    (clobber (reg:CC FLAGS_REG))]
8474   "ix86_binary_operator_ok (AND, QImode, operands)"
8475   "@
8476    and{b}\t{%2, %0|%0, %2}
8477    and{b}\t{%2, %0|%0, %2}
8478    and{l}\t{%k2, %k0|%k0, %k2}"
8479   [(set_attr "type" "alu")
8480    (set_attr "mode" "QI,QI,SI")])
8482 (define_insn "*andqi_1_slp"
8483   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8484         (and:QI (match_dup 0)
8485                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8486    (clobber (reg:CC FLAGS_REG))]
8487   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8488    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8489   "and{b}\t{%1, %0|%0, %1}"
8490   [(set_attr "type" "alu1")
8491    (set_attr "mode" "QI")])
8493 (define_split
8494   [(set (match_operand 0 "register_operand" "")
8495         (and (match_dup 0)
8496              (const_int -65536)))
8497    (clobber (reg:CC FLAGS_REG))]
8498   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8499     || optimize_function_for_size_p (cfun)"
8500   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8501   "operands[1] = gen_lowpart (HImode, operands[0]);")
8503 (define_split
8504   [(set (match_operand 0 "ext_register_operand" "")
8505         (and (match_dup 0)
8506              (const_int -256)))
8507    (clobber (reg:CC FLAGS_REG))]
8508   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8509    && reload_completed"
8510   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8511   "operands[1] = gen_lowpart (QImode, operands[0]);")
8513 (define_split
8514   [(set (match_operand 0 "ext_register_operand" "")
8515         (and (match_dup 0)
8516              (const_int -65281)))
8517    (clobber (reg:CC FLAGS_REG))]
8518   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8519    && reload_completed"
8520   [(parallel [(set (zero_extract:SI (match_dup 0)
8521                                     (const_int 8)
8522                                     (const_int 8))
8523                    (xor:SI
8524                      (zero_extract:SI (match_dup 0)
8525                                       (const_int 8)
8526                                       (const_int 8))
8527                      (zero_extract:SI (match_dup 0)
8528                                       (const_int 8)
8529                                       (const_int 8))))
8530               (clobber (reg:CC FLAGS_REG))])]
8531   "operands[0] = gen_lowpart (SImode, operands[0]);")
8533 (define_insn "*anddi_2"
8534   [(set (reg FLAGS_REG)
8535         (compare
8536          (and:DI
8537           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8538           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8539          (const_int 0)))
8540    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8541         (and:DI (match_dup 1) (match_dup 2)))]
8542   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8543    && ix86_binary_operator_ok (AND, DImode, operands)"
8544   "@
8545    and{l}\t{%k2, %k0|%k0, %k2}
8546    and{q}\t{%2, %0|%0, %2}
8547    and{q}\t{%2, %0|%0, %2}"
8548   [(set_attr "type" "alu")
8549    (set_attr "mode" "SI,DI,DI")])
8551 (define_insn "*andqi_2_maybe_si"
8552   [(set (reg FLAGS_REG)
8553         (compare (and:QI
8554                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8555                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8556                  (const_int 0)))
8557    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8558         (and:QI (match_dup 1) (match_dup 2)))]
8559   "ix86_binary_operator_ok (AND, QImode, operands)
8560    && ix86_match_ccmode (insn,
8561                          CONST_INT_P (operands[2])
8562                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8564   if (which_alternative == 2)
8565     {
8566       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8567         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8568       return "and{l}\t{%2, %k0|%k0, %2}";
8569     }
8570   return "and{b}\t{%2, %0|%0, %2}";
8572   [(set_attr "type" "alu")
8573    (set_attr "mode" "QI,QI,SI")])
8575 (define_insn "*and<mode>_2"
8576   [(set (reg FLAGS_REG)
8577         (compare (and:SWI124
8578                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8579                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8580                  (const_int 0)))
8581    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8582         (and:SWI124 (match_dup 1) (match_dup 2)))]
8583   "ix86_match_ccmode (insn, CCNOmode)
8584    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8585   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8586   [(set_attr "type" "alu")
8587    (set_attr "mode" "<MODE>")])
8589 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8590 (define_insn "*andsi_2_zext"
8591   [(set (reg FLAGS_REG)
8592         (compare (and:SI
8593                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8594                   (match_operand:SI 2 "general_operand" "g"))
8595                  (const_int 0)))
8596    (set (match_operand:DI 0 "register_operand" "=r")
8597         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8598   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8599    && ix86_binary_operator_ok (AND, SImode, operands)"
8600   "and{l}\t{%2, %k0|%k0, %2}"
8601   [(set_attr "type" "alu")
8602    (set_attr "mode" "SI")])
8604 (define_insn "*andqi_2_slp"
8605   [(set (reg FLAGS_REG)
8606         (compare (and:QI
8607                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8608                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8609                  (const_int 0)))
8610    (set (strict_low_part (match_dup 0))
8611         (and:QI (match_dup 0) (match_dup 1)))]
8612   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8613    && ix86_match_ccmode (insn, CCNOmode)
8614    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8615   "and{b}\t{%1, %0|%0, %1}"
8616   [(set_attr "type" "alu1")
8617    (set_attr "mode" "QI")])
8619 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8620 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8621 ;; for a QImode operand, which of course failed.
8622 (define_insn "andqi_ext_0"
8623   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8624                          (const_int 8)
8625                          (const_int 8))
8626         (and:SI
8627           (zero_extract:SI
8628             (match_operand 1 "ext_register_operand" "0")
8629             (const_int 8)
8630             (const_int 8))
8631           (match_operand 2 "const_int_operand" "n")))
8632    (clobber (reg:CC FLAGS_REG))]
8633   ""
8634   "and{b}\t{%2, %h0|%h0, %2}"
8635   [(set_attr "type" "alu")
8636    (set_attr "length_immediate" "1")
8637    (set_attr "modrm" "1")
8638    (set_attr "mode" "QI")])
8640 ;; Generated by peephole translating test to and.  This shows up
8641 ;; often in fp comparisons.
8642 (define_insn "*andqi_ext_0_cc"
8643   [(set (reg FLAGS_REG)
8644         (compare
8645           (and:SI
8646             (zero_extract:SI
8647               (match_operand 1 "ext_register_operand" "0")
8648               (const_int 8)
8649               (const_int 8))
8650             (match_operand 2 "const_int_operand" "n"))
8651           (const_int 0)))
8652    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8653                          (const_int 8)
8654                          (const_int 8))
8655         (and:SI
8656           (zero_extract:SI
8657             (match_dup 1)
8658             (const_int 8)
8659             (const_int 8))
8660           (match_dup 2)))]
8661   "ix86_match_ccmode (insn, CCNOmode)"
8662   "and{b}\t{%2, %h0|%h0, %2}"
8663   [(set_attr "type" "alu")
8664    (set_attr "length_immediate" "1")
8665    (set_attr "modrm" "1")
8666    (set_attr "mode" "QI")])
8668 (define_insn "*andqi_ext_1_rex64"
8669   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8670                          (const_int 8)
8671                          (const_int 8))
8672         (and:SI
8673           (zero_extract:SI
8674             (match_operand 1 "ext_register_operand" "0")
8675             (const_int 8)
8676             (const_int 8))
8677           (zero_extend:SI
8678             (match_operand 2 "ext_register_operand" "Q"))))
8679    (clobber (reg:CC FLAGS_REG))]
8680   "TARGET_64BIT"
8681   "and{b}\t{%2, %h0|%h0, %2}"
8682   [(set_attr "type" "alu")
8683    (set_attr "length_immediate" "0")
8684    (set_attr "mode" "QI")])
8686 (define_insn "*andqi_ext_1"
8687   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8688                          (const_int 8)
8689                          (const_int 8))
8690         (and:SI
8691           (zero_extract:SI
8692             (match_operand 1 "ext_register_operand" "0")
8693             (const_int 8)
8694             (const_int 8))
8695           (zero_extend:SI
8696             (match_operand:QI 2 "general_operand" "Qm"))))
8697    (clobber (reg:CC FLAGS_REG))]
8698   "!TARGET_64BIT"
8699   "and{b}\t{%2, %h0|%h0, %2}"
8700   [(set_attr "type" "alu")
8701    (set_attr "length_immediate" "0")
8702    (set_attr "mode" "QI")])
8704 (define_insn "*andqi_ext_2"
8705   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8706                          (const_int 8)
8707                          (const_int 8))
8708         (and:SI
8709           (zero_extract:SI
8710             (match_operand 1 "ext_register_operand" "%0")
8711             (const_int 8)
8712             (const_int 8))
8713           (zero_extract:SI
8714             (match_operand 2 "ext_register_operand" "Q")
8715             (const_int 8)
8716             (const_int 8))))
8717    (clobber (reg:CC FLAGS_REG))]
8718   ""
8719   "and{b}\t{%h2, %h0|%h0, %h2}"
8720   [(set_attr "type" "alu")
8721    (set_attr "length_immediate" "0")
8722    (set_attr "mode" "QI")])
8724 ;; Convert wide AND instructions with immediate operand to shorter QImode
8725 ;; equivalents when possible.
8726 ;; Don't do the splitting with memory operands, since it introduces risk
8727 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8728 ;; for size, but that can (should?) be handled by generic code instead.
8729 (define_split
8730   [(set (match_operand 0 "register_operand" "")
8731         (and (match_operand 1 "register_operand" "")
8732              (match_operand 2 "const_int_operand" "")))
8733    (clobber (reg:CC FLAGS_REG))]
8734    "reload_completed
8735     && QI_REG_P (operands[0])
8736     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8737     && !(~INTVAL (operands[2]) & ~(255 << 8))
8738     && GET_MODE (operands[0]) != QImode"
8739   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8740                    (and:SI (zero_extract:SI (match_dup 1)
8741                                             (const_int 8) (const_int 8))
8742                            (match_dup 2)))
8743               (clobber (reg:CC FLAGS_REG))])]
8744   "operands[0] = gen_lowpart (SImode, operands[0]);
8745    operands[1] = gen_lowpart (SImode, operands[1]);
8746    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8748 ;; Since AND can be encoded with sign extended immediate, this is only
8749 ;; profitable when 7th bit is not set.
8750 (define_split
8751   [(set (match_operand 0 "register_operand" "")
8752         (and (match_operand 1 "general_operand" "")
8753              (match_operand 2 "const_int_operand" "")))
8754    (clobber (reg:CC FLAGS_REG))]
8755    "reload_completed
8756     && ANY_QI_REG_P (operands[0])
8757     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8758     && !(~INTVAL (operands[2]) & ~255)
8759     && !(INTVAL (operands[2]) & 128)
8760     && GET_MODE (operands[0]) != QImode"
8761   [(parallel [(set (strict_low_part (match_dup 0))
8762                    (and:QI (match_dup 1)
8763                            (match_dup 2)))
8764               (clobber (reg:CC FLAGS_REG))])]
8765   "operands[0] = gen_lowpart (QImode, operands[0]);
8766    operands[1] = gen_lowpart (QImode, operands[1]);
8767    operands[2] = gen_lowpart (QImode, operands[2]);")
8769 ;; Logical inclusive and exclusive OR instructions
8771 ;; %%% This used to optimize known byte-wide and operations to memory.
8772 ;; If this is considered useful, it should be done with splitters.
8774 (define_expand "<code><mode>3"
8775   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8776         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8777                      (match_operand:SWIM 2 "<general_operand>" "")))]
8778   ""
8779   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8781 (define_insn "*<code><mode>_1"
8782   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8783         (any_or:SWI248
8784          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8785          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8786    (clobber (reg:CC FLAGS_REG))]
8787   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8788   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8789   [(set_attr "type" "alu")
8790    (set_attr "mode" "<MODE>")])
8792 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8793 (define_insn "*<code>qi_1"
8794   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8795         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8796                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8797    (clobber (reg:CC FLAGS_REG))]
8798   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8799   "@
8800    <logic>{b}\t{%2, %0|%0, %2}
8801    <logic>{b}\t{%2, %0|%0, %2}
8802    <logic>{l}\t{%k2, %k0|%k0, %k2}"
8803   [(set_attr "type" "alu")
8804    (set_attr "mode" "QI,QI,SI")])
8806 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8807 (define_insn "*<code>si_1_zext"
8808   [(set (match_operand:DI 0 "register_operand" "=r")
8809         (zero_extend:DI
8810          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8811                     (match_operand:SI 2 "general_operand" "g"))))
8812    (clobber (reg:CC FLAGS_REG))]
8813   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8814   "<logic>{l}\t{%2, %k0|%k0, %2}"
8815   [(set_attr "type" "alu")
8816    (set_attr "mode" "SI")])
8818 (define_insn "*<code>si_1_zext_imm"
8819   [(set (match_operand:DI 0 "register_operand" "=r")
8820         (any_or:DI
8821          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8822          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8823    (clobber (reg:CC FLAGS_REG))]
8824   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8825   "<logic>{l}\t{%2, %k0|%k0, %2}"
8826   [(set_attr "type" "alu")
8827    (set_attr "mode" "SI")])
8829 (define_insn "*<code>qi_1_slp"
8830   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8831         (any_or:QI (match_dup 0)
8832                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8833    (clobber (reg:CC FLAGS_REG))]
8834   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8835    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8836   "<logic>{b}\t{%1, %0|%0, %1}"
8837   [(set_attr "type" "alu1")
8838    (set_attr "mode" "QI")])
8840 (define_insn "*<code><mode>_2"
8841   [(set (reg FLAGS_REG)
8842         (compare (any_or:SWI
8843                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8844                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8845                  (const_int 0)))
8846    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8847         (any_or:SWI (match_dup 1) (match_dup 2)))]
8848   "ix86_match_ccmode (insn, CCNOmode)
8849    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8850   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8851   [(set_attr "type" "alu")
8852    (set_attr "mode" "<MODE>")])
8854 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8855 ;; ??? Special case for immediate operand is missing - it is tricky.
8856 (define_insn "*<code>si_2_zext"
8857   [(set (reg FLAGS_REG)
8858         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8859                             (match_operand:SI 2 "general_operand" "g"))
8860                  (const_int 0)))
8861    (set (match_operand:DI 0 "register_operand" "=r")
8862         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8863   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8864    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8865   "<logic>{l}\t{%2, %k0|%k0, %2}"
8866   [(set_attr "type" "alu")
8867    (set_attr "mode" "SI")])
8869 (define_insn "*<code>si_2_zext_imm"
8870   [(set (reg FLAGS_REG)
8871         (compare (any_or:SI
8872                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8873                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8874                  (const_int 0)))
8875    (set (match_operand:DI 0 "register_operand" "=r")
8876         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8877   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8878    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8879   "<logic>{l}\t{%2, %k0|%k0, %2}"
8880   [(set_attr "type" "alu")
8881    (set_attr "mode" "SI")])
8883 (define_insn "*<code>qi_2_slp"
8884   [(set (reg FLAGS_REG)
8885         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8886                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8887                  (const_int 0)))
8888    (set (strict_low_part (match_dup 0))
8889         (any_or:QI (match_dup 0) (match_dup 1)))]
8890   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8891    && ix86_match_ccmode (insn, CCNOmode)
8892    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8893   "<logic>{b}\t{%1, %0|%0, %1}"
8894   [(set_attr "type" "alu1")
8895    (set_attr "mode" "QI")])
8897 (define_insn "*<code><mode>_3"
8898   [(set (reg FLAGS_REG)
8899         (compare (any_or:SWI
8900                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8901                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8902                  (const_int 0)))
8903    (clobber (match_scratch:SWI 0 "=<r>"))]
8904   "ix86_match_ccmode (insn, CCNOmode)
8905    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8906   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8907   [(set_attr "type" "alu")
8908    (set_attr "mode" "<MODE>")])
8910 (define_insn "*<code>qi_ext_0"
8911   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8912                          (const_int 8)
8913                          (const_int 8))
8914         (any_or:SI
8915           (zero_extract:SI
8916             (match_operand 1 "ext_register_operand" "0")
8917             (const_int 8)
8918             (const_int 8))
8919           (match_operand 2 "const_int_operand" "n")))
8920    (clobber (reg:CC FLAGS_REG))]
8921   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8922   "<logic>{b}\t{%2, %h0|%h0, %2}"
8923   [(set_attr "type" "alu")
8924    (set_attr "length_immediate" "1")
8925    (set_attr "modrm" "1")
8926    (set_attr "mode" "QI")])
8928 (define_insn "*<code>qi_ext_1_rex64"
8929   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8930                          (const_int 8)
8931                          (const_int 8))
8932         (any_or:SI
8933           (zero_extract:SI
8934             (match_operand 1 "ext_register_operand" "0")
8935             (const_int 8)
8936             (const_int 8))
8937           (zero_extend:SI
8938             (match_operand 2 "ext_register_operand" "Q"))))
8939    (clobber (reg:CC FLAGS_REG))]
8940   "TARGET_64BIT
8941    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8942   "<logic>{b}\t{%2, %h0|%h0, %2}"
8943   [(set_attr "type" "alu")
8944    (set_attr "length_immediate" "0")
8945    (set_attr "mode" "QI")])
8947 (define_insn "*<code>qi_ext_1"
8948   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8949                          (const_int 8)
8950                          (const_int 8))
8951         (any_or:SI
8952           (zero_extract:SI
8953             (match_operand 1 "ext_register_operand" "0")
8954             (const_int 8)
8955             (const_int 8))
8956           (zero_extend:SI
8957             (match_operand:QI 2 "general_operand" "Qm"))))
8958    (clobber (reg:CC FLAGS_REG))]
8959   "!TARGET_64BIT
8960    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8961   "<logic>{b}\t{%2, %h0|%h0, %2}"
8962   [(set_attr "type" "alu")
8963    (set_attr "length_immediate" "0")
8964    (set_attr "mode" "QI")])
8966 (define_insn "*<code>qi_ext_2"
8967   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8968                          (const_int 8)
8969                          (const_int 8))
8970         (any_or:SI
8971           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8972                            (const_int 8)
8973                            (const_int 8))
8974           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8975                            (const_int 8)
8976                            (const_int 8))))
8977    (clobber (reg:CC FLAGS_REG))]
8978   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8979   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8980   [(set_attr "type" "alu")
8981    (set_attr "length_immediate" "0")
8982    (set_attr "mode" "QI")])
8984 (define_split
8985   [(set (match_operand 0 "register_operand" "")
8986         (any_or (match_operand 1 "register_operand" "")
8987                 (match_operand 2 "const_int_operand" "")))
8988    (clobber (reg:CC FLAGS_REG))]
8989    "reload_completed
8990     && QI_REG_P (operands[0])
8991     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8992     && !(INTVAL (operands[2]) & ~(255 << 8))
8993     && GET_MODE (operands[0]) != QImode"
8994   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8995                    (any_or:SI (zero_extract:SI (match_dup 1)
8996                                                (const_int 8) (const_int 8))
8997                               (match_dup 2)))
8998               (clobber (reg:CC FLAGS_REG))])]
8999   "operands[0] = gen_lowpart (SImode, operands[0]);
9000    operands[1] = gen_lowpart (SImode, operands[1]);
9001    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9003 ;; Since OR can be encoded with sign extended immediate, this is only
9004 ;; profitable when 7th bit is set.
9005 (define_split
9006   [(set (match_operand 0 "register_operand" "")
9007         (any_or (match_operand 1 "general_operand" "")
9008                 (match_operand 2 "const_int_operand" "")))
9009    (clobber (reg:CC FLAGS_REG))]
9010    "reload_completed
9011     && ANY_QI_REG_P (operands[0])
9012     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9013     && !(INTVAL (operands[2]) & ~255)
9014     && (INTVAL (operands[2]) & 128)
9015     && GET_MODE (operands[0]) != QImode"
9016   [(parallel [(set (strict_low_part (match_dup 0))
9017                    (any_or:QI (match_dup 1)
9018                               (match_dup 2)))
9019               (clobber (reg:CC FLAGS_REG))])]
9020   "operands[0] = gen_lowpart (QImode, operands[0]);
9021    operands[1] = gen_lowpart (QImode, operands[1]);
9022    operands[2] = gen_lowpart (QImode, operands[2]);")
9024 (define_expand "xorqi_cc_ext_1"
9025   [(parallel [
9026      (set (reg:CCNO FLAGS_REG)
9027           (compare:CCNO
9028             (xor:SI
9029               (zero_extract:SI
9030                 (match_operand 1 "ext_register_operand" "")
9031                 (const_int 8)
9032                 (const_int 8))
9033               (match_operand:QI 2 "general_operand" ""))
9034             (const_int 0)))
9035      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9036                            (const_int 8)
9037                            (const_int 8))
9038           (xor:SI
9039             (zero_extract:SI
9040              (match_dup 1)
9041              (const_int 8)
9042              (const_int 8))
9043             (match_dup 2)))])]
9044   ""
9045   "")
9047 (define_insn "*xorqi_cc_ext_1_rex64"
9048   [(set (reg FLAGS_REG)
9049         (compare
9050           (xor:SI
9051             (zero_extract:SI
9052               (match_operand 1 "ext_register_operand" "0")
9053               (const_int 8)
9054               (const_int 8))
9055             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9056           (const_int 0)))
9057    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9058                          (const_int 8)
9059                          (const_int 8))
9060         (xor:SI
9061           (zero_extract:SI
9062            (match_dup 1)
9063            (const_int 8)
9064            (const_int 8))
9065           (match_dup 2)))]
9066   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9067   "xor{b}\t{%2, %h0|%h0, %2}"
9068   [(set_attr "type" "alu")
9069    (set_attr "modrm" "1")
9070    (set_attr "mode" "QI")])
9072 (define_insn "*xorqi_cc_ext_1"
9073   [(set (reg FLAGS_REG)
9074         (compare
9075           (xor:SI
9076             (zero_extract:SI
9077               (match_operand 1 "ext_register_operand" "0")
9078               (const_int 8)
9079               (const_int 8))
9080             (match_operand:QI 2 "general_operand" "qmn"))
9081           (const_int 0)))
9082    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9083                          (const_int 8)
9084                          (const_int 8))
9085         (xor:SI
9086           (zero_extract:SI
9087            (match_dup 1)
9088            (const_int 8)
9089            (const_int 8))
9090           (match_dup 2)))]
9091   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9092   "xor{b}\t{%2, %h0|%h0, %2}"
9093   [(set_attr "type" "alu")
9094    (set_attr "modrm" "1")
9095    (set_attr "mode" "QI")])
9097 ;; Negation instructions
9099 (define_expand "neg<mode>2"
9100   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9101         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9102   ""
9103   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9105 (define_insn_and_split "*neg<dwi>2_doubleword"
9106   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9107         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9108    (clobber (reg:CC FLAGS_REG))]
9109   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9110   "#"
9111   "reload_completed"
9112   [(parallel
9113     [(set (reg:CCZ FLAGS_REG)
9114           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9115      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9116    (parallel
9117     [(set (match_dup 2)
9118           (plus:DWIH (match_dup 3)
9119                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9120                                 (const_int 0))))
9121      (clobber (reg:CC FLAGS_REG))])
9122    (parallel
9123     [(set (match_dup 2)
9124           (neg:DWIH (match_dup 2)))
9125      (clobber (reg:CC FLAGS_REG))])]
9126   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9128 (define_insn "*neg<mode>2_1"
9129   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9130         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9131    (clobber (reg:CC FLAGS_REG))]
9132   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9133   "neg{<imodesuffix>}\t%0"
9134   [(set_attr "type" "negnot")
9135    (set_attr "mode" "<MODE>")])
9137 ;; Combine is quite creative about this pattern.
9138 (define_insn "*negsi2_1_zext"
9139   [(set (match_operand:DI 0 "register_operand" "=r")
9140         (lshiftrt:DI
9141           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9142                              (const_int 32)))
9143         (const_int 32)))
9144    (clobber (reg:CC FLAGS_REG))]
9145   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9146   "neg{l}\t%k0"
9147   [(set_attr "type" "negnot")
9148    (set_attr "mode" "SI")])
9150 ;; The problem with neg is that it does not perform (compare x 0),
9151 ;; it really performs (compare 0 x), which leaves us with the zero
9152 ;; flag being the only useful item.
9154 (define_insn "*neg<mode>2_cmpz"
9155   [(set (reg:CCZ FLAGS_REG)
9156         (compare:CCZ
9157           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9158                    (const_int 0)))
9159    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9160         (neg:SWI (match_dup 1)))]
9161   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9162   "neg{<imodesuffix>}\t%0"
9163   [(set_attr "type" "negnot")
9164    (set_attr "mode" "<MODE>")])
9166 (define_insn "*negsi2_cmpz_zext"
9167   [(set (reg:CCZ FLAGS_REG)
9168         (compare:CCZ
9169           (lshiftrt:DI
9170             (neg:DI (ashift:DI
9171                       (match_operand:DI 1 "register_operand" "0")
9172                       (const_int 32)))
9173             (const_int 32))
9174           (const_int 0)))
9175    (set (match_operand:DI 0 "register_operand" "=r")
9176         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9177                                         (const_int 32)))
9178                      (const_int 32)))]
9179   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9180   "neg{l}\t%k0"
9181   [(set_attr "type" "negnot")
9182    (set_attr "mode" "SI")])
9184 ;; Changing of sign for FP values is doable using integer unit too.
9186 (define_expand "<code><mode>2"
9187   [(set (match_operand:X87MODEF 0 "register_operand" "")
9188         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9189   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9190   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9192 (define_insn "*absneg<mode>2_mixed"
9193   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9194         (match_operator:MODEF 3 "absneg_operator"
9195           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9196    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9197    (clobber (reg:CC FLAGS_REG))]
9198   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9199   "#")
9201 (define_insn "*absneg<mode>2_sse"
9202   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9203         (match_operator:MODEF 3 "absneg_operator"
9204           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9205    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9206    (clobber (reg:CC FLAGS_REG))]
9207   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9208   "#")
9210 (define_insn "*absneg<mode>2_i387"
9211   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9212         (match_operator:X87MODEF 3 "absneg_operator"
9213           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9214    (use (match_operand 2 "" ""))
9215    (clobber (reg:CC FLAGS_REG))]
9216   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9217   "#")
9219 (define_expand "<code>tf2"
9220   [(set (match_operand:TF 0 "register_operand" "")
9221         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9222   "TARGET_SSE2"
9223   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9225 (define_insn "*absnegtf2_sse"
9226   [(set (match_operand:TF 0 "register_operand" "=x,x")
9227         (match_operator:TF 3 "absneg_operator"
9228           [(match_operand:TF 1 "register_operand" "0,x")]))
9229    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9230    (clobber (reg:CC FLAGS_REG))]
9231   "TARGET_SSE2"
9232   "#")
9234 ;; Splitters for fp abs and neg.
9236 (define_split
9237   [(set (match_operand 0 "fp_register_operand" "")
9238         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9239    (use (match_operand 2 "" ""))
9240    (clobber (reg:CC FLAGS_REG))]
9241   "reload_completed"
9242   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9244 (define_split
9245   [(set (match_operand 0 "register_operand" "")
9246         (match_operator 3 "absneg_operator"
9247           [(match_operand 1 "register_operand" "")]))
9248    (use (match_operand 2 "nonimmediate_operand" ""))
9249    (clobber (reg:CC FLAGS_REG))]
9250   "reload_completed && SSE_REG_P (operands[0])"
9251   [(set (match_dup 0) (match_dup 3))]
9253   enum machine_mode mode = GET_MODE (operands[0]);
9254   enum machine_mode vmode = GET_MODE (operands[2]);
9255   rtx tmp;
9257   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9258   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9259   if (operands_match_p (operands[0], operands[2]))
9260     {
9261       tmp = operands[1];
9262       operands[1] = operands[2];
9263       operands[2] = tmp;
9264     }
9265   if (GET_CODE (operands[3]) == ABS)
9266     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9267   else
9268     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9269   operands[3] = tmp;
9272 (define_split
9273   [(set (match_operand:SF 0 "register_operand" "")
9274         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9275    (use (match_operand:V4SF 2 "" ""))
9276    (clobber (reg:CC FLAGS_REG))]
9277   "reload_completed"
9278   [(parallel [(set (match_dup 0) (match_dup 1))
9279               (clobber (reg:CC FLAGS_REG))])]
9281   rtx tmp;
9282   operands[0] = gen_lowpart (SImode, operands[0]);
9283   if (GET_CODE (operands[1]) == ABS)
9284     {
9285       tmp = gen_int_mode (0x7fffffff, SImode);
9286       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9287     }
9288   else
9289     {
9290       tmp = gen_int_mode (0x80000000, SImode);
9291       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9292     }
9293   operands[1] = tmp;
9296 (define_split
9297   [(set (match_operand:DF 0 "register_operand" "")
9298         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9299    (use (match_operand 2 "" ""))
9300    (clobber (reg:CC FLAGS_REG))]
9301   "reload_completed"
9302   [(parallel [(set (match_dup 0) (match_dup 1))
9303               (clobber (reg:CC FLAGS_REG))])]
9305   rtx tmp;
9306   if (TARGET_64BIT)
9307     {
9308       tmp = gen_lowpart (DImode, operands[0]);
9309       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9310       operands[0] = tmp;
9312       if (GET_CODE (operands[1]) == ABS)
9313         tmp = const0_rtx;
9314       else
9315         tmp = gen_rtx_NOT (DImode, tmp);
9316     }
9317   else
9318     {
9319       operands[0] = gen_highpart (SImode, operands[0]);
9320       if (GET_CODE (operands[1]) == ABS)
9321         {
9322           tmp = gen_int_mode (0x7fffffff, SImode);
9323           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9324         }
9325       else
9326         {
9327           tmp = gen_int_mode (0x80000000, SImode);
9328           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9329         }
9330     }
9331   operands[1] = tmp;
9334 (define_split
9335   [(set (match_operand:XF 0 "register_operand" "")
9336         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9337    (use (match_operand 2 "" ""))
9338    (clobber (reg:CC FLAGS_REG))]
9339   "reload_completed"
9340   [(parallel [(set (match_dup 0) (match_dup 1))
9341               (clobber (reg:CC FLAGS_REG))])]
9343   rtx tmp;
9344   operands[0] = gen_rtx_REG (SImode,
9345                              true_regnum (operands[0])
9346                              + (TARGET_64BIT ? 1 : 2));
9347   if (GET_CODE (operands[1]) == ABS)
9348     {
9349       tmp = GEN_INT (0x7fff);
9350       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9351     }
9352   else
9353     {
9354       tmp = GEN_INT (0x8000);
9355       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9356     }
9357   operands[1] = tmp;
9360 ;; Conditionalize these after reload. If they match before reload, we
9361 ;; lose the clobber and ability to use integer instructions.
9363 (define_insn "*<code><mode>2_1"
9364   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9365         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9366   "TARGET_80387
9367    && (reload_completed
9368        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9369   "f<absneg_mnemonic>"
9370   [(set_attr "type" "fsgn")
9371    (set_attr "mode" "<MODE>")])
9373 (define_insn "*<code>extendsfdf2"
9374   [(set (match_operand:DF 0 "register_operand" "=f")
9375         (absneg:DF (float_extend:DF
9376                      (match_operand:SF 1 "register_operand" "0"))))]
9377   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9378   "f<absneg_mnemonic>"
9379   [(set_attr "type" "fsgn")
9380    (set_attr "mode" "DF")])
9382 (define_insn "*<code>extendsfxf2"
9383   [(set (match_operand:XF 0 "register_operand" "=f")
9384         (absneg:XF (float_extend:XF
9385                      (match_operand:SF 1 "register_operand" "0"))))]
9386   "TARGET_80387"
9387   "f<absneg_mnemonic>"
9388   [(set_attr "type" "fsgn")
9389    (set_attr "mode" "XF")])
9391 (define_insn "*<code>extenddfxf2"
9392   [(set (match_operand:XF 0 "register_operand" "=f")
9393         (absneg:XF (float_extend:XF
9394                      (match_operand:DF 1 "register_operand" "0"))))]
9395   "TARGET_80387"
9396   "f<absneg_mnemonic>"
9397   [(set_attr "type" "fsgn")
9398    (set_attr "mode" "XF")])
9400 ;; Copysign instructions
9402 (define_mode_iterator CSGNMODE [SF DF TF])
9403 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9405 (define_expand "copysign<mode>3"
9406   [(match_operand:CSGNMODE 0 "register_operand" "")
9407    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9408    (match_operand:CSGNMODE 2 "register_operand" "")]
9409   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9410    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9412   ix86_expand_copysign (operands);
9413   DONE;
9416 (define_insn_and_split "copysign<mode>3_const"
9417   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9418         (unspec:CSGNMODE
9419           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9420            (match_operand:CSGNMODE 2 "register_operand" "0")
9421            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9422           UNSPEC_COPYSIGN))]
9423   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9424    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9425   "#"
9426   "&& reload_completed"
9427   [(const_int 0)]
9429   ix86_split_copysign_const (operands);
9430   DONE;
9433 (define_insn "copysign<mode>3_var"
9434   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9435         (unspec:CSGNMODE
9436           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9437            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9438            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9439            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9440           UNSPEC_COPYSIGN))
9441    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9442   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9443    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9444   "#")
9446 (define_split
9447   [(set (match_operand:CSGNMODE 0 "register_operand" "")
9448         (unspec:CSGNMODE
9449           [(match_operand:CSGNMODE 2 "register_operand" "")
9450            (match_operand:CSGNMODE 3 "register_operand" "")
9451            (match_operand:<CSGNVMODE> 4 "" "")
9452            (match_operand:<CSGNVMODE> 5 "" "")]
9453           UNSPEC_COPYSIGN))
9454    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9455   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9456     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9457    && reload_completed"
9458   [(const_int 0)]
9460   ix86_split_copysign_var (operands);
9461   DONE;
9464 ;; One complement instructions
9466 (define_expand "one_cmpl<mode>2"
9467   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9468         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9469   ""
9470   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9472 (define_insn "*one_cmpl<mode>2_1"
9473   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9474         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9475   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9476   "not{<imodesuffix>}\t%0"
9477   [(set_attr "type" "negnot")
9478    (set_attr "mode" "<MODE>")])
9480 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9481 (define_insn "*one_cmplqi2_1"
9482   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9483         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9484   "ix86_unary_operator_ok (NOT, QImode, operands)"
9485   "@
9486    not{b}\t%0
9487    not{l}\t%k0"
9488   [(set_attr "type" "negnot")
9489    (set_attr "mode" "QI,SI")])
9491 ;; ??? Currently never generated - xor is used instead.
9492 (define_insn "*one_cmplsi2_1_zext"
9493   [(set (match_operand:DI 0 "register_operand" "=r")
9494         (zero_extend:DI
9495           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9496   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9497   "not{l}\t%k0"
9498   [(set_attr "type" "negnot")
9499    (set_attr "mode" "SI")])
9501 (define_insn "*one_cmpl<mode>2_2"
9502   [(set (reg FLAGS_REG)
9503         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9504                  (const_int 0)))
9505    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9506         (not:SWI (match_dup 1)))]
9507   "ix86_match_ccmode (insn, CCNOmode)
9508    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9509   "#"
9510   [(set_attr "type" "alu1")
9511    (set_attr "mode" "<MODE>")])
9513 (define_split
9514   [(set (match_operand 0 "flags_reg_operand" "")
9515         (match_operator 2 "compare_operator"
9516           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9517            (const_int 0)]))
9518    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9519         (not:SWI (match_dup 3)))]
9520   "ix86_match_ccmode (insn, CCNOmode)"
9521   [(parallel [(set (match_dup 0)
9522                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9523                                     (const_int 0)]))
9524               (set (match_dup 1)
9525                    (xor:SWI (match_dup 3) (const_int -1)))])]
9526   "")
9528 ;; ??? Currently never generated - xor is used instead.
9529 (define_insn "*one_cmplsi2_2_zext"
9530   [(set (reg FLAGS_REG)
9531         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9532                  (const_int 0)))
9533    (set (match_operand:DI 0 "register_operand" "=r")
9534         (zero_extend:DI (not:SI (match_dup 1))))]
9535   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9536    && ix86_unary_operator_ok (NOT, SImode, operands)"
9537   "#"
9538   [(set_attr "type" "alu1")
9539    (set_attr "mode" "SI")])
9541 (define_split
9542   [(set (match_operand 0 "flags_reg_operand" "")
9543         (match_operator 2 "compare_operator"
9544           [(not:SI (match_operand:SI 3 "register_operand" ""))
9545            (const_int 0)]))
9546    (set (match_operand:DI 1 "register_operand" "")
9547         (zero_extend:DI (not:SI (match_dup 3))))]
9548   "ix86_match_ccmode (insn, CCNOmode)"
9549   [(parallel [(set (match_dup 0)
9550                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9551                                     (const_int 0)]))
9552               (set (match_dup 1)
9553                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9554   "")
9556 ;; Shift instructions
9558 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9559 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9560 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9561 ;; from the assembler input.
9563 ;; This instruction shifts the target reg/mem as usual, but instead of
9564 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9565 ;; is a left shift double, bits are taken from the high order bits of
9566 ;; reg, else if the insn is a shift right double, bits are taken from the
9567 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9568 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9570 ;; Since sh[lr]d does not change the `reg' operand, that is done
9571 ;; separately, making all shifts emit pairs of shift double and normal
9572 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9573 ;; support a 63 bit shift, each shift where the count is in a reg expands
9574 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9576 ;; If the shift count is a constant, we need never emit more than one
9577 ;; shift pair, instead using moves and sign extension for counts greater
9578 ;; than 31.
9580 (define_expand "ashl<mode>3"
9581   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9582         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9583                       (match_operand:QI 2 "nonmemory_operand" "")))]
9584   ""
9585   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9587 (define_insn "*ashl<mode>3_doubleword"
9588   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9589         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9590                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9591    (clobber (reg:CC FLAGS_REG))]
9592   ""
9593   "#"
9594   [(set_attr "type" "multi")])
9596 (define_split
9597   [(set (match_operand:DWI 0 "register_operand" "")
9598         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9599                     (match_operand:QI 2 "nonmemory_operand" "")))
9600    (clobber (reg:CC FLAGS_REG))]
9601   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9602   [(const_int 0)]
9603   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9605 ;; By default we don't ask for a scratch register, because when DWImode
9606 ;; values are manipulated, registers are already at a premium.  But if
9607 ;; we have one handy, we won't turn it away.
9609 (define_peephole2
9610   [(match_scratch:DWIH 3 "r")
9611    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9612                    (ashift:<DWI>
9613                      (match_operand:<DWI> 1 "nonmemory_operand" "")
9614                      (match_operand:QI 2 "nonmemory_operand" "")))
9615               (clobber (reg:CC FLAGS_REG))])
9616    (match_dup 3)]
9617   "TARGET_CMOVE"
9618   [(const_int 0)]
9619   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9621 (define_insn "x86_64_shld"
9622   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9623         (ior:DI (ashift:DI (match_dup 0)
9624                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9625                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9626                   (minus:QI (const_int 64) (match_dup 2)))))
9627    (clobber (reg:CC FLAGS_REG))]
9628   "TARGET_64BIT"
9629   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9630   [(set_attr "type" "ishift")
9631    (set_attr "prefix_0f" "1")
9632    (set_attr "mode" "DI")
9633    (set_attr "athlon_decode" "vector")
9634    (set_attr "amdfam10_decode" "vector")])
9636 (define_insn "x86_shld"
9637   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9638         (ior:SI (ashift:SI (match_dup 0)
9639                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9640                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9641                   (minus:QI (const_int 32) (match_dup 2)))))
9642    (clobber (reg:CC FLAGS_REG))]
9643   ""
9644   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9645   [(set_attr "type" "ishift")
9646    (set_attr "prefix_0f" "1")
9647    (set_attr "mode" "SI")
9648    (set_attr "pent_pair" "np")
9649    (set_attr "athlon_decode" "vector")
9650    (set_attr "amdfam10_decode" "vector")])
9652 (define_expand "x86_shift<mode>_adj_1"
9653   [(set (reg:CCZ FLAGS_REG)
9654         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9655                              (match_dup 4))
9656                      (const_int 0)))
9657    (set (match_operand:SWI48 0 "register_operand" "")
9658         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9659                             (match_operand:SWI48 1 "register_operand" "")
9660                             (match_dup 0)))
9661    (set (match_dup 1)
9662         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9663                             (match_operand:SWI48 3 "register_operand" "r")
9664                             (match_dup 1)))]
9665   "TARGET_CMOVE"
9666   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9668 (define_expand "x86_shift<mode>_adj_2"
9669   [(use (match_operand:SWI48 0 "register_operand" ""))
9670    (use (match_operand:SWI48 1 "register_operand" ""))
9671    (use (match_operand:QI 2 "register_operand" ""))]
9672   ""
9674   rtx label = gen_label_rtx ();
9675   rtx tmp;
9677   emit_insn (gen_testqi_ccz_1 (operands[2],
9678                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9680   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9681   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9682   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9683                               gen_rtx_LABEL_REF (VOIDmode, label),
9684                               pc_rtx);
9685   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9686   JUMP_LABEL (tmp) = label;
9688   emit_move_insn (operands[0], operands[1]);
9689   ix86_expand_clear (operands[1]);
9691   emit_label (label);
9692   LABEL_NUSES (label) = 1;
9694   DONE;
9697 (define_insn "*ashl<mode>3_1"
9698   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9699         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9700                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9701    (clobber (reg:CC FLAGS_REG))]
9702   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9704   switch (get_attr_type (insn))
9705     {
9706     case TYPE_LEA:
9707       return "#";
9709     case TYPE_ALU:
9710       gcc_assert (operands[2] == const1_rtx);
9711       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9712       return "add{<imodesuffix>}\t%0, %0";
9714     default:
9715       if (operands[2] == const1_rtx
9716           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9717         return "sal{<imodesuffix>}\t%0";
9718       else
9719         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9720     }
9722   [(set (attr "type")
9723      (cond [(eq_attr "alternative" "1")
9724               (const_string "lea")
9725             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9726                           (const_int 0))
9727                       (match_operand 0 "register_operand" ""))
9728                  (match_operand 2 "const1_operand" ""))
9729               (const_string "alu")
9730            ]
9731            (const_string "ishift")))
9732    (set (attr "length_immediate")
9733      (if_then_else
9734        (ior (eq_attr "type" "alu")
9735             (and (eq_attr "type" "ishift")
9736                  (and (match_operand 2 "const1_operand" "")
9737                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9738                           (const_int 0)))))
9739        (const_string "0")
9740        (const_string "*")))
9741    (set_attr "mode" "<MODE>")])
9743 (define_insn "*ashlsi3_1_zext"
9744   [(set (match_operand:DI 0 "register_operand" "=r,r")
9745         (zero_extend:DI
9746           (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9747                      (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9748    (clobber (reg:CC FLAGS_REG))]
9749   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9751   switch (get_attr_type (insn))
9752     {
9753     case TYPE_LEA:
9754       return "#";
9756     case TYPE_ALU:
9757       gcc_assert (operands[2] == const1_rtx);
9758       return "add{l}\t%k0, %k0";
9760     default:
9761       if (operands[2] == const1_rtx
9762           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9763         return "sal{l}\t%k0";
9764       else
9765         return "sal{l}\t{%2, %k0|%k0, %2}";
9766     }
9768   [(set (attr "type")
9769      (cond [(eq_attr "alternative" "1")
9770               (const_string "lea")
9771             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9772                      (const_int 0))
9773                  (match_operand 2 "const1_operand" ""))
9774               (const_string "alu")
9775            ]
9776            (const_string "ishift")))
9777    (set (attr "length_immediate")
9778      (if_then_else
9779        (ior (eq_attr "type" "alu")
9780             (and (eq_attr "type" "ishift")
9781                  (and (match_operand 2 "const1_operand" "")
9782                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9783                           (const_int 0)))))
9784        (const_string "0")
9785        (const_string "*")))
9786    (set_attr "mode" "SI")])
9788 (define_insn "*ashlhi3_1"
9789   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9790         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9791                    (match_operand:QI 2 "nonmemory_operand" "cI")))
9792    (clobber (reg:CC FLAGS_REG))]
9793   "TARGET_PARTIAL_REG_STALL
9794    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9796   switch (get_attr_type (insn))
9797     {
9798     case TYPE_ALU:
9799       gcc_assert (operands[2] == const1_rtx);
9800       return "add{w}\t%0, %0";
9802     default:
9803       if (operands[2] == const1_rtx
9804           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9805         return "sal{w}\t%0";
9806       else
9807         return "sal{w}\t{%2, %0|%0, %2}";
9808     }
9810   [(set (attr "type")
9811      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9812                           (const_int 0))
9813                       (match_operand 0 "register_operand" ""))
9814                  (match_operand 2 "const1_operand" ""))
9815               (const_string "alu")
9816            ]
9817            (const_string "ishift")))
9818    (set (attr "length_immediate")
9819      (if_then_else
9820        (ior (eq_attr "type" "alu")
9821             (and (eq_attr "type" "ishift")
9822                  (and (match_operand 2 "const1_operand" "")
9823                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9824                           (const_int 0)))))
9825        (const_string "0")
9826        (const_string "*")))
9827    (set_attr "mode" "HI")])
9829 (define_insn "*ashlhi3_1_lea"
9830   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9831         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9832                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9833    (clobber (reg:CC FLAGS_REG))]
9834   "!TARGET_PARTIAL_REG_STALL
9835    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9837   switch (get_attr_type (insn))
9838     {
9839     case TYPE_LEA:
9840       return "#";
9842     case TYPE_ALU:
9843       gcc_assert (operands[2] == const1_rtx);
9844       return "add{w}\t%0, %0";
9846     default:
9847       if (operands[2] == const1_rtx
9848           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9849         return "sal{w}\t%0";
9850       else
9851         return "sal{w}\t{%2, %0|%0, %2}";
9852     }
9854   [(set (attr "type")
9855      (cond [(eq_attr "alternative" "1")
9856               (const_string "lea")
9857             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9858                           (const_int 0))
9859                       (match_operand 0 "register_operand" ""))
9860                  (match_operand 2 "const1_operand" ""))
9861               (const_string "alu")
9862            ]
9863            (const_string "ishift")))
9864    (set (attr "length_immediate")
9865      (if_then_else
9866        (ior (eq_attr "type" "alu")
9867             (and (eq_attr "type" "ishift")
9868                  (and (match_operand 2 "const1_operand" "")
9869                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9870                           (const_int 0)))))
9871        (const_string "0")
9872        (const_string "*")))
9873    (set_attr "mode" "HI,SI")])
9875 (define_insn "*ashlqi3_1"
9876   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9877         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9878                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9879    (clobber (reg:CC FLAGS_REG))]
9880   "TARGET_PARTIAL_REG_STALL
9881    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9883   switch (get_attr_type (insn))
9884     {
9885     case TYPE_ALU:
9886       gcc_assert (operands[2] == const1_rtx);
9887       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9888         return "add{l}\t%k0, %k0";
9889       else
9890         return "add{b}\t%0, %0";
9892     default:
9893       if (operands[2] == const1_rtx
9894           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9895         {
9896           if (get_attr_mode (insn) == MODE_SI)
9897             return "sal{l}\t%k0";
9898           else
9899             return "sal{b}\t%0";
9900         }
9901       else
9902         {
9903           if (get_attr_mode (insn) == MODE_SI)
9904             return "sal{l}\t{%2, %k0|%k0, %2}";
9905           else
9906             return "sal{b}\t{%2, %0|%0, %2}";
9907         }
9908     }
9910   [(set (attr "type")
9911      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9912                           (const_int 0))
9913                       (match_operand 0 "register_operand" ""))
9914                  (match_operand 2 "const1_operand" ""))
9915               (const_string "alu")
9916            ]
9917            (const_string "ishift")))
9918    (set (attr "length_immediate")
9919      (if_then_else
9920        (ior (eq_attr "type" "alu")
9921             (and (eq_attr "type" "ishift")
9922                  (and (match_operand 2 "const1_operand" "")
9923                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9924                           (const_int 0)))))
9925        (const_string "0")
9926        (const_string "*")))
9927    (set_attr "mode" "QI,SI")])
9929 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9930 (define_insn "*ashlqi3_1_lea"
9931   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9932         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9933                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9934    (clobber (reg:CC FLAGS_REG))]
9935   "!TARGET_PARTIAL_REG_STALL
9936    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9938   switch (get_attr_type (insn))
9939     {
9940     case TYPE_LEA:
9941       return "#";
9943     case TYPE_ALU:
9944       gcc_assert (operands[2] == const1_rtx);
9945       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9946         return "add{l}\t%k0, %k0";
9947       else
9948         return "add{b}\t%0, %0";
9950     default:
9951       if (operands[2] == const1_rtx
9952           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9953         {
9954           if (get_attr_mode (insn) == MODE_SI)
9955             return "sal{l}\t%k0";
9956           else
9957             return "sal{b}\t%0";
9958         }
9959       else
9960         {
9961           if (get_attr_mode (insn) == MODE_SI)
9962             return "sal{l}\t{%2, %k0|%k0, %2}";
9963           else
9964             return "sal{b}\t{%2, %0|%0, %2}";
9965         }
9966     }
9968   [(set (attr "type")
9969      (cond [(eq_attr "alternative" "2")
9970               (const_string "lea")
9971             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9972                           (const_int 0))
9973                       (match_operand 0 "register_operand" ""))
9974                  (match_operand 2 "const1_operand" ""))
9975               (const_string "alu")
9976            ]
9977            (const_string "ishift")))
9978    (set (attr "length_immediate")
9979      (if_then_else
9980        (ior (eq_attr "type" "alu")
9981             (and (eq_attr "type" "ishift")
9982                  (and (match_operand 2 "const1_operand" "")
9983                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9984                           (const_int 0)))))
9985        (const_string "0")
9986        (const_string "*")))
9987    (set_attr "mode" "QI,SI,SI")])
9989 (define_insn "*ashlqi3_1_slp"
9990   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9991         (ashift:QI (match_dup 0)
9992                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9993    (clobber (reg:CC FLAGS_REG))]
9994   "(optimize_function_for_size_p (cfun)
9995     || !TARGET_PARTIAL_FLAG_REG_STALL
9996     || (operands[1] == const1_rtx
9997         && (TARGET_SHIFT1
9998             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
10000   switch (get_attr_type (insn))
10001     {
10002     case TYPE_ALU:
10003       gcc_assert (operands[1] == const1_rtx);
10004       return "add{b}\t%0, %0";
10006     default:
10007       if (operands[1] == const1_rtx
10008           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10009         return "sal{b}\t%0";
10010       else
10011         return "sal{b}\t{%1, %0|%0, %1}";
10012     }
10014   [(set (attr "type")
10015      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10016                           (const_int 0))
10017                       (match_operand 0 "register_operand" ""))
10018                  (match_operand 1 "const1_operand" ""))
10019               (const_string "alu")
10020            ]
10021            (const_string "ishift1")))
10022    (set (attr "length_immediate")
10023      (if_then_else
10024        (ior (eq_attr "type" "alu")
10025             (and (eq_attr "type" "ishift1")
10026                  (and (match_operand 1 "const1_operand" "")
10027                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10028                           (const_int 0)))))
10029        (const_string "0")
10030        (const_string "*")))
10031    (set_attr "mode" "QI")])
10033 ;; Convert lea to the lea pattern to avoid flags dependency.
10034 (define_split
10035   [(set (match_operand:DI 0 "register_operand" "")
10036         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10037                    (match_operand:QI 2 "const_int_operand" "")))
10038    (clobber (reg:CC FLAGS_REG))]
10039   "TARGET_64BIT && reload_completed
10040    && true_regnum (operands[0]) != true_regnum (operands[1])"
10041   [(set (match_dup 0)
10042         (mult:DI (match_dup 1)
10043                  (match_dup 2)))]
10044   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10046 ;; Convert lea to the lea pattern to avoid flags dependency.
10047 (define_split
10048   [(set (match_operand 0 "register_operand" "")
10049         (ashift (match_operand 1 "index_register_operand" "")
10050                 (match_operand:QI 2 "const_int_operand" "")))
10051    (clobber (reg:CC FLAGS_REG))]
10052   "reload_completed
10053    && true_regnum (operands[0]) != true_regnum (operands[1])
10054    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10055   [(const_int 0)]
10057   rtx pat;
10058   enum machine_mode mode = GET_MODE (operands[0]);
10060   if (GET_MODE_SIZE (mode) < 4)
10061     operands[0] = gen_lowpart (SImode, operands[0]);
10062   if (mode != Pmode)
10063     operands[1] = gen_lowpart (Pmode, operands[1]);
10064   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10066   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10067   if (Pmode != SImode)
10068     pat = gen_rtx_SUBREG (SImode, pat, 0);
10069   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10070   DONE;
10073 ;; Rare case of shifting RSP is handled by generating move and shift
10074 (define_split
10075   [(set (match_operand 0 "register_operand" "")
10076         (ashift (match_operand 1 "register_operand" "")
10077                 (match_operand:QI 2 "const_int_operand" "")))
10078    (clobber (reg:CC FLAGS_REG))]
10079   "reload_completed
10080    && true_regnum (operands[0]) != true_regnum (operands[1])"
10081   [(const_int 0)]
10083   rtx pat, clob;
10084   emit_move_insn (operands[0], operands[1]);
10085   pat = gen_rtx_SET (VOIDmode, operands[0],
10086                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10087                                      operands[0], operands[2]));
10088   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10089   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10090   DONE;
10093 ;; Convert lea to the lea pattern to avoid flags dependency.
10094 (define_split
10095   [(set (match_operand:DI 0 "register_operand" "")
10096         (zero_extend:DI
10097           (ashift:SI (match_operand:SI 1 "register_operand" "")
10098                      (match_operand:QI 2 "const_int_operand" ""))))
10099    (clobber (reg:CC FLAGS_REG))]
10100   "TARGET_64BIT && reload_completed
10101    && true_regnum (operands[0]) != true_regnum (operands[1])"
10102   [(set (match_dup 0)
10103         (zero_extend:DI (subreg:SI (mult:SI (match_dup 1) (match_dup 2)) 0)))]
10105   operands[1] = gen_lowpart (Pmode, operands[1]);
10106   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10109 ;; This pattern can't accept a variable shift count, since shifts by
10110 ;; zero don't affect the flags.  We assume that shifts by constant
10111 ;; zero are optimized away.
10112 (define_insn "*ashl<mode>3_cmp"
10113   [(set (reg FLAGS_REG)
10114         (compare
10115           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10116                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10117           (const_int 0)))
10118    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10119         (ashift:SWI (match_dup 1) (match_dup 2)))]
10120   "(optimize_function_for_size_p (cfun)
10121     || !TARGET_PARTIAL_FLAG_REG_STALL
10122     || (operands[2] == const1_rtx
10123         && (TARGET_SHIFT1
10124             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10125    && ix86_match_ccmode (insn, CCGOCmode)
10126    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10128   switch (get_attr_type (insn))
10129     {
10130     case TYPE_ALU:
10131       gcc_assert (operands[2] == const1_rtx);
10132       return "add{<imodesuffix>}\t%0, %0";
10134     default:
10135       if (operands[2] == const1_rtx
10136           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10137         return "sal{<imodesuffix>}\t%0";
10138       else
10139         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10140     }
10142   [(set (attr "type")
10143      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10144                           (const_int 0))
10145                       (match_operand 0 "register_operand" ""))
10146                  (match_operand 2 "const1_operand" ""))
10147               (const_string "alu")
10148            ]
10149            (const_string "ishift")))
10150    (set (attr "length_immediate")
10151      (if_then_else
10152        (ior (eq_attr "type" "alu")
10153             (and (eq_attr "type" "ishift")
10154                  (and (match_operand 2 "const1_operand" "")
10155                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10156                           (const_int 0)))))
10157        (const_string "0")
10158        (const_string "*")))
10159    (set_attr "mode" "<MODE>")])
10161 (define_insn "*ashlsi3_cmp_zext"
10162   [(set (reg FLAGS_REG)
10163         (compare
10164           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10165                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10166           (const_int 0)))
10167    (set (match_operand:DI 0 "register_operand" "=r")
10168         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10169   "TARGET_64BIT
10170    && (optimize_function_for_size_p (cfun)
10171        || !TARGET_PARTIAL_FLAG_REG_STALL
10172        || (operands[2] == const1_rtx
10173            && (TARGET_SHIFT1
10174                || TARGET_DOUBLE_WITH_ADD)))
10175    && ix86_match_ccmode (insn, CCGOCmode)
10176    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10178   switch (get_attr_type (insn))
10179     {
10180     case TYPE_ALU:
10181       gcc_assert (operands[2] == const1_rtx);
10182       return "add{l}\t%k0, %k0";
10184     default:
10185       if (operands[2] == const1_rtx
10186           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10187         return "sal{l}\t%k0";
10188       else
10189         return "sal{l}\t{%2, %k0|%k0, %2}";
10190     }
10192   [(set (attr "type")
10193      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10194                      (const_int 0))
10195                  (match_operand 2 "const1_operand" ""))
10196               (const_string "alu")
10197            ]
10198            (const_string "ishift")))
10199    (set (attr "length_immediate")
10200      (if_then_else
10201        (ior (eq_attr "type" "alu")
10202             (and (eq_attr "type" "ishift")
10203                  (and (match_operand 2 "const1_operand" "")
10204                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10205                           (const_int 0)))))
10206        (const_string "0")
10207        (const_string "*")))
10208    (set_attr "mode" "SI")])
10210 (define_insn "*ashl<mode>3_cconly"
10211   [(set (reg FLAGS_REG)
10212         (compare
10213           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10214                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10215           (const_int 0)))
10216    (clobber (match_scratch:SWI 0 "=<r>"))]
10217   "(optimize_function_for_size_p (cfun)
10218     || !TARGET_PARTIAL_FLAG_REG_STALL
10219     || (operands[2] == const1_rtx
10220         && (TARGET_SHIFT1
10221             || TARGET_DOUBLE_WITH_ADD)))
10222    && ix86_match_ccmode (insn, CCGOCmode)
10223    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
10225   switch (get_attr_type (insn))
10226     {
10227     case TYPE_ALU:
10228       gcc_assert (operands[2] == const1_rtx);
10229       return "add{<imodesuffix>}\t%0, %0";
10231     default:
10232       if (operands[2] == const1_rtx
10233           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10234         return "sal{<imodesuffix>}\t%0";
10235       else
10236         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
10237     }
10239   [(set (attr "type")
10240      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10241                           (const_int 0))
10242                       (match_operand 0 "register_operand" ""))
10243                  (match_operand 2 "const1_operand" ""))
10244               (const_string "alu")
10245            ]
10246            (const_string "ishift")))
10247    (set (attr "length_immediate")
10248      (if_then_else
10249        (ior (eq_attr "type" "alu")
10250             (and (eq_attr "type" "ishift")
10251                  (and (match_operand 2 "const1_operand" "")
10252                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10253                           (const_int 0)))))
10254        (const_string "0")
10255        (const_string "*")))
10256    (set_attr "mode" "<MODE>")])
10258 ;; See comment above `ashl<mode>3' about how this works.
10260 (define_expand "<shiftrt_insn><mode>3"
10261   [(set (match_operand:SDWIM 0 "<shift_operand>" "")
10262         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
10263                            (match_operand:QI 2 "nonmemory_operand" "")))]
10264   ""
10265   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10267 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
10268   [(set (match_operand:DWI 0 "register_operand" "=r")
10269         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
10270                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
10271    (clobber (reg:CC FLAGS_REG))]
10272   ""
10273   "#"
10274   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
10275   [(const_int 0)]
10276   "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
10277   [(set_attr "type" "multi")])
10279 ;; By default we don't ask for a scratch register, because when DWImode
10280 ;; values are manipulated, registers are already at a premium.  But if
10281 ;; we have one handy, we won't turn it away.
10283 (define_peephole2
10284   [(match_scratch:DWIH 3 "r")
10285    (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
10286                    (any_shiftrt:<DWI>
10287                      (match_operand:<DWI> 1 "register_operand" "")
10288                      (match_operand:QI 2 "nonmemory_operand" "")))
10289               (clobber (reg:CC FLAGS_REG))])
10290    (match_dup 3)]
10291   "TARGET_CMOVE"
10292   [(const_int 0)]
10293   "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
10295 (define_insn "x86_64_shrd"
10296   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10297         (ior:DI (ashiftrt:DI (match_dup 0)
10298                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10299                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10300                   (minus:QI (const_int 64) (match_dup 2)))))
10301    (clobber (reg:CC FLAGS_REG))]
10302   "TARGET_64BIT"
10303   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10304   [(set_attr "type" "ishift")
10305    (set_attr "prefix_0f" "1")
10306    (set_attr "mode" "DI")
10307    (set_attr "athlon_decode" "vector")
10308    (set_attr "amdfam10_decode" "vector")])
10310 (define_insn "x86_shrd"
10311   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10312         (ior:SI (ashiftrt:SI (match_dup 0)
10313                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
10314                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10315                   (minus:QI (const_int 32) (match_dup 2)))))
10316    (clobber (reg:CC FLAGS_REG))]
10317   ""
10318   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10319   [(set_attr "type" "ishift")
10320    (set_attr "prefix_0f" "1")
10321    (set_attr "pent_pair" "np")
10322    (set_attr "mode" "SI")])
10324 (define_insn "ashrdi3_cvt"
10325   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10326         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10327                      (match_operand:QI 2 "const_int_operand" "")))
10328    (clobber (reg:CC FLAGS_REG))]
10329   "TARGET_64BIT && INTVAL (operands[2]) == 63
10330    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10331    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10332   "@
10333    {cqto|cqo}
10334    sar{q}\t{%2, %0|%0, %2}"
10335   [(set_attr "type" "imovx,ishift")
10336    (set_attr "prefix_0f" "0,*")
10337    (set_attr "length_immediate" "0,*")
10338    (set_attr "modrm" "0,1")
10339    (set_attr "mode" "DI")])
10341 (define_insn "ashrsi3_cvt"
10342   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10343         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10344                      (match_operand:QI 2 "const_int_operand" "")))
10345    (clobber (reg:CC FLAGS_REG))]
10346   "INTVAL (operands[2]) == 31
10347    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10348    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10349   "@
10350    {cltd|cdq}
10351    sar{l}\t{%2, %0|%0, %2}"
10352   [(set_attr "type" "imovx,ishift")
10353    (set_attr "prefix_0f" "0,*")
10354    (set_attr "length_immediate" "0,*")
10355    (set_attr "modrm" "0,1")
10356    (set_attr "mode" "SI")])
10358 (define_insn "*ashrsi3_cvt_zext"
10359   [(set (match_operand:DI 0 "register_operand" "=*d,r")
10360         (zero_extend:DI
10361           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10362                        (match_operand:QI 2 "const_int_operand" ""))))
10363    (clobber (reg:CC FLAGS_REG))]
10364   "TARGET_64BIT && INTVAL (operands[2]) == 31
10365    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10366    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10367   "@
10368    {cltd|cdq}
10369    sar{l}\t{%2, %k0|%k0, %2}"
10370   [(set_attr "type" "imovx,ishift")
10371    (set_attr "prefix_0f" "0,*")
10372    (set_attr "length_immediate" "0,*")
10373    (set_attr "modrm" "0,1")
10374    (set_attr "mode" "SI")])
10376 (define_expand "x86_shift<mode>_adj_3"
10377   [(use (match_operand:SWI48 0 "register_operand" ""))
10378    (use (match_operand:SWI48 1 "register_operand" ""))
10379    (use (match_operand:QI 2 "register_operand" ""))]
10380   ""
10382   rtx label = gen_label_rtx ();
10383   rtx tmp;
10385   emit_insn (gen_testqi_ccz_1 (operands[2],
10386                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
10388   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10389   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10390   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10391                               gen_rtx_LABEL_REF (VOIDmode, label),
10392                               pc_rtx);
10393   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10394   JUMP_LABEL (tmp) = label;
10396   emit_move_insn (operands[0], operands[1]);
10397   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
10398                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
10399   emit_label (label);
10400   LABEL_NUSES (label) = 1;
10402   DONE;
10405 (define_insn "*<shiftrt_insn><mode>3_1"
10406   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10407         (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10408                          (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10409    (clobber (reg:CC FLAGS_REG))]
10410   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10412   if (operands[2] == const1_rtx
10413       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10414     return "<shiftrt>{<imodesuffix>}\t%0";
10415   else
10416     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10418   [(set_attr "type" "ishift")
10419    (set (attr "length_immediate")
10420      (if_then_else
10421        (and (match_operand 2 "const1_operand" "")
10422             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10423                 (const_int 0)))
10424        (const_string "0")
10425        (const_string "*")))
10426    (set_attr "mode" "<MODE>")])
10428 (define_insn "*<shiftrt_insn>si3_1_zext"
10429   [(set (match_operand:DI 0 "register_operand" "=r")
10430         (zero_extend:DI
10431           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10432                           (match_operand:QI 2 "nonmemory_operand" "cI"))))
10433    (clobber (reg:CC FLAGS_REG))]
10434   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10436   if (operands[2] == const1_rtx
10437       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10438     return "<shiftrt>{l}\t%k0";
10439   else
10440     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10442   [(set_attr "type" "ishift")
10443    (set (attr "length_immediate")
10444      (if_then_else
10445        (and (match_operand 2 "const1_operand" "")
10446             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10447                 (const_int 0)))
10448        (const_string "0")
10449        (const_string "*")))
10450    (set_attr "mode" "SI")])
10452 (define_insn "*<shiftrt_insn>qi3_1_slp"
10453   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10454         (any_shiftrt:QI (match_dup 0)
10455                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10456    (clobber (reg:CC FLAGS_REG))]
10457   "(optimize_function_for_size_p (cfun)
10458     || !TARGET_PARTIAL_REG_STALL
10459     || (operands[1] == const1_rtx
10460         && TARGET_SHIFT1))"
10462   if (operands[1] == const1_rtx
10463       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10464     return "<shiftrt>{b}\t%0";
10465   else
10466     return "<shiftrt>{b}\t{%1, %0|%0, %1}";
10468   [(set_attr "type" "ishift1")
10469    (set (attr "length_immediate")
10470      (if_then_else
10471        (and (match_operand 1 "const1_operand" "")
10472             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10473                 (const_int 0)))
10474        (const_string "0")
10475        (const_string "*")))
10476    (set_attr "mode" "QI")])
10478 ;; This pattern can't accept a variable shift count, since shifts by
10479 ;; zero don't affect the flags.  We assume that shifts by constant
10480 ;; zero are optimized away.
10481 (define_insn "*<shiftrt_insn><mode>3_cmp"
10482   [(set (reg FLAGS_REG)
10483         (compare
10484           (any_shiftrt:SWI
10485             (match_operand:SWI 1 "nonimmediate_operand" "0")
10486             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10487           (const_int 0)))
10488    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10489         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10490   "(optimize_function_for_size_p (cfun)
10491     || !TARGET_PARTIAL_FLAG_REG_STALL
10492     || (operands[2] == const1_rtx
10493         && TARGET_SHIFT1))
10494    && ix86_match_ccmode (insn, CCGOCmode)
10495    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10497   if (operands[2] == const1_rtx
10498       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10499     return "<shiftrt>{<imodesuffix>}\t%0";
10500   else
10501     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10503   [(set_attr "type" "ishift")
10504    (set (attr "length_immediate")
10505      (if_then_else
10506        (and (match_operand 2 "const1_operand" "")
10507             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10508                 (const_int 0)))
10509        (const_string "0")
10510        (const_string "*")))
10511    (set_attr "mode" "<MODE>")])
10513 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10514   [(set (reg FLAGS_REG)
10515         (compare
10516           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10517                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10518           (const_int 0)))
10519    (set (match_operand:DI 0 "register_operand" "=r")
10520         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10521   "TARGET_64BIT
10522    && (optimize_function_for_size_p (cfun)
10523        || !TARGET_PARTIAL_FLAG_REG_STALL
10524        || (operands[2] == const1_rtx
10525            && TARGET_SHIFT1))
10526    && ix86_match_ccmode (insn, CCGOCmode)
10527    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10529   if (operands[2] == const1_rtx
10530       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10531     return "<shiftrt>{l}\t%k0";
10532   else
10533     return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10535   [(set_attr "type" "ishift")
10536    (set (attr "length_immediate")
10537      (if_then_else
10538        (and (match_operand 2 "const1_operand" "")
10539             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10540                 (const_int 0)))
10541        (const_string "0")
10542        (const_string "*")))
10543    (set_attr "mode" "SI")])
10545 (define_insn "*<shiftrt_insn><mode>3_cconly"
10546   [(set (reg FLAGS_REG)
10547         (compare
10548           (any_shiftrt:SWI
10549             (match_operand:SWI 1 "nonimmediate_operand" "0")
10550             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10551           (const_int 0)))
10552    (clobber (match_scratch:SWI 0 "=<r>"))]
10553   "(optimize_function_for_size_p (cfun)
10554     || !TARGET_PARTIAL_FLAG_REG_STALL
10555     || (operands[2] == const1_rtx
10556         && TARGET_SHIFT1))
10557    && ix86_match_ccmode (insn, CCGOCmode)
10558    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10560   if (operands[2] == const1_rtx
10561       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10562     return "<shiftrt>{<imodesuffix>}\t%0";
10563   else
10564     return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10566   [(set_attr "type" "ishift")
10567    (set (attr "length_immediate")
10568      (if_then_else
10569        (and (match_operand 2 "const1_operand" "")
10570             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10571                 (const_int 0)))
10572        (const_string "0")
10573        (const_string "*")))
10574    (set_attr "mode" "<MODE>")])
10576 ;; Rotate instructions
10578 (define_expand "<rotate_insn>ti3"
10579   [(set (match_operand:TI 0 "register_operand" "")
10580         (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10581                        (match_operand:QI 2 "nonmemory_operand" "")))]
10582   "TARGET_64BIT"
10584   if (const_1_to_63_operand (operands[2], VOIDmode))
10585     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10586                 (operands[0], operands[1], operands[2]));
10587   else
10588     FAIL;
10590   DONE;
10593 (define_expand "<rotate_insn>di3"
10594   [(set (match_operand:DI 0 "shiftdi_operand" "")
10595         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10596                        (match_operand:QI 2 "nonmemory_operand" "")))]
10597  ""
10599   if (TARGET_64BIT)
10600     ix86_expand_binary_operator (<CODE>, DImode, operands);
10601   else if (const_1_to_31_operand (operands[2], VOIDmode))
10602     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10603                 (operands[0], operands[1], operands[2]));
10604   else
10605     FAIL;
10607   DONE;
10610 (define_expand "<rotate_insn><mode>3"
10611   [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10612         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10613                             (match_operand:QI 2 "nonmemory_operand" "")))]
10614   ""
10615   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10617 ;; Implement rotation using two double-precision
10618 ;; shift instructions and a scratch register.
10620 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10621  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10622        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10623                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10624   (clobber (reg:CC FLAGS_REG))
10625   (clobber (match_scratch:DWIH 3 "=&r"))]
10626  ""
10627  "#"
10628  "reload_completed"
10629  [(set (match_dup 3) (match_dup 4))
10630   (parallel
10631    [(set (match_dup 4)
10632          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10633                    (lshiftrt:DWIH (match_dup 5)
10634                                   (minus:QI (match_dup 6) (match_dup 2)))))
10635     (clobber (reg:CC FLAGS_REG))])
10636   (parallel
10637    [(set (match_dup 5)
10638          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10639                    (lshiftrt:DWIH (match_dup 3)
10640                                   (minus:QI (match_dup 6) (match_dup 2)))))
10641     (clobber (reg:CC FLAGS_REG))])]
10643   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10645   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10648 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10649  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10650        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10651                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10652   (clobber (reg:CC FLAGS_REG))
10653   (clobber (match_scratch:DWIH 3 "=&r"))]
10654  ""
10655  "#"
10656  "reload_completed"
10657  [(set (match_dup 3) (match_dup 4))
10658   (parallel
10659    [(set (match_dup 4)
10660          (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10661                    (ashift:DWIH (match_dup 5)
10662                                 (minus:QI (match_dup 6) (match_dup 2)))))
10663     (clobber (reg:CC FLAGS_REG))])
10664   (parallel
10665    [(set (match_dup 5)
10666          (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10667                    (ashift:DWIH (match_dup 3)
10668                                 (minus:QI (match_dup 6) (match_dup 2)))))
10669     (clobber (reg:CC FLAGS_REG))])]
10671   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10673   split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10676 (define_insn "*<rotate_insn><mode>3_1"
10677   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10678         (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10679                         (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10680    (clobber (reg:CC FLAGS_REG))]
10681   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10683   if (operands[2] == const1_rtx
10684       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10685     return "<rotate>{<imodesuffix>}\t%0";
10686   else
10687     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10689   [(set_attr "type" "rotate")
10690    (set (attr "length_immediate")
10691      (if_then_else
10692        (and (match_operand 2 "const1_operand" "")
10693             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10694                 (const_int 0)))
10695        (const_string "0")
10696        (const_string "*")))
10697    (set_attr "mode" "<MODE>")])
10699 (define_insn "*<rotate_insn>si3_1_zext"
10700   [(set (match_operand:DI 0 "register_operand" "=r")
10701         (zero_extend:DI
10702           (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10703                          (match_operand:QI 2 "nonmemory_operand" "cI"))))
10704    (clobber (reg:CC FLAGS_REG))]
10705   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10707     if (operands[2] == const1_rtx
10708         && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10709     return "<rotate>{l}\t%k0";
10710   else
10711     return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10713   [(set_attr "type" "rotate")
10714    (set (attr "length_immediate")
10715      (if_then_else
10716        (and (match_operand 2 "const1_operand" "")
10717             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10718                 (const_int 0)))
10719        (const_string "0")
10720        (const_string "*")))
10721    (set_attr "mode" "SI")])
10723 (define_insn "*<rotate_insn>qi3_1_slp"
10724   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10725         (any_rotate:QI (match_dup 0)
10726                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10727    (clobber (reg:CC FLAGS_REG))]
10728   "(optimize_function_for_size_p (cfun)
10729     || !TARGET_PARTIAL_REG_STALL
10730     || (operands[1] == const1_rtx
10731         && TARGET_SHIFT1))"
10733   if (operands[1] == const1_rtx
10734       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10735     return "<rotate>{b}\t%0";
10736   else
10737     return "<rotate>{b}\t{%1, %0|%0, %1}";
10739   [(set_attr "type" "rotate1")
10740    (set (attr "length_immediate")
10741      (if_then_else
10742        (and (match_operand 1 "const1_operand" "")
10743             (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10744                 (const_int 0)))
10745        (const_string "0")
10746        (const_string "*")))
10747    (set_attr "mode" "QI")])
10749 (define_split
10750  [(set (match_operand:HI 0 "register_operand" "")
10751        (any_rotate:HI (match_dup 0) (const_int 8)))
10752   (clobber (reg:CC FLAGS_REG))]
10753  "reload_completed
10754   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10755  [(parallel [(set (strict_low_part (match_dup 0))
10756                   (bswap:HI (match_dup 0)))
10757              (clobber (reg:CC FLAGS_REG))])]
10758  "")
10760 ;; Bit set / bit test instructions
10762 (define_expand "extv"
10763   [(set (match_operand:SI 0 "register_operand" "")
10764         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10765                          (match_operand:SI 2 "const8_operand" "")
10766                          (match_operand:SI 3 "const8_operand" "")))]
10767   ""
10769   /* Handle extractions from %ah et al.  */
10770   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10771     FAIL;
10773   /* From mips.md: extract_bit_field doesn't verify that our source
10774      matches the predicate, so check it again here.  */
10775   if (! ext_register_operand (operands[1], VOIDmode))
10776     FAIL;
10779 (define_expand "extzv"
10780   [(set (match_operand:SI 0 "register_operand" "")
10781         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10782                          (match_operand:SI 2 "const8_operand" "")
10783                          (match_operand:SI 3 "const8_operand" "")))]
10784   ""
10786   /* Handle extractions from %ah et al.  */
10787   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10788     FAIL;
10790   /* From mips.md: extract_bit_field doesn't verify that our source
10791      matches the predicate, so check it again here.  */
10792   if (! ext_register_operand (operands[1], VOIDmode))
10793     FAIL;
10796 (define_expand "insv"
10797   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10798                       (match_operand 1 "const8_operand" "")
10799                       (match_operand 2 "const8_operand" ""))
10800         (match_operand 3 "register_operand" ""))]
10801   ""
10803   /* Handle insertions to %ah et al.  */
10804   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10805     FAIL;
10807   /* From mips.md: insert_bit_field doesn't verify that our source
10808      matches the predicate, so check it again here.  */
10809   if (! ext_register_operand (operands[0], VOIDmode))
10810     FAIL;
10812   if (TARGET_64BIT)
10813     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
10814   else
10815     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
10817   DONE;
10820 ;; %%% bts, btr, btc, bt.
10821 ;; In general these instructions are *slow* when applied to memory,
10822 ;; since they enforce atomic operation.  When applied to registers,
10823 ;; it depends on the cpu implementation.  They're never faster than
10824 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10825 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10826 ;; within the instruction itself, so operating on bits in the high
10827 ;; 32-bits of a register becomes easier.
10829 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10830 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10831 ;; negdf respectively, so they can never be disabled entirely.
10833 (define_insn "*btsq"
10834   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10835                          (const_int 1)
10836                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10837         (const_int 1))
10838    (clobber (reg:CC FLAGS_REG))]
10839   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10840   "bts{q}\t{%1, %0|%0, %1}"
10841   [(set_attr "type" "alu1")
10842    (set_attr "prefix_0f" "1")
10843    (set_attr "mode" "DI")])
10845 (define_insn "*btrq"
10846   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10847                          (const_int 1)
10848                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10849         (const_int 0))
10850    (clobber (reg:CC FLAGS_REG))]
10851   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10852   "btr{q}\t{%1, %0|%0, %1}"
10853   [(set_attr "type" "alu1")
10854    (set_attr "prefix_0f" "1")
10855    (set_attr "mode" "DI")])
10857 (define_insn "*btcq"
10858   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10859                          (const_int 1)
10860                          (match_operand:DI 1 "const_0_to_63_operand" ""))
10861         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10862    (clobber (reg:CC FLAGS_REG))]
10863   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10864   "btc{q}\t{%1, %0|%0, %1}"
10865   [(set_attr "type" "alu1")
10866    (set_attr "prefix_0f" "1")
10867    (set_attr "mode" "DI")])
10869 ;; Allow Nocona to avoid these instructions if a register is available.
10871 (define_peephole2
10872   [(match_scratch:DI 2 "r")
10873    (parallel [(set (zero_extract:DI
10874                      (match_operand:DI 0 "register_operand" "")
10875                      (const_int 1)
10876                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10877                    (const_int 1))
10878               (clobber (reg:CC FLAGS_REG))])]
10879   "TARGET_64BIT && !TARGET_USE_BT"
10880   [(const_int 0)]
10882   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10883   rtx op1;
10885   if (HOST_BITS_PER_WIDE_INT >= 64)
10886     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10887   else if (i < HOST_BITS_PER_WIDE_INT)
10888     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10889   else
10890     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10892   op1 = immed_double_const (lo, hi, DImode);
10893   if (i >= 31)
10894     {
10895       emit_move_insn (operands[2], op1);
10896       op1 = operands[2];
10897     }
10899   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10900   DONE;
10903 (define_peephole2
10904   [(match_scratch:DI 2 "r")
10905    (parallel [(set (zero_extract:DI
10906                      (match_operand:DI 0 "register_operand" "")
10907                      (const_int 1)
10908                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10909                    (const_int 0))
10910               (clobber (reg:CC FLAGS_REG))])]
10911   "TARGET_64BIT && !TARGET_USE_BT"
10912   [(const_int 0)]
10914   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10915   rtx op1;
10917   if (HOST_BITS_PER_WIDE_INT >= 64)
10918     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10919   else if (i < HOST_BITS_PER_WIDE_INT)
10920     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10921   else
10922     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10924   op1 = immed_double_const (~lo, ~hi, DImode);
10925   if (i >= 32)
10926     {
10927       emit_move_insn (operands[2], op1);
10928       op1 = operands[2];
10929     }
10931   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10932   DONE;
10935 (define_peephole2
10936   [(match_scratch:DI 2 "r")
10937    (parallel [(set (zero_extract:DI
10938                      (match_operand:DI 0 "register_operand" "")
10939                      (const_int 1)
10940                      (match_operand:DI 1 "const_0_to_63_operand" ""))
10941               (not:DI (zero_extract:DI
10942                         (match_dup 0) (const_int 1) (match_dup 1))))
10943               (clobber (reg:CC FLAGS_REG))])]
10944   "TARGET_64BIT && !TARGET_USE_BT"
10945   [(const_int 0)]
10947   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10948   rtx op1;
10950   if (HOST_BITS_PER_WIDE_INT >= 64)
10951     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10952   else if (i < HOST_BITS_PER_WIDE_INT)
10953     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10954   else
10955     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10957   op1 = immed_double_const (lo, hi, DImode);
10958   if (i >= 31)
10959     {
10960       emit_move_insn (operands[2], op1);
10961       op1 = operands[2];
10962     }
10964   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10965   DONE;
10968 (define_insn "*btdi_rex64"
10969   [(set (reg:CCC FLAGS_REG)
10970         (compare:CCC
10971           (zero_extract:DI
10972             (match_operand:DI 0 "register_operand" "r")
10973             (const_int 1)
10974             (match_operand:DI 1 "nonmemory_operand" "rN"))
10975           (const_int 0)))]
10976   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
10977   "bt{q}\t{%1, %0|%0, %1}"
10978   [(set_attr "type" "alu1")
10979    (set_attr "prefix_0f" "1")
10980    (set_attr "mode" "DI")])
10982 (define_insn "*btsi"
10983   [(set (reg:CCC FLAGS_REG)
10984         (compare:CCC
10985           (zero_extract:SI
10986             (match_operand:SI 0 "register_operand" "r")
10987             (const_int 1)
10988             (match_operand:SI 1 "nonmemory_operand" "rN"))
10989           (const_int 0)))]
10990   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10991   "bt{l}\t{%1, %0|%0, %1}"
10992   [(set_attr "type" "alu1")
10993    (set_attr "prefix_0f" "1")
10994    (set_attr "mode" "SI")])
10996 ;; Store-flag instructions.
10998 ;; For all sCOND expanders, also expand the compare or test insn that
10999 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
11001 (define_insn_and_split "*setcc_di_1"
11002   [(set (match_operand:DI 0 "register_operand" "=q")
11003         (match_operator:DI 1 "ix86_comparison_operator"
11004           [(reg FLAGS_REG) (const_int 0)]))]
11005   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
11006   "#"
11007   "&& reload_completed"
11008   [(set (match_dup 2) (match_dup 1))
11009    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
11011   PUT_MODE (operands[1], QImode);
11012   operands[2] = gen_lowpart (QImode, operands[0]);
11015 (define_insn_and_split "*setcc_si_1_and"
11016   [(set (match_operand:SI 0 "register_operand" "=q")
11017         (match_operator:SI 1 "ix86_comparison_operator"
11018           [(reg FLAGS_REG) (const_int 0)]))
11019    (clobber (reg:CC FLAGS_REG))]
11020   "!TARGET_PARTIAL_REG_STALL
11021    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
11022   "#"
11023   "&& reload_completed"
11024   [(set (match_dup 2) (match_dup 1))
11025    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
11026               (clobber (reg:CC FLAGS_REG))])]
11028   PUT_MODE (operands[1], QImode);
11029   operands[2] = gen_lowpart (QImode, operands[0]);
11032 (define_insn_and_split "*setcc_si_1_movzbl"
11033   [(set (match_operand:SI 0 "register_operand" "=q")
11034         (match_operator:SI 1 "ix86_comparison_operator"
11035           [(reg FLAGS_REG) (const_int 0)]))]
11036   "!TARGET_PARTIAL_REG_STALL
11037    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
11038   "#"
11039   "&& reload_completed"
11040   [(set (match_dup 2) (match_dup 1))
11041    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
11043   PUT_MODE (operands[1], QImode);
11044   operands[2] = gen_lowpart (QImode, operands[0]);
11047 (define_insn "*setcc_qi"
11048   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11049         (match_operator:QI 1 "ix86_comparison_operator"
11050           [(reg FLAGS_REG) (const_int 0)]))]
11051   ""
11052   "set%C1\t%0"
11053   [(set_attr "type" "setcc")
11054    (set_attr "mode" "QI")])
11056 (define_insn "*setcc_qi_slp"
11057   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11058         (match_operator:QI 1 "ix86_comparison_operator"
11059           [(reg FLAGS_REG) (const_int 0)]))]
11060   ""
11061   "set%C1\t%0"
11062   [(set_attr "type" "setcc")
11063    (set_attr "mode" "QI")])
11065 ;; In general it is not safe to assume too much about CCmode registers,
11066 ;; so simplify-rtx stops when it sees a second one.  Under certain
11067 ;; conditions this is safe on x86, so help combine not create
11069 ;;      seta    %al
11070 ;;      testb   %al, %al
11071 ;;      sete    %al
11073 (define_split
11074   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11075         (ne:QI (match_operator 1 "ix86_comparison_operator"
11076                  [(reg FLAGS_REG) (const_int 0)])
11077             (const_int 0)))]
11078   ""
11079   [(set (match_dup 0) (match_dup 1))]
11081   PUT_MODE (operands[1], QImode);
11084 (define_split
11085   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11086         (ne:QI (match_operator 1 "ix86_comparison_operator"
11087                  [(reg FLAGS_REG) (const_int 0)])
11088             (const_int 0)))]
11089   ""
11090   [(set (match_dup 0) (match_dup 1))]
11092   PUT_MODE (operands[1], QImode);
11095 (define_split
11096   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11097         (eq:QI (match_operator 1 "ix86_comparison_operator"
11098                  [(reg FLAGS_REG) (const_int 0)])
11099             (const_int 0)))]
11100   ""
11101   [(set (match_dup 0) (match_dup 1))]
11103   rtx new_op1 = copy_rtx (operands[1]);
11104   operands[1] = new_op1;
11105   PUT_MODE (new_op1, QImode);
11106   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11107                                              GET_MODE (XEXP (new_op1, 0))));
11109   /* Make sure that (a) the CCmode we have for the flags is strong
11110      enough for the reversed compare or (b) we have a valid FP compare.  */
11111   if (! ix86_comparison_operator (new_op1, VOIDmode))
11112     FAIL;
11115 (define_split
11116   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
11117         (eq:QI (match_operator 1 "ix86_comparison_operator"
11118                  [(reg FLAGS_REG) (const_int 0)])
11119             (const_int 0)))]
11120   ""
11121   [(set (match_dup 0) (match_dup 1))]
11123   rtx new_op1 = copy_rtx (operands[1]);
11124   operands[1] = new_op1;
11125   PUT_MODE (new_op1, QImode);
11126   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
11127                                              GET_MODE (XEXP (new_op1, 0))));
11129   /* Make sure that (a) the CCmode we have for the flags is strong
11130      enough for the reversed compare or (b) we have a valid FP compare.  */
11131   if (! ix86_comparison_operator (new_op1, VOIDmode))
11132     FAIL;
11135 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
11136 ;; subsequent logical operations are used to imitate conditional moves.
11137 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
11138 ;; it directly.
11140 (define_insn "*avx_setcc<mode>"
11141   [(set (match_operand:MODEF 0 "register_operand" "=x")
11142         (match_operator:MODEF 1 "avx_comparison_float_operator"
11143           [(match_operand:MODEF 2 "register_operand" "x")
11144            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11145   "TARGET_AVX"
11146   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
11147   [(set_attr "type" "ssecmp")
11148    (set_attr "prefix" "vex")
11149    (set_attr "length_immediate" "1")
11150    (set_attr "mode" "<MODE>")])
11152 (define_insn "*sse_setcc<mode>"
11153   [(set (match_operand:MODEF 0 "register_operand" "=x")
11154         (match_operator:MODEF 1 "sse_comparison_operator"
11155           [(match_operand:MODEF 2 "register_operand" "0")
11156            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
11157   "SSE_FLOAT_MODE_P (<MODE>mode)"
11158   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
11159   [(set_attr "type" "ssecmp")
11160    (set_attr "length_immediate" "1")
11161    (set_attr "mode" "<MODE>")])
11163 ;; Basic conditional jump instructions.
11164 ;; We ignore the overflow flag for signed branch instructions.
11166 (define_insn "*jcc_1"
11167   [(set (pc)
11168         (if_then_else (match_operator 1 "ix86_comparison_operator"
11169                                       [(reg FLAGS_REG) (const_int 0)])
11170                       (label_ref (match_operand 0 "" ""))
11171                       (pc)))]
11172   ""
11173   "%+j%C1\t%l0"
11174   [(set_attr "type" "ibr")
11175    (set_attr "modrm" "0")
11176    (set (attr "length")
11177            (if_then_else (and (ge (minus (match_dup 0) (pc))
11178                                   (const_int -126))
11179                               (lt (minus (match_dup 0) (pc))
11180                                   (const_int 128)))
11181              (const_int 2)
11182              (const_int 6)))])
11184 (define_insn "*jcc_2"
11185   [(set (pc)
11186         (if_then_else (match_operator 1 "ix86_comparison_operator"
11187                                       [(reg FLAGS_REG) (const_int 0)])
11188                       (pc)
11189                       (label_ref (match_operand 0 "" ""))))]
11190   ""
11191   "%+j%c1\t%l0"
11192   [(set_attr "type" "ibr")
11193    (set_attr "modrm" "0")
11194    (set (attr "length")
11195            (if_then_else (and (ge (minus (match_dup 0) (pc))
11196                                   (const_int -126))
11197                               (lt (minus (match_dup 0) (pc))
11198                                   (const_int 128)))
11199              (const_int 2)
11200              (const_int 6)))])
11202 ;; In general it is not safe to assume too much about CCmode registers,
11203 ;; so simplify-rtx stops when it sees a second one.  Under certain
11204 ;; conditions this is safe on x86, so help combine not create
11206 ;;      seta    %al
11207 ;;      testb   %al, %al
11208 ;;      je      Lfoo
11210 (define_split
11211   [(set (pc)
11212         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
11213                                       [(reg FLAGS_REG) (const_int 0)])
11214                           (const_int 0))
11215                       (label_ref (match_operand 1 "" ""))
11216                       (pc)))]
11217   ""
11218   [(set (pc)
11219         (if_then_else (match_dup 0)
11220                       (label_ref (match_dup 1))
11221                       (pc)))]
11223   PUT_MODE (operands[0], VOIDmode);
11226 (define_split
11227   [(set (pc)
11228         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
11229                                       [(reg FLAGS_REG) (const_int 0)])
11230                           (const_int 0))
11231                       (label_ref (match_operand 1 "" ""))
11232                       (pc)))]
11233   ""
11234   [(set (pc)
11235         (if_then_else (match_dup 0)
11236                       (label_ref (match_dup 1))
11237                       (pc)))]
11239   rtx new_op0 = copy_rtx (operands[0]);
11240   operands[0] = new_op0;
11241   PUT_MODE (new_op0, VOIDmode);
11242   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
11243                                              GET_MODE (XEXP (new_op0, 0))));
11245   /* Make sure that (a) the CCmode we have for the flags is strong
11246      enough for the reversed compare or (b) we have a valid FP compare.  */
11247   if (! ix86_comparison_operator (new_op0, VOIDmode))
11248     FAIL;
11251 ;; zero_extend in SImode is correct, since this is what combine pass
11252 ;; generates from shift insn with QImode operand.  Actually, the mode of
11253 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
11254 ;; appropriate modulo of the bit offset value.
11256 (define_insn_and_split "*jcc_btdi_rex64"
11257   [(set (pc)
11258         (if_then_else (match_operator 0 "bt_comparison_operator"
11259                         [(zero_extract:DI
11260                            (match_operand:DI 1 "register_operand" "r")
11261                            (const_int 1)
11262                            (zero_extend:SI
11263                              (match_operand:QI 2 "register_operand" "r")))
11264                          (const_int 0)])
11265                       (label_ref (match_operand 3 "" ""))
11266                       (pc)))
11267    (clobber (reg:CC FLAGS_REG))]
11268   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
11269   "#"
11270   "&& 1"
11271   [(set (reg:CCC FLAGS_REG)
11272         (compare:CCC
11273           (zero_extract:DI
11274             (match_dup 1)
11275             (const_int 1)
11276             (match_dup 2))
11277           (const_int 0)))
11278    (set (pc)
11279         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11280                       (label_ref (match_dup 3))
11281                       (pc)))]
11283   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
11285   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11288 ;; avoid useless masking of bit offset operand
11289 (define_insn_and_split "*jcc_btdi_mask_rex64"
11290   [(set (pc)
11291         (if_then_else (match_operator 0 "bt_comparison_operator"
11292                         [(zero_extract:DI
11293                            (match_operand:DI 1 "register_operand" "r")
11294                            (const_int 1)
11295                            (and:SI
11296                              (match_operand:SI 2 "register_operand" "r")
11297                              (match_operand:SI 3 "const_int_operand" "n")))])
11298                       (label_ref (match_operand 4 "" ""))
11299                       (pc)))
11300    (clobber (reg:CC FLAGS_REG))]
11301   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
11302    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
11303   "#"
11304   "&& 1"
11305   [(set (reg:CCC FLAGS_REG)
11306         (compare:CCC
11307           (zero_extract:DI
11308             (match_dup 1)
11309             (const_int 1)
11310             (match_dup 2))
11311           (const_int 0)))
11312    (set (pc)
11313         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11314                       (label_ref (match_dup 4))
11315                       (pc)))]
11317   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
11319   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11322 (define_insn_and_split "*jcc_btsi"
11323   [(set (pc)
11324         (if_then_else (match_operator 0 "bt_comparison_operator"
11325                         [(zero_extract:SI
11326                            (match_operand:SI 1 "register_operand" "r")
11327                            (const_int 1)
11328                            (zero_extend:SI
11329                              (match_operand:QI 2 "register_operand" "r")))
11330                          (const_int 0)])
11331                       (label_ref (match_operand 3 "" ""))
11332                       (pc)))
11333    (clobber (reg:CC FLAGS_REG))]
11334   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11335   "#"
11336   "&& 1"
11337   [(set (reg:CCC FLAGS_REG)
11338         (compare:CCC
11339           (zero_extract:SI
11340             (match_dup 1)
11341             (const_int 1)
11342             (match_dup 2))
11343           (const_int 0)))
11344    (set (pc)
11345         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11346                       (label_ref (match_dup 3))
11347                       (pc)))]
11349   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11351   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11354 ;; avoid useless masking of bit offset operand
11355 (define_insn_and_split "*jcc_btsi_mask"
11356   [(set (pc)
11357         (if_then_else (match_operator 0 "bt_comparison_operator"
11358                         [(zero_extract:SI
11359                            (match_operand:SI 1 "register_operand" "r")
11360                            (const_int 1)
11361                            (and:SI
11362                              (match_operand:SI 2 "register_operand" "r")
11363                              (match_operand:SI 3 "const_int_operand" "n")))])
11364                       (label_ref (match_operand 4 "" ""))
11365                       (pc)))
11366    (clobber (reg:CC FLAGS_REG))]
11367   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11368    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11369   "#"
11370   "&& 1"
11371   [(set (reg:CCC FLAGS_REG)
11372         (compare:CCC
11373           (zero_extract:SI
11374             (match_dup 1)
11375             (const_int 1)
11376             (match_dup 2))
11377           (const_int 0)))
11378    (set (pc)
11379         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11380                       (label_ref (match_dup 4))
11381                       (pc)))]
11382   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11384 (define_insn_and_split "*jcc_btsi_1"
11385   [(set (pc)
11386         (if_then_else (match_operator 0 "bt_comparison_operator"
11387                         [(and:SI
11388                            (lshiftrt:SI
11389                              (match_operand:SI 1 "register_operand" "r")
11390                              (match_operand:QI 2 "register_operand" "r"))
11391                            (const_int 1))
11392                          (const_int 0)])
11393                       (label_ref (match_operand 3 "" ""))
11394                       (pc)))
11395    (clobber (reg:CC FLAGS_REG))]
11396   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11397   "#"
11398   "&& 1"
11399   [(set (reg:CCC FLAGS_REG)
11400         (compare:CCC
11401           (zero_extract:SI
11402             (match_dup 1)
11403             (const_int 1)
11404             (match_dup 2))
11405           (const_int 0)))
11406    (set (pc)
11407         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11408                       (label_ref (match_dup 3))
11409                       (pc)))]
11411   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11413   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11416 ;; avoid useless masking of bit offset operand
11417 (define_insn_and_split "*jcc_btsi_mask_1"
11418   [(set (pc)
11419         (if_then_else
11420           (match_operator 0 "bt_comparison_operator"
11421             [(and:SI
11422                (lshiftrt:SI
11423                  (match_operand:SI 1 "register_operand" "r")
11424                  (subreg:QI
11425                    (and:SI
11426                      (match_operand:SI 2 "register_operand" "r")
11427                      (match_operand:SI 3 "const_int_operand" "n")) 0))
11428                (const_int 1))
11429              (const_int 0)])
11430           (label_ref (match_operand 4 "" ""))
11431           (pc)))
11432    (clobber (reg:CC FLAGS_REG))]
11433   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11434    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11435   "#"
11436   "&& 1"
11437   [(set (reg:CCC FLAGS_REG)
11438         (compare:CCC
11439           (zero_extract:SI
11440             (match_dup 1)
11441             (const_int 1)
11442             (match_dup 2))
11443           (const_int 0)))
11444    (set (pc)
11445         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11446                       (label_ref (match_dup 4))
11447                       (pc)))]
11448   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11450 ;; Define combination compare-and-branch fp compare instructions to help
11451 ;; combine.
11453 (define_insn "*fp_jcc_3_387"
11454   [(set (pc)
11455         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11456                         [(match_operand 1 "register_operand" "f")
11457                          (match_operand 2 "nonimmediate_operand" "fm")])
11458           (label_ref (match_operand 3 "" ""))
11459           (pc)))
11460    (clobber (reg:CCFP FPSR_REG))
11461    (clobber (reg:CCFP FLAGS_REG))
11462    (clobber (match_scratch:HI 4 "=a"))]
11463   "TARGET_80387
11464    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11465    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11466    && SELECT_CC_MODE (GET_CODE (operands[0]),
11467                       operands[1], operands[2]) == CCFPmode
11468    && !TARGET_CMOVE"
11469   "#")
11471 (define_insn "*fp_jcc_4_387"
11472   [(set (pc)
11473         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11474                         [(match_operand 1 "register_operand" "f")
11475                          (match_operand 2 "nonimmediate_operand" "fm")])
11476           (pc)
11477           (label_ref (match_operand 3 "" ""))))
11478    (clobber (reg:CCFP FPSR_REG))
11479    (clobber (reg:CCFP FLAGS_REG))
11480    (clobber (match_scratch:HI 4 "=a"))]
11481   "TARGET_80387
11482    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11483    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11484    && SELECT_CC_MODE (GET_CODE (operands[0]),
11485                       operands[1], operands[2]) == CCFPmode
11486    && !TARGET_CMOVE"
11487   "#")
11489 (define_insn "*fp_jcc_5_387"
11490   [(set (pc)
11491         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11492                         [(match_operand 1 "register_operand" "f")
11493                          (match_operand 2 "register_operand" "f")])
11494           (label_ref (match_operand 3 "" ""))
11495           (pc)))
11496    (clobber (reg:CCFP FPSR_REG))
11497    (clobber (reg:CCFP FLAGS_REG))
11498    (clobber (match_scratch:HI 4 "=a"))]
11499   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11500    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11501    && !TARGET_CMOVE"
11502   "#")
11504 (define_insn "*fp_jcc_6_387"
11505   [(set (pc)
11506         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11507                         [(match_operand 1 "register_operand" "f")
11508                          (match_operand 2 "register_operand" "f")])
11509           (pc)
11510           (label_ref (match_operand 3 "" ""))))
11511    (clobber (reg:CCFP FPSR_REG))
11512    (clobber (reg:CCFP FLAGS_REG))
11513    (clobber (match_scratch:HI 4 "=a"))]
11514   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11515    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11516    && !TARGET_CMOVE"
11517   "#")
11519 (define_insn "*fp_jcc_7_387"
11520   [(set (pc)
11521         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11522                         [(match_operand 1 "register_operand" "f")
11523                          (match_operand 2 "const0_operand" "")])
11524           (label_ref (match_operand 3 "" ""))
11525           (pc)))
11526    (clobber (reg:CCFP FPSR_REG))
11527    (clobber (reg:CCFP FLAGS_REG))
11528    (clobber (match_scratch:HI 4 "=a"))]
11529   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11530    && GET_MODE (operands[1]) == GET_MODE (operands[2])
11531    && SELECT_CC_MODE (GET_CODE (operands[0]),
11532                       operands[1], operands[2]) == CCFPmode
11533    && !TARGET_CMOVE"
11534   "#")
11536 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
11537 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11538 ;; with a precedence over other operators and is always put in the first
11539 ;; place. Swap condition and operands to match ficom instruction.
11541 (define_insn "*fp_jcc_8<mode>_387"
11542   [(set (pc)
11543         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11544                         [(match_operator 1 "float_operator"
11545                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11546                            (match_operand 3 "register_operand" "f,f")])
11547           (label_ref (match_operand 4 "" ""))
11548           (pc)))
11549    (clobber (reg:CCFP FPSR_REG))
11550    (clobber (reg:CCFP FLAGS_REG))
11551    (clobber (match_scratch:HI 5 "=a,a"))]
11552   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11553    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11554    && GET_MODE (operands[1]) == GET_MODE (operands[3])
11555    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11556    && !TARGET_CMOVE"
11557   "#")
11559 (define_split
11560   [(set (pc)
11561         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11562                         [(match_operand 1 "register_operand" "")
11563                          (match_operand 2 "nonimmediate_operand" "")])
11564           (match_operand 3 "" "")
11565           (match_operand 4 "" "")))
11566    (clobber (reg:CCFP FPSR_REG))
11567    (clobber (reg:CCFP FLAGS_REG))]
11568   "reload_completed"
11569   [(const_int 0)]
11571   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11572                         operands[3], operands[4], NULL_RTX, NULL_RTX);
11573   DONE;
11576 (define_split
11577   [(set (pc)
11578         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11579                         [(match_operand 1 "register_operand" "")
11580                          (match_operand 2 "general_operand" "")])
11581           (match_operand 3 "" "")
11582           (match_operand 4 "" "")))
11583    (clobber (reg:CCFP FPSR_REG))
11584    (clobber (reg:CCFP FLAGS_REG))
11585    (clobber (match_scratch:HI 5 "=a"))]
11586   "reload_completed"
11587   [(const_int 0)]
11589   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11590                         operands[3], operands[4], operands[5], NULL_RTX);
11591   DONE;
11594 (define_split
11595   [(set (pc)
11596         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11597                         [(match_operator 1 "float_operator"
11598                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
11599                            (match_operand 3 "register_operand" "")])
11600           (match_operand 4 "" "")
11601           (match_operand 5 "" "")))
11602    (clobber (reg:CCFP FPSR_REG))
11603    (clobber (reg:CCFP FLAGS_REG))
11604    (clobber (match_scratch:HI 6 "=a"))]
11605   "reload_completed"
11606   [(const_int 0)]
11608   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11609   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11610                         operands[3], operands[7],
11611                         operands[4], operands[5], operands[6], NULL_RTX);
11612   DONE;
11615 ;; %%% Kill this when reload knows how to do it.
11616 (define_split
11617   [(set (pc)
11618         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11619                         [(match_operator 1 "float_operator"
11620                            [(match_operand:X87MODEI12 2 "register_operand" "")])
11621                            (match_operand 3 "register_operand" "")])
11622           (match_operand 4 "" "")
11623           (match_operand 5 "" "")))
11624    (clobber (reg:CCFP FPSR_REG))
11625    (clobber (reg:CCFP FLAGS_REG))
11626    (clobber (match_scratch:HI 6 "=a"))]
11627   "reload_completed"
11628   [(const_int 0)]
11630   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11631   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11632   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11633                         operands[3], operands[7],
11634                         operands[4], operands[5], operands[6], operands[2]);
11635   DONE;
11638 ;; Unconditional and other jump instructions
11640 (define_insn "jump"
11641   [(set (pc)
11642         (label_ref (match_operand 0 "" "")))]
11643   ""
11644   "jmp\t%l0"
11645   [(set_attr "type" "ibr")
11646    (set (attr "length")
11647            (if_then_else (and (ge (minus (match_dup 0) (pc))
11648                                   (const_int -126))
11649                               (lt (minus (match_dup 0) (pc))
11650                                   (const_int 128)))
11651              (const_int 2)
11652              (const_int 5)))
11653    (set_attr "modrm" "0")])
11655 (define_expand "indirect_jump"
11656   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11657   ""
11658   "")
11660 (define_insn "*indirect_jump"
11661   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11662   ""
11663   "jmp\t%A0"
11664   [(set_attr "type" "ibr")
11665    (set_attr "length_immediate" "0")])
11667 (define_expand "tablejump"
11668   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11669               (use (label_ref (match_operand 1 "" "")))])]
11670   ""
11672   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11673      relative.  Convert the relative address to an absolute address.  */
11674   if (flag_pic)
11675     {
11676       rtx op0, op1;
11677       enum rtx_code code;
11679       /* We can't use @GOTOFF for text labels on VxWorks;
11680          see gotoff_operand.  */
11681       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11682         {
11683           code = PLUS;
11684           op0 = operands[0];
11685           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11686         }
11687       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11688         {
11689           code = PLUS;
11690           op0 = operands[0];
11691           op1 = pic_offset_table_rtx;
11692         }
11693       else
11694         {
11695           code = MINUS;
11696           op0 = pic_offset_table_rtx;
11697           op1 = operands[0];
11698         }
11700       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11701                                          OPTAB_DIRECT);
11702     }
11705 (define_insn "*tablejump_1"
11706   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11707    (use (label_ref (match_operand 1 "" "")))]
11708   ""
11709   "jmp\t%A0"
11710   [(set_attr "type" "ibr")
11711    (set_attr "length_immediate" "0")])
11713 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11715 (define_peephole2
11716   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11717    (set (match_operand:QI 1 "register_operand" "")
11718         (match_operator:QI 2 "ix86_comparison_operator"
11719           [(reg FLAGS_REG) (const_int 0)]))
11720    (set (match_operand 3 "q_regs_operand" "")
11721         (zero_extend (match_dup 1)))]
11722   "(peep2_reg_dead_p (3, operands[1])
11723     || operands_match_p (operands[1], operands[3]))
11724    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11725   [(set (match_dup 4) (match_dup 0))
11726    (set (strict_low_part (match_dup 5))
11727         (match_dup 2))]
11729   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11730   operands[5] = gen_lowpart (QImode, operands[3]);
11731   ix86_expand_clear (operands[3]);
11734 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11736 (define_peephole2
11737   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11738    (set (match_operand:QI 1 "register_operand" "")
11739         (match_operator:QI 2 "ix86_comparison_operator"
11740           [(reg FLAGS_REG) (const_int 0)]))
11741    (parallel [(set (match_operand 3 "q_regs_operand" "")
11742                    (zero_extend (match_dup 1)))
11743               (clobber (reg:CC FLAGS_REG))])]
11744   "(peep2_reg_dead_p (3, operands[1])
11745     || operands_match_p (operands[1], operands[3]))
11746    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11747   [(set (match_dup 4) (match_dup 0))
11748    (set (strict_low_part (match_dup 5))
11749         (match_dup 2))]
11751   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11752   operands[5] = gen_lowpart (QImode, operands[3]);
11753   ix86_expand_clear (operands[3]);
11756 ;; Call instructions.
11758 ;; The predicates normally associated with named expanders are not properly
11759 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11760 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11762 ;; P6 processors will jump to the address after the decrement when %esp
11763 ;; is used as a call operand, so they will execute return address as a code.
11764 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11766 ;; Call subroutine returning no value.
11768 (define_expand "call_pop"
11769   [(parallel [(call (match_operand:QI 0 "" "")
11770                     (match_operand:SI 1 "" ""))
11771               (set (reg:SI SP_REG)
11772                    (plus:SI (reg:SI SP_REG)
11773                             (match_operand:SI 3 "" "")))])]
11774   "!TARGET_64BIT"
11776   ix86_expand_call (NULL, operands[0], operands[1],
11777                     operands[2], operands[3], 0);
11778   DONE;
11781 (define_insn "*call_pop_0"
11782   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11783          (match_operand:SI 1 "" ""))
11784    (set (reg:SI SP_REG)
11785         (plus:SI (reg:SI SP_REG)
11786                  (match_operand:SI 2 "immediate_operand" "")))]
11787   "!TARGET_64BIT"
11789   if (SIBLING_CALL_P (insn))
11790     return "jmp\t%P0";
11791   else
11792     return "call\t%P0";
11794   [(set_attr "type" "call")])
11796 (define_insn "*call_pop_1"
11797   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11798          (match_operand:SI 1 "" ""))
11799    (set (reg:SI SP_REG)
11800         (plus:SI (reg:SI SP_REG)
11801                  (match_operand:SI 2 "immediate_operand" "i")))]
11802   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11804   if (constant_call_address_operand (operands[0], Pmode))
11805     return "call\t%P0";
11806   return "call\t%A0";
11808   [(set_attr "type" "call")])
11810 (define_insn "*sibcall_pop_1"
11811   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11812          (match_operand:SI 1 "" ""))
11813    (set (reg:SI SP_REG)
11814         (plus:SI (reg:SI SP_REG)
11815                  (match_operand:SI 2 "immediate_operand" "i,i")))]
11816   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11817   "@
11818    jmp\t%P0
11819    jmp\t%A0"
11820   [(set_attr "type" "call")])
11822 (define_expand "call"
11823   [(call (match_operand:QI 0 "" "")
11824          (match_operand 1 "" ""))
11825    (use (match_operand 2 "" ""))]
11826   ""
11828   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11829   DONE;
11832 (define_expand "sibcall"
11833   [(call (match_operand:QI 0 "" "")
11834          (match_operand 1 "" ""))
11835    (use (match_operand 2 "" ""))]
11836   ""
11838   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11839   DONE;
11842 (define_insn "*call_0"
11843   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11844          (match_operand 1 "" ""))]
11845   ""
11847   if (SIBLING_CALL_P (insn))
11848     return "jmp\t%P0";
11849   else
11850     return "call\t%P0";
11852   [(set_attr "type" "call")])
11854 (define_insn "*call_1"
11855   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11856          (match_operand 1 "" ""))]
11857   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11859   if (constant_call_address_operand (operands[0], Pmode))
11860     return "call\t%P0";
11861   return "call\t%A0";
11863   [(set_attr "type" "call")])
11865 (define_insn "*sibcall_1"
11866   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11867          (match_operand 1 "" ""))]
11868   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11869   "@
11870    jmp\t%P0
11871    jmp\t%A0"
11872   [(set_attr "type" "call")])
11874 (define_insn "*call_1_rex64"
11875   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11876          (match_operand 1 "" ""))]
11877   "TARGET_64BIT && !SIBLING_CALL_P (insn)
11878    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11880   if (constant_call_address_operand (operands[0], Pmode))
11881     return "call\t%P0";
11882   return "call\t%A0";
11884   [(set_attr "type" "call")])
11886 (define_insn "*call_1_rex64_ms_sysv"
11887   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11888          (match_operand 1 "" ""))
11889    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11890    (clobber (reg:TI XMM6_REG))
11891    (clobber (reg:TI XMM7_REG))
11892    (clobber (reg:TI XMM8_REG))
11893    (clobber (reg:TI XMM9_REG))
11894    (clobber (reg:TI XMM10_REG))
11895    (clobber (reg:TI XMM11_REG))
11896    (clobber (reg:TI XMM12_REG))
11897    (clobber (reg:TI XMM13_REG))
11898    (clobber (reg:TI XMM14_REG))
11899    (clobber (reg:TI XMM15_REG))
11900    (clobber (reg:DI SI_REG))
11901    (clobber (reg:DI DI_REG))]
11902   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11904   if (constant_call_address_operand (operands[0], Pmode))
11905     return "call\t%P0";
11906   return "call\t%A0";
11908   [(set_attr "type" "call")])
11910 (define_insn "*call_1_rex64_large"
11911   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11912          (match_operand 1 "" ""))]
11913   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11914   "call\t%A0"
11915   [(set_attr "type" "call")])
11917 (define_insn "*sibcall_1_rex64"
11918   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11919          (match_operand 1 "" ""))]
11920   "TARGET_64BIT && SIBLING_CALL_P (insn)"
11921   "@
11922    jmp\t%P0
11923    jmp\t%A0"
11924   [(set_attr "type" "call")])
11926 ;; Call subroutine, returning value in operand 0
11927 (define_expand "call_value_pop"
11928   [(parallel [(set (match_operand 0 "" "")
11929                    (call (match_operand:QI 1 "" "")
11930                          (match_operand:SI 2 "" "")))
11931               (set (reg:SI SP_REG)
11932                    (plus:SI (reg:SI SP_REG)
11933                             (match_operand:SI 4 "" "")))])]
11934   "!TARGET_64BIT"
11936   ix86_expand_call (operands[0], operands[1], operands[2],
11937                     operands[3], operands[4], 0);
11938   DONE;
11941 (define_expand "call_value"
11942   [(set (match_operand 0 "" "")
11943         (call (match_operand:QI 1 "" "")
11944               (match_operand:SI 2 "" "")))
11945    (use (match_operand:SI 3 "" ""))]
11946   ;; Operand 3 is not used on the i386.
11947   ""
11949   ix86_expand_call (operands[0], operands[1], operands[2],
11950                     operands[3], NULL, 0);
11951   DONE;
11954 (define_expand "sibcall_value"
11955   [(set (match_operand 0 "" "")
11956         (call (match_operand:QI 1 "" "")
11957               (match_operand:SI 2 "" "")))
11958    (use (match_operand:SI 3 "" ""))]
11959   ;; Operand 3 is not used on the i386.
11960   ""
11962   ix86_expand_call (operands[0], operands[1], operands[2],
11963                     operands[3], NULL, 1);
11964   DONE;
11967 ;; Call subroutine returning any type.
11969 (define_expand "untyped_call"
11970   [(parallel [(call (match_operand 0 "" "")
11971                     (const_int 0))
11972               (match_operand 1 "" "")
11973               (match_operand 2 "" "")])]
11974   ""
11976   int i;
11978   /* In order to give reg-stack an easier job in validating two
11979      coprocessor registers as containing a possible return value,
11980      simply pretend the untyped call returns a complex long double
11981      value. 
11983      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11984      and should have the default ABI.  */
11986   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11987                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11988                     operands[0], const0_rtx,
11989                     GEN_INT ((TARGET_64BIT
11990                               ? (ix86_abi == SYSV_ABI
11991                                  ? X86_64_SSE_REGPARM_MAX
11992                                  : X86_64_MS_SSE_REGPARM_MAX)
11993                               : X86_32_SSE_REGPARM_MAX)
11994                              - 1),
11995                     NULL, 0);
11997   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11998     {
11999       rtx set = XVECEXP (operands[2], 0, i);
12000       emit_move_insn (SET_DEST (set), SET_SRC (set));
12001     }
12003   /* The optimizer does not know that the call sets the function value
12004      registers we stored in the result block.  We avoid problems by
12005      claiming that all hard registers are used and clobbered at this
12006      point.  */
12007   emit_insn (gen_blockage ());
12009   DONE;
12012 ;; Prologue and epilogue instructions
12014 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
12015 ;; all of memory.  This blocks insns from being moved across this point.
12017 (define_insn "blockage"
12018   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
12019   ""
12020   ""
12021   [(set_attr "length" "0")])
12023 ;; Do not schedule instructions accessing memory across this point.
12025 (define_expand "memory_blockage"
12026   [(set (match_dup 0)
12027         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12028   ""
12030   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
12031   MEM_VOLATILE_P (operands[0]) = 1;
12034 (define_insn "*memory_blockage"
12035   [(set (match_operand:BLK 0 "" "")
12036         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
12037   ""
12038   ""
12039   [(set_attr "length" "0")])
12041 ;; As USE insns aren't meaningful after reload, this is used instead
12042 ;; to prevent deleting instructions setting registers for PIC code
12043 (define_insn "prologue_use"
12044   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
12045   ""
12046   ""
12047   [(set_attr "length" "0")])
12049 ;; Insn emitted into the body of a function to return from a function.
12050 ;; This is only done if the function's epilogue is known to be simple.
12051 ;; See comments for ix86_can_use_return_insn_p in i386.c.
12053 (define_expand "return"
12054   [(return)]
12055   "ix86_can_use_return_insn_p ()"
12057   if (crtl->args.pops_args)
12058     {
12059       rtx popc = GEN_INT (crtl->args.pops_args);
12060       emit_jump_insn (gen_return_pop_internal (popc));
12061       DONE;
12062     }
12065 (define_insn "return_internal"
12066   [(return)]
12067   "reload_completed"
12068   "ret"
12069   [(set_attr "length" "1")
12070    (set_attr "atom_unit" "jeu")
12071    (set_attr "length_immediate" "0")
12072    (set_attr "modrm" "0")])
12074 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
12075 ;; instruction Athlon and K8 have.
12077 (define_insn "return_internal_long"
12078   [(return)
12079    (unspec [(const_int 0)] UNSPEC_REP)]
12080   "reload_completed"
12081   "rep\;ret"
12082   [(set_attr "length" "2")
12083    (set_attr "atom_unit" "jeu")
12084    (set_attr "length_immediate" "0")
12085    (set_attr "prefix_rep" "1")
12086    (set_attr "modrm" "0")])
12088 (define_insn "return_pop_internal"
12089   [(return)
12090    (use (match_operand:SI 0 "const_int_operand" ""))]
12091   "reload_completed"
12092   "ret\t%0"
12093   [(set_attr "length" "3")
12094    (set_attr "atom_unit" "jeu")
12095    (set_attr "length_immediate" "2")
12096    (set_attr "modrm" "0")])
12098 (define_insn "return_indirect_internal"
12099   [(return)
12100    (use (match_operand:SI 0 "register_operand" "r"))]
12101   "reload_completed"
12102   "jmp\t%A0"
12103   [(set_attr "type" "ibr")
12104    (set_attr "length_immediate" "0")])
12106 (define_insn "nop"
12107   [(const_int 0)]
12108   ""
12109   "nop"
12110   [(set_attr "length" "1")
12111    (set_attr "length_immediate" "0")
12112    (set_attr "modrm" "0")])
12114 (define_insn "vswapmov"
12115   [(set (match_operand:SI 0 "register_operand" "=r")
12116         (match_operand:SI 1 "register_operand" "r"))
12117    (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
12118   ""
12119   "movl.s\t{%1, %0|%0, %1}"
12120   [(set_attr "length" "2")
12121    (set_attr "length_immediate" "0")
12122    (set_attr "modrm" "0")])
12124 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
12125 ;; branch prediction penalty for the third jump in a 16-byte
12126 ;; block on K8.
12128 (define_insn "pad"
12129   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
12130   ""
12132 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
12133   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
12134 #else
12135   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
12136      The align insn is used to avoid 3 jump instructions in the row to improve
12137      branch prediction and the benefits hardly outweigh the cost of extra 8
12138      nops on the average inserted by full alignment pseudo operation.  */
12139 #endif
12140   return "";
12142   [(set_attr "length" "16")])
12144 (define_expand "prologue"
12145   [(const_int 0)]
12146   ""
12147   "ix86_expand_prologue (); DONE;")
12149 (define_insn "set_got"
12150   [(set (match_operand:SI 0 "register_operand" "=r")
12151         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12152    (clobber (reg:CC FLAGS_REG))]
12153   "!TARGET_64BIT"
12154   { return output_set_got (operands[0], NULL_RTX); }
12155   [(set_attr "type" "multi")
12156    (set_attr "length" "12")])
12158 (define_insn "set_got_labelled"
12159   [(set (match_operand:SI 0 "register_operand" "=r")
12160         (unspec:SI [(label_ref (match_operand 1 "" ""))]
12161          UNSPEC_SET_GOT))
12162    (clobber (reg:CC FLAGS_REG))]
12163   "!TARGET_64BIT"
12164   { return output_set_got (operands[0], operands[1]); }
12165   [(set_attr "type" "multi")
12166    (set_attr "length" "12")])
12168 (define_insn "set_got_rex64"
12169   [(set (match_operand:DI 0 "register_operand" "=r")
12170         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12171   "TARGET_64BIT"
12172   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12173   [(set_attr "type" "lea")
12174    (set_attr "length_address" "4")
12175    (set_attr "mode" "DI")])
12177 (define_insn "set_rip_rex64"
12178   [(set (match_operand:DI 0 "register_operand" "=r")
12179         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
12180   "TARGET_64BIT"
12181   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12182   [(set_attr "type" "lea")
12183    (set_attr "length_address" "4")
12184    (set_attr "mode" "DI")])
12186 (define_insn "set_got_offset_rex64"
12187   [(set (match_operand:DI 0 "register_operand" "=r")
12188         (unspec:DI
12189           [(label_ref (match_operand 1 "" ""))]
12190           UNSPEC_SET_GOT_OFFSET))]
12191   "TARGET_64BIT"
12192   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12193   [(set_attr "type" "imov")
12194    (set_attr "length_immediate" "0")
12195    (set_attr "length_address" "8")
12196    (set_attr "mode" "DI")])
12198 (define_expand "epilogue"
12199   [(const_int 0)]
12200   ""
12201   "ix86_expand_epilogue (1); DONE;")
12203 (define_expand "sibcall_epilogue"
12204   [(const_int 0)]
12205   ""
12206   "ix86_expand_epilogue (0); DONE;")
12208 (define_expand "eh_return"
12209   [(use (match_operand 0 "register_operand" ""))]
12210   ""
12212   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12214   /* Tricky bit: we write the address of the handler to which we will
12215      be returning into someone else's stack frame, one word below the
12216      stack address we wish to restore.  */
12217   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12218   tmp = plus_constant (tmp, -UNITS_PER_WORD);
12219   tmp = gen_rtx_MEM (Pmode, tmp);
12220   emit_move_insn (tmp, ra);
12222   emit_jump_insn (gen_eh_return_internal ());
12223   emit_barrier ();
12224   DONE;
12227 (define_insn_and_split "eh_return_internal"
12228   [(eh_return)]
12229   ""
12230   "#"
12231   "epilogue_completed"
12232   [(const_int 0)]
12233   "ix86_expand_epilogue (2); DONE;")
12235 (define_insn "leave"
12236   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12237    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12238    (clobber (mem:BLK (scratch)))]
12239   "!TARGET_64BIT"
12240   "leave"
12241   [(set_attr "type" "leave")])
12243 (define_insn "leave_rex64"
12244   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12245    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12246    (clobber (mem:BLK (scratch)))]
12247   "TARGET_64BIT"
12248   "leave"
12249   [(set_attr "type" "leave")])
12251 (define_expand "ffssi2"
12252   [(parallel
12253      [(set (match_operand:SI 0 "register_operand" "")
12254            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
12255       (clobber (match_scratch:SI 2 ""))
12256       (clobber (reg:CC FLAGS_REG))])]
12257   ""
12259   if (TARGET_CMOVE)
12260     {
12261       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
12262       DONE;
12263     }
12266 (define_expand "ffs_cmove"
12267   [(set (match_dup 2) (const_int -1))
12268    (parallel [(set (reg:CCZ FLAGS_REG)
12269                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
12270                                 (const_int 0)))
12271               (set (match_operand:SI 0 "register_operand" "")
12272                    (ctz:SI (match_dup 1)))])
12273    (set (match_dup 0) (if_then_else:SI
12274                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
12275                         (match_dup 2)
12276                         (match_dup 0)))
12277    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12278               (clobber (reg:CC FLAGS_REG))])]
12279   "TARGET_CMOVE"
12280   "operands[2] = gen_reg_rtx (SImode);")
12282 (define_insn_and_split "*ffs_no_cmove"
12283   [(set (match_operand:SI 0 "register_operand" "=r")
12284         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12285    (clobber (match_scratch:SI 2 "=&q"))
12286    (clobber (reg:CC FLAGS_REG))]
12287   "!TARGET_CMOVE"
12288   "#"
12289   "&& reload_completed"
12290   [(parallel [(set (reg:CCZ FLAGS_REG)
12291                    (compare:CCZ (match_dup 1) (const_int 0)))
12292               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12293    (set (strict_low_part (match_dup 3))
12294         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12295    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12296               (clobber (reg:CC FLAGS_REG))])
12297    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12298               (clobber (reg:CC FLAGS_REG))])
12299    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12300               (clobber (reg:CC FLAGS_REG))])]
12302   operands[3] = gen_lowpart (QImode, operands[2]);
12303   ix86_expand_clear (operands[2]);
12306 (define_insn "*ffssi_1"
12307   [(set (reg:CCZ FLAGS_REG)
12308         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
12309                      (const_int 0)))
12310    (set (match_operand:SI 0 "register_operand" "=r")
12311         (ctz:SI (match_dup 1)))]
12312   ""
12313   "bsf{l}\t{%1, %0|%0, %1}"
12314   [(set_attr "type" "alu1")
12315    (set_attr "prefix_0f" "1")
12316    (set_attr "mode" "SI")])
12318 (define_expand "ffsdi2"
12319   [(set (match_dup 2) (const_int -1))
12320    (parallel [(set (reg:CCZ FLAGS_REG)
12321                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
12322                                 (const_int 0)))
12323               (set (match_operand:DI 0 "register_operand" "")
12324                    (ctz:DI (match_dup 1)))])
12325    (set (match_dup 0) (if_then_else:DI
12326                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
12327                         (match_dup 2)
12328                         (match_dup 0)))
12329    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
12330               (clobber (reg:CC FLAGS_REG))])]
12331   "TARGET_64BIT"
12332   "operands[2] = gen_reg_rtx (DImode);")
12334 (define_insn "*ffsdi_1"
12335   [(set (reg:CCZ FLAGS_REG)
12336         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
12337                      (const_int 0)))
12338    (set (match_operand:DI 0 "register_operand" "=r")
12339         (ctz:DI (match_dup 1)))]
12340   "TARGET_64BIT"
12341   "bsf{q}\t{%1, %0|%0, %1}"
12342   [(set_attr "type" "alu1")
12343    (set_attr "prefix_0f" "1")
12344    (set_attr "mode" "DI")])
12346 (define_insn "ctzsi2"
12347   [(set (match_operand:SI 0 "register_operand" "=r")
12348         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12349    (clobber (reg:CC FLAGS_REG))]
12350   ""
12351   "bsf{l}\t{%1, %0|%0, %1}"
12352   [(set_attr "type" "alu1")
12353    (set_attr "prefix_0f" "1")
12354    (set_attr "mode" "SI")])
12356 (define_insn "ctzdi2"
12357   [(set (match_operand:DI 0 "register_operand" "=r")
12358         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
12359    (clobber (reg:CC FLAGS_REG))]
12360   "TARGET_64BIT"
12361   "bsf{q}\t{%1, %0|%0, %1}"
12362   [(set_attr "type" "alu1")
12363    (set_attr "prefix_0f" "1")
12364    (set_attr "mode" "DI")])
12366 (define_expand "clzsi2"
12367   [(parallel
12368      [(set (match_operand:SI 0 "register_operand" "")
12369            (minus:SI (const_int 31)
12370                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
12371       (clobber (reg:CC FLAGS_REG))])
12372    (parallel
12373      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
12374       (clobber (reg:CC FLAGS_REG))])]
12375   ""
12377   if (TARGET_ABM)
12378     {
12379       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
12380       DONE;
12381     }
12384 (define_insn "clzsi2_abm"
12385   [(set (match_operand:SI 0 "register_operand" "=r")
12386         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12387    (clobber (reg:CC FLAGS_REG))]
12388   "TARGET_ABM"
12389   "lzcnt{l}\t{%1, %0|%0, %1}"
12390   [(set_attr "prefix_rep" "1")
12391    (set_attr "type" "bitmanip")
12392    (set_attr "mode" "SI")])
12394 (define_insn "bsr"
12395   [(set (match_operand:SI 0 "register_operand" "=r")
12396         (minus:SI (const_int 31)
12397                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12398    (clobber (reg:CC FLAGS_REG))]
12399   ""
12400   "bsr{l}\t{%1, %0|%0, %1}"
12401   [(set_attr "type" "alu1")
12402    (set_attr "prefix_0f" "1")
12403    (set_attr "mode" "SI")])
12405 (define_insn "popcount<mode>2"
12406   [(set (match_operand:SWI248 0 "register_operand" "=r")
12407         (popcount:SWI248
12408           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12409    (clobber (reg:CC FLAGS_REG))]
12410   "TARGET_POPCNT"
12412 #if TARGET_MACHO
12413   return "popcnt\t{%1, %0|%0, %1}";
12414 #else
12415   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12416 #endif
12418   [(set_attr "prefix_rep" "1")
12419    (set_attr "type" "bitmanip")
12420    (set_attr "mode" "<MODE>")])
12422 (define_insn "*popcount<mode>2_cmp"
12423   [(set (reg FLAGS_REG)
12424         (compare
12425           (popcount:SWI248
12426             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12427           (const_int 0)))
12428    (set (match_operand:SWI248 0 "register_operand" "=r")
12429         (popcount:SWI248 (match_dup 1)))]
12430   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12432 #if TARGET_MACHO
12433   return "popcnt\t{%1, %0|%0, %1}";
12434 #else
12435   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12436 #endif
12438   [(set_attr "prefix_rep" "1")
12439    (set_attr "type" "bitmanip")
12440    (set_attr "mode" "<MODE>")])
12442 (define_insn "*popcountsi2_cmp_zext"
12443   [(set (reg FLAGS_REG)
12444         (compare
12445           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12446           (const_int 0)))
12447    (set (match_operand:DI 0 "register_operand" "=r")
12448         (zero_extend:DI(popcount:SI (match_dup 1))))]
12449   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12451 #if TARGET_MACHO
12452   return "popcnt\t{%1, %0|%0, %1}";
12453 #else
12454   return "popcnt{l}\t{%1, %0|%0, %1}";
12455 #endif
12457   [(set_attr "prefix_rep" "1")
12458    (set_attr "type" "bitmanip")
12459    (set_attr "mode" "SI")])
12461 (define_expand "bswapsi2"
12462   [(set (match_operand:SI 0 "register_operand" "")
12463         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
12464   ""
12466   if (!(TARGET_BSWAP || TARGET_MOVBE))
12467     {
12468       rtx x = operands[0];
12470       emit_move_insn (x, operands[1]);
12471       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12472       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12473       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12474       DONE;
12475     }
12478 (define_insn "*bswapsi_movbe"
12479   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
12480         (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
12481   "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12482   "@
12483     bswap\t%0
12484     movbe\t{%1, %0|%0, %1}
12485     movbe\t{%1, %0|%0, %1}"
12486   [(set_attr "type" "*,imov,imov")
12487    (set_attr "modrm" "*,1,1")
12488    (set_attr "prefix_0f" "1")
12489    (set_attr "prefix_extra" "*,1,1")
12490    (set_attr "length" "2,*,*")
12491    (set_attr "mode" "SI")])
12493 (define_insn "*bswapsi_1"
12494   [(set (match_operand:SI 0 "register_operand" "=r")
12495         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
12496   "TARGET_BSWAP"
12497   "bswap\t%0"
12498   [(set_attr "prefix_0f" "1")
12499    (set_attr "length" "2")])
12501 (define_insn "*bswaphi_lowpart_1"
12502   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12503         (bswap:HI (match_dup 0)))
12504    (clobber (reg:CC FLAGS_REG))]
12505   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12506   "@
12507     xchg{b}\t{%h0, %b0|%b0, %h0}
12508     rol{w}\t{$8, %0|%0, 8}"
12509   [(set_attr "length" "2,4")
12510    (set_attr "mode" "QI,HI")])
12512 (define_insn "bswaphi_lowpart"
12513   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12514         (bswap:HI (match_dup 0)))
12515    (clobber (reg:CC FLAGS_REG))]
12516   ""
12517   "rol{w}\t{$8, %0|%0, 8}"
12518   [(set_attr "length" "4")
12519    (set_attr "mode" "HI")])
12521 (define_expand "bswapdi2"
12522   [(set (match_operand:DI 0 "register_operand" "")
12523         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
12524   "TARGET_64BIT"
12525   "")
12527 (define_insn "*bswapdi_movbe"
12528   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12529         (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12530   "TARGET_64BIT && TARGET_MOVBE
12531    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12532   "@
12533     bswap\t%0
12534     movbe\t{%1, %0|%0, %1}
12535     movbe\t{%1, %0|%0, %1}"
12536   [(set_attr "type" "*,imov,imov")
12537    (set_attr "modrm" "*,1,1")
12538    (set_attr "prefix_0f" "1")
12539    (set_attr "prefix_extra" "*,1,1")
12540    (set_attr "length" "3,*,*")
12541    (set_attr "mode" "DI")])
12543 (define_insn "*bswapdi_1"
12544   [(set (match_operand:DI 0 "register_operand" "=r")
12545         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
12546   "TARGET_64BIT"
12547   "bswap\t%0"
12548   [(set_attr "prefix_0f" "1")
12549    (set_attr "length" "3")])
12551 (define_expand "clzdi2"
12552   [(parallel
12553      [(set (match_operand:DI 0 "register_operand" "")
12554            (minus:DI (const_int 63)
12555                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
12556       (clobber (reg:CC FLAGS_REG))])
12557    (parallel
12558      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
12559       (clobber (reg:CC FLAGS_REG))])]
12560   "TARGET_64BIT"
12562   if (TARGET_ABM)
12563     {
12564       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
12565       DONE;
12566     }
12569 (define_insn "clzdi2_abm"
12570   [(set (match_operand:DI 0 "register_operand" "=r")
12571         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
12572    (clobber (reg:CC FLAGS_REG))]
12573   "TARGET_64BIT && TARGET_ABM"
12574   "lzcnt{q}\t{%1, %0|%0, %1}"
12575   [(set_attr "prefix_rep" "1")
12576    (set_attr "type" "bitmanip")
12577    (set_attr "mode" "DI")])
12579 (define_insn "bsr_rex64"
12580   [(set (match_operand:DI 0 "register_operand" "=r")
12581         (minus:DI (const_int 63)
12582                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12583    (clobber (reg:CC FLAGS_REG))]
12584   "TARGET_64BIT"
12585   "bsr{q}\t{%1, %0|%0, %1}"
12586   [(set_attr "type" "alu1")
12587    (set_attr "prefix_0f" "1")
12588    (set_attr "mode" "DI")])
12590 (define_expand "clzhi2"
12591   [(parallel
12592      [(set (match_operand:HI 0 "register_operand" "")
12593            (minus:HI (const_int 15)
12594                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
12595       (clobber (reg:CC FLAGS_REG))])
12596    (parallel
12597      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
12598       (clobber (reg:CC FLAGS_REG))])]
12599   ""
12601   if (TARGET_ABM)
12602     {
12603       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
12604       DONE;
12605     }
12608 (define_insn "clzhi2_abm"
12609   [(set (match_operand:HI 0 "register_operand" "=r")
12610         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
12611    (clobber (reg:CC FLAGS_REG))]
12612   "TARGET_ABM"
12613   "lzcnt{w}\t{%1, %0|%0, %1}"
12614   [(set_attr "prefix_rep" "1")
12615    (set_attr "type" "bitmanip")
12616    (set_attr "mode" "HI")])
12618 (define_insn "*bsrhi"
12619   [(set (match_operand:HI 0 "register_operand" "=r")
12620         (minus:HI (const_int 15)
12621                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12622    (clobber (reg:CC FLAGS_REG))]
12623   ""
12624   "bsr{w}\t{%1, %0|%0, %1}"
12625   [(set_attr "type" "alu1")
12626    (set_attr "prefix_0f" "1")
12627    (set_attr "mode" "HI")])
12629 (define_expand "paritydi2"
12630   [(set (match_operand:DI 0 "register_operand" "")
12631         (parity:DI (match_operand:DI 1 "register_operand" "")))]
12632   "! TARGET_POPCNT"
12634   rtx scratch = gen_reg_rtx (QImode);
12635   rtx cond;
12637   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12638                                 NULL_RTX, operands[1]));
12640   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12641                          gen_rtx_REG (CCmode, FLAGS_REG),
12642                          const0_rtx);
12643   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12645   if (TARGET_64BIT)
12646     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12647   else
12648     {
12649       rtx tmp = gen_reg_rtx (SImode);
12651       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12652       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12653     }
12654   DONE;
12657 (define_insn_and_split "paritydi2_cmp"
12658   [(set (reg:CC FLAGS_REG)
12659         (parity:CC (match_operand:DI 3 "register_operand" "0")))
12660    (clobber (match_scratch:DI 0 "=r"))
12661    (clobber (match_scratch:SI 1 "=&r"))
12662    (clobber (match_scratch:HI 2 "=Q"))]
12663   "! TARGET_POPCNT"
12664   "#"
12665   "&& reload_completed"
12666   [(parallel
12667      [(set (match_dup 1)
12668            (xor:SI (match_dup 1) (match_dup 4)))
12669       (clobber (reg:CC FLAGS_REG))])
12670    (parallel
12671      [(set (reg:CC FLAGS_REG)
12672            (parity:CC (match_dup 1)))
12673       (clobber (match_dup 1))
12674       (clobber (match_dup 2))])]
12676   operands[4] = gen_lowpart (SImode, operands[3]);
12678   if (TARGET_64BIT)
12679     {
12680       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12681       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12682     }
12683   else
12684     operands[1] = gen_highpart (SImode, operands[3]);
12687 (define_expand "paritysi2"
12688   [(set (match_operand:SI 0 "register_operand" "")
12689         (parity:SI (match_operand:SI 1 "register_operand" "")))]
12690   "! TARGET_POPCNT"
12692   rtx scratch = gen_reg_rtx (QImode);
12693   rtx cond;
12695   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12697   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12698                          gen_rtx_REG (CCmode, FLAGS_REG),
12699                          const0_rtx);
12700   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12702   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12703   DONE;
12706 (define_insn_and_split "paritysi2_cmp"
12707   [(set (reg:CC FLAGS_REG)
12708         (parity:CC (match_operand:SI 2 "register_operand" "0")))
12709    (clobber (match_scratch:SI 0 "=r"))
12710    (clobber (match_scratch:HI 1 "=&Q"))]
12711   "! TARGET_POPCNT"
12712   "#"
12713   "&& reload_completed"
12714   [(parallel
12715      [(set (match_dup 1)
12716            (xor:HI (match_dup 1) (match_dup 3)))
12717       (clobber (reg:CC FLAGS_REG))])
12718    (parallel
12719      [(set (reg:CC FLAGS_REG)
12720            (parity:CC (match_dup 1)))
12721       (clobber (match_dup 1))])]
12723   operands[3] = gen_lowpart (HImode, operands[2]);
12725   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12726   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12729 (define_insn "*parityhi2_cmp"
12730   [(set (reg:CC FLAGS_REG)
12731         (parity:CC (match_operand:HI 1 "register_operand" "0")))
12732    (clobber (match_scratch:HI 0 "=Q"))]
12733   "! TARGET_POPCNT"
12734   "xor{b}\t{%h0, %b0|%b0, %h0}"
12735   [(set_attr "length" "2")
12736    (set_attr "mode" "HI")])
12738 (define_insn "*parityqi2_cmp"
12739   [(set (reg:CC FLAGS_REG)
12740         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
12741   "! TARGET_POPCNT"
12742   "test{b}\t%0, %0"
12743   [(set_attr "length" "2")
12744    (set_attr "mode" "QI")])
12746 ;; Thread-local storage patterns for ELF.
12748 ;; Note that these code sequences must appear exactly as shown
12749 ;; in order to allow linker relaxation.
12751 (define_insn "*tls_global_dynamic_32_gnu"
12752   [(set (match_operand:SI 0 "register_operand" "=a")
12753         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12754                     (match_operand:SI 2 "tls_symbolic_operand" "")
12755                     (match_operand:SI 3 "call_insn_operand" "")]
12756                     UNSPEC_TLS_GD))
12757    (clobber (match_scratch:SI 4 "=d"))
12758    (clobber (match_scratch:SI 5 "=c"))
12759    (clobber (reg:CC FLAGS_REG))]
12760   "!TARGET_64BIT && TARGET_GNU_TLS"
12761   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12762   [(set_attr "type" "multi")
12763    (set_attr "length" "12")])
12765 (define_expand "tls_global_dynamic_32"
12766   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12767                    (unspec:SI
12768                     [(match_dup 2)
12769                      (match_operand:SI 1 "tls_symbolic_operand" "")
12770                      (match_dup 3)]
12771                     UNSPEC_TLS_GD))
12772               (clobber (match_scratch:SI 4 ""))
12773               (clobber (match_scratch:SI 5 ""))
12774               (clobber (reg:CC FLAGS_REG))])]
12775   ""
12777   if (flag_pic)
12778     operands[2] = pic_offset_table_rtx;
12779   else
12780     {
12781       operands[2] = gen_reg_rtx (Pmode);
12782       emit_insn (gen_set_got (operands[2]));
12783     }
12784   if (TARGET_GNU2_TLS)
12785     {
12786        emit_insn (gen_tls_dynamic_gnu2_32
12787                   (operands[0], operands[1], operands[2]));
12788        DONE;
12789     }
12790   operands[3] = ix86_tls_get_addr ();
12793 (define_insn "*tls_global_dynamic_64"
12794   [(set (match_operand:DI 0 "register_operand" "=a")
12795         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12796                  (match_operand:DI 3 "" "")))
12797    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12798               UNSPEC_TLS_GD)]
12799   "TARGET_64BIT"
12800   { 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"; }
12801   [(set_attr "type" "multi")
12802    (set_attr "length" "16")])
12804 (define_expand "tls_global_dynamic_64"
12805   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12806                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12807               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12808                          UNSPEC_TLS_GD)])]
12809   ""
12811   if (TARGET_GNU2_TLS)
12812     {
12813        emit_insn (gen_tls_dynamic_gnu2_64
12814                   (operands[0], operands[1]));
12815        DONE;
12816     }
12817   operands[2] = ix86_tls_get_addr ();
12820 (define_insn "*tls_local_dynamic_base_32_gnu"
12821   [(set (match_operand:SI 0 "register_operand" "=a")
12822         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12823                     (match_operand:SI 2 "call_insn_operand" "")]
12824                    UNSPEC_TLS_LD_BASE))
12825    (clobber (match_scratch:SI 3 "=d"))
12826    (clobber (match_scratch:SI 4 "=c"))
12827    (clobber (reg:CC FLAGS_REG))]
12828   "!TARGET_64BIT && TARGET_GNU_TLS"
12829   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12830   [(set_attr "type" "multi")
12831    (set_attr "length" "11")])
12833 (define_expand "tls_local_dynamic_base_32"
12834   [(parallel [(set (match_operand:SI 0 "register_operand" "")
12835                    (unspec:SI [(match_dup 1) (match_dup 2)]
12836                               UNSPEC_TLS_LD_BASE))
12837               (clobber (match_scratch:SI 3 ""))
12838               (clobber (match_scratch:SI 4 ""))
12839               (clobber (reg:CC FLAGS_REG))])]
12840   ""
12842   if (flag_pic)
12843     operands[1] = pic_offset_table_rtx;
12844   else
12845     {
12846       operands[1] = gen_reg_rtx (Pmode);
12847       emit_insn (gen_set_got (operands[1]));
12848     }
12849   if (TARGET_GNU2_TLS)
12850     {
12851        emit_insn (gen_tls_dynamic_gnu2_32
12852                   (operands[0], ix86_tls_module_base (), operands[1]));
12853        DONE;
12854     }
12855   operands[2] = ix86_tls_get_addr ();
12858 (define_insn "*tls_local_dynamic_base_64"
12859   [(set (match_operand:DI 0 "register_operand" "=a")
12860         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12861                  (match_operand:DI 2 "" "")))
12862    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12863   "TARGET_64BIT"
12864   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12865   [(set_attr "type" "multi")
12866    (set_attr "length" "12")])
12868 (define_expand "tls_local_dynamic_base_64"
12869   [(parallel [(set (match_operand:DI 0 "register_operand" "")
12870                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12871               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12872   ""
12874   if (TARGET_GNU2_TLS)
12875     {
12876        emit_insn (gen_tls_dynamic_gnu2_64
12877                   (operands[0], ix86_tls_module_base ()));
12878        DONE;
12879     }
12880   operands[1] = ix86_tls_get_addr ();
12883 ;; Local dynamic of a single variable is a lose.  Show combine how
12884 ;; to convert that back to global dynamic.
12886 (define_insn_and_split "*tls_local_dynamic_32_once"
12887   [(set (match_operand:SI 0 "register_operand" "=a")
12888         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12889                              (match_operand:SI 2 "call_insn_operand" "")]
12890                             UNSPEC_TLS_LD_BASE)
12891                  (const:SI (unspec:SI
12892                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
12893                             UNSPEC_DTPOFF))))
12894    (clobber (match_scratch:SI 4 "=d"))
12895    (clobber (match_scratch:SI 5 "=c"))
12896    (clobber (reg:CC FLAGS_REG))]
12897   ""
12898   "#"
12899   ""
12900   [(parallel [(set (match_dup 0)
12901                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12902                               UNSPEC_TLS_GD))
12903               (clobber (match_dup 4))
12904               (clobber (match_dup 5))
12905               (clobber (reg:CC FLAGS_REG))])]
12906   "")
12908 ;; Load and add the thread base pointer from %gs:0.
12910 (define_insn "*load_tp_si"
12911   [(set (match_operand:SI 0 "register_operand" "=r")
12912         (unspec:SI [(const_int 0)] UNSPEC_TP))]
12913   "!TARGET_64BIT"
12914   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12915   [(set_attr "type" "imov")
12916    (set_attr "modrm" "0")
12917    (set_attr "length" "7")
12918    (set_attr "memory" "load")
12919    (set_attr "imm_disp" "false")])
12921 (define_insn "*add_tp_si"
12922   [(set (match_operand:SI 0 "register_operand" "=r")
12923         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12924                  (match_operand:SI 1 "register_operand" "0")))
12925    (clobber (reg:CC FLAGS_REG))]
12926   "!TARGET_64BIT"
12927   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12928   [(set_attr "type" "alu")
12929    (set_attr "modrm" "0")
12930    (set_attr "length" "7")
12931    (set_attr "memory" "load")
12932    (set_attr "imm_disp" "false")])
12934 (define_insn "*load_tp_di"
12935   [(set (match_operand:DI 0 "register_operand" "=r")
12936         (unspec:DI [(const_int 0)] UNSPEC_TP))]
12937   "TARGET_64BIT"
12938   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12939   [(set_attr "type" "imov")
12940    (set_attr "modrm" "0")
12941    (set_attr "length" "7")
12942    (set_attr "memory" "load")
12943    (set_attr "imm_disp" "false")])
12945 (define_insn "*add_tp_di"
12946   [(set (match_operand:DI 0 "register_operand" "=r")
12947         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12948                  (match_operand:DI 1 "register_operand" "0")))
12949    (clobber (reg:CC FLAGS_REG))]
12950   "TARGET_64BIT"
12951   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12952   [(set_attr "type" "alu")
12953    (set_attr "modrm" "0")
12954    (set_attr "length" "7")
12955    (set_attr "memory" "load")
12956    (set_attr "imm_disp" "false")])
12958 ;; GNU2 TLS patterns can be split.
12960 (define_expand "tls_dynamic_gnu2_32"
12961   [(set (match_dup 3)
12962         (plus:SI (match_operand:SI 2 "register_operand" "")
12963                  (const:SI
12964                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12965                              UNSPEC_TLSDESC))))
12966    (parallel
12967     [(set (match_operand:SI 0 "register_operand" "")
12968           (unspec:SI [(match_dup 1) (match_dup 3)
12969                       (match_dup 2) (reg:SI SP_REG)]
12970                       UNSPEC_TLSDESC))
12971      (clobber (reg:CC FLAGS_REG))])]
12972   "!TARGET_64BIT && TARGET_GNU2_TLS"
12974   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12975   ix86_tls_descriptor_calls_expanded_in_cfun = true;
12978 (define_insn "*tls_dynamic_lea_32"
12979   [(set (match_operand:SI 0 "register_operand" "=r")
12980         (plus:SI (match_operand:SI 1 "register_operand" "b")
12981                  (const:SI
12982                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12983                               UNSPEC_TLSDESC))))]
12984   "!TARGET_64BIT && TARGET_GNU2_TLS"
12985   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12986   [(set_attr "type" "lea")
12987    (set_attr "mode" "SI")
12988    (set_attr "length" "6")
12989    (set_attr "length_address" "4")])
12991 (define_insn "*tls_dynamic_call_32"
12992   [(set (match_operand:SI 0 "register_operand" "=a")
12993         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12994                     (match_operand:SI 2 "register_operand" "0")
12995                     ;; we have to make sure %ebx still points to the GOT
12996                     (match_operand:SI 3 "register_operand" "b")
12997                     (reg:SI SP_REG)]
12998                    UNSPEC_TLSDESC))
12999    (clobber (reg:CC FLAGS_REG))]
13000   "!TARGET_64BIT && TARGET_GNU2_TLS"
13001   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13002   [(set_attr "type" "call")
13003    (set_attr "length" "2")
13004    (set_attr "length_address" "0")])
13006 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13007   [(set (match_operand:SI 0 "register_operand" "=&a")
13008         (plus:SI
13009          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
13010                      (match_operand:SI 4 "" "")
13011                      (match_operand:SI 2 "register_operand" "b")
13012                      (reg:SI SP_REG)]
13013                     UNSPEC_TLSDESC)
13014          (const:SI (unspec:SI
13015                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
13016                     UNSPEC_DTPOFF))))
13017    (clobber (reg:CC FLAGS_REG))]
13018   "!TARGET_64BIT && TARGET_GNU2_TLS"
13019   "#"
13020   ""
13021   [(set (match_dup 0) (match_dup 5))]
13023   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13024   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13027 (define_expand "tls_dynamic_gnu2_64"
13028   [(set (match_dup 2)
13029         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13030                    UNSPEC_TLSDESC))
13031    (parallel
13032     [(set (match_operand:DI 0 "register_operand" "")
13033           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13034                      UNSPEC_TLSDESC))
13035      (clobber (reg:CC FLAGS_REG))])]
13036   "TARGET_64BIT && TARGET_GNU2_TLS"
13038   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13039   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13042 (define_insn "*tls_dynamic_lea_64"
13043   [(set (match_operand:DI 0 "register_operand" "=r")
13044         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
13045                    UNSPEC_TLSDESC))]
13046   "TARGET_64BIT && TARGET_GNU2_TLS"
13047   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
13048   [(set_attr "type" "lea")
13049    (set_attr "mode" "DI")
13050    (set_attr "length" "7")
13051    (set_attr "length_address" "4")])
13053 (define_insn "*tls_dynamic_call_64"
13054   [(set (match_operand:DI 0 "register_operand" "=a")
13055         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
13056                     (match_operand:DI 2 "register_operand" "0")
13057                     (reg:DI SP_REG)]
13058                    UNSPEC_TLSDESC))
13059    (clobber (reg:CC FLAGS_REG))]
13060   "TARGET_64BIT && TARGET_GNU2_TLS"
13061   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13062   [(set_attr "type" "call")
13063    (set_attr "length" "2")
13064    (set_attr "length_address" "0")])
13066 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13067   [(set (match_operand:DI 0 "register_operand" "=&a")
13068         (plus:DI
13069          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
13070                      (match_operand:DI 3 "" "")
13071                      (reg:DI SP_REG)]
13072                     UNSPEC_TLSDESC)
13073          (const:DI (unspec:DI
13074                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
13075                     UNSPEC_DTPOFF))))
13076    (clobber (reg:CC FLAGS_REG))]
13077   "TARGET_64BIT && TARGET_GNU2_TLS"
13078   "#"
13079   ""
13080   [(set (match_dup 0) (match_dup 4))]
13082   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13083   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13088 ;; These patterns match the binary 387 instructions for addM3, subM3,
13089 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13090 ;; SFmode.  The first is the normal insn, the second the same insn but
13091 ;; with one operand a conversion, and the third the same insn but with
13092 ;; the other operand a conversion.  The conversion may be SFmode or
13093 ;; SImode if the target mode DFmode, but only SImode if the target mode
13094 ;; is SFmode.
13096 ;; Gcc is slightly more smart about handling normal two address instructions
13097 ;; so use special patterns for add and mull.
13099 (define_insn "*fop_<mode>_comm_mixed_avx"
13100   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
13101         (match_operator:MODEF 3 "binary_fp_operator"
13102           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13103            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
13104   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13105    && COMMUTATIVE_ARITH_P (operands[3])
13106    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13107   "* return output_387_binary_op (insn, operands);"
13108   [(set (attr "type")
13109         (if_then_else (eq_attr "alternative" "1")
13110            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13111               (const_string "ssemul")
13112               (const_string "sseadd"))
13113            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13114               (const_string "fmul")
13115               (const_string "fop"))))
13116    (set_attr "prefix" "orig,maybe_vex")
13117    (set_attr "mode" "<MODE>")])
13119 (define_insn "*fop_<mode>_comm_mixed"
13120   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
13121         (match_operator:MODEF 3 "binary_fp_operator"
13122           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
13123            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
13124   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13125    && COMMUTATIVE_ARITH_P (operands[3])
13126    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13127   "* return output_387_binary_op (insn, operands);"
13128   [(set (attr "type")
13129         (if_then_else (eq_attr "alternative" "1")
13130            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13131               (const_string "ssemul")
13132               (const_string "sseadd"))
13133            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13134               (const_string "fmul")
13135               (const_string "fop"))))
13136    (set_attr "mode" "<MODE>")])
13138 (define_insn "*fop_<mode>_comm_avx"
13139   [(set (match_operand:MODEF 0 "register_operand" "=x")
13140         (match_operator:MODEF 3 "binary_fp_operator"
13141           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
13142            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13143   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13144    && COMMUTATIVE_ARITH_P (operands[3])
13145    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13146   "* return output_387_binary_op (insn, operands);"
13147   [(set (attr "type")
13148         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13149            (const_string "ssemul")
13150            (const_string "sseadd")))
13151    (set_attr "prefix" "vex")
13152    (set_attr "mode" "<MODE>")])
13154 (define_insn "*fop_<mode>_comm_sse"
13155   [(set (match_operand:MODEF 0 "register_operand" "=x")
13156         (match_operator:MODEF 3 "binary_fp_operator"
13157           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13158            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13159   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13160    && COMMUTATIVE_ARITH_P (operands[3])
13161    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13162   "* return output_387_binary_op (insn, operands);"
13163   [(set (attr "type")
13164         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13165            (const_string "ssemul")
13166            (const_string "sseadd")))
13167    (set_attr "mode" "<MODE>")])
13169 (define_insn "*fop_<mode>_comm_i387"
13170   [(set (match_operand:MODEF 0 "register_operand" "=f")
13171         (match_operator:MODEF 3 "binary_fp_operator"
13172           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13173            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13174   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13175    && COMMUTATIVE_ARITH_P (operands[3])
13176    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13177   "* return output_387_binary_op (insn, operands);"
13178   [(set (attr "type")
13179         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13180            (const_string "fmul")
13181            (const_string "fop")))
13182    (set_attr "mode" "<MODE>")])
13184 (define_insn "*fop_<mode>_1_mixed_avx"
13185   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13186         (match_operator:MODEF 3 "binary_fp_operator"
13187           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
13188            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13189   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13190    && !COMMUTATIVE_ARITH_P (operands[3])
13191    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13192   "* return output_387_binary_op (insn, operands);"
13193   [(set (attr "type")
13194         (cond [(and (eq_attr "alternative" "2")
13195                     (match_operand:MODEF 3 "mult_operator" ""))
13196                  (const_string "ssemul")
13197                (and (eq_attr "alternative" "2")
13198                     (match_operand:MODEF 3 "div_operator" ""))
13199                  (const_string "ssediv")
13200                (eq_attr "alternative" "2")
13201                  (const_string "sseadd")
13202                (match_operand:MODEF 3 "mult_operator" "")
13203                  (const_string "fmul")
13204                (match_operand:MODEF 3 "div_operator" "")
13205                  (const_string "fdiv")
13206               ]
13207               (const_string "fop")))
13208    (set_attr "prefix" "orig,orig,maybe_vex")
13209    (set_attr "mode" "<MODE>")])
13211 (define_insn "*fop_<mode>_1_mixed"
13212   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
13213         (match_operator:MODEF 3 "binary_fp_operator"
13214           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
13215            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
13216   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13217    && !COMMUTATIVE_ARITH_P (operands[3])
13218    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13219   "* return output_387_binary_op (insn, operands);"
13220   [(set (attr "type")
13221         (cond [(and (eq_attr "alternative" "2")
13222                     (match_operand:MODEF 3 "mult_operator" ""))
13223                  (const_string "ssemul")
13224                (and (eq_attr "alternative" "2")
13225                     (match_operand:MODEF 3 "div_operator" ""))
13226                  (const_string "ssediv")
13227                (eq_attr "alternative" "2")
13228                  (const_string "sseadd")
13229                (match_operand:MODEF 3 "mult_operator" "")
13230                  (const_string "fmul")
13231                (match_operand:MODEF 3 "div_operator" "")
13232                  (const_string "fdiv")
13233               ]
13234               (const_string "fop")))
13235    (set_attr "mode" "<MODE>")])
13237 (define_insn "*rcpsf2_sse"
13238   [(set (match_operand:SF 0 "register_operand" "=x")
13239         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13240                    UNSPEC_RCP))]
13241   "TARGET_SSE_MATH"
13242   "%vrcpss\t{%1, %d0|%d0, %1}"
13243   [(set_attr "type" "sse")
13244    (set_attr "atom_sse_attr" "rcp")
13245    (set_attr "prefix" "maybe_vex")
13246    (set_attr "mode" "SF")])
13248 (define_insn "*fop_<mode>_1_avx"
13249   [(set (match_operand:MODEF 0 "register_operand" "=x")
13250         (match_operator:MODEF 3 "binary_fp_operator"
13251           [(match_operand:MODEF 1 "register_operand" "x")
13252            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13253   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13254    && !COMMUTATIVE_ARITH_P (operands[3])"
13255   "* return output_387_binary_op (insn, operands);"
13256   [(set (attr "type")
13257         (cond [(match_operand:MODEF 3 "mult_operator" "")
13258                  (const_string "ssemul")
13259                (match_operand:MODEF 3 "div_operator" "")
13260                  (const_string "ssediv")
13261               ]
13262               (const_string "sseadd")))
13263    (set_attr "prefix" "vex")
13264    (set_attr "mode" "<MODE>")])
13266 (define_insn "*fop_<mode>_1_sse"
13267   [(set (match_operand:MODEF 0 "register_operand" "=x")
13268         (match_operator:MODEF 3 "binary_fp_operator"
13269           [(match_operand:MODEF 1 "register_operand" "0")
13270            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
13271   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13272    && !COMMUTATIVE_ARITH_P (operands[3])"
13273   "* return output_387_binary_op (insn, operands);"
13274   [(set (attr "type")
13275         (cond [(match_operand:MODEF 3 "mult_operator" "")
13276                  (const_string "ssemul")
13277                (match_operand:MODEF 3 "div_operator" "")
13278                  (const_string "ssediv")
13279               ]
13280               (const_string "sseadd")))
13281    (set_attr "mode" "<MODE>")])
13283 ;; This pattern is not fully shadowed by the pattern above.
13284 (define_insn "*fop_<mode>_1_i387"
13285   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13286         (match_operator:MODEF 3 "binary_fp_operator"
13287           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13288            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13289   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13290    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13291    && !COMMUTATIVE_ARITH_P (operands[3])
13292    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13293   "* return output_387_binary_op (insn, operands);"
13294   [(set (attr "type")
13295         (cond [(match_operand:MODEF 3 "mult_operator" "")
13296                  (const_string "fmul")
13297                (match_operand:MODEF 3 "div_operator" "")
13298                  (const_string "fdiv")
13299               ]
13300               (const_string "fop")))
13301    (set_attr "mode" "<MODE>")])
13303 ;; ??? Add SSE splitters for these!
13304 (define_insn "*fop_<MODEF:mode>_2_i387"
13305   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13306         (match_operator:MODEF 3 "binary_fp_operator"
13307           [(float:MODEF
13308              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13309            (match_operand:MODEF 2 "register_operand" "0,0")]))]
13310   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13311    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13312    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13313   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13314   [(set (attr "type")
13315         (cond [(match_operand:MODEF 3 "mult_operator" "")
13316                  (const_string "fmul")
13317                (match_operand:MODEF 3 "div_operator" "")
13318                  (const_string "fdiv")
13319               ]
13320               (const_string "fop")))
13321    (set_attr "fp_int_src" "true")
13322    (set_attr "mode" "<X87MODEI12:MODE>")])
13324 (define_insn "*fop_<MODEF:mode>_3_i387"
13325   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13326         (match_operator:MODEF 3 "binary_fp_operator"
13327           [(match_operand:MODEF 1 "register_operand" "0,0")
13328            (float:MODEF
13329              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13330   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
13331    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13332    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13333   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13334   [(set (attr "type")
13335         (cond [(match_operand:MODEF 3 "mult_operator" "")
13336                  (const_string "fmul")
13337                (match_operand:MODEF 3 "div_operator" "")
13338                  (const_string "fdiv")
13339               ]
13340               (const_string "fop")))
13341    (set_attr "fp_int_src" "true")
13342    (set_attr "mode" "<MODE>")])
13344 (define_insn "*fop_df_4_i387"
13345   [(set (match_operand:DF 0 "register_operand" "=f,f")
13346         (match_operator:DF 3 "binary_fp_operator"
13347            [(float_extend:DF
13348              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13349             (match_operand:DF 2 "register_operand" "0,f")]))]
13350   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13351    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13352    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13353   "* return output_387_binary_op (insn, operands);"
13354   [(set (attr "type")
13355         (cond [(match_operand:DF 3 "mult_operator" "")
13356                  (const_string "fmul")
13357                (match_operand:DF 3 "div_operator" "")
13358                  (const_string "fdiv")
13359               ]
13360               (const_string "fop")))
13361    (set_attr "mode" "SF")])
13363 (define_insn "*fop_df_5_i387"
13364   [(set (match_operand:DF 0 "register_operand" "=f,f")
13365         (match_operator:DF 3 "binary_fp_operator"
13366           [(match_operand:DF 1 "register_operand" "0,f")
13367            (float_extend:DF
13368             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13369   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13370    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13371   "* return output_387_binary_op (insn, operands);"
13372   [(set (attr "type")
13373         (cond [(match_operand:DF 3 "mult_operator" "")
13374                  (const_string "fmul")
13375                (match_operand:DF 3 "div_operator" "")
13376                  (const_string "fdiv")
13377               ]
13378               (const_string "fop")))
13379    (set_attr "mode" "SF")])
13381 (define_insn "*fop_df_6_i387"
13382   [(set (match_operand:DF 0 "register_operand" "=f,f")
13383         (match_operator:DF 3 "binary_fp_operator"
13384           [(float_extend:DF
13385             (match_operand:SF 1 "register_operand" "0,f"))
13386            (float_extend:DF
13387             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13388   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13389    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13390   "* return output_387_binary_op (insn, operands);"
13391   [(set (attr "type")
13392         (cond [(match_operand:DF 3 "mult_operator" "")
13393                  (const_string "fmul")
13394                (match_operand:DF 3 "div_operator" "")
13395                  (const_string "fdiv")
13396               ]
13397               (const_string "fop")))
13398    (set_attr "mode" "SF")])
13400 (define_insn "*fop_xf_comm_i387"
13401   [(set (match_operand:XF 0 "register_operand" "=f")
13402         (match_operator:XF 3 "binary_fp_operator"
13403                         [(match_operand:XF 1 "register_operand" "%0")
13404                          (match_operand:XF 2 "register_operand" "f")]))]
13405   "TARGET_80387
13406    && COMMUTATIVE_ARITH_P (operands[3])"
13407   "* return output_387_binary_op (insn, operands);"
13408   [(set (attr "type")
13409         (if_then_else (match_operand:XF 3 "mult_operator" "")
13410            (const_string "fmul")
13411            (const_string "fop")))
13412    (set_attr "mode" "XF")])
13414 (define_insn "*fop_xf_1_i387"
13415   [(set (match_operand:XF 0 "register_operand" "=f,f")
13416         (match_operator:XF 3 "binary_fp_operator"
13417                         [(match_operand:XF 1 "register_operand" "0,f")
13418                          (match_operand:XF 2 "register_operand" "f,0")]))]
13419   "TARGET_80387
13420    && !COMMUTATIVE_ARITH_P (operands[3])"
13421   "* return output_387_binary_op (insn, operands);"
13422   [(set (attr "type")
13423         (cond [(match_operand:XF 3 "mult_operator" "")
13424                  (const_string "fmul")
13425                (match_operand:XF 3 "div_operator" "")
13426                  (const_string "fdiv")
13427               ]
13428               (const_string "fop")))
13429    (set_attr "mode" "XF")])
13431 (define_insn "*fop_xf_2_i387"
13432   [(set (match_operand:XF 0 "register_operand" "=f,f")
13433         (match_operator:XF 3 "binary_fp_operator"
13434           [(float:XF
13435              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
13436            (match_operand:XF 2 "register_operand" "0,0")]))]
13437   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13438   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13439   [(set (attr "type")
13440         (cond [(match_operand:XF 3 "mult_operator" "")
13441                  (const_string "fmul")
13442                (match_operand:XF 3 "div_operator" "")
13443                  (const_string "fdiv")
13444               ]
13445               (const_string "fop")))
13446    (set_attr "fp_int_src" "true")
13447    (set_attr "mode" "<MODE>")])
13449 (define_insn "*fop_xf_3_i387"
13450   [(set (match_operand:XF 0 "register_operand" "=f,f")
13451         (match_operator:XF 3 "binary_fp_operator"
13452           [(match_operand:XF 1 "register_operand" "0,0")
13453            (float:XF
13454              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
13455   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13456   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13457   [(set (attr "type")
13458         (cond [(match_operand:XF 3 "mult_operator" "")
13459                  (const_string "fmul")
13460                (match_operand:XF 3 "div_operator" "")
13461                  (const_string "fdiv")
13462               ]
13463               (const_string "fop")))
13464    (set_attr "fp_int_src" "true")
13465    (set_attr "mode" "<MODE>")])
13467 (define_insn "*fop_xf_4_i387"
13468   [(set (match_operand:XF 0 "register_operand" "=f,f")
13469         (match_operator:XF 3 "binary_fp_operator"
13470            [(float_extend:XF
13471               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13472             (match_operand:XF 2 "register_operand" "0,f")]))]
13473   "TARGET_80387"
13474   "* return output_387_binary_op (insn, operands);"
13475   [(set (attr "type")
13476         (cond [(match_operand:XF 3 "mult_operator" "")
13477                  (const_string "fmul")
13478                (match_operand:XF 3 "div_operator" "")
13479                  (const_string "fdiv")
13480               ]
13481               (const_string "fop")))
13482    (set_attr "mode" "<MODE>")])
13484 (define_insn "*fop_xf_5_i387"
13485   [(set (match_operand:XF 0 "register_operand" "=f,f")
13486         (match_operator:XF 3 "binary_fp_operator"
13487           [(match_operand:XF 1 "register_operand" "0,f")
13488            (float_extend:XF
13489              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13490   "TARGET_80387"
13491   "* return output_387_binary_op (insn, operands);"
13492   [(set (attr "type")
13493         (cond [(match_operand:XF 3 "mult_operator" "")
13494                  (const_string "fmul")
13495                (match_operand:XF 3 "div_operator" "")
13496                  (const_string "fdiv")
13497               ]
13498               (const_string "fop")))
13499    (set_attr "mode" "<MODE>")])
13501 (define_insn "*fop_xf_6_i387"
13502   [(set (match_operand:XF 0 "register_operand" "=f,f")
13503         (match_operator:XF 3 "binary_fp_operator"
13504           [(float_extend:XF
13505              (match_operand:MODEF 1 "register_operand" "0,f"))
13506            (float_extend:XF
13507              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13508   "TARGET_80387"
13509   "* return output_387_binary_op (insn, operands);"
13510   [(set (attr "type")
13511         (cond [(match_operand:XF 3 "mult_operator" "")
13512                  (const_string "fmul")
13513                (match_operand:XF 3 "div_operator" "")
13514                  (const_string "fdiv")
13515               ]
13516               (const_string "fop")))
13517    (set_attr "mode" "<MODE>")])
13519 (define_split
13520   [(set (match_operand 0 "register_operand" "")
13521         (match_operator 3 "binary_fp_operator"
13522            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
13523             (match_operand 2 "register_operand" "")]))]
13524   "reload_completed
13525    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13526    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13527   [(const_int 0)]
13529   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13530   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13531   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13532                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13533                                           GET_MODE (operands[3]),
13534                                           operands[4],
13535                                           operands[2])));
13536   ix86_free_from_memory (GET_MODE (operands[1]));
13537   DONE;
13540 (define_split
13541   [(set (match_operand 0 "register_operand" "")
13542         (match_operator 3 "binary_fp_operator"
13543            [(match_operand 1 "register_operand" "")
13544             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
13545   "reload_completed
13546    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13547    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13548   [(const_int 0)]
13550   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13551   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13552   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13553                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
13554                                           GET_MODE (operands[3]),
13555                                           operands[1],
13556                                           operands[4])));
13557   ix86_free_from_memory (GET_MODE (operands[2]));
13558   DONE;
13561 ;; FPU special functions.
13563 ;; This pattern implements a no-op XFmode truncation for
13564 ;; all fancy i386 XFmode math functions.
13566 (define_insn "truncxf<mode>2_i387_noop_unspec"
13567   [(set (match_operand:MODEF 0 "register_operand" "=f")
13568         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13569         UNSPEC_TRUNC_NOOP))]
13570   "TARGET_USE_FANCY_MATH_387"
13571   "* return output_387_reg_move (insn, operands);"
13572   [(set_attr "type" "fmov")
13573    (set_attr "mode" "<MODE>")])
13575 (define_insn "sqrtxf2"
13576   [(set (match_operand:XF 0 "register_operand" "=f")
13577         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13578   "TARGET_USE_FANCY_MATH_387"
13579   "fsqrt"
13580   [(set_attr "type" "fpspc")
13581    (set_attr "mode" "XF")
13582    (set_attr "athlon_decode" "direct")
13583    (set_attr "amdfam10_decode" "direct")])
13585 (define_insn "sqrt_extend<mode>xf2_i387"
13586   [(set (match_operand:XF 0 "register_operand" "=f")
13587         (sqrt:XF
13588           (float_extend:XF
13589             (match_operand:MODEF 1 "register_operand" "0"))))]
13590   "TARGET_USE_FANCY_MATH_387"
13591   "fsqrt"
13592   [(set_attr "type" "fpspc")
13593    (set_attr "mode" "XF")
13594    (set_attr "athlon_decode" "direct")
13595    (set_attr "amdfam10_decode" "direct")])
13597 (define_insn "*rsqrtsf2_sse"
13598   [(set (match_operand:SF 0 "register_operand" "=x")
13599         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13600                    UNSPEC_RSQRT))]
13601   "TARGET_SSE_MATH"
13602   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13603   [(set_attr "type" "sse")
13604    (set_attr "atom_sse_attr" "rcp")
13605    (set_attr "prefix" "maybe_vex")
13606    (set_attr "mode" "SF")])
13608 (define_expand "rsqrtsf2"
13609   [(set (match_operand:SF 0 "register_operand" "")
13610         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13611                    UNSPEC_RSQRT))]
13612   "TARGET_SSE_MATH"
13614   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13615   DONE;
13618 (define_insn "*sqrt<mode>2_sse"
13619   [(set (match_operand:MODEF 0 "register_operand" "=x")
13620         (sqrt:MODEF
13621           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13622   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13623   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13624   [(set_attr "type" "sse")
13625    (set_attr "atom_sse_attr" "sqrt")
13626    (set_attr "prefix" "maybe_vex")
13627    (set_attr "mode" "<MODE>")
13628    (set_attr "athlon_decode" "*")
13629    (set_attr "amdfam10_decode" "*")])
13631 (define_expand "sqrt<mode>2"
13632   [(set (match_operand:MODEF 0 "register_operand" "")
13633         (sqrt:MODEF
13634           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13635   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13636    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13638   if (<MODE>mode == SFmode
13639       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13640       && flag_finite_math_only && !flag_trapping_math
13641       && flag_unsafe_math_optimizations)
13642     {
13643       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13644       DONE;
13645     }
13647   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13648     {
13649       rtx op0 = gen_reg_rtx (XFmode);
13650       rtx op1 = force_reg (<MODE>mode, operands[1]);
13652       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13653       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13654       DONE;
13655    }
13658 (define_insn "fpremxf4_i387"
13659   [(set (match_operand:XF 0 "register_operand" "=f")
13660         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13661                     (match_operand:XF 3 "register_operand" "1")]
13662                    UNSPEC_FPREM_F))
13663    (set (match_operand:XF 1 "register_operand" "=u")
13664         (unspec:XF [(match_dup 2) (match_dup 3)]
13665                    UNSPEC_FPREM_U))
13666    (set (reg:CCFP FPSR_REG)
13667         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13668                      UNSPEC_C2_FLAG))]
13669   "TARGET_USE_FANCY_MATH_387"
13670   "fprem"
13671   [(set_attr "type" "fpspc")
13672    (set_attr "mode" "XF")])
13674 (define_expand "fmodxf3"
13675   [(use (match_operand:XF 0 "register_operand" ""))
13676    (use (match_operand:XF 1 "general_operand" ""))
13677    (use (match_operand:XF 2 "general_operand" ""))]
13678   "TARGET_USE_FANCY_MATH_387"
13680   rtx label = gen_label_rtx ();
13682   rtx op1 = gen_reg_rtx (XFmode);
13683   rtx op2 = gen_reg_rtx (XFmode);
13685   emit_move_insn (op2, operands[2]);
13686   emit_move_insn (op1, operands[1]);
13688   emit_label (label);
13689   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13690   ix86_emit_fp_unordered_jump (label);
13691   LABEL_NUSES (label) = 1;
13693   emit_move_insn (operands[0], op1);
13694   DONE;
13697 (define_expand "fmod<mode>3"
13698   [(use (match_operand:MODEF 0 "register_operand" ""))
13699    (use (match_operand:MODEF 1 "general_operand" ""))
13700    (use (match_operand:MODEF 2 "general_operand" ""))]
13701   "TARGET_USE_FANCY_MATH_387"
13703   rtx label = gen_label_rtx ();
13705   rtx op1 = gen_reg_rtx (XFmode);
13706   rtx op2 = gen_reg_rtx (XFmode);
13708   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13709   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13711   emit_label (label);
13712   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13713   ix86_emit_fp_unordered_jump (label);
13714   LABEL_NUSES (label) = 1;
13716   /* Truncate the result properly for strict SSE math.  */
13717   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13718       && !TARGET_MIX_SSE_I387)
13719     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13720   else
13721     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13723   DONE;
13726 (define_insn "fprem1xf4_i387"
13727   [(set (match_operand:XF 0 "register_operand" "=f")
13728         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13729                     (match_operand:XF 3 "register_operand" "1")]
13730                    UNSPEC_FPREM1_F))
13731    (set (match_operand:XF 1 "register_operand" "=u")
13732         (unspec:XF [(match_dup 2) (match_dup 3)]
13733                    UNSPEC_FPREM1_U))
13734    (set (reg:CCFP FPSR_REG)
13735         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13736                      UNSPEC_C2_FLAG))]
13737   "TARGET_USE_FANCY_MATH_387"
13738   "fprem1"
13739   [(set_attr "type" "fpspc")
13740    (set_attr "mode" "XF")])
13742 (define_expand "remainderxf3"
13743   [(use (match_operand:XF 0 "register_operand" ""))
13744    (use (match_operand:XF 1 "general_operand" ""))
13745    (use (match_operand:XF 2 "general_operand" ""))]
13746   "TARGET_USE_FANCY_MATH_387"
13748   rtx label = gen_label_rtx ();
13750   rtx op1 = gen_reg_rtx (XFmode);
13751   rtx op2 = gen_reg_rtx (XFmode);
13753   emit_move_insn (op2, operands[2]);
13754   emit_move_insn (op1, operands[1]);
13756   emit_label (label);
13757   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13758   ix86_emit_fp_unordered_jump (label);
13759   LABEL_NUSES (label) = 1;
13761   emit_move_insn (operands[0], op1);
13762   DONE;
13765 (define_expand "remainder<mode>3"
13766   [(use (match_operand:MODEF 0 "register_operand" ""))
13767    (use (match_operand:MODEF 1 "general_operand" ""))
13768    (use (match_operand:MODEF 2 "general_operand" ""))]
13769   "TARGET_USE_FANCY_MATH_387"
13771   rtx label = gen_label_rtx ();
13773   rtx op1 = gen_reg_rtx (XFmode);
13774   rtx op2 = gen_reg_rtx (XFmode);
13776   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13777   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13779   emit_label (label);
13781   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13782   ix86_emit_fp_unordered_jump (label);
13783   LABEL_NUSES (label) = 1;
13785   /* Truncate the result properly for strict SSE math.  */
13786   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13787       && !TARGET_MIX_SSE_I387)
13788     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
13789   else
13790     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
13792   DONE;
13795 (define_insn "*sinxf2_i387"
13796   [(set (match_operand:XF 0 "register_operand" "=f")
13797         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13798   "TARGET_USE_FANCY_MATH_387
13799    && flag_unsafe_math_optimizations"
13800   "fsin"
13801   [(set_attr "type" "fpspc")
13802    (set_attr "mode" "XF")])
13804 (define_insn "*sin_extend<mode>xf2_i387"
13805   [(set (match_operand:XF 0 "register_operand" "=f")
13806         (unspec:XF [(float_extend:XF
13807                       (match_operand:MODEF 1 "register_operand" "0"))]
13808                    UNSPEC_SIN))]
13809   "TARGET_USE_FANCY_MATH_387
13810    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13811        || TARGET_MIX_SSE_I387)
13812    && flag_unsafe_math_optimizations"
13813   "fsin"
13814   [(set_attr "type" "fpspc")
13815    (set_attr "mode" "XF")])
13817 (define_insn "*cosxf2_i387"
13818   [(set (match_operand:XF 0 "register_operand" "=f")
13819         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13820   "TARGET_USE_FANCY_MATH_387
13821    && flag_unsafe_math_optimizations"
13822   "fcos"
13823   [(set_attr "type" "fpspc")
13824    (set_attr "mode" "XF")])
13826 (define_insn "*cos_extend<mode>xf2_i387"
13827   [(set (match_operand:XF 0 "register_operand" "=f")
13828         (unspec:XF [(float_extend:XF
13829                       (match_operand:MODEF 1 "register_operand" "0"))]
13830                    UNSPEC_COS))]
13831   "TARGET_USE_FANCY_MATH_387
13832    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13833        || TARGET_MIX_SSE_I387)
13834    && flag_unsafe_math_optimizations"
13835   "fcos"
13836   [(set_attr "type" "fpspc")
13837    (set_attr "mode" "XF")])
13839 ;; When sincos pattern is defined, sin and cos builtin functions will be
13840 ;; expanded to sincos pattern with one of its outputs left unused.
13841 ;; CSE pass will figure out if two sincos patterns can be combined,
13842 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13843 ;; depending on the unused output.
13845 (define_insn "sincosxf3"
13846   [(set (match_operand:XF 0 "register_operand" "=f")
13847         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13848                    UNSPEC_SINCOS_COS))
13849    (set (match_operand:XF 1 "register_operand" "=u")
13850         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13851   "TARGET_USE_FANCY_MATH_387
13852    && flag_unsafe_math_optimizations"
13853   "fsincos"
13854   [(set_attr "type" "fpspc")
13855    (set_attr "mode" "XF")])
13857 (define_split
13858   [(set (match_operand:XF 0 "register_operand" "")
13859         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13860                    UNSPEC_SINCOS_COS))
13861    (set (match_operand:XF 1 "register_operand" "")
13862         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13863   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13864    && !(reload_completed || reload_in_progress)"
13865   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
13866   "")
13868 (define_split
13869   [(set (match_operand:XF 0 "register_operand" "")
13870         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13871                    UNSPEC_SINCOS_COS))
13872    (set (match_operand:XF 1 "register_operand" "")
13873         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13874   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13875    && !(reload_completed || reload_in_progress)"
13876   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
13877   "")
13879 (define_insn "sincos_extend<mode>xf3_i387"
13880   [(set (match_operand:XF 0 "register_operand" "=f")
13881         (unspec:XF [(float_extend:XF
13882                       (match_operand:MODEF 2 "register_operand" "0"))]
13883                    UNSPEC_SINCOS_COS))
13884    (set (match_operand:XF 1 "register_operand" "=u")
13885         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13886   "TARGET_USE_FANCY_MATH_387
13887    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13888        || TARGET_MIX_SSE_I387)
13889    && flag_unsafe_math_optimizations"
13890   "fsincos"
13891   [(set_attr "type" "fpspc")
13892    (set_attr "mode" "XF")])
13894 (define_split
13895   [(set (match_operand:XF 0 "register_operand" "")
13896         (unspec:XF [(float_extend:XF
13897                       (match_operand:MODEF 2 "register_operand" ""))]
13898                    UNSPEC_SINCOS_COS))
13899    (set (match_operand:XF 1 "register_operand" "")
13900         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13901   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13902    && !(reload_completed || reload_in_progress)"
13903   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
13904   "")
13906 (define_split
13907   [(set (match_operand:XF 0 "register_operand" "")
13908         (unspec:XF [(float_extend:XF
13909                       (match_operand:MODEF 2 "register_operand" ""))]
13910                    UNSPEC_SINCOS_COS))
13911    (set (match_operand:XF 1 "register_operand" "")
13912         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13913   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13914    && !(reload_completed || reload_in_progress)"
13915   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
13916   "")
13918 (define_expand "sincos<mode>3"
13919   [(use (match_operand:MODEF 0 "register_operand" ""))
13920    (use (match_operand:MODEF 1 "register_operand" ""))
13921    (use (match_operand:MODEF 2 "register_operand" ""))]
13922   "TARGET_USE_FANCY_MATH_387
13923    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13924        || TARGET_MIX_SSE_I387)
13925    && flag_unsafe_math_optimizations"
13927   rtx op0 = gen_reg_rtx (XFmode);
13928   rtx op1 = gen_reg_rtx (XFmode);
13930   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13931   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13932   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13933   DONE;
13936 (define_insn "fptanxf4_i387"
13937   [(set (match_operand:XF 0 "register_operand" "=f")
13938         (match_operand:XF 3 "const_double_operand" "F"))
13939    (set (match_operand:XF 1 "register_operand" "=u")
13940         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13941                    UNSPEC_TAN))]
13942   "TARGET_USE_FANCY_MATH_387
13943    && flag_unsafe_math_optimizations
13944    && standard_80387_constant_p (operands[3]) == 2"
13945   "fptan"
13946   [(set_attr "type" "fpspc")
13947    (set_attr "mode" "XF")])
13949 (define_insn "fptan_extend<mode>xf4_i387"
13950   [(set (match_operand:MODEF 0 "register_operand" "=f")
13951         (match_operand:MODEF 3 "const_double_operand" "F"))
13952    (set (match_operand:XF 1 "register_operand" "=u")
13953         (unspec:XF [(float_extend:XF
13954                       (match_operand:MODEF 2 "register_operand" "0"))]
13955                    UNSPEC_TAN))]
13956   "TARGET_USE_FANCY_MATH_387
13957    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13958        || TARGET_MIX_SSE_I387)
13959    && flag_unsafe_math_optimizations
13960    && standard_80387_constant_p (operands[3]) == 2"
13961   "fptan"
13962   [(set_attr "type" "fpspc")
13963    (set_attr "mode" "XF")])
13965 (define_expand "tanxf2"
13966   [(use (match_operand:XF 0 "register_operand" ""))
13967    (use (match_operand:XF 1 "register_operand" ""))]
13968   "TARGET_USE_FANCY_MATH_387
13969    && flag_unsafe_math_optimizations"
13971   rtx one = gen_reg_rtx (XFmode);
13972   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13974   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13975   DONE;
13978 (define_expand "tan<mode>2"
13979   [(use (match_operand:MODEF 0 "register_operand" ""))
13980    (use (match_operand:MODEF 1 "register_operand" ""))]
13981   "TARGET_USE_FANCY_MATH_387
13982    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13983        || TARGET_MIX_SSE_I387)
13984    && flag_unsafe_math_optimizations"
13986   rtx op0 = gen_reg_rtx (XFmode);
13988   rtx one = gen_reg_rtx (<MODE>mode);
13989   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13991   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13992                                              operands[1], op2));
13993   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13994   DONE;
13997 (define_insn "*fpatanxf3_i387"
13998   [(set (match_operand:XF 0 "register_operand" "=f")
13999         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14000                     (match_operand:XF 2 "register_operand" "u")]
14001                    UNSPEC_FPATAN))
14002    (clobber (match_scratch:XF 3 "=2"))]
14003   "TARGET_USE_FANCY_MATH_387
14004    && flag_unsafe_math_optimizations"
14005   "fpatan"
14006   [(set_attr "type" "fpspc")
14007    (set_attr "mode" "XF")])
14009 (define_insn "fpatan_extend<mode>xf3_i387"
14010   [(set (match_operand:XF 0 "register_operand" "=f")
14011         (unspec:XF [(float_extend:XF
14012                       (match_operand:MODEF 1 "register_operand" "0"))
14013                     (float_extend:XF
14014                       (match_operand:MODEF 2 "register_operand" "u"))]
14015                    UNSPEC_FPATAN))
14016    (clobber (match_scratch:XF 3 "=2"))]
14017   "TARGET_USE_FANCY_MATH_387
14018    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14019        || TARGET_MIX_SSE_I387)
14020    && flag_unsafe_math_optimizations"
14021   "fpatan"
14022   [(set_attr "type" "fpspc")
14023    (set_attr "mode" "XF")])
14025 (define_expand "atan2xf3"
14026   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14027                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
14028                                (match_operand:XF 1 "register_operand" "")]
14029                               UNSPEC_FPATAN))
14030               (clobber (match_scratch:XF 3 ""))])]
14031   "TARGET_USE_FANCY_MATH_387
14032    && flag_unsafe_math_optimizations"
14033   "")
14035 (define_expand "atan2<mode>3"
14036   [(use (match_operand:MODEF 0 "register_operand" ""))
14037    (use (match_operand:MODEF 1 "register_operand" ""))
14038    (use (match_operand:MODEF 2 "register_operand" ""))]
14039   "TARGET_USE_FANCY_MATH_387
14040    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14041        || TARGET_MIX_SSE_I387)
14042    && flag_unsafe_math_optimizations"
14044   rtx op0 = gen_reg_rtx (XFmode);
14046   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14047   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14048   DONE;
14051 (define_expand "atanxf2"
14052   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14053                    (unspec:XF [(match_dup 2)
14054                                (match_operand:XF 1 "register_operand" "")]
14055                               UNSPEC_FPATAN))
14056               (clobber (match_scratch:XF 3 ""))])]
14057   "TARGET_USE_FANCY_MATH_387
14058    && flag_unsafe_math_optimizations"
14060   operands[2] = gen_reg_rtx (XFmode);
14061   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14064 (define_expand "atan<mode>2"
14065   [(use (match_operand:MODEF 0 "register_operand" ""))
14066    (use (match_operand:MODEF 1 "register_operand" ""))]
14067   "TARGET_USE_FANCY_MATH_387
14068    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14069        || TARGET_MIX_SSE_I387)
14070    && flag_unsafe_math_optimizations"
14072   rtx op0 = gen_reg_rtx (XFmode);
14074   rtx op2 = gen_reg_rtx (<MODE>mode);
14075   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14077   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14078   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14079   DONE;
14082 (define_expand "asinxf2"
14083   [(set (match_dup 2)
14084         (mult:XF (match_operand:XF 1 "register_operand" "")
14085                  (match_dup 1)))
14086    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14087    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14088    (parallel [(set (match_operand:XF 0 "register_operand" "")
14089                    (unspec:XF [(match_dup 5) (match_dup 1)]
14090                               UNSPEC_FPATAN))
14091               (clobber (match_scratch:XF 6 ""))])]
14092   "TARGET_USE_FANCY_MATH_387
14093    && flag_unsafe_math_optimizations"
14095   int i;
14097   if (optimize_insn_for_size_p ())
14098     FAIL;
14100   for (i = 2; i < 6; i++)
14101     operands[i] = gen_reg_rtx (XFmode);
14103   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14106 (define_expand "asin<mode>2"
14107   [(use (match_operand:MODEF 0 "register_operand" ""))
14108    (use (match_operand:MODEF 1 "general_operand" ""))]
14109  "TARGET_USE_FANCY_MATH_387
14110    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14111        || TARGET_MIX_SSE_I387)
14112    && flag_unsafe_math_optimizations"
14114   rtx op0 = gen_reg_rtx (XFmode);
14115   rtx op1 = gen_reg_rtx (XFmode);
14117   if (optimize_insn_for_size_p ())
14118     FAIL;
14120   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14121   emit_insn (gen_asinxf2 (op0, op1));
14122   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14123   DONE;
14126 (define_expand "acosxf2"
14127   [(set (match_dup 2)
14128         (mult:XF (match_operand:XF 1 "register_operand" "")
14129                  (match_dup 1)))
14130    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14131    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14132    (parallel [(set (match_operand:XF 0 "register_operand" "")
14133                    (unspec:XF [(match_dup 1) (match_dup 5)]
14134                               UNSPEC_FPATAN))
14135               (clobber (match_scratch:XF 6 ""))])]
14136   "TARGET_USE_FANCY_MATH_387
14137    && flag_unsafe_math_optimizations"
14139   int i;
14141   if (optimize_insn_for_size_p ())
14142     FAIL;
14144   for (i = 2; i < 6; i++)
14145     operands[i] = gen_reg_rtx (XFmode);
14147   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14150 (define_expand "acos<mode>2"
14151   [(use (match_operand:MODEF 0 "register_operand" ""))
14152    (use (match_operand:MODEF 1 "general_operand" ""))]
14153  "TARGET_USE_FANCY_MATH_387
14154    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14155        || TARGET_MIX_SSE_I387)
14156    && flag_unsafe_math_optimizations"
14158   rtx op0 = gen_reg_rtx (XFmode);
14159   rtx op1 = gen_reg_rtx (XFmode);
14161   if (optimize_insn_for_size_p ())
14162     FAIL;
14164   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14165   emit_insn (gen_acosxf2 (op0, op1));
14166   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14167   DONE;
14170 (define_insn "fyl2xxf3_i387"
14171   [(set (match_operand:XF 0 "register_operand" "=f")
14172         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14173                     (match_operand:XF 2 "register_operand" "u")]
14174                    UNSPEC_FYL2X))
14175    (clobber (match_scratch:XF 3 "=2"))]
14176   "TARGET_USE_FANCY_MATH_387
14177    && flag_unsafe_math_optimizations"
14178   "fyl2x"
14179   [(set_attr "type" "fpspc")
14180    (set_attr "mode" "XF")])
14182 (define_insn "fyl2x_extend<mode>xf3_i387"
14183   [(set (match_operand:XF 0 "register_operand" "=f")
14184         (unspec:XF [(float_extend:XF
14185                       (match_operand:MODEF 1 "register_operand" "0"))
14186                     (match_operand:XF 2 "register_operand" "u")]
14187                    UNSPEC_FYL2X))
14188    (clobber (match_scratch:XF 3 "=2"))]
14189   "TARGET_USE_FANCY_MATH_387
14190    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14191        || TARGET_MIX_SSE_I387)
14192    && flag_unsafe_math_optimizations"
14193   "fyl2x"
14194   [(set_attr "type" "fpspc")
14195    (set_attr "mode" "XF")])
14197 (define_expand "logxf2"
14198   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14199                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14200                                (match_dup 2)] UNSPEC_FYL2X))
14201               (clobber (match_scratch:XF 3 ""))])]
14202   "TARGET_USE_FANCY_MATH_387
14203    && flag_unsafe_math_optimizations"
14205   operands[2] = gen_reg_rtx (XFmode);
14206   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14209 (define_expand "log<mode>2"
14210   [(use (match_operand:MODEF 0 "register_operand" ""))
14211    (use (match_operand:MODEF 1 "register_operand" ""))]
14212   "TARGET_USE_FANCY_MATH_387
14213    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14214        || TARGET_MIX_SSE_I387)
14215    && flag_unsafe_math_optimizations"
14217   rtx op0 = gen_reg_rtx (XFmode);
14219   rtx op2 = gen_reg_rtx (XFmode);
14220   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14222   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14223   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14224   DONE;
14227 (define_expand "log10xf2"
14228   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14229                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14230                                (match_dup 2)] UNSPEC_FYL2X))
14231               (clobber (match_scratch:XF 3 ""))])]
14232   "TARGET_USE_FANCY_MATH_387
14233    && flag_unsafe_math_optimizations"
14235   operands[2] = gen_reg_rtx (XFmode);
14236   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14239 (define_expand "log10<mode>2"
14240   [(use (match_operand:MODEF 0 "register_operand" ""))
14241    (use (match_operand:MODEF 1 "register_operand" ""))]
14242   "TARGET_USE_FANCY_MATH_387
14243    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14244        || TARGET_MIX_SSE_I387)
14245    && flag_unsafe_math_optimizations"
14247   rtx op0 = gen_reg_rtx (XFmode);
14249   rtx op2 = gen_reg_rtx (XFmode);
14250   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14252   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14253   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14254   DONE;
14257 (define_expand "log2xf2"
14258   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14259                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14260                                (match_dup 2)] UNSPEC_FYL2X))
14261               (clobber (match_scratch:XF 3 ""))])]
14262   "TARGET_USE_FANCY_MATH_387
14263    && flag_unsafe_math_optimizations"
14265   operands[2] = gen_reg_rtx (XFmode);
14266   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14269 (define_expand "log2<mode>2"
14270   [(use (match_operand:MODEF 0 "register_operand" ""))
14271    (use (match_operand:MODEF 1 "register_operand" ""))]
14272   "TARGET_USE_FANCY_MATH_387
14273    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14274        || TARGET_MIX_SSE_I387)
14275    && flag_unsafe_math_optimizations"
14277   rtx op0 = gen_reg_rtx (XFmode);
14279   rtx op2 = gen_reg_rtx (XFmode);
14280   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14282   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14283   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14284   DONE;
14287 (define_insn "fyl2xp1xf3_i387"
14288   [(set (match_operand:XF 0 "register_operand" "=f")
14289         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14290                     (match_operand:XF 2 "register_operand" "u")]
14291                    UNSPEC_FYL2XP1))
14292    (clobber (match_scratch:XF 3 "=2"))]
14293   "TARGET_USE_FANCY_MATH_387
14294    && flag_unsafe_math_optimizations"
14295   "fyl2xp1"
14296   [(set_attr "type" "fpspc")
14297    (set_attr "mode" "XF")])
14299 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14300   [(set (match_operand:XF 0 "register_operand" "=f")
14301         (unspec:XF [(float_extend:XF
14302                       (match_operand:MODEF 1 "register_operand" "0"))
14303                     (match_operand:XF 2 "register_operand" "u")]
14304                    UNSPEC_FYL2XP1))
14305    (clobber (match_scratch:XF 3 "=2"))]
14306   "TARGET_USE_FANCY_MATH_387
14307    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14308        || TARGET_MIX_SSE_I387)
14309    && flag_unsafe_math_optimizations"
14310   "fyl2xp1"
14311   [(set_attr "type" "fpspc")
14312    (set_attr "mode" "XF")])
14314 (define_expand "log1pxf2"
14315   [(use (match_operand:XF 0 "register_operand" ""))
14316    (use (match_operand:XF 1 "register_operand" ""))]
14317   "TARGET_USE_FANCY_MATH_387
14318    && flag_unsafe_math_optimizations"
14320   if (optimize_insn_for_size_p ())
14321     FAIL;
14323   ix86_emit_i387_log1p (operands[0], operands[1]);
14324   DONE;
14327 (define_expand "log1p<mode>2"
14328   [(use (match_operand:MODEF 0 "register_operand" ""))
14329    (use (match_operand:MODEF 1 "register_operand" ""))]
14330   "TARGET_USE_FANCY_MATH_387
14331    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14332        || TARGET_MIX_SSE_I387)
14333    && flag_unsafe_math_optimizations"
14335   rtx op0;
14337   if (optimize_insn_for_size_p ())
14338     FAIL;
14340   op0 = gen_reg_rtx (XFmode);
14342   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14344   ix86_emit_i387_log1p (op0, operands[1]);
14345   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14346   DONE;
14349 (define_insn "fxtractxf3_i387"
14350   [(set (match_operand:XF 0 "register_operand" "=f")
14351         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14352                    UNSPEC_XTRACT_FRACT))
14353    (set (match_operand:XF 1 "register_operand" "=u")
14354         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14355   "TARGET_USE_FANCY_MATH_387
14356    && flag_unsafe_math_optimizations"
14357   "fxtract"
14358   [(set_attr "type" "fpspc")
14359    (set_attr "mode" "XF")])
14361 (define_insn "fxtract_extend<mode>xf3_i387"
14362   [(set (match_operand:XF 0 "register_operand" "=f")
14363         (unspec:XF [(float_extend:XF
14364                       (match_operand:MODEF 2 "register_operand" "0"))]
14365                    UNSPEC_XTRACT_FRACT))
14366    (set (match_operand:XF 1 "register_operand" "=u")
14367         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14368   "TARGET_USE_FANCY_MATH_387
14369    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14370        || TARGET_MIX_SSE_I387)
14371    && flag_unsafe_math_optimizations"
14372   "fxtract"
14373   [(set_attr "type" "fpspc")
14374    (set_attr "mode" "XF")])
14376 (define_expand "logbxf2"
14377   [(parallel [(set (match_dup 2)
14378                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14379                               UNSPEC_XTRACT_FRACT))
14380               (set (match_operand:XF 0 "register_operand" "")
14381                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14382   "TARGET_USE_FANCY_MATH_387
14383    && flag_unsafe_math_optimizations"
14385   operands[2] = gen_reg_rtx (XFmode);
14388 (define_expand "logb<mode>2"
14389   [(use (match_operand:MODEF 0 "register_operand" ""))
14390    (use (match_operand:MODEF 1 "register_operand" ""))]
14391   "TARGET_USE_FANCY_MATH_387
14392    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14393        || TARGET_MIX_SSE_I387)
14394    && flag_unsafe_math_optimizations"
14396   rtx op0 = gen_reg_rtx (XFmode);
14397   rtx op1 = gen_reg_rtx (XFmode);
14399   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14400   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14401   DONE;
14404 (define_expand "ilogbxf2"
14405   [(use (match_operand:SI 0 "register_operand" ""))
14406    (use (match_operand:XF 1 "register_operand" ""))]
14407   "TARGET_USE_FANCY_MATH_387
14408    && flag_unsafe_math_optimizations"
14410   rtx op0, op1;
14412   if (optimize_insn_for_size_p ())
14413     FAIL;
14415   op0 = gen_reg_rtx (XFmode);
14416   op1 = gen_reg_rtx (XFmode);
14418   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14419   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14420   DONE;
14423 (define_expand "ilogb<mode>2"
14424   [(use (match_operand:SI 0 "register_operand" ""))
14425    (use (match_operand:MODEF 1 "register_operand" ""))]
14426   "TARGET_USE_FANCY_MATH_387
14427    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14428        || TARGET_MIX_SSE_I387)
14429    && flag_unsafe_math_optimizations"
14431   rtx op0, op1;
14433   if (optimize_insn_for_size_p ())
14434     FAIL;
14436   op0 = gen_reg_rtx (XFmode);
14437   op1 = gen_reg_rtx (XFmode);
14439   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14440   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14441   DONE;
14444 (define_insn "*f2xm1xf2_i387"
14445   [(set (match_operand:XF 0 "register_operand" "=f")
14446         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14447                    UNSPEC_F2XM1))]
14448   "TARGET_USE_FANCY_MATH_387
14449    && flag_unsafe_math_optimizations"
14450   "f2xm1"
14451   [(set_attr "type" "fpspc")
14452    (set_attr "mode" "XF")])
14454 (define_insn "*fscalexf4_i387"
14455   [(set (match_operand:XF 0 "register_operand" "=f")
14456         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14457                     (match_operand:XF 3 "register_operand" "1")]
14458                    UNSPEC_FSCALE_FRACT))
14459    (set (match_operand:XF 1 "register_operand" "=u")
14460         (unspec:XF [(match_dup 2) (match_dup 3)]
14461                    UNSPEC_FSCALE_EXP))]
14462   "TARGET_USE_FANCY_MATH_387
14463    && flag_unsafe_math_optimizations"
14464   "fscale"
14465   [(set_attr "type" "fpspc")
14466    (set_attr "mode" "XF")])
14468 (define_expand "expNcorexf3"
14469   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14470                                (match_operand:XF 2 "register_operand" "")))
14471    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14472    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14473    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14474    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14475    (parallel [(set (match_operand:XF 0 "register_operand" "")
14476                    (unspec:XF [(match_dup 8) (match_dup 4)]
14477                               UNSPEC_FSCALE_FRACT))
14478               (set (match_dup 9)
14479                    (unspec:XF [(match_dup 8) (match_dup 4)]
14480                               UNSPEC_FSCALE_EXP))])]
14481   "TARGET_USE_FANCY_MATH_387
14482    && flag_unsafe_math_optimizations"
14484   int i;
14486   if (optimize_insn_for_size_p ())
14487     FAIL;
14489   for (i = 3; i < 10; i++)
14490     operands[i] = gen_reg_rtx (XFmode);
14492   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14495 (define_expand "expxf2"
14496   [(use (match_operand:XF 0 "register_operand" ""))
14497    (use (match_operand:XF 1 "register_operand" ""))]
14498   "TARGET_USE_FANCY_MATH_387
14499    && flag_unsafe_math_optimizations"
14501   rtx op2;
14503   if (optimize_insn_for_size_p ())
14504     FAIL;
14506   op2 = gen_reg_rtx (XFmode);
14507   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14509   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14510   DONE;
14513 (define_expand "exp<mode>2"
14514   [(use (match_operand:MODEF 0 "register_operand" ""))
14515    (use (match_operand:MODEF 1 "general_operand" ""))]
14516  "TARGET_USE_FANCY_MATH_387
14517    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14518        || TARGET_MIX_SSE_I387)
14519    && flag_unsafe_math_optimizations"
14521   rtx op0, op1;
14523   if (optimize_insn_for_size_p ())
14524     FAIL;
14526   op0 = gen_reg_rtx (XFmode);
14527   op1 = gen_reg_rtx (XFmode);
14529   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14530   emit_insn (gen_expxf2 (op0, op1));
14531   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14532   DONE;
14535 (define_expand "exp10xf2"
14536   [(use (match_operand:XF 0 "register_operand" ""))
14537    (use (match_operand:XF 1 "register_operand" ""))]
14538   "TARGET_USE_FANCY_MATH_387
14539    && flag_unsafe_math_optimizations"
14541   rtx op2;
14543   if (optimize_insn_for_size_p ())
14544     FAIL;
14546   op2 = gen_reg_rtx (XFmode);
14547   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14549   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14550   DONE;
14553 (define_expand "exp10<mode>2"
14554   [(use (match_operand:MODEF 0 "register_operand" ""))
14555    (use (match_operand:MODEF 1 "general_operand" ""))]
14556  "TARGET_USE_FANCY_MATH_387
14557    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14558        || TARGET_MIX_SSE_I387)
14559    && flag_unsafe_math_optimizations"
14561   rtx op0, op1;
14563   if (optimize_insn_for_size_p ())
14564     FAIL;
14566   op0 = gen_reg_rtx (XFmode);
14567   op1 = gen_reg_rtx (XFmode);
14569   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14570   emit_insn (gen_exp10xf2 (op0, op1));
14571   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14572   DONE;
14575 (define_expand "exp2xf2"
14576   [(use (match_operand:XF 0 "register_operand" ""))
14577    (use (match_operand:XF 1 "register_operand" ""))]
14578   "TARGET_USE_FANCY_MATH_387
14579    && flag_unsafe_math_optimizations"
14581   rtx op2;
14583   if (optimize_insn_for_size_p ())
14584     FAIL;
14586   op2 = gen_reg_rtx (XFmode);
14587   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14589   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14590   DONE;
14593 (define_expand "exp2<mode>2"
14594   [(use (match_operand:MODEF 0 "register_operand" ""))
14595    (use (match_operand:MODEF 1 "general_operand" ""))]
14596  "TARGET_USE_FANCY_MATH_387
14597    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14598        || TARGET_MIX_SSE_I387)
14599    && flag_unsafe_math_optimizations"
14601   rtx op0, op1;
14603   if (optimize_insn_for_size_p ())
14604     FAIL;
14606   op0 = gen_reg_rtx (XFmode);
14607   op1 = gen_reg_rtx (XFmode);
14609   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14610   emit_insn (gen_exp2xf2 (op0, op1));
14611   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14612   DONE;
14615 (define_expand "expm1xf2"
14616   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14617                                (match_dup 2)))
14618    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14619    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14620    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14621    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14622    (parallel [(set (match_dup 7)
14623                    (unspec:XF [(match_dup 6) (match_dup 4)]
14624                               UNSPEC_FSCALE_FRACT))
14625               (set (match_dup 8)
14626                    (unspec:XF [(match_dup 6) (match_dup 4)]
14627                               UNSPEC_FSCALE_EXP))])
14628    (parallel [(set (match_dup 10)
14629                    (unspec:XF [(match_dup 9) (match_dup 8)]
14630                               UNSPEC_FSCALE_FRACT))
14631               (set (match_dup 11)
14632                    (unspec:XF [(match_dup 9) (match_dup 8)]
14633                               UNSPEC_FSCALE_EXP))])
14634    (set (match_dup 12) (minus:XF (match_dup 10)
14635                                  (float_extend:XF (match_dup 13))))
14636    (set (match_operand:XF 0 "register_operand" "")
14637         (plus:XF (match_dup 12) (match_dup 7)))]
14638   "TARGET_USE_FANCY_MATH_387
14639    && flag_unsafe_math_optimizations"
14641   int i;
14643   if (optimize_insn_for_size_p ())
14644     FAIL;
14646   for (i = 2; i < 13; i++)
14647     operands[i] = gen_reg_rtx (XFmode);
14649   operands[13]
14650     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14652   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14655 (define_expand "expm1<mode>2"
14656   [(use (match_operand:MODEF 0 "register_operand" ""))
14657    (use (match_operand:MODEF 1 "general_operand" ""))]
14658  "TARGET_USE_FANCY_MATH_387
14659    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14660        || TARGET_MIX_SSE_I387)
14661    && flag_unsafe_math_optimizations"
14663   rtx op0, op1;
14665   if (optimize_insn_for_size_p ())
14666     FAIL;
14668   op0 = gen_reg_rtx (XFmode);
14669   op1 = gen_reg_rtx (XFmode);
14671   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14672   emit_insn (gen_expm1xf2 (op0, op1));
14673   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14674   DONE;
14677 (define_expand "ldexpxf3"
14678   [(set (match_dup 3)
14679         (float:XF (match_operand:SI 2 "register_operand" "")))
14680    (parallel [(set (match_operand:XF 0 " register_operand" "")
14681                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14682                                (match_dup 3)]
14683                               UNSPEC_FSCALE_FRACT))
14684               (set (match_dup 4)
14685                    (unspec:XF [(match_dup 1) (match_dup 3)]
14686                               UNSPEC_FSCALE_EXP))])]
14687   "TARGET_USE_FANCY_MATH_387
14688    && flag_unsafe_math_optimizations"
14690   if (optimize_insn_for_size_p ())
14691     FAIL;
14693   operands[3] = gen_reg_rtx (XFmode);
14694   operands[4] = gen_reg_rtx (XFmode);
14697 (define_expand "ldexp<mode>3"
14698   [(use (match_operand:MODEF 0 "register_operand" ""))
14699    (use (match_operand:MODEF 1 "general_operand" ""))
14700    (use (match_operand:SI 2 "register_operand" ""))]
14701  "TARGET_USE_FANCY_MATH_387
14702    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14703        || TARGET_MIX_SSE_I387)
14704    && flag_unsafe_math_optimizations"
14706   rtx op0, op1;
14708   if (optimize_insn_for_size_p ())
14709     FAIL;
14711   op0 = gen_reg_rtx (XFmode);
14712   op1 = gen_reg_rtx (XFmode);
14714   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14715   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14716   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14717   DONE;
14720 (define_expand "scalbxf3"
14721   [(parallel [(set (match_operand:XF 0 " register_operand" "")
14722                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
14723                                (match_operand:XF 2 "register_operand" "")]
14724                               UNSPEC_FSCALE_FRACT))
14725               (set (match_dup 3)
14726                    (unspec:XF [(match_dup 1) (match_dup 2)]
14727                               UNSPEC_FSCALE_EXP))])]
14728   "TARGET_USE_FANCY_MATH_387
14729    && flag_unsafe_math_optimizations"
14731   if (optimize_insn_for_size_p ())
14732     FAIL;
14734   operands[3] = gen_reg_rtx (XFmode);
14737 (define_expand "scalb<mode>3"
14738   [(use (match_operand:MODEF 0 "register_operand" ""))
14739    (use (match_operand:MODEF 1 "general_operand" ""))
14740    (use (match_operand:MODEF 2 "general_operand" ""))]
14741  "TARGET_USE_FANCY_MATH_387
14742    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14743        || TARGET_MIX_SSE_I387)
14744    && flag_unsafe_math_optimizations"
14746   rtx op0, op1, op2;
14748   if (optimize_insn_for_size_p ())
14749     FAIL;
14751   op0 = gen_reg_rtx (XFmode);
14752   op1 = gen_reg_rtx (XFmode);
14753   op2 = gen_reg_rtx (XFmode);
14755   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14756   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14757   emit_insn (gen_scalbxf3 (op0, op1, op2));
14758   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14759   DONE;
14762 (define_expand "significandxf2"
14763   [(parallel [(set (match_operand:XF 0 "register_operand" "")
14764                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14765                               UNSPEC_XTRACT_FRACT))
14766               (set (match_dup 2)
14767                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14768   "TARGET_USE_FANCY_MATH_387
14769    && flag_unsafe_math_optimizations"
14771   operands[2] = gen_reg_rtx (XFmode);
14774 (define_expand "significand<mode>2"
14775   [(use (match_operand:MODEF 0 "register_operand" ""))
14776    (use (match_operand:MODEF 1 "register_operand" ""))]
14777   "TARGET_USE_FANCY_MATH_387
14778    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14779        || TARGET_MIX_SSE_I387)
14780    && flag_unsafe_math_optimizations"
14782   rtx op0 = gen_reg_rtx (XFmode);
14783   rtx op1 = gen_reg_rtx (XFmode);
14785   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14786   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14787   DONE;
14791 (define_insn "sse4_1_round<mode>2"
14792   [(set (match_operand:MODEF 0 "register_operand" "=x")
14793         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14794                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14795                       UNSPEC_ROUND))]
14796   "TARGET_ROUND"
14797   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14798   [(set_attr "type" "ssecvt")
14799    (set_attr "prefix_extra" "1")
14800    (set_attr "prefix" "maybe_vex")
14801    (set_attr "mode" "<MODE>")])
14803 (define_insn "rintxf2"
14804   [(set (match_operand:XF 0 "register_operand" "=f")
14805         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14806                    UNSPEC_FRNDINT))]
14807   "TARGET_USE_FANCY_MATH_387
14808    && flag_unsafe_math_optimizations"
14809   "frndint"
14810   [(set_attr "type" "fpspc")
14811    (set_attr "mode" "XF")])
14813 (define_expand "rint<mode>2"
14814   [(use (match_operand:MODEF 0 "register_operand" ""))
14815    (use (match_operand:MODEF 1 "register_operand" ""))]
14816   "(TARGET_USE_FANCY_MATH_387
14817     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14818         || TARGET_MIX_SSE_I387)
14819     && flag_unsafe_math_optimizations)
14820    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14821        && !flag_trapping_math)"
14823   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14824       && !flag_trapping_math)
14825     {
14826       if (!TARGET_ROUND && optimize_insn_for_size_p ())
14827         FAIL;
14828       if (TARGET_ROUND)
14829         emit_insn (gen_sse4_1_round<mode>2
14830                    (operands[0], operands[1], GEN_INT (0x04)));
14831       else
14832         ix86_expand_rint (operand0, operand1);
14833     }
14834   else
14835     {
14836       rtx op0 = gen_reg_rtx (XFmode);
14837       rtx op1 = gen_reg_rtx (XFmode);
14839       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14840       emit_insn (gen_rintxf2 (op0, op1));
14842       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14843     }
14844   DONE;
14847 (define_expand "round<mode>2"
14848   [(match_operand:MODEF 0 "register_operand" "")
14849    (match_operand:MODEF 1 "nonimmediate_operand" "")]
14850   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14851    && !flag_trapping_math && !flag_rounding_math"
14853   if (optimize_insn_for_size_p ())
14854     FAIL;
14855   if (TARGET_64BIT || (<MODE>mode != DFmode))
14856     ix86_expand_round (operand0, operand1);
14857   else
14858     ix86_expand_rounddf_32 (operand0, operand1);
14859   DONE;
14862 (define_insn_and_split "*fistdi2_1"
14863   [(set (match_operand:DI 0 "nonimmediate_operand" "")
14864         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14865                    UNSPEC_FIST))]
14866   "TARGET_USE_FANCY_MATH_387
14867    && can_create_pseudo_p ()"
14868   "#"
14869   "&& 1"
14870   [(const_int 0)]
14872   if (memory_operand (operands[0], VOIDmode))
14873     emit_insn (gen_fistdi2 (operands[0], operands[1]));
14874   else
14875     {
14876       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14877       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14878                                          operands[2]));
14879     }
14880   DONE;
14882   [(set_attr "type" "fpspc")
14883    (set_attr "mode" "DI")])
14885 (define_insn "fistdi2"
14886   [(set (match_operand:DI 0 "memory_operand" "=m")
14887         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14888                    UNSPEC_FIST))
14889    (clobber (match_scratch:XF 2 "=&1f"))]
14890   "TARGET_USE_FANCY_MATH_387"
14891   "* return output_fix_trunc (insn, operands, 0);"
14892   [(set_attr "type" "fpspc")
14893    (set_attr "mode" "DI")])
14895 (define_insn "fistdi2_with_temp"
14896   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14897         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14898                    UNSPEC_FIST))
14899    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14900    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14901   "TARGET_USE_FANCY_MATH_387"
14902   "#"
14903   [(set_attr "type" "fpspc")
14904    (set_attr "mode" "DI")])
14906 (define_split
14907   [(set (match_operand:DI 0 "register_operand" "")
14908         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14909                    UNSPEC_FIST))
14910    (clobber (match_operand:DI 2 "memory_operand" ""))
14911    (clobber (match_scratch 3 ""))]
14912   "reload_completed"
14913   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14914               (clobber (match_dup 3))])
14915    (set (match_dup 0) (match_dup 2))]
14916   "")
14918 (define_split
14919   [(set (match_operand:DI 0 "memory_operand" "")
14920         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14921                    UNSPEC_FIST))
14922    (clobber (match_operand:DI 2 "memory_operand" ""))
14923    (clobber (match_scratch 3 ""))]
14924   "reload_completed"
14925   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14926               (clobber (match_dup 3))])]
14927   "")
14929 (define_insn_and_split "*fist<mode>2_1"
14930   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14931         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14932                            UNSPEC_FIST))]
14933   "TARGET_USE_FANCY_MATH_387
14934    && can_create_pseudo_p ()"
14935   "#"
14936   "&& 1"
14937   [(const_int 0)]
14939   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14940   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14941                                         operands[2]));
14942   DONE;
14944   [(set_attr "type" "fpspc")
14945    (set_attr "mode" "<MODE>")])
14947 (define_insn "fist<mode>2"
14948   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14949         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14950                            UNSPEC_FIST))]
14951   "TARGET_USE_FANCY_MATH_387"
14952   "* return output_fix_trunc (insn, operands, 0);"
14953   [(set_attr "type" "fpspc")
14954    (set_attr "mode" "<MODE>")])
14956 (define_insn "fist<mode>2_with_temp"
14957   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14958         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14959                            UNSPEC_FIST))
14960    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14961   "TARGET_USE_FANCY_MATH_387"
14962   "#"
14963   [(set_attr "type" "fpspc")
14964    (set_attr "mode" "<MODE>")])
14966 (define_split
14967   [(set (match_operand:X87MODEI12 0 "register_operand" "")
14968         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14969                            UNSPEC_FIST))
14970    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14971   "reload_completed"
14972   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14973    (set (match_dup 0) (match_dup 2))]
14974   "")
14976 (define_split
14977   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14978         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14979                            UNSPEC_FIST))
14980    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14981   "reload_completed"
14982   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
14983   "")
14985 (define_expand "lrintxf<mode>2"
14986   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14987      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14988                       UNSPEC_FIST))]
14989   "TARGET_USE_FANCY_MATH_387"
14990   "")
14992 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14993   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14994      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14995                         UNSPEC_FIX_NOTRUNC))]
14996   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14997    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14998   "")
15000 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
15001   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
15002    (match_operand:MODEF 1 "register_operand" "")]
15003   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15004    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
15005    && !flag_trapping_math && !flag_rounding_math"
15007   if (optimize_insn_for_size_p ())
15008     FAIL;
15009   ix86_expand_lround (operand0, operand1);
15010   DONE;
15013 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15014 (define_insn_and_split "frndintxf2_floor"
15015   [(set (match_operand:XF 0 "register_operand" "")
15016         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15017          UNSPEC_FRNDINT_FLOOR))
15018    (clobber (reg:CC FLAGS_REG))]
15019   "TARGET_USE_FANCY_MATH_387
15020    && flag_unsafe_math_optimizations
15021    && can_create_pseudo_p ()"
15022   "#"
15023   "&& 1"
15024   [(const_int 0)]
15026   ix86_optimize_mode_switching[I387_FLOOR] = 1;
15028   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15029   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
15031   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
15032                                         operands[2], operands[3]));
15033   DONE;
15035   [(set_attr "type" "frndint")
15036    (set_attr "i387_cw" "floor")
15037    (set_attr "mode" "XF")])
15039 (define_insn "frndintxf2_floor_i387"
15040   [(set (match_operand:XF 0 "register_operand" "=f")
15041         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15042          UNSPEC_FRNDINT_FLOOR))
15043    (use (match_operand:HI 2 "memory_operand" "m"))
15044    (use (match_operand:HI 3 "memory_operand" "m"))]
15045   "TARGET_USE_FANCY_MATH_387
15046    && flag_unsafe_math_optimizations"
15047   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15048   [(set_attr "type" "frndint")
15049    (set_attr "i387_cw" "floor")
15050    (set_attr "mode" "XF")])
15052 (define_expand "floorxf2"
15053   [(use (match_operand:XF 0 "register_operand" ""))
15054    (use (match_operand:XF 1 "register_operand" ""))]
15055   "TARGET_USE_FANCY_MATH_387
15056    && flag_unsafe_math_optimizations"
15058   if (optimize_insn_for_size_p ())
15059     FAIL;
15060   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
15061   DONE;
15064 (define_expand "floor<mode>2"
15065   [(use (match_operand:MODEF 0 "register_operand" ""))
15066    (use (match_operand:MODEF 1 "register_operand" ""))]
15067   "(TARGET_USE_FANCY_MATH_387
15068     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15069         || TARGET_MIX_SSE_I387)
15070     && flag_unsafe_math_optimizations)
15071    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15072        && !flag_trapping_math)"
15074   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15075       && !flag_trapping_math
15076       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15077     {
15078       if (!TARGET_ROUND && optimize_insn_for_size_p ())
15079         FAIL;
15080       if (TARGET_ROUND)
15081         emit_insn (gen_sse4_1_round<mode>2
15082                    (operands[0], operands[1], GEN_INT (0x01)));
15083       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15084         ix86_expand_floorceil (operand0, operand1, true);
15085       else
15086         ix86_expand_floorceildf_32 (operand0, operand1, true);
15087     }
15088   else
15089     {
15090       rtx op0, op1;
15092       if (optimize_insn_for_size_p ())
15093         FAIL;
15095       op0 = gen_reg_rtx (XFmode);
15096       op1 = gen_reg_rtx (XFmode);
15097       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15098       emit_insn (gen_frndintxf2_floor (op0, op1));
15100       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15101     }
15102   DONE;
15105 (define_insn_and_split "*fist<mode>2_floor_1"
15106   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15107         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15108          UNSPEC_FIST_FLOOR))
15109    (clobber (reg:CC FLAGS_REG))]
15110   "TARGET_USE_FANCY_MATH_387
15111    && flag_unsafe_math_optimizations
15112    && can_create_pseudo_p ()"
15113   "#"
15114   "&& 1"
15115   [(const_int 0)]
15117   ix86_optimize_mode_switching[I387_FLOOR] = 1;
15119   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15120   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
15121   if (memory_operand (operands[0], VOIDmode))
15122     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
15123                                       operands[2], operands[3]));
15124   else
15125     {
15126       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15127       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
15128                                                   operands[2], operands[3],
15129                                                   operands[4]));
15130     }
15131   DONE;
15133   [(set_attr "type" "fistp")
15134    (set_attr "i387_cw" "floor")
15135    (set_attr "mode" "<MODE>")])
15137 (define_insn "fistdi2_floor"
15138   [(set (match_operand:DI 0 "memory_operand" "=m")
15139         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15140          UNSPEC_FIST_FLOOR))
15141    (use (match_operand:HI 2 "memory_operand" "m"))
15142    (use (match_operand:HI 3 "memory_operand" "m"))
15143    (clobber (match_scratch:XF 4 "=&1f"))]
15144   "TARGET_USE_FANCY_MATH_387
15145    && flag_unsafe_math_optimizations"
15146   "* return output_fix_trunc (insn, operands, 0);"
15147   [(set_attr "type" "fistp")
15148    (set_attr "i387_cw" "floor")
15149    (set_attr "mode" "DI")])
15151 (define_insn "fistdi2_floor_with_temp"
15152   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15153         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15154          UNSPEC_FIST_FLOOR))
15155    (use (match_operand:HI 2 "memory_operand" "m,m"))
15156    (use (match_operand:HI 3 "memory_operand" "m,m"))
15157    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15158    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15159   "TARGET_USE_FANCY_MATH_387
15160    && flag_unsafe_math_optimizations"
15161   "#"
15162   [(set_attr "type" "fistp")
15163    (set_attr "i387_cw" "floor")
15164    (set_attr "mode" "DI")])
15166 (define_split
15167   [(set (match_operand:DI 0 "register_operand" "")
15168         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15169          UNSPEC_FIST_FLOOR))
15170    (use (match_operand:HI 2 "memory_operand" ""))
15171    (use (match_operand:HI 3 "memory_operand" ""))
15172    (clobber (match_operand:DI 4 "memory_operand" ""))
15173    (clobber (match_scratch 5 ""))]
15174   "reload_completed"
15175   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15176               (use (match_dup 2))
15177               (use (match_dup 3))
15178               (clobber (match_dup 5))])
15179    (set (match_dup 0) (match_dup 4))]
15180   "")
15182 (define_split
15183   [(set (match_operand:DI 0 "memory_operand" "")
15184         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15185          UNSPEC_FIST_FLOOR))
15186    (use (match_operand:HI 2 "memory_operand" ""))
15187    (use (match_operand:HI 3 "memory_operand" ""))
15188    (clobber (match_operand:DI 4 "memory_operand" ""))
15189    (clobber (match_scratch 5 ""))]
15190   "reload_completed"
15191   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15192               (use (match_dup 2))
15193               (use (match_dup 3))
15194               (clobber (match_dup 5))])]
15195   "")
15197 (define_insn "fist<mode>2_floor"
15198   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15199         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15200          UNSPEC_FIST_FLOOR))
15201    (use (match_operand:HI 2 "memory_operand" "m"))
15202    (use (match_operand:HI 3 "memory_operand" "m"))]
15203   "TARGET_USE_FANCY_MATH_387
15204    && flag_unsafe_math_optimizations"
15205   "* return output_fix_trunc (insn, operands, 0);"
15206   [(set_attr "type" "fistp")
15207    (set_attr "i387_cw" "floor")
15208    (set_attr "mode" "<MODE>")])
15210 (define_insn "fist<mode>2_floor_with_temp"
15211   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15212         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15213          UNSPEC_FIST_FLOOR))
15214    (use (match_operand:HI 2 "memory_operand" "m,m"))
15215    (use (match_operand:HI 3 "memory_operand" "m,m"))
15216    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15217   "TARGET_USE_FANCY_MATH_387
15218    && flag_unsafe_math_optimizations"
15219   "#"
15220   [(set_attr "type" "fistp")
15221    (set_attr "i387_cw" "floor")
15222    (set_attr "mode" "<MODE>")])
15224 (define_split
15225   [(set (match_operand:X87MODEI12 0 "register_operand" "")
15226         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15227          UNSPEC_FIST_FLOOR))
15228    (use (match_operand:HI 2 "memory_operand" ""))
15229    (use (match_operand:HI 3 "memory_operand" ""))
15230    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15231   "reload_completed"
15232   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15233                                   UNSPEC_FIST_FLOOR))
15234               (use (match_dup 2))
15235               (use (match_dup 3))])
15236    (set (match_dup 0) (match_dup 4))]
15237   "")
15239 (define_split
15240   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15241         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15242          UNSPEC_FIST_FLOOR))
15243    (use (match_operand:HI 2 "memory_operand" ""))
15244    (use (match_operand:HI 3 "memory_operand" ""))
15245    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15246   "reload_completed"
15247   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15248                                   UNSPEC_FIST_FLOOR))
15249               (use (match_dup 2))
15250               (use (match_dup 3))])]
15251   "")
15253 (define_expand "lfloorxf<mode>2"
15254   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15255                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15256                     UNSPEC_FIST_FLOOR))
15257               (clobber (reg:CC FLAGS_REG))])]
15258   "TARGET_USE_FANCY_MATH_387
15259    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15260    && flag_unsafe_math_optimizations"
15261   "")
15263 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15264   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15265    (match_operand:MODEF 1 "register_operand" "")]
15266   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15267    && !flag_trapping_math"
15269   if (TARGET_64BIT && optimize_insn_for_size_p ())
15270     FAIL;
15271   ix86_expand_lfloorceil (operand0, operand1, true);
15272   DONE;
15275 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15276 (define_insn_and_split "frndintxf2_ceil"
15277   [(set (match_operand:XF 0 "register_operand" "")
15278         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15279          UNSPEC_FRNDINT_CEIL))
15280    (clobber (reg:CC FLAGS_REG))]
15281   "TARGET_USE_FANCY_MATH_387
15282    && flag_unsafe_math_optimizations
15283    && can_create_pseudo_p ()"
15284   "#"
15285   "&& 1"
15286   [(const_int 0)]
15288   ix86_optimize_mode_switching[I387_CEIL] = 1;
15290   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15291   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15293   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15294                                        operands[2], operands[3]));
15295   DONE;
15297   [(set_attr "type" "frndint")
15298    (set_attr "i387_cw" "ceil")
15299    (set_attr "mode" "XF")])
15301 (define_insn "frndintxf2_ceil_i387"
15302   [(set (match_operand:XF 0 "register_operand" "=f")
15303         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15304          UNSPEC_FRNDINT_CEIL))
15305    (use (match_operand:HI 2 "memory_operand" "m"))
15306    (use (match_operand:HI 3 "memory_operand" "m"))]
15307   "TARGET_USE_FANCY_MATH_387
15308    && flag_unsafe_math_optimizations"
15309   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15310   [(set_attr "type" "frndint")
15311    (set_attr "i387_cw" "ceil")
15312    (set_attr "mode" "XF")])
15314 (define_expand "ceilxf2"
15315   [(use (match_operand:XF 0 "register_operand" ""))
15316    (use (match_operand:XF 1 "register_operand" ""))]
15317   "TARGET_USE_FANCY_MATH_387
15318    && flag_unsafe_math_optimizations"
15320   if (optimize_insn_for_size_p ())
15321     FAIL;
15322   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15323   DONE;
15326 (define_expand "ceil<mode>2"
15327   [(use (match_operand:MODEF 0 "register_operand" ""))
15328    (use (match_operand:MODEF 1 "register_operand" ""))]
15329   "(TARGET_USE_FANCY_MATH_387
15330     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15331         || TARGET_MIX_SSE_I387)
15332     && flag_unsafe_math_optimizations)
15333    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15334        && !flag_trapping_math)"
15336   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15337       && !flag_trapping_math
15338       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15339     {
15340       if (TARGET_ROUND)
15341         emit_insn (gen_sse4_1_round<mode>2
15342                    (operands[0], operands[1], GEN_INT (0x02)));
15343       else if (optimize_insn_for_size_p ())
15344         FAIL;
15345       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15346         ix86_expand_floorceil (operand0, operand1, false);
15347       else
15348         ix86_expand_floorceildf_32 (operand0, operand1, false);
15349     }
15350   else
15351     {
15352       rtx op0, op1;
15354       if (optimize_insn_for_size_p ())
15355         FAIL;
15357       op0 = gen_reg_rtx (XFmode);
15358       op1 = gen_reg_rtx (XFmode);
15359       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15360       emit_insn (gen_frndintxf2_ceil (op0, op1));
15362       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15363     }
15364   DONE;
15367 (define_insn_and_split "*fist<mode>2_ceil_1"
15368   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15369         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15370          UNSPEC_FIST_CEIL))
15371    (clobber (reg:CC FLAGS_REG))]
15372   "TARGET_USE_FANCY_MATH_387
15373    && flag_unsafe_math_optimizations
15374    && can_create_pseudo_p ()"
15375   "#"
15376   "&& 1"
15377   [(const_int 0)]
15379   ix86_optimize_mode_switching[I387_CEIL] = 1;
15381   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15382   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15383   if (memory_operand (operands[0], VOIDmode))
15384     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15385                                      operands[2], operands[3]));
15386   else
15387     {
15388       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15389       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15390                                                  operands[2], operands[3],
15391                                                  operands[4]));
15392     }
15393   DONE;
15395   [(set_attr "type" "fistp")
15396    (set_attr "i387_cw" "ceil")
15397    (set_attr "mode" "<MODE>")])
15399 (define_insn "fistdi2_ceil"
15400   [(set (match_operand:DI 0 "memory_operand" "=m")
15401         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15402          UNSPEC_FIST_CEIL))
15403    (use (match_operand:HI 2 "memory_operand" "m"))
15404    (use (match_operand:HI 3 "memory_operand" "m"))
15405    (clobber (match_scratch:XF 4 "=&1f"))]
15406   "TARGET_USE_FANCY_MATH_387
15407    && flag_unsafe_math_optimizations"
15408   "* return output_fix_trunc (insn, operands, 0);"
15409   [(set_attr "type" "fistp")
15410    (set_attr "i387_cw" "ceil")
15411    (set_attr "mode" "DI")])
15413 (define_insn "fistdi2_ceil_with_temp"
15414   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15415         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15416          UNSPEC_FIST_CEIL))
15417    (use (match_operand:HI 2 "memory_operand" "m,m"))
15418    (use (match_operand:HI 3 "memory_operand" "m,m"))
15419    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15420    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15421   "TARGET_USE_FANCY_MATH_387
15422    && flag_unsafe_math_optimizations"
15423   "#"
15424   [(set_attr "type" "fistp")
15425    (set_attr "i387_cw" "ceil")
15426    (set_attr "mode" "DI")])
15428 (define_split
15429   [(set (match_operand:DI 0 "register_operand" "")
15430         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15431          UNSPEC_FIST_CEIL))
15432    (use (match_operand:HI 2 "memory_operand" ""))
15433    (use (match_operand:HI 3 "memory_operand" ""))
15434    (clobber (match_operand:DI 4 "memory_operand" ""))
15435    (clobber (match_scratch 5 ""))]
15436   "reload_completed"
15437   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15438               (use (match_dup 2))
15439               (use (match_dup 3))
15440               (clobber (match_dup 5))])
15441    (set (match_dup 0) (match_dup 4))]
15442   "")
15444 (define_split
15445   [(set (match_operand:DI 0 "memory_operand" "")
15446         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15447          UNSPEC_FIST_CEIL))
15448    (use (match_operand:HI 2 "memory_operand" ""))
15449    (use (match_operand:HI 3 "memory_operand" ""))
15450    (clobber (match_operand:DI 4 "memory_operand" ""))
15451    (clobber (match_scratch 5 ""))]
15452   "reload_completed"
15453   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15454               (use (match_dup 2))
15455               (use (match_dup 3))
15456               (clobber (match_dup 5))])]
15457   "")
15459 (define_insn "fist<mode>2_ceil"
15460   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
15461         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
15462          UNSPEC_FIST_CEIL))
15463    (use (match_operand:HI 2 "memory_operand" "m"))
15464    (use (match_operand:HI 3 "memory_operand" "m"))]
15465   "TARGET_USE_FANCY_MATH_387
15466    && flag_unsafe_math_optimizations"
15467   "* return output_fix_trunc (insn, operands, 0);"
15468   [(set_attr "type" "fistp")
15469    (set_attr "i387_cw" "ceil")
15470    (set_attr "mode" "<MODE>")])
15472 (define_insn "fist<mode>2_ceil_with_temp"
15473   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
15474         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
15475          UNSPEC_FIST_CEIL))
15476    (use (match_operand:HI 2 "memory_operand" "m,m"))
15477    (use (match_operand:HI 3 "memory_operand" "m,m"))
15478    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
15479   "TARGET_USE_FANCY_MATH_387
15480    && flag_unsafe_math_optimizations"
15481   "#"
15482   [(set_attr "type" "fistp")
15483    (set_attr "i387_cw" "ceil")
15484    (set_attr "mode" "<MODE>")])
15486 (define_split
15487   [(set (match_operand:X87MODEI12 0 "register_operand" "")
15488         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15489          UNSPEC_FIST_CEIL))
15490    (use (match_operand:HI 2 "memory_operand" ""))
15491    (use (match_operand:HI 3 "memory_operand" ""))
15492    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15493   "reload_completed"
15494   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
15495                                   UNSPEC_FIST_CEIL))
15496               (use (match_dup 2))
15497               (use (match_dup 3))])
15498    (set (match_dup 0) (match_dup 4))]
15499   "")
15501 (define_split
15502   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
15503         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
15504          UNSPEC_FIST_CEIL))
15505    (use (match_operand:HI 2 "memory_operand" ""))
15506    (use (match_operand:HI 3 "memory_operand" ""))
15507    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
15508   "reload_completed"
15509   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
15510                                   UNSPEC_FIST_CEIL))
15511               (use (match_dup 2))
15512               (use (match_dup 3))])]
15513   "")
15515 (define_expand "lceilxf<mode>2"
15516   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
15517                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
15518                     UNSPEC_FIST_CEIL))
15519               (clobber (reg:CC FLAGS_REG))])]
15520   "TARGET_USE_FANCY_MATH_387
15521    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15522    && flag_unsafe_math_optimizations"
15523   "")
15525 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15526   [(match_operand:SWI48 0 "nonimmediate_operand" "")
15527    (match_operand:MODEF 1 "register_operand" "")]
15528   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15529    && !flag_trapping_math"
15531   ix86_expand_lfloorceil (operand0, operand1, false);
15532   DONE;
15535 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15536 (define_insn_and_split "frndintxf2_trunc"
15537   [(set (match_operand:XF 0 "register_operand" "")
15538         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15539          UNSPEC_FRNDINT_TRUNC))
15540    (clobber (reg:CC FLAGS_REG))]
15541   "TARGET_USE_FANCY_MATH_387
15542    && flag_unsafe_math_optimizations
15543    && can_create_pseudo_p ()"
15544   "#"
15545   "&& 1"
15546   [(const_int 0)]
15548   ix86_optimize_mode_switching[I387_TRUNC] = 1;
15550   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15551   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15553   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15554                                         operands[2], operands[3]));
15555   DONE;
15557   [(set_attr "type" "frndint")
15558    (set_attr "i387_cw" "trunc")
15559    (set_attr "mode" "XF")])
15561 (define_insn "frndintxf2_trunc_i387"
15562   [(set (match_operand:XF 0 "register_operand" "=f")
15563         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15564          UNSPEC_FRNDINT_TRUNC))
15565    (use (match_operand:HI 2 "memory_operand" "m"))
15566    (use (match_operand:HI 3 "memory_operand" "m"))]
15567   "TARGET_USE_FANCY_MATH_387
15568    && flag_unsafe_math_optimizations"
15569   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15570   [(set_attr "type" "frndint")
15571    (set_attr "i387_cw" "trunc")
15572    (set_attr "mode" "XF")])
15574 (define_expand "btruncxf2"
15575   [(use (match_operand:XF 0 "register_operand" ""))
15576    (use (match_operand:XF 1 "register_operand" ""))]
15577   "TARGET_USE_FANCY_MATH_387
15578    && flag_unsafe_math_optimizations"
15580   if (optimize_insn_for_size_p ())
15581     FAIL;
15582   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15583   DONE;
15586 (define_expand "btrunc<mode>2"
15587   [(use (match_operand:MODEF 0 "register_operand" ""))
15588    (use (match_operand:MODEF 1 "register_operand" ""))]
15589   "(TARGET_USE_FANCY_MATH_387
15590     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15591         || TARGET_MIX_SSE_I387)
15592     && flag_unsafe_math_optimizations)
15593    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15594        && !flag_trapping_math)"
15596   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15597       && !flag_trapping_math
15598       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
15599     {
15600       if (TARGET_ROUND)
15601         emit_insn (gen_sse4_1_round<mode>2
15602                    (operands[0], operands[1], GEN_INT (0x03)));
15603       else if (optimize_insn_for_size_p ())
15604         FAIL;
15605       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15606         ix86_expand_trunc (operand0, operand1);
15607       else
15608         ix86_expand_truncdf_32 (operand0, operand1);
15609     }
15610   else
15611     {
15612       rtx op0, op1;
15614       if (optimize_insn_for_size_p ())
15615         FAIL;
15617       op0 = gen_reg_rtx (XFmode);
15618       op1 = gen_reg_rtx (XFmode);
15619       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15620       emit_insn (gen_frndintxf2_trunc (op0, op1));
15622       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15623     }
15624   DONE;
15627 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15628 (define_insn_and_split "frndintxf2_mask_pm"
15629   [(set (match_operand:XF 0 "register_operand" "")
15630         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15631          UNSPEC_FRNDINT_MASK_PM))
15632    (clobber (reg:CC FLAGS_REG))]
15633   "TARGET_USE_FANCY_MATH_387
15634    && flag_unsafe_math_optimizations
15635    && can_create_pseudo_p ()"
15636   "#"
15637   "&& 1"
15638   [(const_int 0)]
15640   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15642   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15643   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15645   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15646                                           operands[2], operands[3]));
15647   DONE;
15649   [(set_attr "type" "frndint")
15650    (set_attr "i387_cw" "mask_pm")
15651    (set_attr "mode" "XF")])
15653 (define_insn "frndintxf2_mask_pm_i387"
15654   [(set (match_operand:XF 0 "register_operand" "=f")
15655         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15656          UNSPEC_FRNDINT_MASK_PM))
15657    (use (match_operand:HI 2 "memory_operand" "m"))
15658    (use (match_operand:HI 3 "memory_operand" "m"))]
15659   "TARGET_USE_FANCY_MATH_387
15660    && flag_unsafe_math_optimizations"
15661   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15662   [(set_attr "type" "frndint")
15663    (set_attr "i387_cw" "mask_pm")
15664    (set_attr "mode" "XF")])
15666 (define_expand "nearbyintxf2"
15667   [(use (match_operand:XF 0 "register_operand" ""))
15668    (use (match_operand:XF 1 "register_operand" ""))]
15669   "TARGET_USE_FANCY_MATH_387
15670    && flag_unsafe_math_optimizations"
15672   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15674   DONE;
15677 (define_expand "nearbyint<mode>2"
15678   [(use (match_operand:MODEF 0 "register_operand" ""))
15679    (use (match_operand:MODEF 1 "register_operand" ""))]
15680   "TARGET_USE_FANCY_MATH_387
15681    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15682        || TARGET_MIX_SSE_I387)
15683    && flag_unsafe_math_optimizations"
15685   rtx op0 = gen_reg_rtx (XFmode);
15686   rtx op1 = gen_reg_rtx (XFmode);
15688   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15689   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15691   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15692   DONE;
15695 (define_insn "fxam<mode>2_i387"
15696   [(set (match_operand:HI 0 "register_operand" "=a")
15697         (unspec:HI
15698           [(match_operand:X87MODEF 1 "register_operand" "f")]
15699           UNSPEC_FXAM))]
15700   "TARGET_USE_FANCY_MATH_387"
15701   "fxam\n\tfnstsw\t%0"
15702   [(set_attr "type" "multi")
15703    (set_attr "length" "4")
15704    (set_attr "unit" "i387")
15705    (set_attr "mode" "<MODE>")])
15707 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15708   [(set (match_operand:HI 0 "register_operand" "")
15709         (unspec:HI
15710           [(match_operand:MODEF 1 "memory_operand" "")]
15711           UNSPEC_FXAM_MEM))]
15712   "TARGET_USE_FANCY_MATH_387
15713    && can_create_pseudo_p ()"
15714   "#"
15715   "&& 1"
15716   [(set (match_dup 2)(match_dup 1))
15717    (set (match_dup 0)
15718         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15720   operands[2] = gen_reg_rtx (<MODE>mode);
15722   MEM_VOLATILE_P (operands[1]) = 1;
15724   [(set_attr "type" "multi")
15725    (set_attr "unit" "i387")
15726    (set_attr "mode" "<MODE>")])
15728 (define_expand "isinfxf2"
15729   [(use (match_operand:SI 0 "register_operand" ""))
15730    (use (match_operand:XF 1 "register_operand" ""))]
15731   "TARGET_USE_FANCY_MATH_387
15732    && TARGET_C99_FUNCTIONS"
15734   rtx mask = GEN_INT (0x45);
15735   rtx val = GEN_INT (0x05);
15737   rtx cond;
15739   rtx scratch = gen_reg_rtx (HImode);
15740   rtx res = gen_reg_rtx (QImode);
15742   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15744   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15745   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15746   cond = gen_rtx_fmt_ee (EQ, QImode,
15747                          gen_rtx_REG (CCmode, FLAGS_REG),
15748                          const0_rtx);
15749   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15750   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15751   DONE;
15754 (define_expand "isinf<mode>2"
15755   [(use (match_operand:SI 0 "register_operand" ""))
15756    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15757   "TARGET_USE_FANCY_MATH_387
15758    && TARGET_C99_FUNCTIONS
15759    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15761   rtx mask = GEN_INT (0x45);
15762   rtx val = GEN_INT (0x05);
15764   rtx cond;
15766   rtx scratch = gen_reg_rtx (HImode);
15767   rtx res = gen_reg_rtx (QImode);
15769   /* Remove excess precision by forcing value through memory. */
15770   if (memory_operand (operands[1], VOIDmode))
15771     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15772   else
15773     {
15774       enum ix86_stack_slot slot = (virtuals_instantiated
15775                                    ? SLOT_TEMP
15776                                    : SLOT_VIRTUAL);
15777       rtx temp = assign_386_stack_local (<MODE>mode, slot);
15779       emit_move_insn (temp, operands[1]);
15780       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15781     }
15783   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15784   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15785   cond = gen_rtx_fmt_ee (EQ, QImode,
15786                          gen_rtx_REG (CCmode, FLAGS_REG),
15787                          const0_rtx);
15788   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15789   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15790   DONE;
15793 (define_expand "signbit<mode>2"
15794   [(use (match_operand:SI 0 "register_operand" ""))
15795    (use (match_operand:X87MODEF 1 "register_operand" ""))]
15796   "TARGET_USE_FANCY_MATH_387
15797    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15799   rtx mask = GEN_INT (0x0200);
15801   rtx scratch = gen_reg_rtx (HImode);
15803   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
15804   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
15805   DONE;
15808 ;; Block operation instructions
15810 (define_insn "cld"
15811   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15812   ""
15813   "cld"
15814   [(set_attr "length" "1")
15815    (set_attr "length_immediate" "0")
15816    (set_attr "modrm" "0")])
15818 (define_expand "movmemsi"
15819   [(use (match_operand:BLK 0 "memory_operand" ""))
15820    (use (match_operand:BLK 1 "memory_operand" ""))
15821    (use (match_operand:SI 2 "nonmemory_operand" ""))
15822    (use (match_operand:SI 3 "const_int_operand" ""))
15823    (use (match_operand:SI 4 "const_int_operand" ""))
15824    (use (match_operand:SI 5 "const_int_operand" ""))]
15825   ""
15827  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15828                          operands[4], operands[5]))
15829    DONE;
15830  else
15831    FAIL;
15834 (define_expand "movmemdi"
15835   [(use (match_operand:BLK 0 "memory_operand" ""))
15836    (use (match_operand:BLK 1 "memory_operand" ""))
15837    (use (match_operand:DI 2 "nonmemory_operand" ""))
15838    (use (match_operand:DI 3 "const_int_operand" ""))
15839    (use (match_operand:SI 4 "const_int_operand" ""))
15840    (use (match_operand:SI 5 "const_int_operand" ""))]
15841   "TARGET_64BIT"
15843  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15844                          operands[4], operands[5]))
15845    DONE;
15846  else
15847    FAIL;
15850 ;; Most CPUs don't like single string operations
15851 ;; Handle this case here to simplify previous expander.
15853 (define_expand "strmov"
15854   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15855    (set (match_operand 1 "memory_operand" "") (match_dup 4))
15856    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15857               (clobber (reg:CC FLAGS_REG))])
15858    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15859               (clobber (reg:CC FLAGS_REG))])]
15860   ""
15862   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15864   /* If .md ever supports :P for Pmode, these can be directly
15865      in the pattern above.  */
15866   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15867   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15869   /* Can't use this if the user has appropriated esi or edi.  */
15870   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15871       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15872     {
15873       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15874                                       operands[2], operands[3],
15875                                       operands[5], operands[6]));
15876       DONE;
15877     }
15879   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15882 (define_expand "strmov_singleop"
15883   [(parallel [(set (match_operand 1 "memory_operand" "")
15884                    (match_operand 3 "memory_operand" ""))
15885               (set (match_operand 0 "register_operand" "")
15886                    (match_operand 4 "" ""))
15887               (set (match_operand 2 "register_operand" "")
15888                    (match_operand 5 "" ""))])]
15889   ""
15890   "ix86_current_function_needs_cld = 1;")
15892 (define_insn "*strmovdi_rex_1"
15893   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15894         (mem:DI (match_operand:DI 3 "register_operand" "1")))
15895    (set (match_operand:DI 0 "register_operand" "=D")
15896         (plus:DI (match_dup 2)
15897                  (const_int 8)))
15898    (set (match_operand:DI 1 "register_operand" "=S")
15899         (plus:DI (match_dup 3)
15900                  (const_int 8)))]
15901   "TARGET_64BIT"
15902   "movsq"
15903   [(set_attr "type" "str")
15904    (set_attr "mode" "DI")
15905    (set_attr "memory" "both")])
15907 (define_insn "*strmovsi_1"
15908   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15909         (mem:SI (match_operand:SI 3 "register_operand" "1")))
15910    (set (match_operand:SI 0 "register_operand" "=D")
15911         (plus:SI (match_dup 2)
15912                  (const_int 4)))
15913    (set (match_operand:SI 1 "register_operand" "=S")
15914         (plus:SI (match_dup 3)
15915                  (const_int 4)))]
15916   "!TARGET_64BIT"
15917   "movs{l|d}"
15918   [(set_attr "type" "str")
15919    (set_attr "mode" "SI")
15920    (set_attr "memory" "both")])
15922 (define_insn "*strmovsi_rex_1"
15923   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15924         (mem:SI (match_operand:DI 3 "register_operand" "1")))
15925    (set (match_operand:DI 0 "register_operand" "=D")
15926         (plus:DI (match_dup 2)
15927                  (const_int 4)))
15928    (set (match_operand:DI 1 "register_operand" "=S")
15929         (plus:DI (match_dup 3)
15930                  (const_int 4)))]
15931   "TARGET_64BIT"
15932   "movs{l|d}"
15933   [(set_attr "type" "str")
15934    (set_attr "mode" "SI")
15935    (set_attr "memory" "both")])
15937 (define_insn "*strmovhi_1"
15938   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15939         (mem:HI (match_operand:SI 3 "register_operand" "1")))
15940    (set (match_operand:SI 0 "register_operand" "=D")
15941         (plus:SI (match_dup 2)
15942                  (const_int 2)))
15943    (set (match_operand:SI 1 "register_operand" "=S")
15944         (plus:SI (match_dup 3)
15945                  (const_int 2)))]
15946   "!TARGET_64BIT"
15947   "movsw"
15948   [(set_attr "type" "str")
15949    (set_attr "memory" "both")
15950    (set_attr "mode" "HI")])
15952 (define_insn "*strmovhi_rex_1"
15953   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15954         (mem:HI (match_operand:DI 3 "register_operand" "1")))
15955    (set (match_operand:DI 0 "register_operand" "=D")
15956         (plus:DI (match_dup 2)
15957                  (const_int 2)))
15958    (set (match_operand:DI 1 "register_operand" "=S")
15959         (plus:DI (match_dup 3)
15960                  (const_int 2)))]
15961   "TARGET_64BIT"
15962   "movsw"
15963   [(set_attr "type" "str")
15964    (set_attr "memory" "both")
15965    (set_attr "mode" "HI")])
15967 (define_insn "*strmovqi_1"
15968   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15969         (mem:QI (match_operand:SI 3 "register_operand" "1")))
15970    (set (match_operand:SI 0 "register_operand" "=D")
15971         (plus:SI (match_dup 2)
15972                  (const_int 1)))
15973    (set (match_operand:SI 1 "register_operand" "=S")
15974         (plus:SI (match_dup 3)
15975                  (const_int 1)))]
15976   "!TARGET_64BIT"
15977   "movsb"
15978   [(set_attr "type" "str")
15979    (set_attr "memory" "both")
15980    (set_attr "mode" "QI")])
15982 (define_insn "*strmovqi_rex_1"
15983   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15984         (mem:QI (match_operand:DI 3 "register_operand" "1")))
15985    (set (match_operand:DI 0 "register_operand" "=D")
15986         (plus:DI (match_dup 2)
15987                  (const_int 1)))
15988    (set (match_operand:DI 1 "register_operand" "=S")
15989         (plus:DI (match_dup 3)
15990                  (const_int 1)))]
15991   "TARGET_64BIT"
15992   "movsb"
15993   [(set_attr "type" "str")
15994    (set_attr "memory" "both")
15995    (set_attr "prefix_rex" "0")
15996    (set_attr "mode" "QI")])
15998 (define_expand "rep_mov"
15999   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
16000               (set (match_operand 0 "register_operand" "")
16001                    (match_operand 5 "" ""))
16002               (set (match_operand 2 "register_operand" "")
16003                    (match_operand 6 "" ""))
16004               (set (match_operand 1 "memory_operand" "")
16005                    (match_operand 3 "memory_operand" ""))
16006               (use (match_dup 4))])]
16007   ""
16008   "ix86_current_function_needs_cld = 1;")
16010 (define_insn "*rep_movdi_rex64"
16011   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16012    (set (match_operand:DI 0 "register_operand" "=D")
16013         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16014                             (const_int 3))
16015                  (match_operand:DI 3 "register_operand" "0")))
16016    (set (match_operand:DI 1 "register_operand" "=S")
16017         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
16018                  (match_operand:DI 4 "register_operand" "1")))
16019    (set (mem:BLK (match_dup 3))
16020         (mem:BLK (match_dup 4)))
16021    (use (match_dup 5))]
16022   "TARGET_64BIT"
16023   "rep movsq"
16024   [(set_attr "type" "str")
16025    (set_attr "prefix_rep" "1")
16026    (set_attr "memory" "both")
16027    (set_attr "mode" "DI")])
16029 (define_insn "*rep_movsi"
16030   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16031    (set (match_operand:SI 0 "register_operand" "=D")
16032         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
16033                             (const_int 2))
16034                  (match_operand:SI 3 "register_operand" "0")))
16035    (set (match_operand:SI 1 "register_operand" "=S")
16036         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
16037                  (match_operand:SI 4 "register_operand" "1")))
16038    (set (mem:BLK (match_dup 3))
16039         (mem:BLK (match_dup 4)))
16040    (use (match_dup 5))]
16041   "!TARGET_64BIT"
16042   "rep movs{l|d}"
16043   [(set_attr "type" "str")
16044    (set_attr "prefix_rep" "1")
16045    (set_attr "memory" "both")
16046    (set_attr "mode" "SI")])
16048 (define_insn "*rep_movsi_rex64"
16049   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16050    (set (match_operand:DI 0 "register_operand" "=D")
16051         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
16052                             (const_int 2))
16053                  (match_operand:DI 3 "register_operand" "0")))
16054    (set (match_operand:DI 1 "register_operand" "=S")
16055         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
16056                  (match_operand:DI 4 "register_operand" "1")))
16057    (set (mem:BLK (match_dup 3))
16058         (mem:BLK (match_dup 4)))
16059    (use (match_dup 5))]
16060   "TARGET_64BIT"
16061   "rep movs{l|d}"
16062   [(set_attr "type" "str")
16063    (set_attr "prefix_rep" "1")
16064    (set_attr "memory" "both")
16065    (set_attr "mode" "SI")])
16067 (define_insn "*rep_movqi"
16068   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
16069    (set (match_operand:SI 0 "register_operand" "=D")
16070         (plus:SI (match_operand:SI 3 "register_operand" "0")
16071                  (match_operand:SI 5 "register_operand" "2")))
16072    (set (match_operand:SI 1 "register_operand" "=S")
16073         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
16074    (set (mem:BLK (match_dup 3))
16075         (mem:BLK (match_dup 4)))
16076    (use (match_dup 5))]
16077   "!TARGET_64BIT"
16078   "rep movsb"
16079   [(set_attr "type" "str")
16080    (set_attr "prefix_rep" "1")
16081    (set_attr "memory" "both")
16082    (set_attr "mode" "SI")])
16084 (define_insn "*rep_movqi_rex64"
16085   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
16086    (set (match_operand:DI 0 "register_operand" "=D")
16087         (plus:DI (match_operand:DI 3 "register_operand" "0")
16088                  (match_operand:DI 5 "register_operand" "2")))
16089    (set (match_operand:DI 1 "register_operand" "=S")
16090         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
16091    (set (mem:BLK (match_dup 3))
16092         (mem:BLK (match_dup 4)))
16093    (use (match_dup 5))]
16094   "TARGET_64BIT"
16095   "rep movsb"
16096   [(set_attr "type" "str")
16097    (set_attr "prefix_rep" "1")
16098    (set_attr "memory" "both")
16099    (set_attr "mode" "SI")])
16101 (define_expand "setmemsi"
16102    [(use (match_operand:BLK 0 "memory_operand" ""))
16103     (use (match_operand:SI 1 "nonmemory_operand" ""))
16104     (use (match_operand 2 "const_int_operand" ""))
16105     (use (match_operand 3 "const_int_operand" ""))
16106     (use (match_operand:SI 4 "const_int_operand" ""))
16107     (use (match_operand:SI 5 "const_int_operand" ""))]
16108   ""
16110  if (ix86_expand_setmem (operands[0], operands[1],
16111                          operands[2], operands[3],
16112                          operands[4], operands[5]))
16113    DONE;
16114  else
16115    FAIL;
16118 (define_expand "setmemdi"
16119    [(use (match_operand:BLK 0 "memory_operand" ""))
16120     (use (match_operand:DI 1 "nonmemory_operand" ""))
16121     (use (match_operand 2 "const_int_operand" ""))
16122     (use (match_operand 3 "const_int_operand" ""))
16123     (use (match_operand 4 "const_int_operand" ""))
16124     (use (match_operand 5 "const_int_operand" ""))]
16125   "TARGET_64BIT"
16127  if (ix86_expand_setmem (operands[0], operands[1],
16128                          operands[2], operands[3],
16129                          operands[4], operands[5]))
16130    DONE;
16131  else
16132    FAIL;
16135 ;; Most CPUs don't like single string operations
16136 ;; Handle this case here to simplify previous expander.
16138 (define_expand "strset"
16139   [(set (match_operand 1 "memory_operand" "")
16140         (match_operand 2 "register_operand" ""))
16141    (parallel [(set (match_operand 0 "register_operand" "")
16142                    (match_dup 3))
16143               (clobber (reg:CC FLAGS_REG))])]
16144   ""
16146   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
16147     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
16149   /* If .md ever supports :P for Pmode, this can be directly
16150      in the pattern above.  */
16151   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
16152                               GEN_INT (GET_MODE_SIZE (GET_MODE
16153                                                       (operands[2]))));
16154   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16155     {
16156       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16157                                       operands[3]));
16158       DONE;
16159     }
16162 (define_expand "strset_singleop"
16163   [(parallel [(set (match_operand 1 "memory_operand" "")
16164                    (match_operand 2 "register_operand" ""))
16165               (set (match_operand 0 "register_operand" "")
16166                    (match_operand 3 "" ""))])]
16167   ""
16168   "ix86_current_function_needs_cld = 1;")
16170 (define_insn "*strsetdi_rex_1"
16171   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
16172         (match_operand:DI 2 "register_operand" "a"))
16173    (set (match_operand:DI 0 "register_operand" "=D")
16174         (plus:DI (match_dup 1)
16175                  (const_int 8)))]
16176   "TARGET_64BIT"
16177   "stosq"
16178   [(set_attr "type" "str")
16179    (set_attr "memory" "store")
16180    (set_attr "mode" "DI")])
16182 (define_insn "*strsetsi_1"
16183   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
16184         (match_operand:SI 2 "register_operand" "a"))
16185    (set (match_operand:SI 0 "register_operand" "=D")
16186         (plus:SI (match_dup 1)
16187                  (const_int 4)))]
16188   "!TARGET_64BIT"
16189   "stos{l|d}"
16190   [(set_attr "type" "str")
16191    (set_attr "memory" "store")
16192    (set_attr "mode" "SI")])
16194 (define_insn "*strsetsi_rex_1"
16195   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
16196         (match_operand:SI 2 "register_operand" "a"))
16197    (set (match_operand:DI 0 "register_operand" "=D")
16198         (plus:DI (match_dup 1)
16199                  (const_int 4)))]
16200   "TARGET_64BIT"
16201   "stos{l|d}"
16202   [(set_attr "type" "str")
16203    (set_attr "memory" "store")
16204    (set_attr "mode" "SI")])
16206 (define_insn "*strsethi_1"
16207   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
16208         (match_operand:HI 2 "register_operand" "a"))
16209    (set (match_operand:SI 0 "register_operand" "=D")
16210         (plus:SI (match_dup 1)
16211                  (const_int 2)))]
16212   "!TARGET_64BIT"
16213   "stosw"
16214   [(set_attr "type" "str")
16215    (set_attr "memory" "store")
16216    (set_attr "mode" "HI")])
16218 (define_insn "*strsethi_rex_1"
16219   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
16220         (match_operand:HI 2 "register_operand" "a"))
16221    (set (match_operand:DI 0 "register_operand" "=D")
16222         (plus:DI (match_dup 1)
16223                  (const_int 2)))]
16224   "TARGET_64BIT"
16225   "stosw"
16226   [(set_attr "type" "str")
16227    (set_attr "memory" "store")
16228    (set_attr "mode" "HI")])
16230 (define_insn "*strsetqi_1"
16231   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
16232         (match_operand:QI 2 "register_operand" "a"))
16233    (set (match_operand:SI 0 "register_operand" "=D")
16234         (plus:SI (match_dup 1)
16235                  (const_int 1)))]
16236   "!TARGET_64BIT"
16237   "stosb"
16238   [(set_attr "type" "str")
16239    (set_attr "memory" "store")
16240    (set_attr "mode" "QI")])
16242 (define_insn "*strsetqi_rex_1"
16243   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
16244         (match_operand:QI 2 "register_operand" "a"))
16245    (set (match_operand:DI 0 "register_operand" "=D")
16246         (plus:DI (match_dup 1)
16247                  (const_int 1)))]
16248   "TARGET_64BIT"
16249   "stosb"
16250   [(set_attr "type" "str")
16251    (set_attr "memory" "store")
16252    (set_attr "prefix_rex" "0")
16253    (set_attr "mode" "QI")])
16255 (define_expand "rep_stos"
16256   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
16257               (set (match_operand 0 "register_operand" "")
16258                    (match_operand 4 "" ""))
16259               (set (match_operand 2 "memory_operand" "") (const_int 0))
16260               (use (match_operand 3 "register_operand" ""))
16261               (use (match_dup 1))])]
16262   ""
16263   "ix86_current_function_needs_cld = 1;")
16265 (define_insn "*rep_stosdi_rex64"
16266   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16267    (set (match_operand:DI 0 "register_operand" "=D")
16268         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16269                             (const_int 3))
16270                  (match_operand:DI 3 "register_operand" "0")))
16271    (set (mem:BLK (match_dup 3))
16272         (const_int 0))
16273    (use (match_operand:DI 2 "register_operand" "a"))
16274    (use (match_dup 4))]
16275   "TARGET_64BIT"
16276   "rep stosq"
16277   [(set_attr "type" "str")
16278    (set_attr "prefix_rep" "1")
16279    (set_attr "memory" "store")
16280    (set_attr "mode" "DI")])
16282 (define_insn "*rep_stossi"
16283   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16284    (set (match_operand:SI 0 "register_operand" "=D")
16285         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
16286                             (const_int 2))
16287                  (match_operand:SI 3 "register_operand" "0")))
16288    (set (mem:BLK (match_dup 3))
16289         (const_int 0))
16290    (use (match_operand:SI 2 "register_operand" "a"))
16291    (use (match_dup 4))]
16292   "!TARGET_64BIT"
16293   "rep stos{l|d}"
16294   [(set_attr "type" "str")
16295    (set_attr "prefix_rep" "1")
16296    (set_attr "memory" "store")
16297    (set_attr "mode" "SI")])
16299 (define_insn "*rep_stossi_rex64"
16300   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16301    (set (match_operand:DI 0 "register_operand" "=D")
16302         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16303                             (const_int 2))
16304                  (match_operand:DI 3 "register_operand" "0")))
16305    (set (mem:BLK (match_dup 3))
16306         (const_int 0))
16307    (use (match_operand:SI 2 "register_operand" "a"))
16308    (use (match_dup 4))]
16309   "TARGET_64BIT"
16310   "rep stos{l|d}"
16311   [(set_attr "type" "str")
16312    (set_attr "prefix_rep" "1")
16313    (set_attr "memory" "store")
16314    (set_attr "mode" "SI")])
16316 (define_insn "*rep_stosqi"
16317   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
16318    (set (match_operand:SI 0 "register_operand" "=D")
16319         (plus:SI (match_operand:SI 3 "register_operand" "0")
16320                  (match_operand:SI 4 "register_operand" "1")))
16321    (set (mem:BLK (match_dup 3))
16322         (const_int 0))
16323    (use (match_operand:QI 2 "register_operand" "a"))
16324    (use (match_dup 4))]
16325   "!TARGET_64BIT"
16326   "rep stosb"
16327   [(set_attr "type" "str")
16328    (set_attr "prefix_rep" "1")
16329    (set_attr "memory" "store")
16330    (set_attr "mode" "QI")])
16332 (define_insn "*rep_stosqi_rex64"
16333   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
16334    (set (match_operand:DI 0 "register_operand" "=D")
16335         (plus:DI (match_operand:DI 3 "register_operand" "0")
16336                  (match_operand:DI 4 "register_operand" "1")))
16337    (set (mem:BLK (match_dup 3))
16338         (const_int 0))
16339    (use (match_operand:QI 2 "register_operand" "a"))
16340    (use (match_dup 4))]
16341   "TARGET_64BIT"
16342   "rep stosb"
16343   [(set_attr "type" "str")
16344    (set_attr "prefix_rep" "1")
16345    (set_attr "memory" "store")
16346    (set_attr "prefix_rex" "0")
16347    (set_attr "mode" "QI")])
16349 (define_expand "cmpstrnsi"
16350   [(set (match_operand:SI 0 "register_operand" "")
16351         (compare:SI (match_operand:BLK 1 "general_operand" "")
16352                     (match_operand:BLK 2 "general_operand" "")))
16353    (use (match_operand 3 "general_operand" ""))
16354    (use (match_operand 4 "immediate_operand" ""))]
16355   ""
16357   rtx addr1, addr2, out, outlow, count, countreg, align;
16359   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16360     FAIL;
16362   /* Can't use this if the user has appropriated esi or edi.  */
16363   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
16364     FAIL;
16366   out = operands[0];
16367   if (!REG_P (out))
16368     out = gen_reg_rtx (SImode);
16370   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16371   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16372   if (addr1 != XEXP (operands[1], 0))
16373     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16374   if (addr2 != XEXP (operands[2], 0))
16375     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16377   count = operands[3];
16378   countreg = ix86_zero_extend_to_Pmode (count);
16380   /* %%% Iff we are testing strict equality, we can use known alignment
16381      to good advantage.  This may be possible with combine, particularly
16382      once cc0 is dead.  */
16383   align = operands[4];
16385   if (CONST_INT_P (count))
16386     {
16387       if (INTVAL (count) == 0)
16388         {
16389           emit_move_insn (operands[0], const0_rtx);
16390           DONE;
16391         }
16392       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16393                                      operands[1], operands[2]));
16394     }
16395   else
16396     {
16397       rtx (*cmp_insn)(rtx, rtx);
16399       if (TARGET_64BIT)
16400         cmp_insn = gen_cmpdi_1;
16401       else
16402         cmp_insn = gen_cmpsi_1;
16403       emit_insn (cmp_insn (countreg, countreg));
16404       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16405                                   operands[1], operands[2]));
16406     }
16408   outlow = gen_lowpart (QImode, out);
16409   emit_insn (gen_cmpintqi (outlow));
16410   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16412   if (operands[0] != out)
16413     emit_move_insn (operands[0], out);
16415   DONE;
16418 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16420 (define_expand "cmpintqi"
16421   [(set (match_dup 1)
16422         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16423    (set (match_dup 2)
16424         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16425    (parallel [(set (match_operand:QI 0 "register_operand" "")
16426                    (minus:QI (match_dup 1)
16427                              (match_dup 2)))
16428               (clobber (reg:CC FLAGS_REG))])]
16429   ""
16430   "operands[1] = gen_reg_rtx (QImode);
16431    operands[2] = gen_reg_rtx (QImode);")
16433 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16434 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16436 (define_expand "cmpstrnqi_nz_1"
16437   [(parallel [(set (reg:CC FLAGS_REG)
16438                    (compare:CC (match_operand 4 "memory_operand" "")
16439                                (match_operand 5 "memory_operand" "")))
16440               (use (match_operand 2 "register_operand" ""))
16441               (use (match_operand:SI 3 "immediate_operand" ""))
16442               (clobber (match_operand 0 "register_operand" ""))
16443               (clobber (match_operand 1 "register_operand" ""))
16444               (clobber (match_dup 2))])]
16445   ""
16446   "ix86_current_function_needs_cld = 1;")
16448 (define_insn "*cmpstrnqi_nz_1"
16449   [(set (reg:CC FLAGS_REG)
16450         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16451                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
16452    (use (match_operand:SI 6 "register_operand" "2"))
16453    (use (match_operand:SI 3 "immediate_operand" "i"))
16454    (clobber (match_operand:SI 0 "register_operand" "=S"))
16455    (clobber (match_operand:SI 1 "register_operand" "=D"))
16456    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16457   "!TARGET_64BIT"
16458   "repz cmpsb"
16459   [(set_attr "type" "str")
16460    (set_attr "mode" "QI")
16461    (set_attr "prefix_rep" "1")])
16463 (define_insn "*cmpstrnqi_nz_rex_1"
16464   [(set (reg:CC FLAGS_REG)
16465         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16466                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
16467    (use (match_operand:DI 6 "register_operand" "2"))
16468    (use (match_operand:SI 3 "immediate_operand" "i"))
16469    (clobber (match_operand:DI 0 "register_operand" "=S"))
16470    (clobber (match_operand:DI 1 "register_operand" "=D"))
16471    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16472   "TARGET_64BIT"
16473   "repz cmpsb"
16474   [(set_attr "type" "str")
16475    (set_attr "mode" "QI")
16476    (set_attr "prefix_rex" "0")
16477    (set_attr "prefix_rep" "1")])
16479 ;; The same, but the count is not known to not be zero.
16481 (define_expand "cmpstrnqi_1"
16482   [(parallel [(set (reg:CC FLAGS_REG)
16483                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16484                                      (const_int 0))
16485                   (compare:CC (match_operand 4 "memory_operand" "")
16486                               (match_operand 5 "memory_operand" ""))
16487                   (const_int 0)))
16488               (use (match_operand:SI 3 "immediate_operand" ""))
16489               (use (reg:CC FLAGS_REG))
16490               (clobber (match_operand 0 "register_operand" ""))
16491               (clobber (match_operand 1 "register_operand" ""))
16492               (clobber (match_dup 2))])]
16493   ""
16494   "ix86_current_function_needs_cld = 1;")
16496 (define_insn "*cmpstrnqi_1"
16497   [(set (reg:CC FLAGS_REG)
16498         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
16499                              (const_int 0))
16500           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
16501                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
16502           (const_int 0)))
16503    (use (match_operand:SI 3 "immediate_operand" "i"))
16504    (use (reg:CC FLAGS_REG))
16505    (clobber (match_operand:SI 0 "register_operand" "=S"))
16506    (clobber (match_operand:SI 1 "register_operand" "=D"))
16507    (clobber (match_operand:SI 2 "register_operand" "=c"))]
16508   "!TARGET_64BIT"
16509   "repz cmpsb"
16510   [(set_attr "type" "str")
16511    (set_attr "mode" "QI")
16512    (set_attr "prefix_rep" "1")])
16514 (define_insn "*cmpstrnqi_rex_1"
16515   [(set (reg:CC FLAGS_REG)
16516         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
16517                              (const_int 0))
16518           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
16519                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
16520           (const_int 0)))
16521    (use (match_operand:SI 3 "immediate_operand" "i"))
16522    (use (reg:CC FLAGS_REG))
16523    (clobber (match_operand:DI 0 "register_operand" "=S"))
16524    (clobber (match_operand:DI 1 "register_operand" "=D"))
16525    (clobber (match_operand:DI 2 "register_operand" "=c"))]
16526   "TARGET_64BIT"
16527   "repz cmpsb"
16528   [(set_attr "type" "str")
16529    (set_attr "mode" "QI")
16530    (set_attr "prefix_rex" "0")
16531    (set_attr "prefix_rep" "1")])
16533 (define_expand "strlensi"
16534   [(set (match_operand:SI 0 "register_operand" "")
16535         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
16536                     (match_operand:QI 2 "immediate_operand" "")
16537                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16538   ""
16540  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16541    DONE;
16542  else
16543    FAIL;
16546 (define_expand "strlendi"
16547   [(set (match_operand:DI 0 "register_operand" "")
16548         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
16549                     (match_operand:QI 2 "immediate_operand" "")
16550                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
16551   ""
16553  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16554    DONE;
16555  else
16556    FAIL;
16559 (define_expand "strlenqi_1"
16560   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
16561               (clobber (match_operand 1 "register_operand" ""))
16562               (clobber (reg:CC FLAGS_REG))])]
16563   ""
16564   "ix86_current_function_needs_cld = 1;")
16566 (define_insn "*strlenqi_1"
16567   [(set (match_operand:SI 0 "register_operand" "=&c")
16568         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
16569                     (match_operand:QI 2 "register_operand" "a")
16570                     (match_operand:SI 3 "immediate_operand" "i")
16571                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
16572    (clobber (match_operand:SI 1 "register_operand" "=D"))
16573    (clobber (reg:CC FLAGS_REG))]
16574   "!TARGET_64BIT"
16575   "repnz scasb"
16576   [(set_attr "type" "str")
16577    (set_attr "mode" "QI")
16578    (set_attr "prefix_rep" "1")])
16580 (define_insn "*strlenqi_rex_1"
16581   [(set (match_operand:DI 0 "register_operand" "=&c")
16582         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
16583                     (match_operand:QI 2 "register_operand" "a")
16584                     (match_operand:DI 3 "immediate_operand" "i")
16585                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
16586    (clobber (match_operand:DI 1 "register_operand" "=D"))
16587    (clobber (reg:CC FLAGS_REG))]
16588   "TARGET_64BIT"
16589   "repnz scasb"
16590   [(set_attr "type" "str")
16591    (set_attr "mode" "QI")
16592    (set_attr "prefix_rex" "0")
16593    (set_attr "prefix_rep" "1")])
16595 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16596 ;; handled in combine, but it is not currently up to the task.
16597 ;; When used for their truth value, the cmpstrn* expanders generate
16598 ;; code like this:
16600 ;;   repz cmpsb
16601 ;;   seta       %al
16602 ;;   setb       %dl
16603 ;;   cmpb       %al, %dl
16604 ;;   jcc        label
16606 ;; The intermediate three instructions are unnecessary.
16608 ;; This one handles cmpstrn*_nz_1...
16609 (define_peephole2
16610   [(parallel[
16611      (set (reg:CC FLAGS_REG)
16612           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16613                       (mem:BLK (match_operand 5 "register_operand" ""))))
16614      (use (match_operand 6 "register_operand" ""))
16615      (use (match_operand:SI 3 "immediate_operand" ""))
16616      (clobber (match_operand 0 "register_operand" ""))
16617      (clobber (match_operand 1 "register_operand" ""))
16618      (clobber (match_operand 2 "register_operand" ""))])
16619    (set (match_operand:QI 7 "register_operand" "")
16620         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16621    (set (match_operand:QI 8 "register_operand" "")
16622         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16623    (set (reg FLAGS_REG)
16624         (compare (match_dup 7) (match_dup 8)))
16625   ]
16626   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16627   [(parallel[
16628      (set (reg:CC FLAGS_REG)
16629           (compare:CC (mem:BLK (match_dup 4))
16630                       (mem:BLK (match_dup 5))))
16631      (use (match_dup 6))
16632      (use (match_dup 3))
16633      (clobber (match_dup 0))
16634      (clobber (match_dup 1))
16635      (clobber (match_dup 2))])]
16636   "")
16638 ;; ...and this one handles cmpstrn*_1.
16639 (define_peephole2
16640   [(parallel[
16641      (set (reg:CC FLAGS_REG)
16642           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16643                                (const_int 0))
16644             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16645                         (mem:BLK (match_operand 5 "register_operand" "")))
16646             (const_int 0)))
16647      (use (match_operand:SI 3 "immediate_operand" ""))
16648      (use (reg:CC FLAGS_REG))
16649      (clobber (match_operand 0 "register_operand" ""))
16650      (clobber (match_operand 1 "register_operand" ""))
16651      (clobber (match_operand 2 "register_operand" ""))])
16652    (set (match_operand:QI 7 "register_operand" "")
16653         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16654    (set (match_operand:QI 8 "register_operand" "")
16655         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16656    (set (reg FLAGS_REG)
16657         (compare (match_dup 7) (match_dup 8)))
16658   ]
16659   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16660   [(parallel[
16661      (set (reg:CC FLAGS_REG)
16662           (if_then_else:CC (ne (match_dup 6)
16663                                (const_int 0))
16664             (compare:CC (mem:BLK (match_dup 4))
16665                         (mem:BLK (match_dup 5)))
16666             (const_int 0)))
16667      (use (match_dup 3))
16668      (use (reg:CC FLAGS_REG))
16669      (clobber (match_dup 0))
16670      (clobber (match_dup 1))
16671      (clobber (match_dup 2))])]
16672   "")
16676 ;; Conditional move instructions.
16678 (define_expand "mov<mode>cc"
16679   [(set (match_operand:SWIM 0 "register_operand" "")
16680         (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
16681                            (match_operand:SWIM 2 "general_operand" "")
16682                            (match_operand:SWIM 3 "general_operand" "")))]
16683   ""
16684   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16686 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16687 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16688 ;; So just document what we're doing explicitly.
16690 (define_expand "x86_mov<mode>cc_0_m1"
16691   [(parallel
16692     [(set (match_operand:SWI48 0 "register_operand" "")
16693           (if_then_else:SWI48
16694             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16695              [(match_operand 1 "flags_reg_operand" "")
16696               (const_int 0)])
16697             (const_int -1)
16698             (const_int 0)))
16699      (clobber (reg:CC FLAGS_REG))])]
16700   ""
16701   "")
16703 (define_insn "*x86_mov<mode>cc_0_m1"
16704   [(set (match_operand:SWI48 0 "register_operand" "=r")
16705         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16706                              [(reg FLAGS_REG) (const_int 0)])
16707           (const_int -1)
16708           (const_int 0)))
16709    (clobber (reg:CC FLAGS_REG))]
16710   ""
16711   "sbb{<imodesuffix>}\t%0, %0"
16712   ; Since we don't have the proper number of operands for an alu insn,
16713   ; fill in all the blanks.
16714   [(set_attr "type" "alu")
16715    (set_attr "use_carry" "1")
16716    (set_attr "pent_pair" "pu")
16717    (set_attr "memory" "none")
16718    (set_attr "imm_disp" "false")
16719    (set_attr "mode" "<MODE>")
16720    (set_attr "length_immediate" "0")])
16722 (define_insn "*x86_mov<mode>cc_0_m1_se"
16723   [(set (match_operand:SWI48 0 "register_operand" "=r")
16724         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16725                              [(reg FLAGS_REG) (const_int 0)])
16726                             (const_int 1)
16727                             (const_int 0)))
16728    (clobber (reg:CC FLAGS_REG))]
16729   ""
16730   "sbb{<imodesuffix>}\t%0, %0"
16731   [(set_attr "type" "alu")
16732    (set_attr "use_carry" "1")
16733    (set_attr "pent_pair" "pu")
16734    (set_attr "memory" "none")
16735    (set_attr "imm_disp" "false")
16736    (set_attr "mode" "<MODE>")
16737    (set_attr "length_immediate" "0")])
16739 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16740   [(set (match_operand:SWI48 0 "register_operand" "=r")
16741         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16742                     [(reg FLAGS_REG) (const_int 0)])))]
16743   ""
16744   "sbb{<imodesuffix>}\t%0, %0"
16745   [(set_attr "type" "alu")
16746    (set_attr "use_carry" "1")
16747    (set_attr "pent_pair" "pu")
16748    (set_attr "memory" "none")
16749    (set_attr "imm_disp" "false")
16750    (set_attr "mode" "<MODE>")
16751    (set_attr "length_immediate" "0")])
16753 (define_insn "*mov<mode>cc_noc"
16754   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16755         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16756                                [(reg FLAGS_REG) (const_int 0)])
16757           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16758           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16759   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16760   "@
16761    cmov%O2%C1\t{%2, %0|%0, %2}
16762    cmov%O2%c1\t{%3, %0|%0, %3}"
16763   [(set_attr "type" "icmov")
16764    (set_attr "mode" "<MODE>")])
16766 (define_insn_and_split "*movqicc_noc"
16767   [(set (match_operand:QI 0 "register_operand" "=r,r")
16768         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16769                            [(match_operand 4 "flags_reg_operand" "")
16770                             (const_int 0)])
16771                       (match_operand:QI 2 "register_operand" "r,0")
16772                       (match_operand:QI 3 "register_operand" "0,r")))]
16773   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16774   "#"
16775   "&& reload_completed"
16776   [(set (match_dup 0)
16777         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16778                       (match_dup 2)
16779                       (match_dup 3)))]
16780   "operands[0] = gen_lowpart (SImode, operands[0]);
16781    operands[2] = gen_lowpart (SImode, operands[2]);
16782    operands[3] = gen_lowpart (SImode, operands[3]);"
16783   [(set_attr "type" "icmov")
16784    (set_attr "mode" "SI")])
16786 (define_expand "mov<mode>cc"
16787   [(set (match_operand:X87MODEF 0 "register_operand" "")
16788         (if_then_else:X87MODEF
16789           (match_operand 1 "ix86_fp_comparison_operator" "")
16790           (match_operand:X87MODEF 2 "register_operand" "")
16791           (match_operand:X87MODEF 3 "register_operand" "")))]
16792   "(TARGET_80387 && TARGET_CMOVE)
16793    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16794   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16796 (define_insn "*movsfcc_1_387"
16797   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16798         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16799                                 [(reg FLAGS_REG) (const_int 0)])
16800                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16801                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16802   "TARGET_80387 && TARGET_CMOVE
16803    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16804   "@
16805    fcmov%F1\t{%2, %0|%0, %2}
16806    fcmov%f1\t{%3, %0|%0, %3}
16807    cmov%O2%C1\t{%2, %0|%0, %2}
16808    cmov%O2%c1\t{%3, %0|%0, %3}"
16809   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16810    (set_attr "mode" "SF,SF,SI,SI")])
16812 (define_insn "*movdfcc_1"
16813   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16814         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16815                                 [(reg FLAGS_REG) (const_int 0)])
16816                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16817                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16818   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16819    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16820   "@
16821    fcmov%F1\t{%2, %0|%0, %2}
16822    fcmov%f1\t{%3, %0|%0, %3}
16823    #
16824    #"
16825   [(set_attr "type" "fcmov,fcmov,multi,multi")
16826    (set_attr "mode" "DF")])
16828 (define_insn "*movdfcc_1_rex64"
16829   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16830         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16831                                 [(reg FLAGS_REG) (const_int 0)])
16832                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16833                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16834   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16835    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16836   "@
16837    fcmov%F1\t{%2, %0|%0, %2}
16838    fcmov%f1\t{%3, %0|%0, %3}
16839    cmov%O2%C1\t{%2, %0|%0, %2}
16840    cmov%O2%c1\t{%3, %0|%0, %3}"
16841   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16842    (set_attr "mode" "DF")])
16844 (define_split
16845   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16846         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16847                                 [(match_operand 4 "flags_reg_operand" "")
16848                                  (const_int 0)])
16849                       (match_operand:DF 2 "nonimmediate_operand" "")
16850                       (match_operand:DF 3 "nonimmediate_operand" "")))]
16851   "!TARGET_64BIT && reload_completed"
16852   [(set (match_dup 2)
16853         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16854                       (match_dup 5)
16855                       (match_dup 6)))
16856    (set (match_dup 3)
16857         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16858                       (match_dup 7)
16859                       (match_dup 8)))]
16860   "split_di (&operands[2], 2, &operands[5], &operands[7]);
16861    split_di (&operands[0], 1, &operands[2], &operands[3]);")
16863 (define_insn "*movxfcc_1"
16864   [(set (match_operand:XF 0 "register_operand" "=f,f")
16865         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16866                                 [(reg FLAGS_REG) (const_int 0)])
16867                       (match_operand:XF 2 "register_operand" "f,0")
16868                       (match_operand:XF 3 "register_operand" "0,f")))]
16869   "TARGET_80387 && TARGET_CMOVE"
16870   "@
16871    fcmov%F1\t{%2, %0|%0, %2}
16872    fcmov%f1\t{%3, %0|%0, %3}"
16873   [(set_attr "type" "fcmov")
16874    (set_attr "mode" "XF")])
16876 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16877 ;; the scalar versions to have only XMM registers as operands.
16879 ;; XOP conditional move
16880 (define_insn "*xop_pcmov_<mode>"
16881   [(set (match_operand:MODEF 0 "register_operand" "=x")
16882         (if_then_else:MODEF
16883           (match_operand:MODEF 1 "register_operand" "x")
16884           (match_operand:MODEF 2 "register_operand" "x")
16885           (match_operand:MODEF 3 "register_operand" "x")))]
16886   "TARGET_XOP"
16887   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16888   [(set_attr "type" "sse4arg")])
16890 ;; These versions of the min/max patterns are intentionally ignorant of
16891 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16892 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16893 ;; are undefined in this condition, we're certain this is correct.
16895 (define_insn "*avx_<code><mode>3"
16896   [(set (match_operand:MODEF 0 "register_operand" "=x")
16897         (smaxmin:MODEF
16898           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16899           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16900   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16901   "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16902   [(set_attr "type" "sseadd")
16903    (set_attr "prefix" "vex")
16904    (set_attr "mode" "<MODE>")])
16906 (define_insn "<code><mode>3"
16907   [(set (match_operand:MODEF 0 "register_operand" "=x")
16908         (smaxmin:MODEF
16909           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16910           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16911   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16912   "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16913   [(set_attr "type" "sseadd")
16914    (set_attr "mode" "<MODE>")])
16916 ;; These versions of the min/max patterns implement exactly the operations
16917 ;;   min = (op1 < op2 ? op1 : op2)
16918 ;;   max = (!(op1 < op2) ? op1 : op2)
16919 ;; Their operands are not commutative, and thus they may be used in the
16920 ;; presence of -0.0 and NaN.
16922 (define_insn "*avx_ieee_smin<mode>3"
16923   [(set (match_operand:MODEF 0 "register_operand" "=x")
16924         (unspec:MODEF
16925           [(match_operand:MODEF 1 "register_operand" "x")
16926            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16927          UNSPEC_IEEE_MIN))]
16928   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16929   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16930   [(set_attr "type" "sseadd")
16931    (set_attr "prefix" "vex")
16932    (set_attr "mode" "<MODE>")])
16934 (define_insn "*ieee_smin<mode>3"
16935   [(set (match_operand:MODEF 0 "register_operand" "=x")
16936         (unspec:MODEF
16937           [(match_operand:MODEF 1 "register_operand" "0")
16938            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16939          UNSPEC_IEEE_MIN))]
16940   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16941   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16942   [(set_attr "type" "sseadd")
16943    (set_attr "mode" "<MODE>")])
16945 (define_insn "*avx_ieee_smax<mode>3"
16946   [(set (match_operand:MODEF 0 "register_operand" "=x")
16947         (unspec:MODEF
16948           [(match_operand:MODEF 1 "register_operand" "0")
16949            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16950          UNSPEC_IEEE_MAX))]
16951   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16952   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16953   [(set_attr "type" "sseadd")
16954    (set_attr "prefix" "vex")
16955    (set_attr "mode" "<MODE>")])
16957 (define_insn "*ieee_smax<mode>3"
16958   [(set (match_operand:MODEF 0 "register_operand" "=x")
16959         (unspec:MODEF
16960           [(match_operand:MODEF 1 "register_operand" "0")
16961            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16962          UNSPEC_IEEE_MAX))]
16963   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16964   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16965   [(set_attr "type" "sseadd")
16966    (set_attr "mode" "<MODE>")])
16968 ;; Make two stack loads independent:
16969 ;;   fld aa              fld aa
16970 ;;   fld %st(0)     ->   fld bb
16971 ;;   fmul bb             fmul %st(1), %st
16973 ;; Actually we only match the last two instructions for simplicity.
16974 (define_peephole2
16975   [(set (match_operand 0 "fp_register_operand" "")
16976         (match_operand 1 "fp_register_operand" ""))
16977    (set (match_dup 0)
16978         (match_operator 2 "binary_fp_operator"
16979            [(match_dup 0)
16980             (match_operand 3 "memory_operand" "")]))]
16981   "REGNO (operands[0]) != REGNO (operands[1])"
16982   [(set (match_dup 0) (match_dup 3))
16983    (set (match_dup 0) (match_dup 4))]
16985   ;; The % modifier is not operational anymore in peephole2's, so we have to
16986   ;; swap the operands manually in the case of addition and multiplication.
16987   "if (COMMUTATIVE_ARITH_P (operands[2]))
16988      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16989                                  operands[0], operands[1]);
16990    else
16991      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
16992                                  operands[1], operands[0]);")
16994 ;; Conditional addition patterns
16995 (define_expand "add<mode>cc"
16996   [(match_operand:SWI 0 "register_operand" "")
16997    (match_operand 1 "comparison_operator" "")
16998    (match_operand:SWI 2 "register_operand" "")
16999    (match_operand:SWI 3 "const_int_operand" "")]
17000   ""
17001   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
17004 ;; Misc patterns (?)
17006 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
17007 ;; Otherwise there will be nothing to keep
17009 ;; [(set (reg ebp) (reg esp))]
17010 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
17011 ;;  (clobber (eflags)]
17012 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
17014 ;; in proper program order.
17015 (define_insn "pro_epilogue_adjust_stack_1"
17016   [(set (match_operand:SI 0 "register_operand" "=r,r")
17017         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
17018                  (match_operand:SI 2 "immediate_operand" "i,i")))
17019    (clobber (reg:CC FLAGS_REG))
17020    (clobber (mem:BLK (scratch)))]
17021   "!TARGET_64BIT"
17023   switch (get_attr_type (insn))
17024     {
17025     case TYPE_IMOV:
17026       return "mov{l}\t{%1, %0|%0, %1}";
17028     case TYPE_ALU:
17029       if (CONST_INT_P (operands[2])
17030           && (INTVAL (operands[2]) == 128
17031               || (INTVAL (operands[2]) < 0
17032                   && INTVAL (operands[2]) != -128)))
17033         {
17034           operands[2] = GEN_INT (-INTVAL (operands[2]));
17035           return "sub{l}\t{%2, %0|%0, %2}";
17036         }
17037       return "add{l}\t{%2, %0|%0, %2}";
17039     case TYPE_LEA:
17040       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17041       return "lea{l}\t{%a2, %0|%0, %a2}";
17043     default:
17044       gcc_unreachable ();
17045     }
17047   [(set (attr "type")
17048         (cond [(and (eq_attr "alternative" "0") 
17049                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
17050                  (const_string "alu")
17051                (match_operand:SI 2 "const0_operand" "")
17052                  (const_string "imov")
17053               ]
17054               (const_string "lea")))
17055    (set (attr "length_immediate")
17056         (cond [(eq_attr "type" "imov")
17057                  (const_string "0")
17058                (and (eq_attr "type" "alu")
17059                     (match_operand 2 "const128_operand" ""))
17060                  (const_string "1")
17061               ]
17062               (const_string "*")))
17063    (set_attr "mode" "SI")])
17065 (define_insn "pro_epilogue_adjust_stack_rex64"
17066   [(set (match_operand:DI 0 "register_operand" "=r,r")
17067         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17068                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
17069    (clobber (reg:CC FLAGS_REG))
17070    (clobber (mem:BLK (scratch)))]
17071   "TARGET_64BIT"
17073   switch (get_attr_type (insn))
17074     {
17075     case TYPE_IMOV:
17076       return "mov{q}\t{%1, %0|%0, %1}";
17078     case TYPE_ALU:
17079       if (CONST_INT_P (operands[2])
17080           /* Avoid overflows.  */
17081           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
17082           && (INTVAL (operands[2]) == 128
17083               || (INTVAL (operands[2]) < 0
17084                   && INTVAL (operands[2]) != -128)))
17085         {
17086           operands[2] = GEN_INT (-INTVAL (operands[2]));
17087           return "sub{q}\t{%2, %0|%0, %2}";
17088         }
17089       return "add{q}\t{%2, %0|%0, %2}";
17091     case TYPE_LEA:
17092       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
17093       return "lea{q}\t{%a2, %0|%0, %a2}";
17095     default:
17096       gcc_unreachable ();
17097     }
17099   [(set (attr "type")
17100         (cond [(and (eq_attr "alternative" "0")
17101                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
17102                  (const_string "alu")
17103                (match_operand:DI 2 "const0_operand" "")
17104                  (const_string "imov")
17105               ]
17106               (const_string "lea")))
17107    (set (attr "length_immediate")
17108         (cond [(eq_attr "type" "imov")
17109                  (const_string "0")
17110                (and (eq_attr "type" "alu")
17111                     (match_operand 2 "const128_operand" ""))
17112                  (const_string "1")
17113               ]
17114               (const_string "*")))
17115    (set_attr "mode" "DI")])
17117 (define_insn "pro_epilogue_adjust_stack_rex64_2"
17118   [(set (match_operand:DI 0 "register_operand" "=r,r")
17119         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
17120                  (match_operand:DI 3 "immediate_operand" "i,i")))
17121    (use (match_operand:DI 2 "register_operand" "r,r"))
17122    (clobber (reg:CC FLAGS_REG))
17123    (clobber (mem:BLK (scratch)))]
17124   "TARGET_64BIT"
17126   switch (get_attr_type (insn))
17127     {
17128     case TYPE_ALU:
17129       return "add{q}\t{%2, %0|%0, %2}";
17131     case TYPE_LEA:
17132       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
17133       return "lea{q}\t{%a2, %0|%0, %a2}";
17135     default:
17136       gcc_unreachable ();
17137     }
17139   [(set_attr "type" "alu,lea")
17140    (set_attr "mode" "DI")])
17142 (define_insn "allocate_stack_worker_32"
17143   [(set (match_operand:SI 0 "register_operand" "=a")
17144         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
17145                             UNSPECV_STACK_PROBE))
17146    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
17147    (clobber (reg:CC FLAGS_REG))]
17148   "!TARGET_64BIT && TARGET_STACK_PROBE"
17149   "call\t___chkstk"
17150   [(set_attr "type" "multi")
17151    (set_attr "length" "5")])
17153 (define_insn "allocate_stack_worker_64"
17154   [(set (match_operand:DI 0 "register_operand" "=a")
17155         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
17156                             UNSPECV_STACK_PROBE))
17157    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
17158    (clobber (reg:DI R10_REG))
17159    (clobber (reg:DI R11_REG))
17160    (clobber (reg:CC FLAGS_REG))]
17161   "TARGET_64BIT && TARGET_STACK_PROBE"
17162   "call\t___chkstk"
17163   [(set_attr "type" "multi")
17164    (set_attr "length" "5")])
17166 (define_expand "allocate_stack"
17167   [(match_operand 0 "register_operand" "")
17168    (match_operand 1 "general_operand" "")]
17169   "TARGET_STACK_PROBE"
17171   rtx x;
17173 #ifndef CHECK_STACK_LIMIT
17174 #define CHECK_STACK_LIMIT 0
17175 #endif
17177   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
17178       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
17179     {
17180       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
17181                                stack_pointer_rtx, 0, OPTAB_DIRECT);
17182       if (x != stack_pointer_rtx)
17183         emit_move_insn (stack_pointer_rtx, x);
17184     }
17185   else
17186     {
17187       x = copy_to_mode_reg (Pmode, operands[1]);
17188       if (TARGET_64BIT)
17189         x = gen_allocate_stack_worker_64 (x, x);
17190       else
17191         x = gen_allocate_stack_worker_32 (x, x);
17192       emit_insn (x);
17193     }
17195   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
17196   DONE;
17199 ;; Use IOR for stack probes, this is shorter.
17200 (define_expand "probe_stack"
17201   [(match_operand 0 "memory_operand" "")]
17202   ""
17204   if (GET_MODE (operands[0]) == DImode)
17205     emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
17206   else
17207     emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
17208   DONE;
17211 (define_expand "builtin_setjmp_receiver"
17212   [(label_ref (match_operand 0 "" ""))]
17213   "!TARGET_64BIT && flag_pic"
17215 #if TARGET_MACHO
17216   if (TARGET_MACHO)
17217     {
17218       rtx xops[3];
17219       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
17220       rtx label_rtx = gen_label_rtx ();
17221       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
17222       xops[0] = xops[1] = picreg;
17223       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
17224       ix86_expand_binary_operator (MINUS, SImode, xops);
17225     }
17226   else
17227 #endif
17228     emit_insn (gen_set_got (pic_offset_table_rtx));
17229   DONE;
17232 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
17234 (define_split
17235   [(set (match_operand 0 "register_operand" "")
17236         (match_operator 3 "promotable_binary_operator"
17237            [(match_operand 1 "register_operand" "")
17238             (match_operand 2 "aligned_operand" "")]))
17239    (clobber (reg:CC FLAGS_REG))]
17240   "! TARGET_PARTIAL_REG_STALL && reload_completed
17241    && ((GET_MODE (operands[0]) == HImode
17242         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
17243             /* ??? next two lines just !satisfies_constraint_K (...) */
17244             || !CONST_INT_P (operands[2])
17245             || satisfies_constraint_K (operands[2])))
17246        || (GET_MODE (operands[0]) == QImode
17247            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
17248   [(parallel [(set (match_dup 0)
17249                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17250               (clobber (reg:CC FLAGS_REG))])]
17251   "operands[0] = gen_lowpart (SImode, operands[0]);
17252    operands[1] = gen_lowpart (SImode, operands[1]);
17253    if (GET_CODE (operands[3]) != ASHIFT)
17254      operands[2] = gen_lowpart (SImode, operands[2]);
17255    PUT_MODE (operands[3], SImode);")
17257 ; Promote the QImode tests, as i386 has encoding of the AND
17258 ; instruction with 32-bit sign-extended immediate and thus the
17259 ; instruction size is unchanged, except in the %eax case for
17260 ; which it is increased by one byte, hence the ! optimize_size.
17261 (define_split
17262   [(set (match_operand 0 "flags_reg_operand" "")
17263         (match_operator 2 "compare_operator"
17264           [(and (match_operand 3 "aligned_operand" "")
17265                 (match_operand 4 "const_int_operand" ""))
17266            (const_int 0)]))
17267    (set (match_operand 1 "register_operand" "")
17268         (and (match_dup 3) (match_dup 4)))]
17269   "! TARGET_PARTIAL_REG_STALL && reload_completed
17270    && optimize_insn_for_speed_p ()
17271    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17272        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17273    /* Ensure that the operand will remain sign-extended immediate.  */
17274    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17275   [(parallel [(set (match_dup 0)
17276                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17277                                     (const_int 0)]))
17278               (set (match_dup 1)
17279                    (and:SI (match_dup 3) (match_dup 4)))])]
17281   operands[4]
17282     = gen_int_mode (INTVAL (operands[4])
17283                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17284   operands[1] = gen_lowpart (SImode, operands[1]);
17285   operands[3] = gen_lowpart (SImode, operands[3]);
17288 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17289 ; the TEST instruction with 32-bit sign-extended immediate and thus
17290 ; the instruction size would at least double, which is not what we
17291 ; want even with ! optimize_size.
17292 (define_split
17293   [(set (match_operand 0 "flags_reg_operand" "")
17294         (match_operator 1 "compare_operator"
17295           [(and (match_operand:HI 2 "aligned_operand" "")
17296                 (match_operand:HI 3 "const_int_operand" ""))
17297            (const_int 0)]))]
17298   "! TARGET_PARTIAL_REG_STALL && reload_completed
17299    && ! TARGET_FAST_PREFIX
17300    && optimize_insn_for_speed_p ()
17301    /* Ensure that the operand will remain sign-extended immediate.  */
17302    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17303   [(set (match_dup 0)
17304         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17305                          (const_int 0)]))]
17307   operands[3]
17308     = gen_int_mode (INTVAL (operands[3])
17309                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17310   operands[2] = gen_lowpart (SImode, operands[2]);
17313 (define_split
17314   [(set (match_operand 0 "register_operand" "")
17315         (neg (match_operand 1 "register_operand" "")))
17316    (clobber (reg:CC FLAGS_REG))]
17317   "! TARGET_PARTIAL_REG_STALL && reload_completed
17318    && (GET_MODE (operands[0]) == HImode
17319        || (GET_MODE (operands[0]) == QImode
17320            && (TARGET_PROMOTE_QImode
17321                || optimize_insn_for_size_p ())))"
17322   [(parallel [(set (match_dup 0)
17323                    (neg:SI (match_dup 1)))
17324               (clobber (reg:CC FLAGS_REG))])]
17325   "operands[0] = gen_lowpart (SImode, operands[0]);
17326    operands[1] = gen_lowpart (SImode, operands[1]);")
17328 (define_split
17329   [(set (match_operand 0 "register_operand" "")
17330         (not (match_operand 1 "register_operand" "")))]
17331   "! TARGET_PARTIAL_REG_STALL && reload_completed
17332    && (GET_MODE (operands[0]) == HImode
17333        || (GET_MODE (operands[0]) == QImode
17334            && (TARGET_PROMOTE_QImode
17335                || optimize_insn_for_size_p ())))"
17336   [(set (match_dup 0)
17337         (not:SI (match_dup 1)))]
17338   "operands[0] = gen_lowpart (SImode, operands[0]);
17339    operands[1] = gen_lowpart (SImode, operands[1]);")
17341 (define_split
17342   [(set (match_operand 0 "register_operand" "")
17343         (if_then_else (match_operator 1 "comparison_operator"
17344                                 [(reg FLAGS_REG) (const_int 0)])
17345                       (match_operand 2 "register_operand" "")
17346                       (match_operand 3 "register_operand" "")))]
17347   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17348    && (GET_MODE (operands[0]) == HImode
17349        || (GET_MODE (operands[0]) == QImode
17350            && (TARGET_PROMOTE_QImode
17351                || optimize_insn_for_size_p ())))"
17352   [(set (match_dup 0)
17353         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17354   "operands[0] = gen_lowpart (SImode, operands[0]);
17355    operands[2] = gen_lowpart (SImode, operands[2]);
17356    operands[3] = gen_lowpart (SImode, operands[3]);")
17359 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17360 ;; transform a complex memory operation into two memory to register operations.
17362 ;; Don't push memory operands
17363 (define_peephole2
17364   [(set (match_operand:SI 0 "push_operand" "")
17365         (match_operand:SI 1 "memory_operand" ""))
17366    (match_scratch:SI 2 "r")]
17367   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17368    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17369   [(set (match_dup 2) (match_dup 1))
17370    (set (match_dup 0) (match_dup 2))]
17371   "")
17373 (define_peephole2
17374   [(set (match_operand:DI 0 "push_operand" "")
17375         (match_operand:DI 1 "memory_operand" ""))
17376    (match_scratch:DI 2 "r")]
17377   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17378    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17379   [(set (match_dup 2) (match_dup 1))
17380    (set (match_dup 0) (match_dup 2))]
17381   "")
17383 ;; We need to handle SFmode only, because DFmode and XFmode is split to
17384 ;; SImode pushes.
17385 (define_peephole2
17386   [(set (match_operand:SF 0 "push_operand" "")
17387         (match_operand:SF 1 "memory_operand" ""))
17388    (match_scratch:SF 2 "r")]
17389   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17390    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17391   [(set (match_dup 2) (match_dup 1))
17392    (set (match_dup 0) (match_dup 2))]
17393   "")
17395 (define_peephole2
17396   [(set (match_operand:HI 0 "push_operand" "")
17397         (match_operand:HI 1 "memory_operand" ""))
17398    (match_scratch:HI 2 "r")]
17399   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17400    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17401   [(set (match_dup 2) (match_dup 1))
17402    (set (match_dup 0) (match_dup 2))]
17403   "")
17405 (define_peephole2
17406   [(set (match_operand:QI 0 "push_operand" "")
17407         (match_operand:QI 1 "memory_operand" ""))
17408    (match_scratch:QI 2 "q")]
17409   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
17410    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17411   [(set (match_dup 2) (match_dup 1))
17412    (set (match_dup 0) (match_dup 2))]
17413   "")
17415 ;; Don't move an immediate directly to memory when the instruction
17416 ;; gets too big.
17417 (define_peephole2
17418   [(match_scratch:SI 1 "r")
17419    (set (match_operand:SI 0 "memory_operand" "")
17420         (const_int 0))]
17421   "optimize_insn_for_speed_p ()
17422    && ! TARGET_USE_MOV0
17423    && TARGET_SPLIT_LONG_MOVES
17424    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17425    && peep2_regno_dead_p (0, FLAGS_REG)"
17426   [(parallel [(set (match_dup 1) (const_int 0))
17427               (clobber (reg:CC FLAGS_REG))])
17428    (set (match_dup 0) (match_dup 1))]
17429   "")
17431 (define_peephole2
17432   [(match_scratch:HI 1 "r")
17433    (set (match_operand:HI 0 "memory_operand" "")
17434         (const_int 0))]
17435   "optimize_insn_for_speed_p ()
17436    && ! TARGET_USE_MOV0
17437    && TARGET_SPLIT_LONG_MOVES
17438    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17439    && peep2_regno_dead_p (0, FLAGS_REG)"
17440   [(parallel [(set (match_dup 2) (const_int 0))
17441               (clobber (reg:CC FLAGS_REG))])
17442    (set (match_dup 0) (match_dup 1))]
17443   "operands[2] = gen_lowpart (SImode, operands[1]);")
17445 (define_peephole2
17446   [(match_scratch:QI 1 "q")
17447    (set (match_operand:QI 0 "memory_operand" "")
17448         (const_int 0))]
17449   "optimize_insn_for_speed_p ()
17450    && ! TARGET_USE_MOV0
17451    && TARGET_SPLIT_LONG_MOVES
17452    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
17453    && peep2_regno_dead_p (0, FLAGS_REG)"
17454   [(parallel [(set (match_dup 2) (const_int 0))
17455               (clobber (reg:CC FLAGS_REG))])
17456    (set (match_dup 0) (match_dup 1))]
17457   "operands[2] = gen_lowpart (SImode, operands[1]);")
17459 (define_peephole2
17460   [(match_scratch:SI 2 "r")
17461    (set (match_operand:SI 0 "memory_operand" "")
17462         (match_operand:SI 1 "immediate_operand" ""))]
17463   "optimize_insn_for_speed_p ()
17464    && TARGET_SPLIT_LONG_MOVES
17465    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17466   [(set (match_dup 2) (match_dup 1))
17467    (set (match_dup 0) (match_dup 2))]
17468   "")
17470 (define_peephole2
17471   [(match_scratch:HI 2 "r")
17472    (set (match_operand:HI 0 "memory_operand" "")
17473         (match_operand:HI 1 "immediate_operand" ""))]
17474   "optimize_insn_for_speed_p ()
17475    && TARGET_SPLIT_LONG_MOVES
17476    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17477   [(set (match_dup 2) (match_dup 1))
17478    (set (match_dup 0) (match_dup 2))]
17479   "")
17481 (define_peephole2
17482   [(match_scratch:QI 2 "q")
17483    (set (match_operand:QI 0 "memory_operand" "")
17484         (match_operand:QI 1 "immediate_operand" ""))]
17485   "optimize_insn_for_speed_p ()
17486    && TARGET_SPLIT_LONG_MOVES
17487    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
17488   [(set (match_dup 2) (match_dup 1))
17489    (set (match_dup 0) (match_dup 2))]
17490   "")
17492 ;; Don't compare memory with zero, load and use a test instead.
17493 (define_peephole2
17494   [(set (match_operand 0 "flags_reg_operand" "")
17495         (match_operator 1 "compare_operator"
17496           [(match_operand:SI 2 "memory_operand" "")
17497            (const_int 0)]))
17498    (match_scratch:SI 3 "r")]
17499   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17500   [(set (match_dup 3) (match_dup 2))
17501    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
17502   "")
17504 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17505 ;; Don't split NOTs with a displacement operand, because resulting XOR
17506 ;; will not be pairable anyway.
17508 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17509 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17510 ;; so this split helps here as well.
17512 ;; Note: Can't do this as a regular split because we can't get proper
17513 ;; lifetime information then.
17515 (define_peephole2
17516   [(set (match_operand:SI 0 "nonimmediate_operand" "")
17517         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
17518   "optimize_insn_for_speed_p ()
17519    && ((TARGET_NOT_UNPAIRABLE
17520         && (!MEM_P (operands[0])
17521             || !memory_displacement_operand (operands[0], SImode)))
17522        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
17523    && peep2_regno_dead_p (0, FLAGS_REG)"
17524   [(parallel [(set (match_dup 0)
17525                    (xor:SI (match_dup 1) (const_int -1)))
17526               (clobber (reg:CC FLAGS_REG))])]
17527   "")
17529 (define_peephole2
17530   [(set (match_operand:HI 0 "nonimmediate_operand" "")
17531         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
17532   "optimize_insn_for_speed_p ()
17533    && ((TARGET_NOT_UNPAIRABLE
17534         && (!MEM_P (operands[0])
17535             || !memory_displacement_operand (operands[0], HImode)))
17536        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
17537    && peep2_regno_dead_p (0, FLAGS_REG)"
17538   [(parallel [(set (match_dup 0)
17539                    (xor:HI (match_dup 1) (const_int -1)))
17540               (clobber (reg:CC FLAGS_REG))])]
17541   "")
17543 (define_peephole2
17544   [(set (match_operand:QI 0 "nonimmediate_operand" "")
17545         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
17546   "optimize_insn_for_speed_p ()
17547    && ((TARGET_NOT_UNPAIRABLE
17548         && (!MEM_P (operands[0])
17549             || !memory_displacement_operand (operands[0], QImode)))
17550        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
17551    && peep2_regno_dead_p (0, FLAGS_REG)"
17552   [(parallel [(set (match_dup 0)
17553                    (xor:QI (match_dup 1) (const_int -1)))
17554               (clobber (reg:CC FLAGS_REG))])]
17555   "")
17557 ;; Non pairable "test imm, reg" instructions can be translated to
17558 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17559 ;; byte opcode instead of two, have a short form for byte operands),
17560 ;; so do it for other CPUs as well.  Given that the value was dead,
17561 ;; this should not create any new dependencies.  Pass on the sub-word
17562 ;; versions if we're concerned about partial register stalls.
17564 (define_peephole2
17565   [(set (match_operand 0 "flags_reg_operand" "")
17566         (match_operator 1 "compare_operator"
17567           [(and:SI (match_operand:SI 2 "register_operand" "")
17568                    (match_operand:SI 3 "immediate_operand" ""))
17569            (const_int 0)]))]
17570   "ix86_match_ccmode (insn, CCNOmode)
17571    && (true_regnum (operands[2]) != AX_REG
17572        || satisfies_constraint_K (operands[3]))
17573    && peep2_reg_dead_p (1, operands[2])"
17574   [(parallel
17575      [(set (match_dup 0)
17576            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17577                             (const_int 0)]))
17578       (set (match_dup 2)
17579            (and:SI (match_dup 2) (match_dup 3)))])]
17580   "")
17582 ;; We don't need to handle HImode case, because it will be promoted to SImode
17583 ;; on ! TARGET_PARTIAL_REG_STALL
17585 (define_peephole2
17586   [(set (match_operand 0 "flags_reg_operand" "")
17587         (match_operator 1 "compare_operator"
17588           [(and:QI (match_operand:QI 2 "register_operand" "")
17589                    (match_operand:QI 3 "immediate_operand" ""))
17590            (const_int 0)]))]
17591   "! TARGET_PARTIAL_REG_STALL
17592    && ix86_match_ccmode (insn, CCNOmode)
17593    && true_regnum (operands[2]) != AX_REG
17594    && peep2_reg_dead_p (1, operands[2])"
17595   [(parallel
17596      [(set (match_dup 0)
17597            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17598                             (const_int 0)]))
17599       (set (match_dup 2)
17600            (and:QI (match_dup 2) (match_dup 3)))])]
17601   "")
17603 (define_peephole2
17604   [(set (match_operand 0 "flags_reg_operand" "")
17605         (match_operator 1 "compare_operator"
17606           [(and:SI
17607              (zero_extract:SI
17608                (match_operand 2 "ext_register_operand" "")
17609                (const_int 8)
17610                (const_int 8))
17611              (match_operand 3 "const_int_operand" ""))
17612            (const_int 0)]))]
17613   "! TARGET_PARTIAL_REG_STALL
17614    && ix86_match_ccmode (insn, CCNOmode)
17615    && true_regnum (operands[2]) != AX_REG
17616    && peep2_reg_dead_p (1, operands[2])"
17617   [(parallel [(set (match_dup 0)
17618                    (match_op_dup 1
17619                      [(and:SI
17620                         (zero_extract:SI
17621                           (match_dup 2)
17622                           (const_int 8)
17623                           (const_int 8))
17624                         (match_dup 3))
17625                       (const_int 0)]))
17626               (set (zero_extract:SI (match_dup 2)
17627                                     (const_int 8)
17628                                     (const_int 8))
17629                    (and:SI
17630                      (zero_extract:SI
17631                        (match_dup 2)
17632                        (const_int 8)
17633                        (const_int 8))
17634                      (match_dup 3)))])]
17635   "")
17637 ;; Don't do logical operations with memory inputs.
17638 (define_peephole2
17639   [(match_scratch:SI 2 "r")
17640    (parallel [(set (match_operand:SI 0 "register_operand" "")
17641                    (match_operator:SI 3 "arith_or_logical_operator"
17642                      [(match_dup 0)
17643                       (match_operand:SI 1 "memory_operand" "")]))
17644               (clobber (reg:CC FLAGS_REG))])]
17645   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17646   [(set (match_dup 2) (match_dup 1))
17647    (parallel [(set (match_dup 0)
17648                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17649               (clobber (reg:CC FLAGS_REG))])]
17650   "")
17652 (define_peephole2
17653   [(match_scratch:SI 2 "r")
17654    (parallel [(set (match_operand:SI 0 "register_operand" "")
17655                    (match_operator:SI 3 "arith_or_logical_operator"
17656                      [(match_operand:SI 1 "memory_operand" "")
17657                       (match_dup 0)]))
17658               (clobber (reg:CC FLAGS_REG))])]
17659   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
17660   [(set (match_dup 2) (match_dup 1))
17661    (parallel [(set (match_dup 0)
17662                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17663               (clobber (reg:CC FLAGS_REG))])]
17664   "")
17666 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17667 ;; refers to the destination of the load!
17669 (define_peephole2
17670   [(set (match_operand:SI 0 "register_operand" "")
17671         (match_operand:SI 1 "register_operand" ""))
17672    (parallel [(set (match_dup 0)
17673                    (match_operator:SI 3 "commutative_operator"
17674                      [(match_dup 0)
17675                       (match_operand:SI 2 "memory_operand" "")]))
17676               (clobber (reg:CC FLAGS_REG))])]
17677   "REGNO (operands[0]) != REGNO (operands[1])
17678    && GENERAL_REGNO_P (REGNO (operands[0]))
17679    && GENERAL_REGNO_P (REGNO (operands[1]))"
17680   [(set (match_dup 0) (match_dup 4))
17681    (parallel [(set (match_dup 0)
17682                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17683               (clobber (reg:CC FLAGS_REG))])]
17684   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17686 (define_peephole2
17687   [(set (match_operand 0 "register_operand" "")
17688         (match_operand 1 "register_operand" ""))
17689    (set (match_dup 0)
17690                    (match_operator 3 "commutative_operator"
17691                      [(match_dup 0)
17692                       (match_operand 2 "memory_operand" "")]))]
17693   "REGNO (operands[0]) != REGNO (operands[1])
17694    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17695        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17696   [(set (match_dup 0) (match_dup 2))
17697    (set (match_dup 0)
17698         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
17699   "")
17701 ; Don't do logical operations with memory outputs
17703 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17704 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17705 ; the same decoder scheduling characteristics as the original.
17707 (define_peephole2
17708   [(match_scratch:SI 2 "r")
17709    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17710                    (match_operator:SI 3 "arith_or_logical_operator"
17711                      [(match_dup 0)
17712                       (match_operand:SI 1 "nonmemory_operand" "")]))
17713               (clobber (reg:CC FLAGS_REG))])]
17714   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17715    /* Do not split stack checking probes.  */
17716    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17717   [(set (match_dup 2) (match_dup 0))
17718    (parallel [(set (match_dup 2)
17719                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17720               (clobber (reg:CC FLAGS_REG))])
17721    (set (match_dup 0) (match_dup 2))]
17722   "")
17724 (define_peephole2
17725   [(match_scratch:SI 2 "r")
17726    (parallel [(set (match_operand:SI 0 "memory_operand" "")
17727                    (match_operator:SI 3 "arith_or_logical_operator"
17728                      [(match_operand:SI 1 "nonmemory_operand" "")
17729                       (match_dup 0)]))
17730               (clobber (reg:CC FLAGS_REG))])]
17731   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
17732    /* Do not split stack checking probes.  */
17733    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17734   [(set (match_dup 2) (match_dup 0))
17735    (parallel [(set (match_dup 2)
17736                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17737               (clobber (reg:CC FLAGS_REG))])
17738    (set (match_dup 0) (match_dup 2))]
17739   "")
17741 ;; Attempt to always use XOR for zeroing registers.
17742 (define_peephole2
17743   [(set (match_operand 0 "register_operand" "")
17744         (match_operand 1 "const0_operand" ""))]
17745   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17746    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17747    && GENERAL_REG_P (operands[0])
17748    && peep2_regno_dead_p (0, FLAGS_REG)"
17749   [(parallel [(set (match_dup 0) (const_int 0))
17750               (clobber (reg:CC FLAGS_REG))])]
17752   operands[0] = gen_lowpart (word_mode, operands[0]);
17755 (define_peephole2
17756   [(set (strict_low_part (match_operand 0 "register_operand" ""))
17757         (const_int 0))]
17758   "(GET_MODE (operands[0]) == QImode
17759     || GET_MODE (operands[0]) == HImode)
17760    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17761    && peep2_regno_dead_p (0, FLAGS_REG)"
17762   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17763               (clobber (reg:CC FLAGS_REG))])])
17765 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
17766 (define_peephole2
17767   [(set (match_operand 0 "register_operand" "")
17768         (const_int -1))]
17769   "(GET_MODE (operands[0]) == HImode
17770     || GET_MODE (operands[0]) == SImode
17771     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
17772    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17773    && peep2_regno_dead_p (0, FLAGS_REG)"
17774   [(parallel [(set (match_dup 0) (const_int -1))
17775               (clobber (reg:CC FLAGS_REG))])]
17776   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
17777                               operands[0]);")
17779 ;; Attempt to convert simple leas to adds. These can be created by
17780 ;; move expanders.
17781 (define_peephole2
17782   [(set (match_operand:SI 0 "register_operand" "")
17783         (plus:SI (match_dup 0)
17784                  (match_operand:SI 1 "nonmemory_operand" "")))]
17785   "peep2_regno_dead_p (0, FLAGS_REG)"
17786   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17787               (clobber (reg:CC FLAGS_REG))])]
17788   "")
17790 (define_peephole2
17791   [(set (match_operand:SI 0 "register_operand" "")
17792         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17793                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17794   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
17795   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17796               (clobber (reg:CC FLAGS_REG))])]
17797   "operands[2] = gen_lowpart (SImode, operands[2]);")
17799 (define_peephole2
17800   [(set (match_operand:DI 0 "register_operand" "")
17801         (plus:DI (match_dup 0)
17802                  (match_operand:DI 1 "x86_64_general_operand" "")))]
17803   "peep2_regno_dead_p (0, FLAGS_REG)"
17804   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
17805               (clobber (reg:CC FLAGS_REG))])]
17806   "")
17808 (define_peephole2
17809   [(set (match_operand:SI 0 "register_operand" "")
17810         (mult:SI (match_dup 0)
17811                  (match_operand:SI 1 "const_int_operand" "")))]
17812   "exact_log2 (INTVAL (operands[1])) >= 0
17813    && peep2_regno_dead_p (0, FLAGS_REG)"
17814   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17815               (clobber (reg:CC FLAGS_REG))])]
17816   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17818 (define_peephole2
17819   [(set (match_operand:DI 0 "register_operand" "")
17820         (mult:DI (match_dup 0)
17821                  (match_operand:DI 1 "const_int_operand" "")))]
17822   "exact_log2 (INTVAL (operands[1])) >= 0
17823    && peep2_regno_dead_p (0, FLAGS_REG)"
17824   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
17825               (clobber (reg:CC FLAGS_REG))])]
17826   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17828 (define_peephole2
17829   [(set (match_operand:SI 0 "register_operand" "")
17830         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17831                    (match_operand:DI 2 "const_int_operand" "")) 0))]
17832   "exact_log2 (INTVAL (operands[2])) >= 0
17833    && REGNO (operands[0]) == REGNO (operands[1])
17834    && peep2_regno_dead_p (0, FLAGS_REG)"
17835   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17836               (clobber (reg:CC FLAGS_REG))])]
17837   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17839 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17840 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
17841 ;; many CPUs it is also faster, since special hardware to avoid esp
17842 ;; dependencies is present.
17844 ;; While some of these conversions may be done using splitters, we use peepholes
17845 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
17847 ;; Convert prologue esp subtractions to push.
17848 ;; We need register to push.  In order to keep verify_flow_info happy we have
17849 ;; two choices
17850 ;; - use scratch and clobber it in order to avoid dependencies
17851 ;; - use already live register
17852 ;; We can't use the second way right now, since there is no reliable way how to
17853 ;; verify that given register is live.  First choice will also most likely in
17854 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17855 ;; call clobbered registers are dead.  We may want to use base pointer as an
17856 ;; alternative when no register is available later.
17858 (define_peephole2
17859   [(match_scratch:SI 0 "r")
17860    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17861               (clobber (reg:CC FLAGS_REG))
17862               (clobber (mem:BLK (scratch)))])]
17863   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17864   [(clobber (match_dup 0))
17865    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17866               (clobber (mem:BLK (scratch)))])])
17868 (define_peephole2
17869   [(match_scratch:SI 0 "r")
17870    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17871               (clobber (reg:CC FLAGS_REG))
17872               (clobber (mem:BLK (scratch)))])]
17873   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17874   [(clobber (match_dup 0))
17875    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17876    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17877               (clobber (mem:BLK (scratch)))])])
17879 ;; Convert esp subtractions to push.
17880 (define_peephole2
17881   [(match_scratch:SI 0 "r")
17882    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
17883               (clobber (reg:CC FLAGS_REG))])]
17884   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17885   [(clobber (match_dup 0))
17886    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17888 (define_peephole2
17889   [(match_scratch:SI 0 "r")
17890    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
17891               (clobber (reg:CC FLAGS_REG))])]
17892   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
17893   [(clobber (match_dup 0))
17894    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
17895    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
17897 ;; Convert epilogue deallocator to pop.
17898 (define_peephole2
17899   [(match_scratch:SI 0 "r")
17900    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17901               (clobber (reg:CC FLAGS_REG))
17902               (clobber (mem:BLK (scratch)))])]
17903   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
17904   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17905               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17906               (clobber (mem:BLK (scratch)))])]
17907   "")
17909 ;; Two pops case is tricky, since pop causes dependency on destination register.
17910 ;; We use two registers if available.
17911 (define_peephole2
17912   [(match_scratch:SI 0 "r")
17913    (match_scratch:SI 1 "r")
17914    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17915               (clobber (reg:CC FLAGS_REG))
17916               (clobber (mem:BLK (scratch)))])]
17917   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
17918   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17919               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17920               (clobber (mem:BLK (scratch)))])
17921    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17922               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17923   "")
17925 (define_peephole2
17926   [(match_scratch:SI 0 "r")
17927    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17928               (clobber (reg:CC FLAGS_REG))
17929               (clobber (mem:BLK (scratch)))])]
17930   "optimize_insn_for_size_p ()"
17931   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17932               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17933               (clobber (mem:BLK (scratch)))])
17934    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17935               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17936   "")
17938 ;; Convert esp additions to pop.
17939 (define_peephole2
17940   [(match_scratch:SI 0 "r")
17941    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
17942               (clobber (reg:CC FLAGS_REG))])]
17943   ""
17944   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17945               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17946   "")
17948 ;; Two pops case is tricky, since pop causes dependency on destination register.
17949 ;; We use two registers if available.
17950 (define_peephole2
17951   [(match_scratch:SI 0 "r")
17952    (match_scratch:SI 1 "r")
17953    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17954               (clobber (reg:CC FLAGS_REG))])]
17955   ""
17956   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17957               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17958    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
17959               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17960   "")
17962 (define_peephole2
17963   [(match_scratch:SI 0 "r")
17964    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
17965               (clobber (reg:CC FLAGS_REG))])]
17966   "optimize_insn_for_size_p ()"
17967   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17968               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
17969    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
17970               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
17971   "")
17973 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17974 ;; required and register dies.  Similarly for 128 to -128.
17975 (define_peephole2
17976   [(set (match_operand 0 "flags_reg_operand" "")
17977         (match_operator 1 "compare_operator"
17978           [(match_operand 2 "register_operand" "")
17979            (match_operand 3 "const_int_operand" "")]))]
17980   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17981      && incdec_operand (operands[3], GET_MODE (operands[3])))
17982     || (!TARGET_FUSE_CMP_AND_BRANCH
17983         && INTVAL (operands[3]) == 128))
17984    && ix86_match_ccmode (insn, CCGCmode)
17985    && peep2_reg_dead_p (1, operands[2])"
17986   [(parallel [(set (match_dup 0)
17987                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17988               (clobber (match_dup 2))])]
17989   "")
17991 (define_peephole2
17992   [(match_scratch:DI 0 "r")
17993    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
17994               (clobber (reg:CC FLAGS_REG))
17995               (clobber (mem:BLK (scratch)))])]
17996   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
17997   [(clobber (match_dup 0))
17998    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
17999               (clobber (mem:BLK (scratch)))])])
18001 (define_peephole2
18002   [(match_scratch:DI 0 "r")
18003    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18004               (clobber (reg:CC FLAGS_REG))
18005               (clobber (mem:BLK (scratch)))])]
18006   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
18007   [(clobber (match_dup 0))
18008    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18009    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18010               (clobber (mem:BLK (scratch)))])])
18012 ;; Convert esp subtractions to push.
18013 (define_peephole2
18014   [(match_scratch:DI 0 "r")
18015    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
18016               (clobber (reg:CC FLAGS_REG))])]
18017   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
18018   [(clobber (match_dup 0))
18019    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18021 (define_peephole2
18022   [(match_scratch:DI 0 "r")
18023    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
18024               (clobber (reg:CC FLAGS_REG))])]
18025   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
18026   [(clobber (match_dup 0))
18027    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
18028    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
18030 ;; Convert epilogue deallocator to pop.
18031 (define_peephole2
18032   [(match_scratch:DI 0 "r")
18033    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18034               (clobber (reg:CC FLAGS_REG))
18035               (clobber (mem:BLK (scratch)))])]
18036   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
18037   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18038               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18039               (clobber (mem:BLK (scratch)))])]
18040   "")
18042 ;; Two pops case is tricky, since pop causes dependency on destination register.
18043 ;; We use two registers if available.
18044 (define_peephole2
18045   [(match_scratch:DI 0 "r")
18046    (match_scratch:DI 1 "r")
18047    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18048               (clobber (reg:CC FLAGS_REG))
18049               (clobber (mem:BLK (scratch)))])]
18050   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
18051   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18052               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18053               (clobber (mem:BLK (scratch)))])
18054    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18055               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18056   "")
18058 (define_peephole2
18059   [(match_scratch:DI 0 "r")
18060    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18061               (clobber (reg:CC FLAGS_REG))
18062               (clobber (mem:BLK (scratch)))])]
18063   "optimize_insn_for_size_p ()"
18064   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18065               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18066               (clobber (mem:BLK (scratch)))])
18067    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18068               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18069   "")
18071 ;; Convert esp additions to pop.
18072 (define_peephole2
18073   [(match_scratch:DI 0 "r")
18074    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
18075               (clobber (reg:CC FLAGS_REG))])]
18076   ""
18077   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18078               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18079   "")
18081 ;; Two pops case is tricky, since pop causes dependency on destination register.
18082 ;; We use two registers if available.
18083 (define_peephole2
18084   [(match_scratch:DI 0 "r")
18085    (match_scratch:DI 1 "r")
18086    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18087               (clobber (reg:CC FLAGS_REG))])]
18088   ""
18089   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18090               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18091    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
18092               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18093   "")
18095 (define_peephole2
18096   [(match_scratch:DI 0 "r")
18097    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
18098               (clobber (reg:CC FLAGS_REG))])]
18099   "optimize_insn_for_size_p ()"
18100   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18101               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
18102    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
18103               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
18104   "")
18106 ;; Convert imul by three, five and nine into lea
18107 (define_peephole2
18108   [(parallel
18109     [(set (match_operand:SI 0 "register_operand" "")
18110           (mult:SI (match_operand:SI 1 "register_operand" "")
18111                    (match_operand:SI 2 "const_int_operand" "")))
18112      (clobber (reg:CC FLAGS_REG))])]
18113   "INTVAL (operands[2]) == 3
18114    || INTVAL (operands[2]) == 5
18115    || INTVAL (operands[2]) == 9"
18116   [(set (match_dup 0)
18117         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
18118                  (match_dup 1)))]
18119   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18121 (define_peephole2
18122   [(parallel
18123     [(set (match_operand:SI 0 "register_operand" "")
18124           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18125                    (match_operand:SI 2 "const_int_operand" "")))
18126      (clobber (reg:CC FLAGS_REG))])]
18127   "optimize_insn_for_speed_p ()
18128    && (INTVAL (operands[2]) == 3
18129        || INTVAL (operands[2]) == 5
18130        || INTVAL (operands[2]) == 9)"
18131   [(set (match_dup 0) (match_dup 1))
18132    (set (match_dup 0)
18133         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
18134                  (match_dup 0)))]
18135   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18137 (define_peephole2
18138   [(parallel
18139     [(set (match_operand:DI 0 "register_operand" "")
18140           (mult:DI (match_operand:DI 1 "register_operand" "")
18141                    (match_operand:DI 2 "const_int_operand" "")))
18142      (clobber (reg:CC FLAGS_REG))])]
18143   "TARGET_64BIT
18144    && (INTVAL (operands[2]) == 3
18145        || INTVAL (operands[2]) == 5
18146        || INTVAL (operands[2]) == 9)"
18147   [(set (match_dup 0)
18148         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
18149                  (match_dup 1)))]
18150   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18152 (define_peephole2
18153   [(parallel
18154     [(set (match_operand:DI 0 "register_operand" "")
18155           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18156                    (match_operand:DI 2 "const_int_operand" "")))
18157      (clobber (reg:CC FLAGS_REG))])]
18158   "TARGET_64BIT
18159    && optimize_insn_for_speed_p ()
18160    && (INTVAL (operands[2]) == 3
18161        || INTVAL (operands[2]) == 5
18162        || INTVAL (operands[2]) == 9)"
18163   [(set (match_dup 0) (match_dup 1))
18164    (set (match_dup 0)
18165         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
18166                  (match_dup 0)))]
18167   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
18169 ;; Imul $32bit_imm, mem, reg is vector decoded, while
18170 ;; imul $32bit_imm, reg, reg is direct decoded.
18171 (define_peephole2
18172   [(match_scratch:DI 3 "r")
18173    (parallel [(set (match_operand:DI 0 "register_operand" "")
18174                    (mult:DI (match_operand:DI 1 "memory_operand" "")
18175                             (match_operand:DI 2 "immediate_operand" "")))
18176               (clobber (reg:CC FLAGS_REG))])]
18177   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18178    && !satisfies_constraint_K (operands[2])"
18179   [(set (match_dup 3) (match_dup 1))
18180    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
18181               (clobber (reg:CC FLAGS_REG))])]
18184 (define_peephole2
18185   [(match_scratch:SI 3 "r")
18186    (parallel [(set (match_operand:SI 0 "register_operand" "")
18187                    (mult:SI (match_operand:SI 1 "memory_operand" "")
18188                             (match_operand:SI 2 "immediate_operand" "")))
18189               (clobber (reg:CC FLAGS_REG))])]
18190   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18191    && !satisfies_constraint_K (operands[2])"
18192   [(set (match_dup 3) (match_dup 1))
18193    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
18194               (clobber (reg:CC FLAGS_REG))])]
18197 (define_peephole2
18198   [(match_scratch:SI 3 "r")
18199    (parallel [(set (match_operand:DI 0 "register_operand" "")
18200                    (zero_extend:DI
18201                      (mult:SI (match_operand:SI 1 "memory_operand" "")
18202                               (match_operand:SI 2 "immediate_operand" ""))))
18203               (clobber (reg:CC FLAGS_REG))])]
18204   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
18205    && !satisfies_constraint_K (operands[2])"
18206   [(set (match_dup 3) (match_dup 1))
18207    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
18208               (clobber (reg:CC FLAGS_REG))])]
18211 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
18212 ;; Convert it into imul reg, reg
18213 ;; It would be better to force assembler to encode instruction using long
18214 ;; immediate, but there is apparently no way to do so.
18215 (define_peephole2
18216   [(parallel [(set (match_operand:DI 0 "register_operand" "")
18217                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
18218                             (match_operand:DI 2 "const_int_operand" "")))
18219               (clobber (reg:CC FLAGS_REG))])
18220    (match_scratch:DI 3 "r")]
18221   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18222    && satisfies_constraint_K (operands[2])"
18223   [(set (match_dup 3) (match_dup 2))
18224    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
18225               (clobber (reg:CC FLAGS_REG))])]
18227   if (!rtx_equal_p (operands[0], operands[1]))
18228     emit_move_insn (operands[0], operands[1]);
18231 (define_peephole2
18232   [(parallel [(set (match_operand:SI 0 "register_operand" "")
18233                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
18234                             (match_operand:SI 2 "const_int_operand" "")))
18235               (clobber (reg:CC FLAGS_REG))])
18236    (match_scratch:SI 3 "r")]
18237   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
18238    && satisfies_constraint_K (operands[2])"
18239   [(set (match_dup 3) (match_dup 2))
18240    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
18241               (clobber (reg:CC FLAGS_REG))])]
18243   if (!rtx_equal_p (operands[0], operands[1]))
18244     emit_move_insn (operands[0], operands[1]);
18247 (define_peephole2
18248   [(parallel [(set (match_operand:HI 0 "register_operand" "")
18249                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
18250                             (match_operand:HI 2 "immediate_operand" "")))
18251               (clobber (reg:CC FLAGS_REG))])
18252    (match_scratch:HI 3 "r")]
18253   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
18254   [(set (match_dup 3) (match_dup 2))
18255    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
18256               (clobber (reg:CC FLAGS_REG))])]
18258   if (!rtx_equal_p (operands[0], operands[1]))
18259     emit_move_insn (operands[0], operands[1]);
18262 ;; After splitting up read-modify operations, array accesses with memory
18263 ;; operands might end up in form:
18264 ;;  sall    $2, %eax
18265 ;;  movl    4(%esp), %edx
18266 ;;  addl    %edx, %eax
18267 ;; instead of pre-splitting:
18268 ;;  sall    $2, %eax
18269 ;;  addl    4(%esp), %eax
18270 ;; Turn it into:
18271 ;;  movl    4(%esp), %edx
18272 ;;  leal    (%edx,%eax,4), %eax
18274 (define_peephole2
18275   [(parallel [(set (match_operand 0 "register_operand" "")
18276                    (ashift (match_operand 1 "register_operand" "")
18277                            (match_operand 2 "const_int_operand" "")))
18278                (clobber (reg:CC FLAGS_REG))])
18279    (set (match_operand 3 "register_operand")
18280         (match_operand 4 "x86_64_general_operand" ""))
18281    (parallel [(set (match_operand 5 "register_operand" "")
18282                    (plus (match_operand 6 "register_operand" "")
18283                          (match_operand 7 "register_operand" "")))
18284                    (clobber (reg:CC FLAGS_REG))])]
18285   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
18286    /* Validate MODE for lea.  */
18287    && ((!TARGET_PARTIAL_REG_STALL
18288         && (GET_MODE (operands[0]) == QImode
18289             || GET_MODE (operands[0]) == HImode))
18290        || GET_MODE (operands[0]) == SImode
18291        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
18292    /* We reorder load and the shift.  */
18293    && !rtx_equal_p (operands[1], operands[3])
18294    && !reg_overlap_mentioned_p (operands[0], operands[4])
18295    /* Last PLUS must consist of operand 0 and 3.  */
18296    && !rtx_equal_p (operands[0], operands[3])
18297    && (rtx_equal_p (operands[3], operands[6])
18298        || rtx_equal_p (operands[3], operands[7]))
18299    && (rtx_equal_p (operands[0], operands[6])
18300        || rtx_equal_p (operands[0], operands[7]))
18301    /* The intermediate operand 0 must die or be same as output.  */
18302    && (rtx_equal_p (operands[0], operands[5])
18303        || peep2_reg_dead_p (3, operands[0]))"
18304   [(set (match_dup 3) (match_dup 4))
18305    (set (match_dup 0) (match_dup 1))]
18307   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
18308   int scale = 1 << INTVAL (operands[2]);
18309   rtx index = gen_lowpart (Pmode, operands[1]);
18310   rtx base = gen_lowpart (Pmode, operands[3]);
18311   rtx dest = gen_lowpart (mode, operands[5]);
18313   operands[1] = gen_rtx_PLUS (Pmode, base,
18314                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
18315   if (mode != Pmode)
18316     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
18317   operands[0] = dest;
18320 ;; Call-value patterns last so that the wildcard operand does not
18321 ;; disrupt insn-recog's switch tables.
18323 (define_insn "*call_value_pop_0"
18324   [(set (match_operand 0 "" "")
18325         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18326               (match_operand:SI 2 "" "")))
18327    (set (reg:SI SP_REG)
18328         (plus:SI (reg:SI SP_REG)
18329                  (match_operand:SI 3 "immediate_operand" "")))]
18330   "!TARGET_64BIT"
18332   if (SIBLING_CALL_P (insn))
18333     return "jmp\t%P1";
18334   else
18335     return "call\t%P1";
18337   [(set_attr "type" "callv")])
18339 (define_insn "*call_value_pop_1"
18340   [(set (match_operand 0 "" "")
18341         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18342               (match_operand:SI 2 "" "")))
18343    (set (reg:SI SP_REG)
18344         (plus:SI (reg:SI SP_REG)
18345                  (match_operand:SI 3 "immediate_operand" "i")))]
18346   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18348   if (constant_call_address_operand (operands[1], Pmode))
18349     return "call\t%P1";
18350   return "call\t%A1";
18352   [(set_attr "type" "callv")])
18354 (define_insn "*sibcall_value_pop_1"
18355   [(set (match_operand 0 "" "")
18356         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18357               (match_operand:SI 2 "" "")))
18358    (set (reg:SI SP_REG)
18359         (plus:SI (reg:SI SP_REG)
18360                  (match_operand:SI 3 "immediate_operand" "i,i")))]
18361   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18362   "@
18363    jmp\t%P1
18364    jmp\t%A1"
18365   [(set_attr "type" "callv")])
18367 (define_insn "*call_value_0"
18368   [(set (match_operand 0 "" "")
18369         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
18370               (match_operand:SI 2 "" "")))]
18371   "!TARGET_64BIT"
18373   if (SIBLING_CALL_P (insn))
18374     return "jmp\t%P1";
18375   else
18376     return "call\t%P1";
18378   [(set_attr "type" "callv")])
18380 (define_insn "*call_value_0_rex64"
18381   [(set (match_operand 0 "" "")
18382         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18383               (match_operand:DI 2 "const_int_operand" "")))]
18384   "TARGET_64BIT"
18386   if (SIBLING_CALL_P (insn))
18387     return "jmp\t%P1";
18388   else
18389     return "call\t%P1";
18391   [(set_attr "type" "callv")])
18393 (define_insn "*call_value_0_rex64_ms_sysv"
18394   [(set (match_operand 0 "" "")
18395         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
18396               (match_operand:DI 2 "const_int_operand" "")))
18397    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18398    (clobber (reg:TI XMM6_REG))
18399    (clobber (reg:TI XMM7_REG))
18400    (clobber (reg:TI XMM8_REG))
18401    (clobber (reg:TI XMM9_REG))
18402    (clobber (reg:TI XMM10_REG))
18403    (clobber (reg:TI XMM11_REG))
18404    (clobber (reg:TI XMM12_REG))
18405    (clobber (reg:TI XMM13_REG))
18406    (clobber (reg:TI XMM14_REG))
18407    (clobber (reg:TI XMM15_REG))
18408    (clobber (reg:DI SI_REG))
18409    (clobber (reg:DI DI_REG))]
18410   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18412   if (SIBLING_CALL_P (insn))
18413     return "jmp\t%P1";
18414   else
18415     return "call\t%P1";
18417   [(set_attr "type" "callv")])
18419 (define_insn "*call_value_1"
18420   [(set (match_operand 0 "" "")
18421         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
18422               (match_operand:SI 2 "" "")))]
18423   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
18425   if (constant_call_address_operand (operands[1], Pmode))
18426     return "call\t%P1";
18427   return "call\t%A1";
18429   [(set_attr "type" "callv")])
18431 (define_insn "*sibcall_value_1"
18432   [(set (match_operand 0 "" "")
18433         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
18434               (match_operand:SI 2 "" "")))]
18435   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
18436   "@
18437    jmp\t%P1
18438    jmp\t%A1"
18439   [(set_attr "type" "callv")])
18441 (define_insn "*call_value_1_rex64"
18442   [(set (match_operand 0 "" "")
18443         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18444               (match_operand:DI 2 "" "")))]
18445   "TARGET_64BIT && !SIBLING_CALL_P (insn)
18446    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
18448   if (constant_call_address_operand (operands[1], Pmode))
18449     return "call\t%P1";
18450   return "call\t%A1";
18452   [(set_attr "type" "callv")])
18454 (define_insn "*call_value_1_rex64_ms_sysv"
18455   [(set (match_operand 0 "" "")
18456         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
18457               (match_operand:DI 2 "" "")))
18458    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
18459    (clobber (reg:TI XMM6_REG))
18460    (clobber (reg:TI XMM7_REG))
18461    (clobber (reg:TI XMM8_REG))
18462    (clobber (reg:TI XMM9_REG))
18463    (clobber (reg:TI XMM10_REG))
18464    (clobber (reg:TI XMM11_REG))
18465    (clobber (reg:TI XMM12_REG))
18466    (clobber (reg:TI XMM13_REG))
18467    (clobber (reg:TI XMM14_REG))
18468    (clobber (reg:TI XMM15_REG))
18469    (clobber (reg:DI SI_REG))
18470    (clobber (reg:DI DI_REG))]
18471   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18473   if (constant_call_address_operand (operands[1], Pmode))
18474     return "call\t%P1";
18475   return "call\t%A1";
18477   [(set_attr "type" "callv")])
18479 (define_insn "*call_value_1_rex64_large"
18480   [(set (match_operand 0 "" "")
18481         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
18482               (match_operand:DI 2 "" "")))]
18483   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
18484   "call\t%A1"
18485   [(set_attr "type" "callv")])
18487 (define_insn "*sibcall_value_1_rex64"
18488   [(set (match_operand 0 "" "")
18489         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
18490               (match_operand:DI 2 "" "")))]
18491   "TARGET_64BIT && SIBLING_CALL_P (insn)"
18492   "@
18493    jmp\t%P1
18494    jmp\t%A1"
18495   [(set_attr "type" "callv")])
18497 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
18498 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
18499 ;; caught for use by garbage collectors and the like.  Using an insn that
18500 ;; maps to SIGILL makes it more likely the program will rightfully die.
18501 ;; Keeping with tradition, "6" is in honor of #UD.
18502 (define_insn "trap"
18503   [(trap_if (const_int 1) (const_int 6))]
18504   ""
18505   { return ASM_SHORT "0x0b0f"; }
18506   [(set_attr "length" "2")])
18508 (define_expand "sse_prologue_save"
18509   [(parallel [(set (match_operand:BLK 0 "" "")
18510                    (unspec:BLK [(reg:DI XMM0_REG)
18511                                 (reg:DI XMM1_REG)
18512                                 (reg:DI XMM2_REG)
18513                                 (reg:DI XMM3_REG)
18514                                 (reg:DI XMM4_REG)
18515                                 (reg:DI XMM5_REG)
18516                                 (reg:DI XMM6_REG)
18517                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18518               (use (match_operand:DI 1 "register_operand" ""))
18519               (use (match_operand:DI 2 "immediate_operand" ""))
18520               (use (label_ref:DI (match_operand 3 "" "")))])]
18521   "TARGET_64BIT"
18522   "")
18524 (define_insn "*sse_prologue_save_insn"
18525   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
18526                           (match_operand:DI 4 "const_int_operand" "n")))
18527         (unspec:BLK [(reg:DI XMM0_REG)
18528                      (reg:DI XMM1_REG)
18529                      (reg:DI XMM2_REG)
18530                      (reg:DI XMM3_REG)
18531                      (reg:DI XMM4_REG)
18532                      (reg:DI XMM5_REG)
18533                      (reg:DI XMM6_REG)
18534                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
18535    (use (match_operand:DI 1 "register_operand" "r"))
18536    (use (match_operand:DI 2 "const_int_operand" "i"))
18537    (use (label_ref:DI (match_operand 3 "" "X")))]
18538   "TARGET_64BIT
18539    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
18540    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
18542   int i;
18543   operands[0] = gen_rtx_MEM (Pmode,
18544                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
18545   /* VEX instruction with a REX prefix will #UD.  */
18546   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
18547     gcc_unreachable ();
18549   output_asm_insn ("jmp\t%A1", operands);
18550   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
18551     {
18552       operands[4] = adjust_address (operands[0], DImode, i*16);
18553       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
18554       PUT_MODE (operands[4], TImode);
18555       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
18556         output_asm_insn ("rex", operands);
18557       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
18558     }
18559   (*targetm.asm_out.internal_label) (asm_out_file, "L",
18560                                      CODE_LABEL_NUMBER (operands[3]));
18561   return "";
18563   [(set_attr "type" "other")
18564    (set_attr "length_immediate" "0")
18565    (set_attr "length_address" "0")
18566    (set (attr "length")
18567      (if_then_else
18568        (eq (symbol_ref "TARGET_AVX") (const_int 0))
18569        (const_string "34")
18570        (const_string "42")))
18571    (set_attr "memory" "store")
18572    (set_attr "modrm" "0")
18573    (set_attr "prefix" "maybe_vex")
18574    (set_attr "mode" "DI")])
18576 (define_expand "prefetch"
18577   [(prefetch (match_operand 0 "address_operand" "")
18578              (match_operand:SI 1 "const_int_operand" "")
18579              (match_operand:SI 2 "const_int_operand" ""))]
18580   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
18582   int rw = INTVAL (operands[1]);
18583   int locality = INTVAL (operands[2]);
18585   gcc_assert (rw == 0 || rw == 1);
18586   gcc_assert (locality >= 0 && locality <= 3);
18587   gcc_assert (GET_MODE (operands[0]) == Pmode
18588               || GET_MODE (operands[0]) == VOIDmode);
18590   /* Use 3dNOW prefetch in case we are asking for write prefetch not
18591      supported by SSE counterpart or the SSE prefetch is not available
18592      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
18593      of locality.  */
18594   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
18595     operands[2] = GEN_INT (3);
18596   else
18597     operands[1] = const0_rtx;
18600 (define_insn "*prefetch_sse"
18601   [(prefetch (match_operand:SI 0 "address_operand" "p")
18602              (const_int 0)
18603              (match_operand:SI 1 "const_int_operand" ""))]
18604   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
18606   static const char * const patterns[4] = {
18607    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18608   };
18610   int locality = INTVAL (operands[1]);
18611   gcc_assert (locality >= 0 && locality <= 3);
18613   return patterns[locality];
18615   [(set_attr "type" "sse")
18616    (set_attr "atom_sse_attr" "prefetch")
18617    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18618    (set_attr "memory" "none")])
18620 (define_insn "*prefetch_sse_rex"
18621   [(prefetch (match_operand:DI 0 "address_operand" "p")
18622              (const_int 0)
18623              (match_operand:SI 1 "const_int_operand" ""))]
18624   "TARGET_PREFETCH_SSE && TARGET_64BIT"
18626   static const char * const patterns[4] = {
18627    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
18628   };
18630   int locality = INTVAL (operands[1]);
18631   gcc_assert (locality >= 0 && locality <= 3);
18633   return patterns[locality];
18635   [(set_attr "type" "sse")
18636    (set_attr "atom_sse_attr" "prefetch")
18637    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18638    (set_attr "memory" "none")])
18640 (define_insn "*prefetch_3dnow"
18641   [(prefetch (match_operand:SI 0 "address_operand" "p")
18642              (match_operand:SI 1 "const_int_operand" "n")
18643              (const_int 3))]
18644   "TARGET_3DNOW && !TARGET_64BIT"
18646   if (INTVAL (operands[1]) == 0)
18647     return "prefetch\t%a0";
18648   else
18649     return "prefetchw\t%a0";
18651   [(set_attr "type" "mmx")
18652    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18653    (set_attr "memory" "none")])
18655 (define_insn "*prefetch_3dnow_rex"
18656   [(prefetch (match_operand:DI 0 "address_operand" "p")
18657              (match_operand:SI 1 "const_int_operand" "n")
18658              (const_int 3))]
18659   "TARGET_3DNOW && TARGET_64BIT"
18661   if (INTVAL (operands[1]) == 0)
18662     return "prefetch\t%a0";
18663   else
18664     return "prefetchw\t%a0";
18666   [(set_attr "type" "mmx")
18667    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
18668    (set_attr "memory" "none")])
18670 (define_expand "stack_protect_set"
18671   [(match_operand 0 "memory_operand" "")
18672    (match_operand 1 "memory_operand" "")]
18673   ""
18675 #ifdef TARGET_THREAD_SSP_OFFSET
18676   if (TARGET_64BIT)
18677     emit_insn (gen_stack_tls_protect_set_di (operands[0],
18678                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18679   else
18680     emit_insn (gen_stack_tls_protect_set_si (operands[0],
18681                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18682 #else
18683   if (TARGET_64BIT)
18684     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
18685   else
18686     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
18687 #endif
18688   DONE;
18691 (define_insn "stack_protect_set_si"
18692   [(set (match_operand:SI 0 "memory_operand" "=m")
18693         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18694    (set (match_scratch:SI 2 "=&r") (const_int 0))
18695    (clobber (reg:CC FLAGS_REG))]
18696   ""
18697   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18698   [(set_attr "type" "multi")])
18700 (define_insn "stack_protect_set_di"
18701   [(set (match_operand:DI 0 "memory_operand" "=m")
18702         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
18703    (set (match_scratch:DI 2 "=&r") (const_int 0))
18704    (clobber (reg:CC FLAGS_REG))]
18705   "TARGET_64BIT"
18706   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
18707   [(set_attr "type" "multi")])
18709 (define_insn "stack_tls_protect_set_si"
18710   [(set (match_operand:SI 0 "memory_operand" "=m")
18711         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18712    (set (match_scratch:SI 2 "=&r") (const_int 0))
18713    (clobber (reg:CC FLAGS_REG))]
18714   ""
18715   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
18716   [(set_attr "type" "multi")])
18718 (define_insn "stack_tls_protect_set_di"
18719   [(set (match_operand:DI 0 "memory_operand" "=m")
18720         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
18721    (set (match_scratch:DI 2 "=&r") (const_int 0))
18722    (clobber (reg:CC FLAGS_REG))]
18723   "TARGET_64BIT"
18724   {
18725      /* The kernel uses a different segment register for performance reasons; a
18726         system call would not have to trash the userspace segment register,
18727         which would be expensive */
18728      if (ix86_cmodel != CM_KERNEL)
18729         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18730      else
18731         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
18732   }
18733   [(set_attr "type" "multi")])
18735 (define_expand "stack_protect_test"
18736   [(match_operand 0 "memory_operand" "")
18737    (match_operand 1 "memory_operand" "")
18738    (match_operand 2 "" "")]
18739   ""
18741   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
18743 #ifdef TARGET_THREAD_SSP_OFFSET
18744   if (TARGET_64BIT)
18745     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
18746                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18747   else
18748     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
18749                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
18750 #else
18751   if (TARGET_64BIT)
18752     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
18753   else
18754     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
18755 #endif
18757   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18758                                   flags, const0_rtx, operands[2]));
18759   DONE;
18762 (define_insn "stack_protect_test_si"
18763   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18764         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18765                      (match_operand:SI 2 "memory_operand" "m")]
18766                     UNSPEC_SP_TEST))
18767    (clobber (match_scratch:SI 3 "=&r"))]
18768   ""
18769   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
18770   [(set_attr "type" "multi")])
18772 (define_insn "stack_protect_test_di"
18773   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18774         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18775                      (match_operand:DI 2 "memory_operand" "m")]
18776                     UNSPEC_SP_TEST))
18777    (clobber (match_scratch:DI 3 "=&r"))]
18778   "TARGET_64BIT"
18779   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
18780   [(set_attr "type" "multi")])
18782 (define_insn "stack_tls_protect_test_si"
18783   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18784         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
18785                      (match_operand:SI 2 "const_int_operand" "i")]
18786                     UNSPEC_SP_TLS_TEST))
18787    (clobber (match_scratch:SI 3 "=r"))]
18788   ""
18789   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
18790   [(set_attr "type" "multi")])
18792 (define_insn "stack_tls_protect_test_di"
18793   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
18794         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
18795                      (match_operand:DI 2 "const_int_operand" "i")]
18796                     UNSPEC_SP_TLS_TEST))
18797    (clobber (match_scratch:DI 3 "=r"))]
18798   "TARGET_64BIT"
18799   {
18800      /* The kernel uses a different segment register for performance reasons; a
18801         system call would not have to trash the userspace segment register,
18802         which would be expensive */
18803      if (ix86_cmodel != CM_KERNEL)
18804         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
18805      else
18806         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
18807   }
18808   [(set_attr "type" "multi")])
18810 (define_insn "sse4_2_crc32<mode>"
18811   [(set (match_operand:SI 0 "register_operand" "=r")
18812         (unspec:SI
18813           [(match_operand:SI 1 "register_operand" "0")
18814            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18815           UNSPEC_CRC32))]
18816   "TARGET_SSE4_2 || TARGET_CRC32"
18817   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18818   [(set_attr "type" "sselog1")
18819    (set_attr "prefix_rep" "1")
18820    (set_attr "prefix_extra" "1")
18821    (set (attr "prefix_data16")
18822      (if_then_else (match_operand:HI 2 "" "")
18823        (const_string "1")
18824        (const_string "*")))
18825    (set (attr "prefix_rex")
18826      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
18827        (const_string "1")
18828        (const_string "*")))
18829    (set_attr "mode" "SI")])
18831 (define_insn "sse4_2_crc32di"
18832   [(set (match_operand:DI 0 "register_operand" "=r")
18833         (unspec:DI
18834           [(match_operand:DI 1 "register_operand" "0")
18835            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18836           UNSPEC_CRC32))]
18837   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18838   "crc32{q}\t{%2, %0|%0, %2}"
18839   [(set_attr "type" "sselog1")
18840    (set_attr "prefix_rep" "1")
18841    (set_attr "prefix_extra" "1")
18842    (set_attr "mode" "DI")])
18844 (define_expand "rdpmc"
18845   [(match_operand:DI 0 "register_operand" "")
18846    (match_operand:SI 1 "register_operand" "")]
18847   ""
18849   rtx reg = gen_reg_rtx (DImode);
18850   rtx si;
18852   /* Force operand 1 into ECX.  */
18853   rtx ecx = gen_rtx_REG (SImode, CX_REG);
18854   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
18855   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
18856                                 UNSPECV_RDPMC);
18858   if (TARGET_64BIT)
18859     {
18860       rtvec vec = rtvec_alloc (2);
18861       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18862       rtx upper = gen_reg_rtx (DImode);
18863       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18864                                         gen_rtvec (1, const0_rtx),
18865                                         UNSPECV_RDPMC);
18866       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
18867       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18868       emit_insn (load);
18869       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18870                                    NULL, 1, OPTAB_DIRECT);
18871       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18872                                  OPTAB_DIRECT);
18873     }
18874   else
18875     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
18876   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18877   DONE;
18880 (define_insn "*rdpmc"
18881   [(set (match_operand:DI 0 "register_operand" "=A")
18882         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18883                             UNSPECV_RDPMC))]
18884   "!TARGET_64BIT"
18885   "rdpmc"
18886   [(set_attr "type" "other")
18887    (set_attr "length" "2")])
18889 (define_insn "*rdpmc_rex64"
18890   [(set (match_operand:DI 0 "register_operand" "=a")
18891         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18892                             UNSPECV_RDPMC))
18893   (set (match_operand:DI 1 "register_operand" "=d")
18894        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18895   "TARGET_64BIT"
18896   "rdpmc"
18897   [(set_attr "type" "other")
18898    (set_attr "length" "2")])
18900 (define_expand "rdtsc"
18901   [(set (match_operand:DI 0 "register_operand" "")
18902         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18903   ""
18905   if (TARGET_64BIT)
18906     {
18907       rtvec vec = rtvec_alloc (2);
18908       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18909       rtx upper = gen_reg_rtx (DImode);
18910       rtx lower = gen_reg_rtx (DImode);
18911       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18912                                          gen_rtvec (1, const0_rtx),
18913                                          UNSPECV_RDTSC);
18914       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18915       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18916       emit_insn (load);
18917       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18918                                    NULL, 1, OPTAB_DIRECT);
18919       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18920                                    OPTAB_DIRECT);
18921       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18922       DONE;
18923     }
18926 (define_insn "*rdtsc"
18927   [(set (match_operand:DI 0 "register_operand" "=A")
18928         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18929   "!TARGET_64BIT"
18930   "rdtsc"
18931   [(set_attr "type" "other")
18932    (set_attr "length" "2")])
18934 (define_insn "*rdtsc_rex64"
18935   [(set (match_operand:DI 0 "register_operand" "=a")
18936         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18937    (set (match_operand:DI 1 "register_operand" "=d")
18938         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18939   "TARGET_64BIT"
18940   "rdtsc"
18941   [(set_attr "type" "other")
18942    (set_attr "length" "2")])
18944 (define_expand "rdtscp"
18945   [(match_operand:DI 0 "register_operand" "")
18946    (match_operand:SI 1 "memory_operand" "")]
18947   ""
18949   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18950                                     gen_rtvec (1, const0_rtx),
18951                                     UNSPECV_RDTSCP);
18952   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18953                                     gen_rtvec (1, const0_rtx),
18954                                     UNSPECV_RDTSCP);
18955   rtx reg = gen_reg_rtx (DImode);
18956   rtx tmp = gen_reg_rtx (SImode);
18958   if (TARGET_64BIT)
18959     {
18960       rtvec vec = rtvec_alloc (3);
18961       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18962       rtx upper = gen_reg_rtx (DImode);
18963       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18964       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18965       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18966       emit_insn (load);
18967       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18968                                    NULL, 1, OPTAB_DIRECT);
18969       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18970                                  OPTAB_DIRECT);
18971     }
18972   else
18973     {
18974       rtvec vec = rtvec_alloc (2);
18975       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18976       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18977       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18978       emit_insn (load);
18979     }
18980   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18981   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18982   DONE;
18985 (define_insn "*rdtscp"
18986   [(set (match_operand:DI 0 "register_operand" "=A")
18987         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18988    (set (match_operand:SI 1 "register_operand" "=c")
18989         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18990   "!TARGET_64BIT"
18991   "rdtscp"
18992   [(set_attr "type" "other")
18993    (set_attr "length" "3")])
18995 (define_insn "*rdtscp_rex64"
18996   [(set (match_operand:DI 0 "register_operand" "=a")
18997         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18998    (set (match_operand:DI 1 "register_operand" "=d")
18999         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
19000    (set (match_operand:SI 2 "register_operand" "=c")
19001         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
19002   "TARGET_64BIT"
19003   "rdtscp"
19004   [(set_attr "type" "other")
19005    (set_attr "length" "3")])
19007 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19009 ;; LWP instructions
19011 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
19013 (define_expand "lwp_llwpcb"
19014   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
19015                     UNSPECV_LLWP_INTRINSIC)]
19016   "TARGET_LWP"
19017   "")
19019 (define_insn "*lwp_llwpcb<mode>1"
19020   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
19021                     UNSPECV_LLWP_INTRINSIC)]
19022   "TARGET_LWP"
19023   "llwpcb\t%0"
19024   [(set_attr "type" "lwp")
19025    (set_attr "mode" "<MODE>")
19026    (set_attr "length" "5")])
19028 (define_expand "lwp_slwpcb"
19029   [(set (match_operand 0 "register_operand" "=r")
19030         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19031   "TARGET_LWP"
19032   {
19033     if (TARGET_64BIT)
19034       emit_insn (gen_lwp_slwpcbdi (operands[0]));
19035     else
19036       emit_insn (gen_lwp_slwpcbsi (operands[0]));
19037     DONE;
19038   })
19040 (define_insn "lwp_slwpcb<mode>"
19041   [(set (match_operand:P 0 "register_operand" "=r")
19042         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
19043   "TARGET_LWP"
19044   "slwpcb\t%0"
19045   [(set_attr "type" "lwp")
19046    (set_attr "mode" "<MODE>")
19047    (set_attr "length" "5")])
19049 (define_expand "lwp_lwpval<mode>3"
19050   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
19051                      (match_operand:SI 2 "nonimmediate_operand" "rm")
19052                      (match_operand:SI 3 "const_int_operand" "i")]
19053                     UNSPECV_LWPVAL_INTRINSIC)]
19054   "TARGET_LWP"
19055   "/* Avoid unused variable warning.  */
19056    (void) operand0;")
19058 (define_insn "*lwp_lwpval<mode>3_1"
19059   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
19060                      (match_operand:SI 1 "nonimmediate_operand" "rm")
19061                      (match_operand:SI 2 "const_int_operand" "i")]
19062                     UNSPECV_LWPVAL_INTRINSIC)]
19063   "TARGET_LWP"
19064   "lwpval\t{%2, %1, %0|%0, %1, %2}"
19065   [(set_attr "type" "lwp")
19066    (set_attr "mode" "<MODE>")
19067    (set (attr "length")
19068         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19070 (define_expand "lwp_lwpins<mode>3"
19071   [(set (reg:CCC FLAGS_REG)
19072         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
19073                               (match_operand:SI 2 "nonimmediate_operand" "rm")
19074                               (match_operand:SI 3 "const_int_operand" "i")]
19075                              UNSPECV_LWPINS_INTRINSIC))
19076    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
19077         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
19078   "TARGET_LWP"
19079   "")
19081 (define_insn "*lwp_lwpins<mode>3_1"
19082   [(set (reg:CCC FLAGS_REG)
19083         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
19084                               (match_operand:SI 1 "nonimmediate_operand" "rm")
19085                               (match_operand:SI 2 "const_int_operand" "i")]
19086                              UNSPECV_LWPINS_INTRINSIC))]
19087   "TARGET_LWP"
19088   "lwpins\t{%2, %1, %0|%0, %1, %2}"
19089   [(set_attr "type" "lwp")
19090    (set_attr "mode" "<MODE>")
19091    (set (attr "length")
19092         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
19094 (include "mmx.md")
19095 (include "sse.md")
19096 (include "sync.md")