* config/i386/i386.c (ix86_decompose_address): Replace open-coded
[official-gcc.git] / gcc / config / i386 / i386.md
blob83619b1a2edfac3a551c4fdaa4df4fd4fcfb77d5
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2014 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
5 ;;
6 ;; This file is part of GCC.
7 ;;
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
11 ;; any later version.
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.  */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
33 ;;      otherwise nothing
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
42 ;;      delimiter.
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;;      %b0 would print %al if operands[0] is reg 0.
45 ;; w --  likewise, print the HImode name of the register.
46 ;; k --  likewise, print the SImode name of the register.
47 ;; q --  likewise, print the DImode name of the register.
48 ;; x --  likewise, print the V4SFmode name of the register.
49 ;; t --  likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
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 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
66 ;; ! -- print MPX prefix for jxx/call/ret instructions if required.
68 (define_c_enum "unspec" [
69   ;; Relocation specifiers
70   UNSPEC_GOT
71   UNSPEC_GOTOFF
72   UNSPEC_GOTPCREL
73   UNSPEC_GOTTPOFF
74   UNSPEC_TPOFF
75   UNSPEC_NTPOFF
76   UNSPEC_DTPOFF
77   UNSPEC_GOTNTPOFF
78   UNSPEC_INDNTPOFF
79   UNSPEC_PLTOFF
80   UNSPEC_MACHOPIC_OFFSET
81   UNSPEC_PCREL
82   UNSPEC_SIZEOF
84   ;; Prologue support
85   UNSPEC_STACK_ALLOC
86   UNSPEC_SET_GOT
87   UNSPEC_SET_RIP
88   UNSPEC_SET_GOT_OFFSET
89   UNSPEC_MEMORY_BLOCKAGE
90   UNSPEC_STACK_CHECK
92   ;; TLS support
93   UNSPEC_TP
94   UNSPEC_TLS_GD
95   UNSPEC_TLS_LD_BASE
96   UNSPEC_TLSDESC
97   UNSPEC_TLS_IE_SUN
99   ;; Other random patterns
100   UNSPEC_SCAS
101   UNSPEC_FNSTSW
102   UNSPEC_SAHF
103   UNSPEC_PARITY
104   UNSPEC_FSTCW
105   UNSPEC_ADD_CARRY
106   UNSPEC_FLDCW
107   UNSPEC_REP
108   UNSPEC_LD_MPIC        ; load_macho_picbase
109   UNSPEC_TRUNC_NOOP
110   UNSPEC_DIV_ALREADY_SPLIT
111   UNSPEC_PAUSE
112   UNSPEC_LEA_ADDR
113   UNSPEC_XBEGIN_ABORT
114   UNSPEC_STOS
115   UNSPEC_PEEPSIB
116   UNSPEC_INSN_FALSE_DEP
118   ;; For SSE/MMX support:
119   UNSPEC_FIX_NOTRUNC
120   UNSPEC_MASKMOV
121   UNSPEC_MOVMSK
122   UNSPEC_RCP
123   UNSPEC_RSQRT
124   UNSPEC_PSADBW
126   ;; Generic math support
127   UNSPEC_COPYSIGN
128   UNSPEC_IEEE_MIN       ; not commutative
129   UNSPEC_IEEE_MAX       ; not commutative
131   ;; x87 Floating point
132   UNSPEC_SIN
133   UNSPEC_COS
134   UNSPEC_FPATAN
135   UNSPEC_FYL2X
136   UNSPEC_FYL2XP1
137   UNSPEC_FRNDINT
138   UNSPEC_FIST
139   UNSPEC_F2XM1
140   UNSPEC_TAN
141   UNSPEC_FXAM
143   ;; x87 Rounding
144   UNSPEC_FRNDINT_FLOOR
145   UNSPEC_FRNDINT_CEIL
146   UNSPEC_FRNDINT_TRUNC
147   UNSPEC_FRNDINT_MASK_PM
148   UNSPEC_FIST_FLOOR
149   UNSPEC_FIST_CEIL
151   ;; x87 Double output FP
152   UNSPEC_SINCOS_COS
153   UNSPEC_SINCOS_SIN
154   UNSPEC_XTRACT_FRACT
155   UNSPEC_XTRACT_EXP
156   UNSPEC_FSCALE_FRACT
157   UNSPEC_FSCALE_EXP
158   UNSPEC_FPREM_F
159   UNSPEC_FPREM_U
160   UNSPEC_FPREM1_F
161   UNSPEC_FPREM1_U
163   UNSPEC_C2_FLAG
164   UNSPEC_FXAM_MEM
166   ;; SSP patterns
167   UNSPEC_SP_SET
168   UNSPEC_SP_TEST
169   UNSPEC_SP_TLS_SET
170   UNSPEC_SP_TLS_TEST
172   ;; For ROUND support
173   UNSPEC_ROUND
175   ;; For CRC32 support
176   UNSPEC_CRC32
178   ;; For BMI support
179   UNSPEC_BEXTR
181   ;; For BMI2 support
182   UNSPEC_PDEP
183   UNSPEC_PEXT
185   ;; For AVX512F support
186   UNSPEC_KMOV
188   UNSPEC_BNDMK
189   UNSPEC_BNDMK_ADDR
190   UNSPEC_BNDSTX
191   UNSPEC_BNDLDX
192   UNSPEC_BNDLDX_ADDR
193   UNSPEC_BNDCL
194   UNSPEC_BNDCU
195   UNSPEC_BNDCN
196   UNSPEC_MPX_FENCE
199 (define_c_enum "unspecv" [
200   UNSPECV_BLOCKAGE
201   UNSPECV_STACK_PROBE
202   UNSPECV_PROBE_STACK_RANGE
203   UNSPECV_ALIGN
204   UNSPECV_PROLOGUE_USE
205   UNSPECV_SPLIT_STACK_RETURN
206   UNSPECV_CLD
207   UNSPECV_NOPS
208   UNSPECV_RDTSC
209   UNSPECV_RDTSCP
210   UNSPECV_RDPMC
211   UNSPECV_LLWP_INTRINSIC
212   UNSPECV_SLWP_INTRINSIC
213   UNSPECV_LWPVAL_INTRINSIC
214   UNSPECV_LWPINS_INTRINSIC
215   UNSPECV_RDFSBASE
216   UNSPECV_RDGSBASE
217   UNSPECV_WRFSBASE
218   UNSPECV_WRGSBASE
219   UNSPECV_FXSAVE
220   UNSPECV_FXRSTOR
221   UNSPECV_FXSAVE64
222   UNSPECV_FXRSTOR64
223   UNSPECV_XSAVE
224   UNSPECV_XRSTOR
225   UNSPECV_XSAVE64
226   UNSPECV_XRSTOR64
227   UNSPECV_XSAVEOPT
228   UNSPECV_XSAVEOPT64
229   UNSPECV_XSAVES
230   UNSPECV_XRSTORS
231   UNSPECV_XSAVES64
232   UNSPECV_XRSTORS64
233   UNSPECV_XSAVEC
234   UNSPECV_XSAVEC64
236   ;; For atomic compound assignments.
237   UNSPECV_FNSTENV
238   UNSPECV_FLDENV
239   UNSPECV_FNSTSW
240   UNSPECV_FNCLEX
242   ;; For RDRAND support
243   UNSPECV_RDRAND
245   ;; For RDSEED support
246   UNSPECV_RDSEED
248   ;; For RTM support
249   UNSPECV_XBEGIN
250   UNSPECV_XEND
251   UNSPECV_XABORT
252   UNSPECV_XTEST
254   UNSPECV_NLGR
256   ;; For CLFLUSHOPT support
257   UNSPECV_CLFLUSHOPT
260 ;; Constants to represent rounding modes in the ROUND instruction
261 (define_constants
262   [(ROUND_FLOOR                 0x1)
263    (ROUND_CEIL                  0x2)
264    (ROUND_TRUNC                 0x3)
265    (ROUND_MXCSR                 0x4)
266    (ROUND_NO_EXC                0x8)
267   ])
269 ;; Constants to represent AVX512F embeded rounding
270 (define_constants
271   [(ROUND_NEAREST_INT                   0)
272    (ROUND_NEG_INF                       1)
273    (ROUND_POS_INF                       2)
274    (ROUND_ZERO                          3)
275    (NO_ROUND                            4)
276    (ROUND_SAE                           8)
277   ])
279 ;; Constants to represent pcomtrue/pcomfalse variants
280 (define_constants
281   [(PCOM_FALSE                  0)
282    (PCOM_TRUE                   1)
283    (COM_FALSE_S                 2)
284    (COM_FALSE_P                 3)
285    (COM_TRUE_S                  4)
286    (COM_TRUE_P                  5)
287   ])
289 ;; Constants used in the XOP pperm instruction
290 (define_constants
291   [(PPERM_SRC                   0x00)   /* copy source */
292    (PPERM_INVERT                0x20)   /* invert source */
293    (PPERM_REVERSE               0x40)   /* bit reverse source */
294    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
295    (PPERM_ZERO                  0x80)   /* all 0's */
296    (PPERM_ONES                  0xa0)   /* all 1's */
297    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
298    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
299    (PPERM_SRC1                  0x00)   /* use first source byte */
300    (PPERM_SRC2                  0x10)   /* use second source byte */
301    ])
303 ;; Registers by name.
304 (define_constants
305   [(AX_REG                       0)
306    (DX_REG                       1)
307    (CX_REG                       2)
308    (BX_REG                       3)
309    (SI_REG                       4)
310    (DI_REG                       5)
311    (BP_REG                       6)
312    (SP_REG                       7)
313    (ST0_REG                      8)
314    (ST1_REG                      9)
315    (ST2_REG                     10)
316    (ST3_REG                     11)
317    (ST4_REG                     12)
318    (ST5_REG                     13)
319    (ST6_REG                     14)
320    (ST7_REG                     15)
321    (FLAGS_REG                   17)
322    (FPSR_REG                    18)
323    (FPCR_REG                    19)
324    (XMM0_REG                    21)
325    (XMM1_REG                    22)
326    (XMM2_REG                    23)
327    (XMM3_REG                    24)
328    (XMM4_REG                    25)
329    (XMM5_REG                    26)
330    (XMM6_REG                    27)
331    (XMM7_REG                    28)
332    (MM0_REG                     29)
333    (MM1_REG                     30)
334    (MM2_REG                     31)
335    (MM3_REG                     32)
336    (MM4_REG                     33)
337    (MM5_REG                     34)
338    (MM6_REG                     35)
339    (MM7_REG                     36)
340    (R8_REG                      37)
341    (R9_REG                      38)
342    (R10_REG                     39)
343    (R11_REG                     40)
344    (R12_REG                     41)
345    (R13_REG                     42)
346    (R14_REG                     43)
347    (R15_REG                     44)
348    (XMM8_REG                    45)
349    (XMM9_REG                    46)
350    (XMM10_REG                   47)
351    (XMM11_REG                   48)
352    (XMM12_REG                   49)
353    (XMM13_REG                   50)
354    (XMM14_REG                   51)
355    (XMM15_REG                   52)
356    (XMM16_REG                   53)
357    (XMM17_REG                   54)
358    (XMM18_REG                   55)
359    (XMM19_REG                   56)
360    (XMM20_REG                   57)
361    (XMM21_REG                   58)
362    (XMM22_REG                   59)
363    (XMM23_REG                   60)
364    (XMM24_REG                   61)
365    (XMM25_REG                   62)
366    (XMM26_REG                   63)
367    (XMM27_REG                   64)
368    (XMM28_REG                   65)
369    (XMM29_REG                   66)
370    (XMM30_REG                   67)
371    (XMM31_REG                   68)
372    (MASK0_REG                   69)
373    (MASK1_REG                   70)
374    (MASK2_REG                   71)
375    (MASK3_REG                   72)
376    (MASK4_REG                   73)
377    (MASK5_REG                   74)
378    (MASK6_REG                   75)
379    (MASK7_REG                   76)
380    (BND0_REG                    77)
381    (BND1_REG                    78)
382   ])
384 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
385 ;; from i386.c.
387 ;; In C guard expressions, put expressions which may be compile-time
388 ;; constants first.  This allows for better optimization.  For
389 ;; example, write "TARGET_64BIT && reload_completed", not
390 ;; "reload_completed && TARGET_64BIT".
393 ;; Processor type.
394 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,nehalem,
395                     atom,slm,generic,amdfam10,bdver1,bdver2,bdver3,bdver4,
396                     btver2"
397   (const (symbol_ref "ix86_schedule")))
399 ;; A basic instruction type.  Refinements due to arguments to be
400 ;; provided in other attributes.
401 (define_attr "type"
402   "other,multi,
403    alu,alu1,negnot,imov,imovx,lea,
404    incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
405    imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
406    push,pop,call,callv,leave,
407    str,bitmanip,
408    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
409    fxch,fistp,fisttp,frndint,
410    sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
411    ssemul,sseimul,ssediv,sselog,sselog1,
412    sseishft,sseishft1,ssecmp,ssecomi,
413    ssecvt,ssecvt1,sseicvt,sseins,
414    sseshuf,sseshuf1,ssemuladd,sse4arg,
415    lwp,mskmov,msklog,
416    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft,
417    mpxmov,mpxmk,mpxchk,mpxld,mpxst"
418   (const_string "other"))
420 ;; Main data type used by the insn
421 (define_attr "mode"
422   "unknown,none,QI,HI,SI,DI,TI,OI,XI,SF,DF,XF,TF,V16SF,V8SF,V4DF,V4SF,
423   V2DF,V2SF,V1DF,V8DF"
424   (const_string "unknown"))
426 ;; The CPU unit operations uses.
427 (define_attr "unit" "integer,i387,sse,mmx,unknown"
428   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
429                           fxch,fistp,fisttp,frndint")
430            (const_string "i387")
431          (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
432                           ssemul,sseimul,ssediv,sselog,sselog1,
433                           sseishft,sseishft1,ssecmp,ssecomi,
434                           ssecvt,ssecvt1,sseicvt,sseins,
435                           sseshuf,sseshuf1,ssemuladd,sse4arg,mskmov")
436            (const_string "sse")
437          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
438            (const_string "mmx")
439          (eq_attr "type" "other")
440            (const_string "unknown")]
441          (const_string "integer")))
443 ;; The minimum required alignment of vector mode memory operands of the SSE
444 ;; (non-VEX/EVEX) instruction in bits, if it is different from
445 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0.  If an instruction has
446 ;; multiple alternatives, this should be conservative maximum of those minimum
447 ;; required alignments.
448 (define_attr "ssememalign" "" (const_int 0))
450 ;; The (bounding maximum) length of an instruction immediate.
451 (define_attr "length_immediate" ""
452   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
453                           bitmanip,imulx,msklog,mskmov,mpxmk,mpxmov,mpxchk,
454                           mpxld,mpxst")
455            (const_int 0)
456          (eq_attr "unit" "i387,sse,mmx")
457            (const_int 0)
458          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
459                           rotate,rotatex,rotate1,imul,icmp,push,pop")
460            (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
461          (eq_attr "type" "imov,test")
462            (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
463          (eq_attr "type" "call")
464            (if_then_else (match_operand 0 "constant_call_address_operand")
465              (const_int 4)
466              (const_int 0))
467          (eq_attr "type" "callv")
468            (if_then_else (match_operand 1 "constant_call_address_operand")
469              (const_int 4)
470              (const_int 0))
471          ;; We don't know the size before shorten_branches.  Expect
472          ;; the instruction to fit for better scheduling.
473          (eq_attr "type" "ibr")
474            (const_int 1)
475          ]
476          (symbol_ref "/* Update immediate_length and other attributes! */
477                       gcc_unreachable (),1")))
479 ;; The (bounding maximum) length of an instruction address.
480 (define_attr "length_address" ""
481   (cond [(eq_attr "type" "str,other,multi,fxch")
482            (const_int 0)
483          (and (eq_attr "type" "call")
484               (match_operand 0 "constant_call_address_operand"))
485              (const_int 0)
486          (and (eq_attr "type" "callv")
487               (match_operand 1 "constant_call_address_operand"))
488              (const_int 0)
489          ]
490          (symbol_ref "ix86_attr_length_address_default (insn)")))
492 ;; Set when length prefix is used.
493 (define_attr "prefix_data16" ""
494   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
495            (const_int 0)
496          (eq_attr "mode" "HI")
497            (const_int 1)
498          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
499            (const_int 1)
500         ]
501         (const_int 0)))
503 ;; Set when string REP prefix is used.
504 (define_attr "prefix_rep" ""
505   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
506            (const_int 0)
507          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
508            (const_int 1)
509          (and (eq_attr "type" "ibr,call,callv")
510               (match_test "ix86_bnd_prefixed_insn_p (insn)"))
511            (const_int 1)
512         ]
513         (const_int 0)))
515 ;; Set when 0f opcode prefix is used.
516 (define_attr "prefix_0f" ""
517   (if_then_else
518     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip,msklog,mskmov,
519                           mpxmk,mpxmov,mpxchk,mpxld,mpxst")
520          (eq_attr "unit" "sse,mmx"))
521     (const_int 1)
522     (const_int 0)))
524 ;; Set when REX opcode prefix is used.
525 (define_attr "prefix_rex" ""
526   (cond [(not (match_test "TARGET_64BIT"))
527            (const_int 0)
528          (and (eq_attr "mode" "DI")
529               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
530                    (eq_attr "unit" "!mmx")))
531            (const_int 1)
532          (and (eq_attr "mode" "QI")
533               (match_test "x86_extended_QIreg_mentioned_p (insn)"))
534            (const_int 1)
535          (match_test "x86_extended_reg_mentioned_p (insn)")
536            (const_int 1)
537          (and (eq_attr "type" "imovx")
538               (match_operand:QI 1 "ext_QIreg_operand"))
539            (const_int 1)
540         ]
541         (const_int 0)))
543 ;; There are also additional prefixes in 3DNOW, SSSE3.
544 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
545 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
546 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
547 (define_attr "prefix_extra" ""
548   (cond [(eq_attr "type" "ssemuladd,sse4arg")
549            (const_int 2)
550          (eq_attr "type" "sseiadd1,ssecvt1")
551            (const_int 1)
552         ]
553         (const_int 0)))
555 ;; Prefix used: original, VEX or maybe VEX.
556 (define_attr "prefix" "orig,vex,maybe_vex,evex,maybe_evex"
557   (cond [(eq_attr "mode" "OI,V8SF,V4DF")
558            (const_string "vex")
559          (eq_attr "mode" "XI,V16SF,V8DF")
560            (const_string "evex")
561         ]
562         (const_string "orig")))
564 ;; VEX W bit is used.
565 (define_attr "prefix_vex_w" "" (const_int 0))
567 ;; The length of VEX prefix
568 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
569 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
570 ;; still prefix_0f 1, with prefix_extra 1.
571 (define_attr "length_vex" ""
572   (if_then_else (and (eq_attr "prefix_0f" "1")
573                      (eq_attr "prefix_extra" "0"))
574     (if_then_else (eq_attr "prefix_vex_w" "1")
575       (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
576       (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
577     (if_then_else (eq_attr "prefix_vex_w" "1")
578       (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
579       (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
581 ;; 4-bytes evex prefix and 1 byte opcode.
582 (define_attr "length_evex" "" (const_int 5))
584 ;; Set when modrm byte is used.
585 (define_attr "modrm" ""
586   (cond [(eq_attr "type" "str,leave")
587            (const_int 0)
588          (eq_attr "unit" "i387")
589            (const_int 0)
590          (and (eq_attr "type" "incdec")
591               (and (not (match_test "TARGET_64BIT"))
592                    (ior (match_operand:SI 1 "register_operand")
593                         (match_operand:HI 1 "register_operand"))))
594            (const_int 0)
595          (and (eq_attr "type" "push")
596               (not (match_operand 1 "memory_operand")))
597            (const_int 0)
598          (and (eq_attr "type" "pop")
599               (not (match_operand 0 "memory_operand")))
600            (const_int 0)
601          (and (eq_attr "type" "imov")
602               (and (not (eq_attr "mode" "DI"))
603                    (ior (and (match_operand 0 "register_operand")
604                              (match_operand 1 "immediate_operand"))
605                         (ior (and (match_operand 0 "ax_reg_operand")
606                                   (match_operand 1 "memory_displacement_only_operand"))
607                              (and (match_operand 0 "memory_displacement_only_operand")
608                                   (match_operand 1 "ax_reg_operand"))))))
609            (const_int 0)
610          (and (eq_attr "type" "call")
611               (match_operand 0 "constant_call_address_operand"))
612              (const_int 0)
613          (and (eq_attr "type" "callv")
614               (match_operand 1 "constant_call_address_operand"))
615              (const_int 0)
616          (and (eq_attr "type" "alu,alu1,icmp,test")
617               (match_operand 0 "ax_reg_operand"))
618              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
619          ]
620          (const_int 1)))
622 ;; When this attribute is set, calculate total insn length from
623 ;; length_nobnd attribute, prefixed with eventual bnd prefix byte
624 (define_attr "length_nobnd" "" (const_int 0))
626 ;; The (bounding maximum) length of an instruction in bytes.
627 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
628 ;; Later we may want to split them and compute proper length as for
629 ;; other insns.
630 (define_attr "length" ""
631   (cond [(eq_attr "length_nobnd" "!0")
632            (plus (symbol_ref ("ix86_bnd_prefixed_insn_p (insn)"))
633                  (attr "length_nobnd"))
634          (eq_attr "type" "other,multi,fistp,frndint")
635            (const_int 16)
636          (eq_attr "type" "fcmp")
637            (const_int 4)
638          (eq_attr "unit" "i387")
639            (plus (const_int 2)
640                  (plus (attr "prefix_data16")
641                        (attr "length_address")))
642          (ior (eq_attr "prefix" "evex")
643               (and (ior (eq_attr "prefix" "maybe_evex")
644                         (eq_attr "prefix" "maybe_vex"))
645                    (match_test "TARGET_AVX512F")))
646            (plus (attr "length_evex")
647                  (plus (attr "length_immediate")
648                        (plus (attr "modrm")
649                              (attr "length_address"))))
650          (ior (eq_attr "prefix" "vex")
651               (and (ior (eq_attr "prefix" "maybe_vex")
652                         (eq_attr "prefix" "maybe_evex"))
653                    (match_test "TARGET_AVX")))
654            (plus (attr "length_vex")
655                  (plus (attr "length_immediate")
656                        (plus (attr "modrm")
657                              (attr "length_address"))))]
658          (plus (plus (attr "modrm")
659                      (plus (attr "prefix_0f")
660                            (plus (attr "prefix_rex")
661                                  (plus (attr "prefix_extra")
662                                        (const_int 1)))))
663                (plus (attr "prefix_rep")
664                      (plus (attr "prefix_data16")
665                            (plus (attr "length_immediate")
666                                  (attr "length_address")))))))
668 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
669 ;; `store' if there is a simple memory reference therein, or `unknown'
670 ;; if the instruction is complex.
672 (define_attr "memory" "none,load,store,both,unknown"
673   (cond [(eq_attr "type" "other,multi,str,lwp")
674            (const_string "unknown")
675          (eq_attr "type" "lea,fcmov,fpspc,mpxmk,mpxchk")
676            (const_string "none")
677          (eq_attr "type" "fistp,leave")
678            (const_string "both")
679          (eq_attr "type" "frndint")
680            (const_string "load")
681          (eq_attr "type" "mpxld")
682            (const_string "load")
683          (eq_attr "type" "mpxst")
684            (const_string "store")
685          (eq_attr "type" "push")
686            (if_then_else (match_operand 1 "memory_operand")
687              (const_string "both")
688              (const_string "store"))
689          (eq_attr "type" "pop")
690            (if_then_else (match_operand 0 "memory_operand")
691              (const_string "both")
692              (const_string "load"))
693          (eq_attr "type" "setcc")
694            (if_then_else (match_operand 0 "memory_operand")
695              (const_string "store")
696              (const_string "none"))
697          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
698            (if_then_else (ior (match_operand 0 "memory_operand")
699                               (match_operand 1 "memory_operand"))
700              (const_string "load")
701              (const_string "none"))
702          (eq_attr "type" "ibr")
703            (if_then_else (match_operand 0 "memory_operand")
704              (const_string "load")
705              (const_string "none"))
706          (eq_attr "type" "call")
707            (if_then_else (match_operand 0 "constant_call_address_operand")
708              (const_string "none")
709              (const_string "load"))
710          (eq_attr "type" "callv")
711            (if_then_else (match_operand 1 "constant_call_address_operand")
712              (const_string "none")
713              (const_string "load"))
714          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
715               (match_operand 1 "memory_operand"))
716            (const_string "both")
717          (and (match_operand 0 "memory_operand")
718               (match_operand 1 "memory_operand"))
719            (const_string "both")
720          (match_operand 0 "memory_operand")
721            (const_string "store")
722          (match_operand 1 "memory_operand")
723            (const_string "load")
724          (and (eq_attr "type"
725                  "!alu1,negnot,ishift1,
726                    imov,imovx,icmp,test,bitmanip,
727                    fmov,fcmp,fsgn,
728                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
729                    sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
730                    mmx,mmxmov,mmxcmp,mmxcvt,mskmov,msklog,mpxmov")
731               (match_operand 2 "memory_operand"))
732            (const_string "load")
733          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
734               (match_operand 3 "memory_operand"))
735            (const_string "load")
736         ]
737         (const_string "none")))
739 ;; Indicates if an instruction has both an immediate and a displacement.
741 (define_attr "imm_disp" "false,true,unknown"
742   (cond [(eq_attr "type" "other,multi")
743            (const_string "unknown")
744          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
745               (and (match_operand 0 "memory_displacement_operand")
746                    (match_operand 1 "immediate_operand")))
747            (const_string "true")
748          (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
749               (and (match_operand 0 "memory_displacement_operand")
750                    (match_operand 2 "immediate_operand")))
751            (const_string "true")
752         ]
753         (const_string "false")))
755 ;; Indicates if an FP operation has an integer source.
757 (define_attr "fp_int_src" "false,true"
758   (const_string "false"))
760 ;; Defines rounding mode of an FP operation.
762 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
763   (const_string "any"))
765 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
766 (define_attr "use_carry" "0,1" (const_string "0"))
768 ;; Define attribute to indicate unaligned ssemov insns
769 (define_attr "movu" "0,1" (const_string "0"))
771 ;; Used to control the "enabled" attribute on a per-instruction basis.
772 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
773                     sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
774                     avx2,noavx2,bmi,bmi2,fma4,fma,avx512f,noavx512f,
775                     fma_avx512f,avx512bw,noavx512bw,avx512dq,noavx512dq"
776   (const_string "base"))
778 (define_attr "enabled" ""
779   (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
780          (eq_attr "isa" "x64_sse4")
781            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
782          (eq_attr "isa" "x64_sse4_noavx")
783            (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
784          (eq_attr "isa" "x64_avx")
785            (symbol_ref "TARGET_64BIT && TARGET_AVX")
786          (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
787          (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
788          (eq_attr "isa" "sse2_noavx")
789            (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
790          (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
791          (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
792          (eq_attr "isa" "sse4_noavx")
793            (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
794          (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
795          (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
796          (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
797          (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
798          (eq_attr "isa" "bmi") (symbol_ref "TARGET_BMI")
799          (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
800          (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
801          (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
802          (eq_attr "isa" "avx512f") (symbol_ref "TARGET_AVX512F")
803          (eq_attr "isa" "noavx512f") (symbol_ref "!TARGET_AVX512F")
804          (eq_attr "isa" "fma_avx512f")
805            (symbol_ref "TARGET_FMA || TARGET_AVX512F")
806          (eq_attr "isa" "avx512bw") (symbol_ref "TARGET_AVX512BW")
807          (eq_attr "isa" "noavx512bw") (symbol_ref "!TARGET_AVX512BW")
808          (eq_attr "isa" "avx512dq") (symbol_ref "TARGET_AVX512DQ")
809          (eq_attr "isa" "noavx512dq") (symbol_ref "!TARGET_AVX512DQ")
810         ]
811         (const_int 1)))
813 (define_attr "preferred_for_speed" "" (const_int 1))
815 ;; Describe a user's asm statement.
816 (define_asm_attributes
817   [(set_attr "length" "128")
818    (set_attr "type" "multi")])
820 (define_code_iterator plusminus [plus minus])
822 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
824 (define_code_iterator multdiv [mult div])
826 ;; Base name for define_insn
827 (define_code_attr plusminus_insn
828   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
829    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
831 ;; Base name for insn mnemonic.
832 (define_code_attr plusminus_mnemonic
833   [(plus "add") (ss_plus "adds") (us_plus "addus")
834    (minus "sub") (ss_minus "subs") (us_minus "subus")])
835 (define_code_attr plusminus_carry_mnemonic
836   [(plus "adc") (minus "sbb")])
837 (define_code_attr multdiv_mnemonic
838   [(mult "mul") (div "div")])
840 ;; Mark commutative operators as such in constraints.
841 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
842                         (minus "") (ss_minus "") (us_minus "")])
844 ;; Mapping of max and min
845 (define_code_iterator maxmin [smax smin umax umin])
847 ;; Mapping of signed max and min
848 (define_code_iterator smaxmin [smax smin])
850 ;; Mapping of unsigned max and min
851 (define_code_iterator umaxmin [umax umin])
853 ;; Base name for integer and FP insn mnemonic
854 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
855                               (umax "maxu") (umin "minu")])
856 (define_code_attr maxmin_float [(smax "max") (smin "min")])
858 ;; Mapping of logic operators
859 (define_code_iterator any_logic [and ior xor])
860 (define_code_iterator any_or [ior xor])
861 (define_code_iterator fpint_logic [and xor])
863 ;; Base name for insn mnemonic.
864 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
866 ;; Mapping of logic-shift operators
867 (define_code_iterator any_lshift [ashift lshiftrt])
869 ;; Mapping of shift-right operators
870 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
872 ;; Mapping of all shift operators
873 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
875 ;; Base name for define_insn
876 (define_code_attr shift_insn
877   [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
879 ;; Base name for insn mnemonic.
880 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
881 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
883 ;; Mapping of rotate operators
884 (define_code_iterator any_rotate [rotate rotatert])
886 ;; Base name for define_insn
887 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
889 ;; Base name for insn mnemonic.
890 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
892 ;; Mapping of abs neg operators
893 (define_code_iterator absneg [abs neg])
895 ;; Base name for x87 insn mnemonic.
896 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
898 ;; Used in signed and unsigned widening multiplications.
899 (define_code_iterator any_extend [sign_extend zero_extend])
901 ;; Prefix for insn menmonic.
902 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
904 ;; Prefix for define_insn
905 (define_code_attr u [(sign_extend "") (zero_extend "u")])
906 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
907 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
909 ;; Used in signed and unsigned truncations.
910 (define_code_iterator any_truncate [ss_truncate truncate us_truncate])
911 ;; Instruction suffix for truncations.
912 (define_code_attr trunsuffix [(ss_truncate "s") (truncate "") (us_truncate "us")])
914 ;; Used in signed and unsigned fix.
915 (define_code_iterator any_fix [fix unsigned_fix])
916 (define_code_attr fixsuffix [(fix "") (unsigned_fix "u")])
918 ;; Used in signed and unsigned float.
919 (define_code_iterator any_float [float unsigned_float])
920 (define_code_attr floatsuffix [(float "") (unsigned_float "u")])
922 ;; All integer modes.
923 (define_mode_iterator SWI1248x [QI HI SI DI])
925 ;; All integer modes with AVX512BW.
926 (define_mode_iterator SWI1248_AVX512BW
927   [QI HI (SI "TARGET_AVX512BW") (DI "TARGET_AVX512BW")])
929 ;; All integer modes without QImode.
930 (define_mode_iterator SWI248x [HI SI DI])
932 ;; All integer modes without QImode and HImode.
933 (define_mode_iterator SWI48x [SI DI])
935 ;; All integer modes without SImode and DImode.
936 (define_mode_iterator SWI12 [QI HI])
938 ;; All integer modes without DImode.
939 (define_mode_iterator SWI124 [QI HI SI])
941 ;; All integer modes without QImode and DImode.
942 (define_mode_iterator SWI24 [HI SI])
944 ;; Single word integer modes.
945 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
947 ;; Single word integer modes without QImode.
948 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
950 ;; Single word integer modes without QImode and HImode.
951 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
953 ;; All math-dependant single and double word integer modes.
954 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
955                              (HI "TARGET_HIMODE_MATH")
956                              SI DI (TI "TARGET_64BIT")])
958 ;; Math-dependant single word integer modes.
959 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
960                             (HI "TARGET_HIMODE_MATH")
961                             SI (DI "TARGET_64BIT")])
963 ;; Math-dependant integer modes without DImode.
964 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
965                                (HI "TARGET_HIMODE_MATH")
966                                SI])
968 ;; Math-dependant single word integer modes without QImode.
969 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
970                                SI (DI "TARGET_64BIT")])
972 ;; Double word integer modes.
973 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
974                            (TI "TARGET_64BIT")])
976 ;; GET_MODE_SIZE for selected modes.  As GET_MODE_SIZE is not
977 ;; compile time constant, it is faster to use <MODE_SIZE> than
978 ;; GET_MODE_SIZE (<MODE>mode).  For XFmode which depends on
979 ;; command line options just use GET_MODE_SIZE macro.
980 (define_mode_attr MODE_SIZE [(QI "1") (HI "2") (SI "4") (DI "8") (TI "16")
981                              (SF "4") (DF "8") (XF "GET_MODE_SIZE (XFmode)")
982                              (V16QI "16") (V32QI "32") (V64QI "64")
983                              (V8HI "16") (V16HI "32") (V32HI "64")
984                              (V4SI "16") (V8SI "32") (V16SI "64")
985                              (V2DI "16") (V4DI "32") (V8DI "64")
986                              (V1TI "16") (V2TI "32") (V4TI "64")
987                              (V2DF "16") (V4DF "32") (V8DF "64")
988                              (V4SF "16") (V8SF "32") (V16SF "64")])
990 ;; Double word integer modes as mode attribute.
991 (define_mode_attr DWI [(QI "HI") (HI "SI") (SI "DI") (DI "TI")])
992 (define_mode_attr dwi [(QI "hi") (HI "si") (SI "di") (DI "ti")])
994 ;; Half mode for double word integer modes.
995 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
996                             (DI "TARGET_64BIT")])
998 ;; Bound modes.
999 (define_mode_iterator BND [(BND32 "!TARGET_LP64")
1000                            (BND64 "TARGET_LP64")])
1002 ;; Pointer mode corresponding to bound mode.
1003 (define_mode_attr bnd_ptr [(BND32 "SI") (BND64 "DI")])
1005 ;; MPX check types
1006 (define_int_iterator BNDCHECK [UNSPEC_BNDCL UNSPEC_BNDCU UNSPEC_BNDCN])
1008 ;; Check name
1009 (define_int_attr bndcheck [(UNSPEC_BNDCL "cl")
1010                            (UNSPEC_BNDCU "cu")
1011                            (UNSPEC_BNDCN "cn")])
1013 ;; Instruction suffix for integer modes.
1014 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
1016 ;; Instruction suffix for masks.
1017 (define_mode_attr mskmodesuffix [(QI "b") (HI "w") (SI "d") (DI "q")])
1019 ;; Pointer size prefix for integer modes (Intel asm dialect)
1020 (define_mode_attr iptrsize [(QI "BYTE")
1021                             (HI "WORD")
1022                             (SI "DWORD")
1023                             (DI "QWORD")])
1025 ;; Register class for integer modes.
1026 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
1028 ;; Immediate operand constraint for integer modes.
1029 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
1031 ;; General operand constraint for word modes.
1032 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
1034 ;; Immediate operand constraint for double integer modes.
1035 (define_mode_attr di [(SI "nF") (DI "e")])
1037 ;; Immediate operand constraint for shifts.
1038 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
1040 ;; General operand predicate for integer modes.
1041 (define_mode_attr general_operand
1042         [(QI "general_operand")
1043          (HI "general_operand")
1044          (SI "x86_64_general_operand")
1045          (DI "x86_64_general_operand")
1046          (TI "x86_64_general_operand")])
1048 ;; General sign extend operand predicate for integer modes,
1049 ;; which disallows VOIDmode operands and thus it is suitable
1050 ;; for use inside sign_extend.
1051 (define_mode_attr general_sext_operand
1052         [(QI "sext_operand")
1053          (HI "sext_operand")
1054          (SI "x86_64_sext_operand")
1055          (DI "x86_64_sext_operand")])
1057 ;; General sign/zero extend operand predicate for integer modes.
1058 (define_mode_attr general_szext_operand
1059         [(QI "general_operand")
1060          (HI "general_operand")
1061          (SI "x86_64_szext_general_operand")
1062          (DI "x86_64_szext_general_operand")])
1064 ;; Immediate operand predicate for integer modes.
1065 (define_mode_attr immediate_operand
1066         [(QI "immediate_operand")
1067          (HI "immediate_operand")
1068          (SI "x86_64_immediate_operand")
1069          (DI "x86_64_immediate_operand")])
1071 ;; Nonmemory operand predicate for integer modes.
1072 (define_mode_attr nonmemory_operand
1073         [(QI "nonmemory_operand")
1074          (HI "nonmemory_operand")
1075          (SI "x86_64_nonmemory_operand")
1076          (DI "x86_64_nonmemory_operand")])
1078 ;; Operand predicate for shifts.
1079 (define_mode_attr shift_operand
1080         [(QI "nonimmediate_operand")
1081          (HI "nonimmediate_operand")
1082          (SI "nonimmediate_operand")
1083          (DI "shiftdi_operand")
1084          (TI "register_operand")])
1086 ;; Operand predicate for shift argument.
1087 (define_mode_attr shift_immediate_operand
1088         [(QI "const_1_to_31_operand")
1089          (HI "const_1_to_31_operand")
1090          (SI "const_1_to_31_operand")
1091          (DI "const_1_to_63_operand")])
1093 ;; Input operand predicate for arithmetic left shifts.
1094 (define_mode_attr ashl_input_operand
1095         [(QI "nonimmediate_operand")
1096          (HI "nonimmediate_operand")
1097          (SI "nonimmediate_operand")
1098          (DI "ashldi_input_operand")
1099          (TI "reg_or_pm1_operand")])
1101 ;; SSE and x87 SFmode and DFmode floating point modes
1102 (define_mode_iterator MODEF [SF DF])
1104 ;; All x87 floating point modes
1105 (define_mode_iterator X87MODEF [SF DF XF])
1107 ;; SSE instruction suffix for various modes
1108 (define_mode_attr ssemodesuffix
1109   [(SF "ss") (DF "sd")
1110    (V16SF "ps") (V8DF "pd")
1111    (V8SF "ps") (V4DF "pd")
1112    (V4SF "ps") (V2DF "pd")
1113    (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
1114    (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")
1115    (V64QI "b") (V32HI "w") (V16SI "d") (V8DI "q")])
1117 ;; SSE vector suffix for floating point modes
1118 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
1120 ;; SSE vector mode corresponding to a scalar mode
1121 (define_mode_attr ssevecmode
1122   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
1123 (define_mode_attr ssevecmodelower
1124   [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
1126 ;; Instruction suffix for REX 64bit operators.
1127 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
1129 ;; This mode iterator allows :P to be used for patterns that operate on
1130 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
1131 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
1133 ;; This mode iterator allows :W to be used for patterns that operate on
1134 ;; word_mode sized quantities.
1135 (define_mode_iterator W
1136   [(SI "word_mode == SImode") (DI "word_mode == DImode")])
1138 ;; This mode iterator allows :PTR to be used for patterns that operate on
1139 ;; ptr_mode sized quantities.
1140 (define_mode_iterator PTR
1141   [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
1143 ;; Scheduling descriptions
1145 (include "pentium.md")
1146 (include "ppro.md")
1147 (include "k6.md")
1148 (include "athlon.md")
1149 (include "bdver1.md")
1150 (include "bdver3.md")
1151 (include "btver2.md")
1152 (include "geode.md")
1153 (include "atom.md")
1154 (include "slm.md")
1155 (include "core2.md")
1158 ;; Operand and operator predicates and constraints
1160 (include "predicates.md")
1161 (include "constraints.md")
1164 ;; Compare and branch/compare and store instructions.
1166 (define_expand "cbranch<mode>4"
1167   [(set (reg:CC FLAGS_REG)
1168         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
1169                     (match_operand:SDWIM 2 "<general_operand>")))
1170    (set (pc) (if_then_else
1171                (match_operator 0 "ordered_comparison_operator"
1172                 [(reg:CC FLAGS_REG) (const_int 0)])
1173                (label_ref (match_operand 3))
1174                (pc)))]
1175   ""
1177   if (MEM_P (operands[1]) && MEM_P (operands[2]))
1178     operands[1] = force_reg (<MODE>mode, operands[1]);
1179   ix86_expand_branch (GET_CODE (operands[0]),
1180                       operands[1], operands[2], operands[3]);
1181   DONE;
1184 (define_expand "cstore<mode>4"
1185   [(set (reg:CC FLAGS_REG)
1186         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1187                     (match_operand:SWIM 3 "<general_operand>")))
1188    (set (match_operand:QI 0 "register_operand")
1189         (match_operator 1 "ordered_comparison_operator"
1190           [(reg:CC FLAGS_REG) (const_int 0)]))]
1191   ""
1193   if (MEM_P (operands[2]) && MEM_P (operands[3]))
1194     operands[2] = force_reg (<MODE>mode, operands[2]);
1195   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1196                      operands[2], operands[3]);
1197   DONE;
1200 (define_expand "cmp<mode>_1"
1201   [(set (reg:CC FLAGS_REG)
1202         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1203                     (match_operand:SWI48 1 "<general_operand>")))])
1205 (define_insn "*cmp<mode>_ccno_1"
1206   [(set (reg FLAGS_REG)
1207         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1208                  (match_operand:SWI 1 "const0_operand")))]
1209   "ix86_match_ccmode (insn, CCNOmode)"
1210   "@
1211    test{<imodesuffix>}\t%0, %0
1212    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1213   [(set_attr "type" "test,icmp")
1214    (set_attr "length_immediate" "0,1")
1215    (set_attr "mode" "<MODE>")])
1217 (define_insn "*cmp<mode>_1"
1218   [(set (reg FLAGS_REG)
1219         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1220                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1221   "ix86_match_ccmode (insn, CCmode)"
1222   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1223   [(set_attr "type" "icmp")
1224    (set_attr "mode" "<MODE>")])
1226 (define_insn "*cmp<mode>_minus_1"
1227   [(set (reg FLAGS_REG)
1228         (compare
1229           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1230                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1231           (const_int 0)))]
1232   "ix86_match_ccmode (insn, CCGOCmode)"
1233   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1234   [(set_attr "type" "icmp")
1235    (set_attr "mode" "<MODE>")])
1237 (define_insn "*cmpqi_ext_1"
1238   [(set (reg FLAGS_REG)
1239         (compare
1240           (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1241           (subreg:QI
1242             (zero_extract:SI
1243               (match_operand 1 "ext_register_operand" "Q,Q")
1244               (const_int 8)
1245               (const_int 8)) 0)))]
1246   "ix86_match_ccmode (insn, CCmode)"
1247   "cmp{b}\t{%h1, %0|%0, %h1}"
1248   [(set_attr "isa" "*,nox64")
1249    (set_attr "type" "icmp")
1250    (set_attr "mode" "QI")])
1252 (define_insn "*cmpqi_ext_2"
1253   [(set (reg FLAGS_REG)
1254         (compare
1255           (subreg:QI
1256             (zero_extract:SI
1257               (match_operand 0 "ext_register_operand" "Q")
1258               (const_int 8)
1259               (const_int 8)) 0)
1260           (match_operand:QI 1 "const0_operand")))]
1261   "ix86_match_ccmode (insn, CCNOmode)"
1262   "test{b}\t%h0, %h0"
1263   [(set_attr "type" "test")
1264    (set_attr "length_immediate" "0")
1265    (set_attr "mode" "QI")])
1267 (define_expand "cmpqi_ext_3"
1268   [(set (reg:CC FLAGS_REG)
1269         (compare:CC
1270           (subreg:QI
1271             (zero_extract:SI
1272               (match_operand 0 "ext_register_operand")
1273               (const_int 8)
1274               (const_int 8)) 0)
1275           (match_operand:QI 1 "const_int_operand")))])
1277 (define_insn "*cmpqi_ext_3"
1278   [(set (reg FLAGS_REG)
1279         (compare
1280           (subreg:QI
1281             (zero_extract:SI
1282               (match_operand 0 "ext_register_operand" "Q,Q")
1283               (const_int 8)
1284               (const_int 8)) 0)
1285           (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1286   "ix86_match_ccmode (insn, CCmode)"
1287   "cmp{b}\t{%1, %h0|%h0, %1}"
1288   [(set_attr "isa" "*,nox64")
1289    (set_attr "type" "icmp")
1290    (set_attr "modrm" "1")
1291    (set_attr "mode" "QI")])
1293 (define_insn "*cmpqi_ext_4"
1294   [(set (reg FLAGS_REG)
1295         (compare
1296           (subreg:QI
1297             (zero_extract:SI
1298               (match_operand 0 "ext_register_operand" "Q")
1299               (const_int 8)
1300               (const_int 8)) 0)
1301           (subreg:QI
1302             (zero_extract:SI
1303               (match_operand 1 "ext_register_operand" "Q")
1304               (const_int 8)
1305               (const_int 8)) 0)))]
1306   "ix86_match_ccmode (insn, CCmode)"
1307   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1308   [(set_attr "type" "icmp")
1309    (set_attr "mode" "QI")])
1311 ;; These implement float point compares.
1312 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1313 ;; which would allow mix and match FP modes on the compares.  Which is what
1314 ;; the old patterns did, but with many more of them.
1316 (define_expand "cbranchxf4"
1317   [(set (reg:CC FLAGS_REG)
1318         (compare:CC (match_operand:XF 1 "nonmemory_operand")
1319                     (match_operand:XF 2 "nonmemory_operand")))
1320    (set (pc) (if_then_else
1321               (match_operator 0 "ix86_fp_comparison_operator"
1322                [(reg:CC FLAGS_REG)
1323                 (const_int 0)])
1324               (label_ref (match_operand 3))
1325               (pc)))]
1326   "TARGET_80387"
1328   ix86_expand_branch (GET_CODE (operands[0]),
1329                       operands[1], operands[2], operands[3]);
1330   DONE;
1333 (define_expand "cstorexf4"
1334   [(set (reg:CC FLAGS_REG)
1335         (compare:CC (match_operand:XF 2 "nonmemory_operand")
1336                     (match_operand:XF 3 "nonmemory_operand")))
1337    (set (match_operand:QI 0 "register_operand")
1338               (match_operator 1 "ix86_fp_comparison_operator"
1339                [(reg:CC FLAGS_REG)
1340                 (const_int 0)]))]
1341   "TARGET_80387"
1343   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1344                      operands[2], operands[3]);
1345   DONE;
1348 (define_expand "cbranch<mode>4"
1349   [(set (reg:CC FLAGS_REG)
1350         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1351                     (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1352    (set (pc) (if_then_else
1353               (match_operator 0 "ix86_fp_comparison_operator"
1354                [(reg:CC FLAGS_REG)
1355                 (const_int 0)])
1356               (label_ref (match_operand 3))
1357               (pc)))]
1358   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1360   ix86_expand_branch (GET_CODE (operands[0]),
1361                       operands[1], operands[2], operands[3]);
1362   DONE;
1365 (define_expand "cstore<mode>4"
1366   [(set (reg:CC FLAGS_REG)
1367         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1368                     (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1369    (set (match_operand:QI 0 "register_operand")
1370               (match_operator 1 "ix86_fp_comparison_operator"
1371                [(reg:CC FLAGS_REG)
1372                 (const_int 0)]))]
1373   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1375   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1376                      operands[2], operands[3]);
1377   DONE;
1380 (define_expand "cbranchcc4"
1381   [(set (pc) (if_then_else
1382               (match_operator 0 "comparison_operator"
1383                [(match_operand 1 "flags_reg_operand")
1384                 (match_operand 2 "const0_operand")])
1385               (label_ref (match_operand 3))
1386               (pc)))]
1387   ""
1389   ix86_expand_branch (GET_CODE (operands[0]),
1390                       operands[1], operands[2], operands[3]);
1391   DONE;
1394 (define_expand "cstorecc4"
1395   [(set (match_operand:QI 0 "register_operand")
1396               (match_operator 1 "comparison_operator"
1397                [(match_operand 2 "flags_reg_operand")
1398                 (match_operand 3 "const0_operand")]))]
1399   ""
1401   ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1402                      operands[2], operands[3]);
1403   DONE;
1407 ;; FP compares, step 1:
1408 ;; Set the FP condition codes.
1410 ;; CCFPmode     compare with exceptions
1411 ;; CCFPUmode    compare with no exceptions
1413 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1414 ;; used to manage the reg stack popping would not be preserved.
1416 (define_insn "*cmp<mode>_0_i387"
1417   [(set (match_operand:HI 0 "register_operand" "=a")
1418         (unspec:HI
1419           [(compare:CCFP
1420              (match_operand:X87MODEF 1 "register_operand" "f")
1421              (match_operand:X87MODEF 2 "const0_operand"))]
1422         UNSPEC_FNSTSW))]
1423   "TARGET_80387"
1424   "* return output_fp_compare (insn, operands, false, false);"
1425   [(set_attr "type" "multi")
1426    (set_attr "unit" "i387")
1427    (set_attr "mode" "<MODE>")])
1429 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1430   [(set (reg:CCFP FLAGS_REG)
1431         (compare:CCFP
1432           (match_operand:X87MODEF 1 "register_operand" "f")
1433           (match_operand:X87MODEF 2 "const0_operand")))
1434    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1435   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1436   "#"
1437   "&& reload_completed"
1438   [(set (match_dup 0)
1439         (unspec:HI
1440           [(compare:CCFP (match_dup 1)(match_dup 2))]
1441         UNSPEC_FNSTSW))
1442    (set (reg:CC FLAGS_REG)
1443         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1444   ""
1445   [(set_attr "type" "multi")
1446    (set_attr "unit" "i387")
1447    (set_attr "mode" "<MODE>")])
1449 (define_insn "*cmpxf_i387"
1450   [(set (match_operand:HI 0 "register_operand" "=a")
1451         (unspec:HI
1452           [(compare:CCFP
1453              (match_operand:XF 1 "register_operand" "f")
1454              (match_operand:XF 2 "register_operand" "f"))]
1455           UNSPEC_FNSTSW))]
1456   "TARGET_80387"
1457   "* return output_fp_compare (insn, operands, false, false);"
1458   [(set_attr "type" "multi")
1459    (set_attr "unit" "i387")
1460    (set_attr "mode" "XF")])
1462 (define_insn_and_split "*cmpxf_cc_i387"
1463   [(set (reg:CCFP FLAGS_REG)
1464         (compare:CCFP
1465           (match_operand:XF 1 "register_operand" "f")
1466           (match_operand:XF 2 "register_operand" "f")))
1467    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1468   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1469   "#"
1470   "&& reload_completed"
1471   [(set (match_dup 0)
1472         (unspec:HI
1473           [(compare:CCFP (match_dup 1)(match_dup 2))]
1474         UNSPEC_FNSTSW))
1475    (set (reg:CC FLAGS_REG)
1476         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1477   ""
1478   [(set_attr "type" "multi")
1479    (set_attr "unit" "i387")
1480    (set_attr "mode" "XF")])
1482 (define_insn "*cmp<mode>_i387"
1483   [(set (match_operand:HI 0 "register_operand" "=a")
1484         (unspec:HI
1485           [(compare:CCFP
1486              (match_operand:MODEF 1 "register_operand" "f")
1487              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1488           UNSPEC_FNSTSW))]
1489   "TARGET_80387"
1490   "* return output_fp_compare (insn, operands, false, false);"
1491   [(set_attr "type" "multi")
1492    (set_attr "unit" "i387")
1493    (set_attr "mode" "<MODE>")])
1495 (define_insn_and_split "*cmp<mode>_cc_i387"
1496   [(set (reg:CCFP FLAGS_REG)
1497         (compare:CCFP
1498           (match_operand:MODEF 1 "register_operand" "f")
1499           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1500    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1501   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1502   "#"
1503   "&& reload_completed"
1504   [(set (match_dup 0)
1505         (unspec:HI
1506           [(compare:CCFP (match_dup 1)(match_dup 2))]
1507         UNSPEC_FNSTSW))
1508    (set (reg:CC FLAGS_REG)
1509         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1510   ""
1511   [(set_attr "type" "multi")
1512    (set_attr "unit" "i387")
1513    (set_attr "mode" "<MODE>")])
1515 (define_insn "*cmpu<mode>_i387"
1516   [(set (match_operand:HI 0 "register_operand" "=a")
1517         (unspec:HI
1518           [(compare:CCFPU
1519              (match_operand:X87MODEF 1 "register_operand" "f")
1520              (match_operand:X87MODEF 2 "register_operand" "f"))]
1521           UNSPEC_FNSTSW))]
1522   "TARGET_80387"
1523   "* return output_fp_compare (insn, operands, false, true);"
1524   [(set_attr "type" "multi")
1525    (set_attr "unit" "i387")
1526    (set_attr "mode" "<MODE>")])
1528 (define_insn_and_split "*cmpu<mode>_cc_i387"
1529   [(set (reg:CCFPU FLAGS_REG)
1530         (compare:CCFPU
1531           (match_operand:X87MODEF 1 "register_operand" "f")
1532           (match_operand:X87MODEF 2 "register_operand" "f")))
1533    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1534   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1535   "#"
1536   "&& reload_completed"
1537   [(set (match_dup 0)
1538         (unspec:HI
1539           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1540         UNSPEC_FNSTSW))
1541    (set (reg:CC FLAGS_REG)
1542         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1543   ""
1544   [(set_attr "type" "multi")
1545    (set_attr "unit" "i387")
1546    (set_attr "mode" "<MODE>")])
1548 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1549   [(set (match_operand:HI 0 "register_operand" "=a")
1550         (unspec:HI
1551           [(compare:CCFP
1552              (match_operand:X87MODEF 1 "register_operand" "f")
1553              (match_operator:X87MODEF 3 "float_operator"
1554                [(match_operand:SWI24 2 "memory_operand" "m")]))]
1555           UNSPEC_FNSTSW))]
1556   "TARGET_80387
1557    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1558        || optimize_function_for_size_p (cfun))"
1559   "* return output_fp_compare (insn, operands, false, false);"
1560   [(set_attr "type" "multi")
1561    (set_attr "unit" "i387")
1562    (set_attr "fp_int_src" "true")
1563    (set_attr "mode" "<SWI24:MODE>")])
1565 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1566   [(set (reg:CCFP FLAGS_REG)
1567         (compare:CCFP
1568           (match_operand:X87MODEF 1 "register_operand" "f")
1569           (match_operator:X87MODEF 3 "float_operator"
1570             [(match_operand:SWI24 2 "memory_operand" "m")])))
1571    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1572   "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1573    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1574        || optimize_function_for_size_p (cfun))"
1575   "#"
1576   "&& reload_completed"
1577   [(set (match_dup 0)
1578         (unspec:HI
1579           [(compare:CCFP
1580              (match_dup 1)
1581              (match_op_dup 3 [(match_dup 2)]))]
1582         UNSPEC_FNSTSW))
1583    (set (reg:CC FLAGS_REG)
1584         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1585   ""
1586   [(set_attr "type" "multi")
1587    (set_attr "unit" "i387")
1588    (set_attr "fp_int_src" "true")
1589    (set_attr "mode" "<SWI24:MODE>")])
1591 ;; FP compares, step 2
1592 ;; Move the fpsw to ax.
1594 (define_insn "x86_fnstsw_1"
1595   [(set (match_operand:HI 0 "register_operand" "=a")
1596         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1597   "TARGET_80387"
1598   "fnstsw\t%0"
1599   [(set_attr "length" "2")
1600    (set_attr "mode" "SI")
1601    (set_attr "unit" "i387")])
1603 ;; FP compares, step 3
1604 ;; Get ax into flags, general case.
1606 (define_insn "x86_sahf_1"
1607   [(set (reg:CC FLAGS_REG)
1608         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1609                    UNSPEC_SAHF))]
1610   "TARGET_SAHF"
1612 #ifndef HAVE_AS_IX86_SAHF
1613   if (TARGET_64BIT)
1614     return ASM_BYTE "0x9e";
1615   else
1616 #endif
1617   return "sahf";
1619   [(set_attr "length" "1")
1620    (set_attr "athlon_decode" "vector")
1621    (set_attr "amdfam10_decode" "direct")
1622    (set_attr "bdver1_decode" "direct")
1623    (set_attr "mode" "SI")])
1625 ;; Pentium Pro can do steps 1 through 3 in one go.
1626 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1627 ;; (these i387 instructions set flags directly)
1629 (define_mode_iterator FPCMP [CCFP CCFPU])
1630 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1632 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1633   [(set (reg:FPCMP FLAGS_REG)
1634         (compare:FPCMP
1635           (match_operand:MODEF 0 "register_operand" "f,x")
1636           (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1637   "TARGET_MIX_SSE_I387
1638    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1639   "* return output_fp_compare (insn, operands, true,
1640                                <FPCMP:MODE>mode == CCFPUmode);"
1641   [(set_attr "type" "fcmp,ssecomi")
1642    (set_attr "prefix" "orig,maybe_vex")
1643    (set_attr "mode" "<MODEF:MODE>")
1644    (set (attr "prefix_rep")
1645         (if_then_else (eq_attr "type" "ssecomi")
1646                       (const_string "0")
1647                       (const_string "*")))
1648    (set (attr "prefix_data16")
1649         (cond [(eq_attr "type" "fcmp")
1650                  (const_string "*")
1651                (eq_attr "mode" "DF")
1652                  (const_string "1")
1653               ]
1654               (const_string "0")))
1655    (set_attr "athlon_decode" "vector")
1656    (set_attr "amdfam10_decode" "direct")
1657    (set_attr "bdver1_decode" "double")])
1659 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1660   [(set (reg:FPCMP FLAGS_REG)
1661         (compare:FPCMP
1662           (match_operand:MODEF 0 "register_operand" "x")
1663           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1664   "TARGET_SSE_MATH
1665    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1666   "* return output_fp_compare (insn, operands, true,
1667                                <FPCMP:MODE>mode == CCFPUmode);"
1668   [(set_attr "type" "ssecomi")
1669    (set_attr "prefix" "maybe_vex")
1670    (set_attr "mode" "<MODEF:MODE>")
1671    (set_attr "prefix_rep" "0")
1672    (set (attr "prefix_data16")
1673         (if_then_else (eq_attr "mode" "DF")
1674                       (const_string "1")
1675                       (const_string "0")))
1676    (set_attr "athlon_decode" "vector")
1677    (set_attr "amdfam10_decode" "direct")
1678    (set_attr "bdver1_decode" "double")])
1680 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1681   [(set (reg:FPCMP FLAGS_REG)
1682         (compare:FPCMP
1683           (match_operand:X87MODEF 0 "register_operand" "f")
1684           (match_operand:X87MODEF 1 "register_operand" "f")))]
1685   "TARGET_80387 && TARGET_CMOVE
1686    && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1687   "* return output_fp_compare (insn, operands, true,
1688                                <FPCMP:MODE>mode == CCFPUmode);"
1689   [(set_attr "type" "fcmp")
1690    (set_attr "mode" "<X87MODEF:MODE>")
1691    (set_attr "athlon_decode" "vector")
1692    (set_attr "amdfam10_decode" "direct")
1693    (set_attr "bdver1_decode" "double")])
1695 ;; Push/pop instructions.
1697 (define_insn "*push<mode>2"
1698   [(set (match_operand:DWI 0 "push_operand" "=<")
1699         (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1700   ""
1701   "#"
1702   [(set_attr "type" "multi")
1703    (set_attr "mode" "<MODE>")])
1705 (define_split
1706   [(set (match_operand:TI 0 "push_operand")
1707         (match_operand:TI 1 "general_operand"))]
1708   "TARGET_64BIT && reload_completed
1709    && !SSE_REG_P (operands[1])"
1710   [(const_int 0)]
1711   "ix86_split_long_move (operands); DONE;")
1713 (define_insn "*pushdi2_rex64"
1714   [(set (match_operand:DI 0 "push_operand" "=<,!<")
1715         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1716   "TARGET_64BIT"
1717   "@
1718    push{q}\t%1
1719    #"
1720   [(set_attr "type" "push,multi")
1721    (set_attr "mode" "DI")])
1723 ;; Convert impossible pushes of immediate to existing instructions.
1724 ;; First try to get scratch register and go through it.  In case this
1725 ;; fails, push sign extended lower part first and then overwrite
1726 ;; upper part by 32bit move.
1727 (define_peephole2
1728   [(match_scratch:DI 2 "r")
1729    (set (match_operand:DI 0 "push_operand")
1730         (match_operand:DI 1 "immediate_operand"))]
1731   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1732    && !x86_64_immediate_operand (operands[1], DImode)"
1733   [(set (match_dup 2) (match_dup 1))
1734    (set (match_dup 0) (match_dup 2))])
1736 ;; We need to define this as both peepholer and splitter for case
1737 ;; peephole2 pass is not run.
1738 ;; "&& 1" is needed to keep it from matching the previous pattern.
1739 (define_peephole2
1740   [(set (match_operand:DI 0 "push_operand")
1741         (match_operand:DI 1 "immediate_operand"))]
1742   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1743    && !x86_64_immediate_operand (operands[1], DImode) && 1"
1744   [(set (match_dup 0) (match_dup 1))
1745    (set (match_dup 2) (match_dup 3))]
1747   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1749   operands[1] = gen_lowpart (DImode, operands[2]);
1750   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1751                                                    GEN_INT (4)));
1754 (define_split
1755   [(set (match_operand:DI 0 "push_operand")
1756         (match_operand:DI 1 "immediate_operand"))]
1757   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1758                     ? epilogue_completed : reload_completed)
1759    && !symbolic_operand (operands[1], DImode)
1760    && !x86_64_immediate_operand (operands[1], DImode)"
1761   [(set (match_dup 0) (match_dup 1))
1762    (set (match_dup 2) (match_dup 3))]
1764   split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1766   operands[1] = gen_lowpart (DImode, operands[2]);
1767   operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1768                                                    GEN_INT (4)));
1771 (define_split
1772   [(set (match_operand:DI 0 "push_operand")
1773         (match_operand:DI 1 "general_operand"))]
1774   "!TARGET_64BIT && reload_completed
1775    && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1776   [(const_int 0)]
1777   "ix86_split_long_move (operands); DONE;")
1779 (define_insn "*pushsi2"
1780   [(set (match_operand:SI 0 "push_operand" "=<")
1781         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1782   "!TARGET_64BIT"
1783   "push{l}\t%1"
1784   [(set_attr "type" "push")
1785    (set_attr "mode" "SI")])
1787 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1788 ;; "push a byte/word".  But actually we use pushl, which has the effect
1789 ;; of rounding the amount pushed up to a word.
1791 ;; For TARGET_64BIT we always round up to 8 bytes.
1792 (define_insn "*push<mode>2_rex64"
1793   [(set (match_operand:SWI124 0 "push_operand" "=X")
1794         (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1795   "TARGET_64BIT"
1796   "push{q}\t%q1"
1797   [(set_attr "type" "push")
1798    (set_attr "mode" "DI")])
1800 (define_insn "*push<mode>2"
1801   [(set (match_operand:SWI12 0 "push_operand" "=X")
1802         (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1803   "!TARGET_64BIT"
1804   "push{l}\t%k1"
1805   [(set_attr "type" "push")
1806    (set_attr "mode" "SI")])
1808 (define_insn "*push<mode>2_prologue"
1809   [(set (match_operand:W 0 "push_operand" "=<")
1810         (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1811    (clobber (mem:BLK (scratch)))]
1812   ""
1813   "push{<imodesuffix>}\t%1"
1814   [(set_attr "type" "push")
1815    (set_attr "mode" "<MODE>")])
1817 (define_insn "*pop<mode>1"
1818   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1819         (match_operand:W 1 "pop_operand" ">"))]
1820   ""
1821   "pop{<imodesuffix>}\t%0"
1822   [(set_attr "type" "pop")
1823    (set_attr "mode" "<MODE>")])
1825 (define_insn "*pop<mode>1_epilogue"
1826   [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1827         (match_operand:W 1 "pop_operand" ">"))
1828    (clobber (mem:BLK (scratch)))]
1829   ""
1830   "pop{<imodesuffix>}\t%0"
1831   [(set_attr "type" "pop")
1832    (set_attr "mode" "<MODE>")])
1834 (define_insn "*pushfl<mode>2"
1835   [(set (match_operand:W 0 "push_operand" "=<")
1836         (match_operand:W 1 "flags_reg_operand"))]
1837   ""
1838   "pushf{<imodesuffix>}"
1839   [(set_attr "type" "push")
1840    (set_attr "mode" "<MODE>")])
1842 (define_insn "*popfl<mode>1"
1843   [(set (match_operand:W 0 "flags_reg_operand")
1844         (match_operand:W 1 "pop_operand" ">"))]
1845   ""
1846   "popf{<imodesuffix>}"
1847   [(set_attr "type" "pop")
1848    (set_attr "mode" "<MODE>")])
1851 ;; Move instructions.
1853 (define_expand "movxi"
1854   [(set (match_operand:XI 0 "nonimmediate_operand")
1855         (match_operand:XI 1 "general_operand"))]
1856   "TARGET_AVX512F"
1857   "ix86_expand_move (XImode, operands); DONE;")
1859 ;; Reload patterns to support multi-word load/store
1860 ;; with non-offsetable address.
1861 (define_expand "reload_noff_store"
1862   [(parallel [(match_operand 0 "memory_operand" "=m")
1863               (match_operand 1 "register_operand" "r")
1864               (match_operand:DI 2 "register_operand" "=&r")])]
1865   "TARGET_64BIT"
1867   rtx mem = operands[0];
1868   rtx addr = XEXP (mem, 0);
1870   emit_move_insn (operands[2], addr);
1871   mem = replace_equiv_address_nv (mem, operands[2]);
1873   emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1874   DONE;
1877 (define_expand "reload_noff_load"
1878   [(parallel [(match_operand 0 "register_operand" "=r")
1879               (match_operand 1 "memory_operand" "m")
1880               (match_operand:DI 2 "register_operand" "=r")])]
1881   "TARGET_64BIT"
1883   rtx mem = operands[1];
1884   rtx addr = XEXP (mem, 0);
1886   emit_move_insn (operands[2], addr);
1887   mem = replace_equiv_address_nv (mem, operands[2]);
1889   emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1890   DONE;
1893 (define_expand "movoi"
1894   [(set (match_operand:OI 0 "nonimmediate_operand")
1895         (match_operand:OI 1 "general_operand"))]
1896   "TARGET_AVX"
1897   "ix86_expand_move (OImode, operands); DONE;")
1899 (define_expand "movti"
1900   [(set (match_operand:TI 0 "nonimmediate_operand")
1901         (match_operand:TI 1 "nonimmediate_operand"))]
1902   "TARGET_64BIT || TARGET_SSE"
1904   if (TARGET_64BIT)
1905     ix86_expand_move (TImode, operands);
1906   else
1907     ix86_expand_vector_move (TImode, operands);
1908   DONE;
1911 ;; This expands to what emit_move_complex would generate if we didn't
1912 ;; have a movti pattern.  Having this avoids problems with reload on
1913 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1914 ;; to have around all the time.
1915 (define_expand "movcdi"
1916   [(set (match_operand:CDI 0 "nonimmediate_operand")
1917         (match_operand:CDI 1 "general_operand"))]
1918   ""
1920   if (push_operand (operands[0], CDImode))
1921     emit_move_complex_push (CDImode, operands[0], operands[1]);
1922   else
1923     emit_move_complex_parts (operands[0], operands[1]);
1924   DONE;
1927 (define_expand "mov<mode>"
1928   [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1929         (match_operand:SWI1248x 1 "general_operand"))]
1930   ""
1931   "ix86_expand_move (<MODE>mode, operands); DONE;")
1933 (define_insn "*mov<mode>_xor"
1934   [(set (match_operand:SWI48 0 "register_operand" "=r")
1935         (match_operand:SWI48 1 "const0_operand"))
1936    (clobber (reg:CC FLAGS_REG))]
1937   "reload_completed"
1938   "xor{l}\t%k0, %k0"
1939   [(set_attr "type" "alu1")
1940    (set_attr "mode" "SI")
1941    (set_attr "length_immediate" "0")])
1943 (define_insn "*mov<mode>_or"
1944   [(set (match_operand:SWI48 0 "register_operand" "=r")
1945         (match_operand:SWI48 1 "const_int_operand"))
1946    (clobber (reg:CC FLAGS_REG))]
1947   "reload_completed
1948    && operands[1] == constm1_rtx"
1949   "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1950   [(set_attr "type" "alu1")
1951    (set_attr "mode" "<MODE>")
1952    (set_attr "length_immediate" "1")])
1954 (define_insn "*movxi_internal_avx512f"
1955   [(set (match_operand:XI 0 "nonimmediate_operand" "=x,x ,m")
1956         (match_operand:XI 1 "vector_move_operand"  "C ,xm,x"))]
1957   "TARGET_AVX512F && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1959   switch (which_alternative)
1960     {
1961     case 0:
1962       return standard_sse_constant_opcode (insn, operands[1]);
1963     case 1:
1964     case 2:
1965       if (misaligned_operand (operands[0], XImode)
1966           || misaligned_operand (operands[1], XImode))
1967         return "vmovdqu32\t{%1, %0|%0, %1}";
1968       else
1969         return "vmovdqa32\t{%1, %0|%0, %1}";
1970     default:
1971       gcc_unreachable ();
1972     }
1974   [(set_attr "type" "sselog1,ssemov,ssemov")
1975    (set_attr "prefix" "evex")
1976    (set_attr "mode" "XI")])
1978 (define_insn "*movoi_internal_avx"
1979   [(set (match_operand:OI 0 "nonimmediate_operand" "=v,v ,m")
1980         (match_operand:OI 1 "vector_move_operand"  "C ,vm,v"))]
1981   "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1983   switch (get_attr_type (insn))
1984     {
1985     case TYPE_SSELOG1:
1986       return standard_sse_constant_opcode (insn, operands[1]);
1988     case TYPE_SSEMOV:
1989       if (misaligned_operand (operands[0], OImode)
1990           || misaligned_operand (operands[1], OImode))
1991         {
1992           if (get_attr_mode (insn) == MODE_V8SF)
1993             return "vmovups\t{%1, %0|%0, %1}";
1994           else if (get_attr_mode (insn) == MODE_XI)
1995             return "vmovdqu32\t{%1, %0|%0, %1}";
1996           else
1997             return "vmovdqu\t{%1, %0|%0, %1}";
1998         }
1999       else
2000         {
2001           if (get_attr_mode (insn) == MODE_V8SF)
2002             return "vmovaps\t{%1, %0|%0, %1}";
2003           else if (get_attr_mode (insn) == MODE_XI)
2004             return "vmovdqa32\t{%1, %0|%0, %1}";
2005           else
2006             return "vmovdqa\t{%1, %0|%0, %1}";
2007         }
2009     default:
2010       gcc_unreachable ();
2011     }
2013   [(set_attr "type" "sselog1,ssemov,ssemov")
2014    (set_attr "prefix" "vex")
2015    (set (attr "mode")
2016         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2017                     (match_operand 1 "ext_sse_reg_operand"))
2018                  (const_string "XI")
2019                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2020                  (const_string "V8SF")
2021                (and (eq_attr "alternative" "2")
2022                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2023                  (const_string "V8SF")
2024               ]
2025               (const_string "OI")))])
2027 (define_insn "*movti_internal"
2028   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,v,v ,m")
2029         (match_operand:TI 1 "general_operand"      "riFo,re,C,vm,v"))]
2030   "(TARGET_64BIT || TARGET_SSE)
2031    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2033   switch (get_attr_type (insn))
2034     {
2035     case TYPE_MULTI:
2036       return "#";
2038     case TYPE_SSELOG1:
2039       return standard_sse_constant_opcode (insn, operands[1]);
2041     case TYPE_SSEMOV:
2042       /* TDmode values are passed as TImode on the stack.  Moving them
2043          to stack may result in unaligned memory access.  */
2044       if (misaligned_operand (operands[0], TImode)
2045           || misaligned_operand (operands[1], TImode))
2046         {
2047           if (get_attr_mode (insn) == MODE_V4SF)
2048             return "%vmovups\t{%1, %0|%0, %1}";
2049           else if (get_attr_mode (insn) == MODE_XI)
2050             return "vmovdqu32\t{%1, %0|%0, %1}";
2051           else
2052             return "%vmovdqu\t{%1, %0|%0, %1}";
2053         }
2054       else
2055         {
2056           if (get_attr_mode (insn) == MODE_V4SF)
2057             return "%vmovaps\t{%1, %0|%0, %1}";
2058           else if (get_attr_mode (insn) == MODE_XI)
2059             return "vmovdqa32\t{%1, %0|%0, %1}";
2060           else
2061             return "%vmovdqa\t{%1, %0|%0, %1}";
2062         }
2064     default:
2065       gcc_unreachable ();
2066     }
2068   [(set_attr "isa" "x64,x64,*,*,*")
2069    (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
2070    (set (attr "prefix")
2071      (if_then_else (eq_attr "type" "sselog1,ssemov")
2072        (const_string "maybe_vex")
2073        (const_string "orig")))
2074    (set (attr "mode")
2075         (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2076                     (match_operand 1 "ext_sse_reg_operand"))
2077                  (const_string "XI")
2078                (eq_attr "alternative" "0,1")
2079                  (const_string "DI")
2080                (ior (not (match_test "TARGET_SSE2"))
2081                     (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2082                  (const_string "V4SF")
2083                (and (eq_attr "alternative" "4")
2084                     (match_test "TARGET_SSE_TYPELESS_STORES"))
2085                  (const_string "V4SF")
2086                (match_test "TARGET_AVX")
2087                  (const_string "TI")
2088                (match_test "optimize_function_for_size_p (cfun)")
2089                  (const_string "V4SF")
2090                ]
2091                (const_string "TI")))])
2093 (define_split
2094   [(set (match_operand:TI 0 "nonimmediate_operand")
2095         (match_operand:TI 1 "general_operand"))]
2096   "reload_completed
2097    && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
2098   [(const_int 0)]
2099   "ix86_split_long_move (operands); DONE;")
2101 (define_insn "*movdi_internal"
2102   [(set (match_operand:DI 0 "nonimmediate_operand"
2103     "=r  ,o  ,r,r  ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*v,*v,*v,m ,?r ,?r,?*Yi,?*Ym,?*Yi,*k,*k ,*r ,*m")
2104         (match_operand:DI 1 "general_operand"
2105     "riFo,riF,Z,rem,i,re,C ,*y,m  ,*y,*Yn,r   ,C ,*v,m ,*v,*Yj,*v,r   ,*Yj ,*Yn ,*r ,*km,*k,*k"))]
2106   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2108   switch (get_attr_type (insn))
2109     {
2110     case TYPE_MSKMOV:
2111       return "kmovq\t{%1, %0|%0, %1}";
2113     case TYPE_MULTI:
2114       return "#";
2116     case TYPE_MMX:
2117       return "pxor\t%0, %0";
2119     case TYPE_MMXMOV:
2120       /* Handle broken assemblers that require movd instead of movq.  */
2121       if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2122           && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2123         return "movd\t{%1, %0|%0, %1}";
2124       return "movq\t{%1, %0|%0, %1}";
2126     case TYPE_SSELOG1:
2127       if (GENERAL_REG_P (operands[0]))
2128         return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
2130       return standard_sse_constant_opcode (insn, operands[1]);
2132     case TYPE_SSEMOV:
2133       switch (get_attr_mode (insn))
2134         {
2135         case MODE_DI:
2136           /* Handle broken assemblers that require movd instead of movq.  */
2137           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
2138               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
2139             return "%vmovd\t{%1, %0|%0, %1}";
2140           return "%vmovq\t{%1, %0|%0, %1}";
2141         case MODE_TI:
2142           return "%vmovdqa\t{%1, %0|%0, %1}";
2143         case MODE_XI:
2144           return "vmovdqa64\t{%g1, %g0|%g0, %g1}";
2146         case MODE_V2SF:
2147           gcc_assert (!TARGET_AVX);
2148           return "movlps\t{%1, %0|%0, %1}";
2149         case MODE_V4SF:
2150           return "%vmovaps\t{%1, %0|%0, %1}";
2152         default:
2153           gcc_unreachable ();
2154         }
2156     case TYPE_SSECVT:
2157       if (SSE_REG_P (operands[0]))
2158         return "movq2dq\t{%1, %0|%0, %1}";
2159       else
2160         return "movdq2q\t{%1, %0|%0, %1}";
2162     case TYPE_LEA:
2163       return "lea{q}\t{%E1, %0|%0, %E1}";
2165     case TYPE_IMOV:
2166       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2167       if (get_attr_mode (insn) == MODE_SI)
2168         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2169       else if (which_alternative == 4)
2170         return "movabs{q}\t{%1, %0|%0, %1}";
2171       else if (ix86_use_lea_for_mov (insn, operands))
2172         return "lea{q}\t{%E1, %0|%0, %E1}";
2173       else
2174         return "mov{q}\t{%1, %0|%0, %1}";
2176     default:
2177       gcc_unreachable ();
2178     }
2180   [(set (attr "isa")
2181      (cond [(eq_attr "alternative" "0,1")
2182               (const_string "nox64")
2183             (eq_attr "alternative" "2,3,4,5,10,11,16,18,21,23")
2184               (const_string "x64")
2185             (eq_attr "alternative" "17")
2186               (const_string "x64_sse4")
2187            ]
2188            (const_string "*")))
2189    (set (attr "type")
2190      (cond [(eq_attr "alternative" "0,1")
2191               (const_string "multi")
2192             (eq_attr "alternative" "6")
2193               (const_string "mmx")
2194             (eq_attr "alternative" "7,8,9,10,11")
2195               (const_string "mmxmov")
2196             (eq_attr "alternative" "12,17")
2197               (const_string "sselog1")
2198             (eq_attr "alternative" "13,14,15,16,18")
2199               (const_string "ssemov")
2200             (eq_attr "alternative" "19,20")
2201               (const_string "ssecvt")
2202             (eq_attr "alternative" "21,22,23,24")
2203               (const_string "mskmov")
2204             (match_operand 1 "pic_32bit_operand")
2205               (const_string "lea")
2206            ]
2207            (const_string "imov")))
2208    (set (attr "modrm")
2209      (if_then_else
2210        (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2211          (const_string "0")
2212          (const_string "*")))
2213    (set (attr "length_immediate")
2214      (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
2215               (const_string "8")
2216             (eq_attr "alternative" "17")
2217               (const_string "1")
2218            ]
2219            (const_string "*")))
2220    (set (attr "prefix_rex")
2221      (if_then_else (eq_attr "alternative" "10,11,16,17,18")
2222        (const_string "1")
2223        (const_string "*")))
2224    (set (attr "prefix_extra")
2225      (if_then_else (eq_attr "alternative" "17")
2226        (const_string "1")
2227        (const_string "*")))
2228    (set (attr "prefix")
2229      (if_then_else (eq_attr "type" "sselog1,ssemov")
2230        (const_string "maybe_vex")
2231        (const_string "orig")))
2232    (set (attr "prefix_data16")
2233      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2234        (const_string "1")
2235        (const_string "*")))
2236    (set (attr "mode")
2237      (cond [(eq_attr "alternative" "2")
2238               (const_string "SI")
2239             (eq_attr "alternative" "12,13")
2240               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2241                           (match_operand 1 "ext_sse_reg_operand"))
2242                        (const_string "XI")
2243                      (ior (not (match_test "TARGET_SSE2"))
2244                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2245                        (const_string "V4SF")
2246                      (match_test "TARGET_AVX")
2247                        (const_string "TI")
2248                      (match_test "optimize_function_for_size_p (cfun)")
2249                        (const_string "V4SF")
2250                     ]
2251                     (const_string "TI"))
2253             (and (eq_attr "alternative" "14,15")
2254                  (not (match_test "TARGET_SSE2")))
2255               (const_string "V2SF")
2256             (eq_attr "alternative" "17")
2257               (const_string "TI")
2258            ]
2259            (const_string "DI")))])
2261 (define_split
2262   [(set (match_operand:DI 0 "nonimmediate_operand")
2263         (match_operand:DI 1 "general_operand"))]
2264   "!TARGET_64BIT && reload_completed
2265    && !(MMX_REG_P (operands[0])
2266         || SSE_REG_P (operands[0])
2267         || MASK_REG_P (operands[0]))
2268    && !(MMX_REG_P (operands[1])
2269         || SSE_REG_P (operands[1])
2270         || MASK_REG_P (operands[1]))"
2271   [(const_int 0)]
2272   "ix86_split_long_move (operands); DONE;")
2274 (define_insn "*movsi_internal"
2275   [(set (match_operand:SI 0 "nonimmediate_operand"
2276                         "=r,m ,*y,*y,?rm,?*y,*v,*v,*v,m ,?r ,?r,?*Yi,*k  ,*rm")
2277         (match_operand:SI 1 "general_operand"
2278                         "g ,re,C ,*y,*y ,rm ,C ,*v,m ,*v,*Yj,*v,r   ,*krm,*k"))]
2279   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2281   switch (get_attr_type (insn))
2282     {
2283     case TYPE_SSELOG1:
2284       if (GENERAL_REG_P (operands[0]))
2285         return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2287       return standard_sse_constant_opcode (insn, operands[1]);
2289     case TYPE_MSKMOV:
2290       return "kmovd\t{%1, %0|%0, %1}";
2292     case TYPE_SSEMOV:
2293       switch (get_attr_mode (insn))
2294         {
2295         case MODE_SI:
2296           return "%vmovd\t{%1, %0|%0, %1}";
2297         case MODE_TI:
2298           return "%vmovdqa\t{%1, %0|%0, %1}";
2299         case MODE_XI:
2300           return "vmovdqa32\t{%g1, %g0|%g0, %g1}";
2302         case MODE_V4SF:
2303           return "%vmovaps\t{%1, %0|%0, %1}";
2305         case MODE_SF:
2306           gcc_assert (!TARGET_AVX);
2307           return "movss\t{%1, %0|%0, %1}";
2309         default:
2310           gcc_unreachable ();
2311         }
2313     case TYPE_MMX:
2314       return "pxor\t%0, %0";
2316     case TYPE_MMXMOV:
2317       switch (get_attr_mode (insn))
2318         {
2319         case MODE_DI:
2320           return "movq\t{%1, %0|%0, %1}";
2321         case MODE_SI:
2322           return "movd\t{%1, %0|%0, %1}";
2324         default:
2325           gcc_unreachable ();
2326         }
2328     case TYPE_LEA:
2329       return "lea{l}\t{%E1, %0|%0, %E1}";
2331     case TYPE_IMOV:
2332       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2333       if (ix86_use_lea_for_mov (insn, operands))
2334         return "lea{l}\t{%E1, %0|%0, %E1}";
2335       else
2336         return "mov{l}\t{%1, %0|%0, %1}";
2338     default:
2339       gcc_unreachable ();
2340     }
2342   [(set (attr "isa")
2343      (if_then_else (eq_attr "alternative" "11")
2344        (const_string "sse4")
2345        (const_string "*")))
2346    (set (attr "type")
2347      (cond [(eq_attr "alternative" "2")
2348               (const_string "mmx")
2349             (eq_attr "alternative" "3,4,5")
2350               (const_string "mmxmov")
2351             (eq_attr "alternative" "6,11")
2352               (const_string "sselog1")
2353             (eq_attr "alternative" "7,8,9,10,12")
2354               (const_string "ssemov")
2355             (eq_attr "alternative" "13,14")
2356               (const_string "mskmov")
2357             (match_operand 1 "pic_32bit_operand")
2358               (const_string "lea")
2359            ]
2360            (const_string "imov")))
2361    (set (attr "length_immediate")
2362      (if_then_else (eq_attr "alternative" "11")
2363        (const_string "1")
2364        (const_string "*")))
2365    (set (attr "prefix_extra")
2366      (if_then_else (eq_attr "alternative" "11")
2367        (const_string "1")
2368        (const_string "*")))
2369    (set (attr "prefix")
2370      (if_then_else (eq_attr "type" "sselog1,ssemov")
2371        (const_string "maybe_vex")
2372        (const_string "orig")))
2373    (set (attr "prefix_data16")
2374      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2375        (const_string "1")
2376        (const_string "*")))
2377    (set (attr "mode")
2378      (cond [(eq_attr "alternative" "2,3")
2379               (const_string "DI")
2380             (eq_attr "alternative" "6,7")
2381               (cond [(ior (match_operand 0 "ext_sse_reg_operand")
2382                           (match_operand 1 "ext_sse_reg_operand"))
2383                        (const_string "XI")
2384                      (ior (not (match_test "TARGET_SSE2"))
2385                           (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2386                        (const_string "V4SF")
2387                      (match_test "TARGET_AVX")
2388                        (const_string "TI")
2389                      (match_test "optimize_function_for_size_p (cfun)")
2390                        (const_string "V4SF")
2391                     ]
2392                     (const_string "TI"))
2394             (and (eq_attr "alternative" "8,9")
2395                  (not (match_test "TARGET_SSE2")))
2396               (const_string "SF")
2397             (eq_attr "alternative" "11")
2398               (const_string "TI")
2399            ]
2400            (const_string "SI")))])
2402 (define_insn "kmovw"
2403   [(set (match_operand:HI 0 "nonimmediate_operand" "=k,k")
2404         (unspec:HI
2405           [(match_operand:HI 1 "nonimmediate_operand" "rm,k")]
2406           UNSPEC_KMOV))]
2407   "!(MEM_P (operands[0]) && MEM_P (operands[1])) && TARGET_AVX512F"
2408   "@
2409    kmovw\t{%k1, %0|%0, %k1}
2410    kmovw\t{%1, %0|%0, %1}";
2411   [(set_attr "mode" "HI")
2412    (set_attr "type" "mskmov")
2413    (set_attr "prefix" "vex")])
2416 (define_insn "*movhi_internal"
2417   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m ,k,k,rm")
2418         (match_operand:HI 1 "general_operand"      "r ,rn,rm,rn,rm,k,k"))]
2419   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2421   switch (get_attr_type (insn))
2422     {
2423     case TYPE_IMOVX:
2424       /* movzwl is faster than movw on p2 due to partial word stalls,
2425          though not as fast as an aligned movl.  */
2426       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2428     case TYPE_MSKMOV:
2429       switch (which_alternative)
2430         {
2431         case 4: return "kmovw\t{%k1, %0|%0, %k1}";
2432         case 5: return "kmovw\t{%1, %0|%0, %1}";
2433         case 6: return "kmovw\t{%1, %k0|%k0, %1}";
2434         default: gcc_unreachable ();
2435         }
2437     default:
2438       if (get_attr_mode (insn) == MODE_SI)
2439         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2440       else
2441         return "mov{w}\t{%1, %0|%0, %1}";
2442     }
2444   [(set (attr "type")
2445      (cond [(eq_attr "alternative" "4,5,6")
2446               (const_string "mskmov")
2447             (match_test "optimize_function_for_size_p (cfun)")
2448               (const_string "imov")
2449             (and (eq_attr "alternative" "0")
2450                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2451                       (not (match_test "TARGET_HIMODE_MATH"))))
2452               (const_string "imov")
2453             (and (eq_attr "alternative" "1,2")
2454                  (match_operand:HI 1 "aligned_operand"))
2455               (const_string "imov")
2456             (and (match_test "TARGET_MOVX")
2457                  (eq_attr "alternative" "0,2"))
2458               (const_string "imovx")
2459            ]
2460            (const_string "imov")))
2461     (set (attr "prefix")
2462       (if_then_else (eq_attr "alternative" "4,5,6")
2463         (const_string "vex")
2464         (const_string "orig")))
2465     (set (attr "mode")
2466       (cond [(eq_attr "type" "imovx")
2467                (const_string "SI")
2468              (and (eq_attr "alternative" "1,2")
2469                   (match_operand:HI 1 "aligned_operand"))
2470                (const_string "SI")
2471              (and (eq_attr "alternative" "0")
2472                   (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2473                        (not (match_test "TARGET_HIMODE_MATH"))))
2474                (const_string "SI")
2475             ]
2476             (const_string "HI")))])
2478 ;; Situation is quite tricky about when to choose full sized (SImode) move
2479 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
2480 ;; partial register dependency machines (such as AMD Athlon), where QImode
2481 ;; moves issue extra dependency and for partial register stalls machines
2482 ;; that don't use QImode patterns (and QImode move cause stall on the next
2483 ;; instruction).
2485 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2486 ;; register stall machines with, where we use QImode instructions, since
2487 ;; partial register stall can be caused there.  Then we use movzx.
2489 (define_insn "*movqi_internal"
2490   [(set (match_operand:QI 0 "nonimmediate_operand"
2491                         "=q,q ,q ,r,r ,?r,m ,k,k,r ,m,k")
2492         (match_operand:QI 1 "general_operand"
2493                         "q ,qn,qm,q,rn,qm,qn,r ,k,k,k,m"))]
2494   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2496   switch (get_attr_type (insn))
2497     {
2498     case TYPE_IMOVX:
2499       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2500       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2502     case TYPE_MSKMOV:
2503       switch (which_alternative)
2504         {
2505         case 7: return TARGET_AVX512DQ ? "kmovb\t{%k1, %0|%0, %k1}"
2506                                        : "kmovw\t{%k1, %0|%0, %k1}";
2507         case 8: return TARGET_AVX512DQ ? "kmovb\t{%1, %0|%0, %1}"
2508                                        : "kmovw\t{%1, %0|%0, %1}";
2509         case 9: return TARGET_AVX512DQ ? "kmovb\t{%1, %k0|%k0, %1}"
2510                                        : "kmovw\t{%1, %k0|%k0, %1}";
2511         case 10:
2512         case 11:
2513           gcc_assert (TARGET_AVX512DQ);
2514           return "kmovb\t{%1, %0|%0, %1}";
2515         default: gcc_unreachable ();
2516         }
2518     default:
2519       if (get_attr_mode (insn) == MODE_SI)
2520         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2521       else
2522         return "mov{b}\t{%1, %0|%0, %1}";
2523     }
2525   [(set_attr "isa" "*,*,*,*,*,*,*,*,*,*,avx512dq,avx512dq")
2526    (set (attr "type")
2527      (cond [(eq_attr "alternative" "3,5")
2528               (const_string "imovx")
2529             (eq_attr "alternative" "7,8,9,10,11")
2530               (const_string "mskmov")
2531             (and (eq_attr "alternative" "5")
2532                  (not (match_operand:QI 1 "aligned_operand")))
2533               (const_string "imovx")
2534             (match_test "optimize_function_for_size_p (cfun)")
2535               (const_string "imov")
2536             (and (eq_attr "alternative" "3")
2537                  (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2538                       (not (match_test "TARGET_QIMODE_MATH"))))
2539               (const_string "imov")
2540             (and (match_test "TARGET_MOVX")
2541                  (eq_attr "alternative" "2"))
2542               (const_string "imovx")
2543            ]
2544            (const_string "imov")))
2545    (set (attr "prefix")
2546      (if_then_else (eq_attr "alternative" "7,8,9")
2547        (const_string "vex")
2548        (const_string "orig")))
2549    (set (attr "mode")
2550       (cond [(eq_attr "alternative" "3,4,5")
2551                (const_string "SI")
2552              (eq_attr "alternative" "6")
2553                (const_string "QI")
2554              (eq_attr "type" "imovx")
2555                (const_string "SI")
2556              (and (eq_attr "type" "imov")
2557                   (and (eq_attr "alternative" "0,1")
2558                        (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2559                             (and (not (match_test "optimize_function_for_size_p (cfun)"))
2560                                  (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2561                (const_string "SI")
2562              ;; Avoid partial register stalls when not using QImode arithmetic
2563              (and (eq_attr "type" "imov")
2564                   (and (eq_attr "alternative" "0,1")
2565                        (and (match_test "TARGET_PARTIAL_REG_STALL")
2566                             (not (match_test "TARGET_QIMODE_MATH")))))
2567                (const_string "SI")
2568            ]
2569            (const_string "QI")))])
2571 ;; Stores and loads of ax to arbitrary constant address.
2572 ;; We fake an second form of instruction to force reload to load address
2573 ;; into register when rax is not available
2574 (define_insn "*movabs<mode>_1"
2575   [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2576         (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2577   "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2578   "@
2579    movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2580    mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2581   [(set_attr "type" "imov")
2582    (set_attr "modrm" "0,*")
2583    (set_attr "length_address" "8,0")
2584    (set_attr "length_immediate" "0,*")
2585    (set_attr "memory" "store")
2586    (set_attr "mode" "<MODE>")])
2588 (define_insn "*movabs<mode>_2"
2589   [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2590         (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2591   "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2592   "@
2593    movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2594    mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2595   [(set_attr "type" "imov")
2596    (set_attr "modrm" "0,*")
2597    (set_attr "length_address" "8,0")
2598    (set_attr "length_immediate" "0")
2599    (set_attr "memory" "load")
2600    (set_attr "mode" "<MODE>")])
2602 (define_insn "*swap<mode>"
2603   [(set (match_operand:SWI48 0 "register_operand" "+r")
2604         (match_operand:SWI48 1 "register_operand" "+r"))
2605    (set (match_dup 1)
2606         (match_dup 0))]
2607   ""
2608   "xchg{<imodesuffix>}\t%1, %0"
2609   [(set_attr "type" "imov")
2610    (set_attr "mode" "<MODE>")
2611    (set_attr "pent_pair" "np")
2612    (set_attr "athlon_decode" "vector")
2613    (set_attr "amdfam10_decode" "double")
2614    (set_attr "bdver1_decode" "double")])
2616 (define_insn "*swap<mode>_1"
2617   [(set (match_operand:SWI12 0 "register_operand" "+r")
2618         (match_operand:SWI12 1 "register_operand" "+r"))
2619    (set (match_dup 1)
2620         (match_dup 0))]
2621   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2622   "xchg{l}\t%k1, %k0"
2623   [(set_attr "type" "imov")
2624    (set_attr "mode" "SI")
2625    (set_attr "pent_pair" "np")
2626    (set_attr "athlon_decode" "vector")
2627    (set_attr "amdfam10_decode" "double")
2628    (set_attr "bdver1_decode" "double")])
2630 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2631 ;; is disabled for AMDFAM10
2632 (define_insn "*swap<mode>_2"
2633   [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2634         (match_operand:SWI12 1 "register_operand" "+<r>"))
2635    (set (match_dup 1)
2636         (match_dup 0))]
2637   "TARGET_PARTIAL_REG_STALL"
2638   "xchg{<imodesuffix>}\t%1, %0"
2639   [(set_attr "type" "imov")
2640    (set_attr "mode" "<MODE>")
2641    (set_attr "pent_pair" "np")
2642    (set_attr "athlon_decode" "vector")])
2644 (define_expand "movstrict<mode>"
2645   [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2646         (match_operand:SWI12 1 "general_operand"))]
2647   ""
2649   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2650     FAIL;
2651   if (GET_CODE (operands[0]) == SUBREG
2652       && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2653     FAIL;
2654   /* Don't generate memory->memory moves, go through a register */
2655   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2656     operands[1] = force_reg (<MODE>mode, operands[1]);
2659 (define_insn "*movstrict<mode>_1"
2660   [(set (strict_low_part
2661           (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2662         (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2663   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2664    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2665   "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2666   [(set_attr "type" "imov")
2667    (set_attr "mode" "<MODE>")])
2669 (define_insn "*movstrict<mode>_xor"
2670   [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2671         (match_operand:SWI12 1 "const0_operand"))
2672    (clobber (reg:CC FLAGS_REG))]
2673   "reload_completed"
2674   "xor{<imodesuffix>}\t%0, %0"
2675   [(set_attr "type" "alu1")
2676    (set_attr "mode" "<MODE>")
2677    (set_attr "length_immediate" "0")])
2679 (define_insn "*mov<mode>_extv_1"
2680   [(set (match_operand:SWI24 0 "register_operand" "=R")
2681         (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2682                             (const_int 8)
2683                             (const_int 8)))]
2684   ""
2685   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2686   [(set_attr "type" "imovx")
2687    (set_attr "mode" "SI")])
2689 (define_insn "*movqi_extv_1"
2690   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2691         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2692                          (const_int 8)
2693                          (const_int 8)))]
2694   ""
2696   switch (get_attr_type (insn))
2697     {
2698     case TYPE_IMOVX:
2699       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2700     default:
2701       return "mov{b}\t{%h1, %0|%0, %h1}";
2702     }
2704   [(set_attr "isa" "*,*,nox64")
2705    (set (attr "type")
2706      (if_then_else (and (match_operand:QI 0 "register_operand")
2707                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2708                              (match_test "TARGET_MOVX")))
2709         (const_string "imovx")
2710         (const_string "imov")))
2711    (set (attr "mode")
2712      (if_then_else (eq_attr "type" "imovx")
2713         (const_string "SI")
2714         (const_string "QI")))])
2716 (define_insn "*mov<mode>_extzv_1"
2717   [(set (match_operand:SWI48 0 "register_operand" "=R")
2718         (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2719                             (const_int 8)
2720                             (const_int 8)))]
2721   ""
2722   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2723   [(set_attr "type" "imovx")
2724    (set_attr "mode" "SI")])
2726 (define_insn "*movqi_extzv_2"
2727   [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2728         (subreg:QI
2729           (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2730                            (const_int 8)
2731                            (const_int 8)) 0))]
2732   ""
2734   switch (get_attr_type (insn))
2735     {
2736     case TYPE_IMOVX:
2737       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2738     default:
2739       return "mov{b}\t{%h1, %0|%0, %h1}";
2740     }
2742   [(set_attr "isa" "*,*,nox64")
2743    (set (attr "type")
2744      (if_then_else (and (match_operand:QI 0 "register_operand")
2745                         (ior (not (match_operand:QI 0 "QIreg_operand"))
2746                              (match_test "TARGET_MOVX")))
2747         (const_string "imovx")
2748         (const_string "imov")))
2749    (set (attr "mode")
2750      (if_then_else (eq_attr "type" "imovx")
2751         (const_string "SI")
2752         (const_string "QI")))])
2754 (define_insn "mov<mode>_insv_1"
2755   [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2756                              (const_int 8)
2757                              (const_int 8))
2758         (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2759   ""
2761   if (CONST_INT_P (operands[1]))
2762     operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2763   return "mov{b}\t{%b1, %h0|%h0, %b1}";
2765   [(set_attr "isa" "*,nox64")
2766    (set_attr "type" "imov")
2767    (set_attr "mode" "QI")])
2769 (define_insn "*movqi_insv_2"
2770   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2771                          (const_int 8)
2772                          (const_int 8))
2773         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2774                      (const_int 8)))]
2775   ""
2776   "mov{b}\t{%h1, %h0|%h0, %h1}"
2777   [(set_attr "type" "imov")
2778    (set_attr "mode" "QI")])
2780 ;; Floating point push instructions.
2782 (define_insn "*pushtf"
2783   [(set (match_operand:TF 0 "push_operand" "=<,<")
2784         (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2785   "TARGET_64BIT || TARGET_SSE"
2787   /* This insn should be already split before reg-stack.  */
2788   gcc_unreachable ();
2790   [(set_attr "isa" "*,x64")
2791    (set_attr "type" "multi")
2792    (set_attr "unit" "sse,*")
2793    (set_attr "mode" "TF,DI")])
2795 ;; %%% Kill this when call knows how to work this out.
2796 (define_split
2797   [(set (match_operand:TF 0 "push_operand")
2798         (match_operand:TF 1 "sse_reg_operand"))]
2799   "TARGET_SSE && reload_completed"
2800   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2801    (set (match_dup 0) (match_dup 1))]
2803   /* Preserve memory attributes. */
2804   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2807 (define_insn "*pushxf"
2808   [(set (match_operand:XF 0 "push_operand" "=<,<")
2809         (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2810   ""
2812   /* This insn should be already split before reg-stack.  */
2813   gcc_unreachable ();
2815   [(set_attr "type" "multi")
2816    (set_attr "unit" "i387,*")
2817    (set (attr "mode")
2818         (cond [(eq_attr "alternative" "1")
2819                  (if_then_else (match_test "TARGET_64BIT")
2820                    (const_string "DI")
2821                    (const_string "SI"))
2822               ]
2823               (const_string "XF")))])
2825 ;; %%% Kill this when call knows how to work this out.
2826 (define_split
2827   [(set (match_operand:XF 0 "push_operand")
2828         (match_operand:XF 1 "fp_register_operand"))]
2829   "reload_completed"
2830   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2831    (set (match_dup 0) (match_dup 1))]
2833   operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));
2834   /* Preserve memory attributes. */
2835   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2838 (define_insn "*pushdf"
2839   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2840         (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2841   ""
2843   /* This insn should be already split before reg-stack.  */
2844   gcc_unreachable ();
2846   [(set_attr "isa" "*,nox64,x64,sse2")
2847    (set_attr "type" "multi")
2848    (set_attr "unit" "i387,*,*,sse")
2849    (set_attr "mode" "DF,SI,DI,DF")])
2851 ;; %%% Kill this when call knows how to work this out.
2852 (define_split
2853   [(set (match_operand:DF 0 "push_operand")
2854         (match_operand:DF 1 "any_fp_register_operand"))]
2855   "reload_completed"
2856   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2857    (set (match_dup 0) (match_dup 1))]
2859   /* Preserve memory attributes. */
2860   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2863 (define_insn "*pushsf_rex64"
2864   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2865         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2866   "TARGET_64BIT"
2868   /* Anything else should be already split before reg-stack.  */
2869   gcc_assert (which_alternative == 1);
2870   return "push{q}\t%q1";
2872   [(set_attr "type" "multi,push,multi")
2873    (set_attr "unit" "i387,*,*")
2874    (set_attr "mode" "SF,DI,SF")])
2876 (define_insn "*pushsf"
2877   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2878         (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2879   "!TARGET_64BIT"
2881   /* Anything else should be already split before reg-stack.  */
2882   gcc_assert (which_alternative == 1);
2883   return "push{l}\t%1";
2885   [(set_attr "type" "multi,push,multi")
2886    (set_attr "unit" "i387,*,*")
2887    (set_attr "mode" "SF,SI,SF")])
2889 ;; %%% Kill this when call knows how to work this out.
2890 (define_split
2891   [(set (match_operand:SF 0 "push_operand")
2892         (match_operand:SF 1 "any_fp_register_operand"))]
2893   "reload_completed"
2894   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2895    (set (match_dup 0) (match_dup 1))]
2897   rtx op = XEXP (operands[0], 0);
2898   if (GET_CODE (op) == PRE_DEC)
2899     {
2900       gcc_assert (!TARGET_64BIT);
2901       op = GEN_INT (-4);
2902     }
2903   else
2904     {
2905       op = XEXP (XEXP (op, 1), 1);
2906       gcc_assert (CONST_INT_P (op));
2907     }
2908   operands[2] = op;
2909   /* Preserve memory attributes. */
2910   operands[0] = replace_equiv_address (operands[0], stack_pointer_rtx);
2913 (define_split
2914   [(set (match_operand:SF 0 "push_operand")
2915         (match_operand:SF 1 "memory_operand"))]
2916   "reload_completed
2917    && (operands[2] = find_constant_src (insn))"
2918   [(set (match_dup 0) (match_dup 2))])
2920 (define_split
2921   [(set (match_operand 0 "push_operand")
2922         (match_operand 1 "general_operand"))]
2923   "reload_completed
2924    && (GET_MODE (operands[0]) == TFmode
2925        || GET_MODE (operands[0]) == XFmode
2926        || GET_MODE (operands[0]) == DFmode)
2927    && !ANY_FP_REG_P (operands[1])"
2928   [(const_int 0)]
2929   "ix86_split_long_move (operands); DONE;")
2931 ;; Floating point move instructions.
2933 (define_expand "movtf"
2934   [(set (match_operand:TF 0 "nonimmediate_operand")
2935         (match_operand:TF 1 "nonimmediate_operand"))]
2936   "TARGET_64BIT || TARGET_SSE"
2937   "ix86_expand_move (TFmode, operands); DONE;")
2939 (define_expand "mov<mode>"
2940   [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2941         (match_operand:X87MODEF 1 "general_operand"))]
2942   ""
2943   "ix86_expand_move (<MODE>mode, operands); DONE;")
2945 (define_insn "*movtf_internal"
2946   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2947         (match_operand:TF 1 "general_operand"      "C ,xm,x,*roF,*rC"))]
2948   "(TARGET_64BIT || TARGET_SSE)
2949    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2950    && (!can_create_pseudo_p ()
2951        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2952        || GET_CODE (operands[1]) != CONST_DOUBLE
2953        || (optimize_function_for_size_p (cfun)
2954            && standard_sse_constant_p (operands[1])
2955            && !memory_operand (operands[0], TFmode))
2956        || (!TARGET_MEMORY_MISMATCH_STALL
2957            && memory_operand (operands[0], TFmode)))"
2959   switch (get_attr_type (insn))
2960     {
2961     case TYPE_SSELOG1:
2962       return standard_sse_constant_opcode (insn, operands[1]);
2964     case TYPE_SSEMOV:
2965       /* Handle misaligned load/store since we
2966          don't have movmisaligntf pattern. */
2967       if (misaligned_operand (operands[0], TFmode)
2968           || misaligned_operand (operands[1], TFmode))
2969         {
2970           if (get_attr_mode (insn) == MODE_V4SF)
2971             return "%vmovups\t{%1, %0|%0, %1}";
2972           else
2973             return "%vmovdqu\t{%1, %0|%0, %1}";
2974         }
2975       else
2976         {
2977           if (get_attr_mode (insn) == MODE_V4SF)
2978             return "%vmovaps\t{%1, %0|%0, %1}";
2979           else
2980             return "%vmovdqa\t{%1, %0|%0, %1}";
2981         }
2983     case TYPE_MULTI:
2984         return "#";
2986     default:
2987       gcc_unreachable ();
2988     }
2990   [(set_attr "isa" "*,*,*,x64,x64")
2991    (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2992    (set (attr "prefix")
2993      (if_then_else (eq_attr "type" "sselog1,ssemov")
2994        (const_string "maybe_vex")
2995        (const_string "orig")))
2996    (set (attr "mode")
2997         (cond [(eq_attr "alternative" "3,4")
2998                  (const_string "DI")
2999                (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3000                  (const_string "V4SF")
3001                (and (eq_attr "alternative" "2")
3002                     (match_test "TARGET_SSE_TYPELESS_STORES"))
3003                  (const_string "V4SF")
3004                (match_test "TARGET_AVX")
3005                  (const_string "TI")
3006                (ior (not (match_test "TARGET_SSE2"))
3007                     (match_test "optimize_function_for_size_p (cfun)"))
3008                  (const_string "V4SF")
3009                ]
3010                (const_string "TI")))])
3012 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
3013 (define_insn "*movxf_internal"
3014   [(set (match_operand:XF 0 "nonimmediate_operand"
3015          "=f,m,f,?Yx*r ,!o   ,!o")
3016         (match_operand:XF 1 "general_operand"
3017          "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
3018   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3019    && (!can_create_pseudo_p ()
3020        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3021        || GET_CODE (operands[1]) != CONST_DOUBLE
3022        || (optimize_function_for_size_p (cfun)
3023            && standard_80387_constant_p (operands[1]) > 0
3024            && !memory_operand (operands[0], XFmode))
3025        || (!TARGET_MEMORY_MISMATCH_STALL
3026            && memory_operand (operands[0], XFmode)))"
3028   switch (get_attr_type (insn))
3029     {
3030     case TYPE_FMOV:
3031       if (which_alternative == 2)
3032         return standard_80387_constant_opcode (operands[1]);
3033       return output_387_reg_move (insn, operands);
3035     case TYPE_MULTI:
3036       return "#";
3038     default:
3039       gcc_unreachable ();
3040     }
3042   [(set_attr "isa" "*,*,*,*,nox64,x64")
3043    (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
3044    (set (attr "mode")
3045         (cond [(eq_attr "alternative" "3,4,5")
3046                  (if_then_else (match_test "TARGET_64BIT")
3047                    (const_string "DI")
3048                    (const_string "SI"))
3049               ]
3050               (const_string "XF")))])
3052 ;; Possible store forwarding (partial memory) stall in alternative 4.
3053 (define_insn "*movdf_internal"
3054   [(set (match_operand:DF 0 "nonimmediate_operand"
3055     "=Yf*f,m   ,Yf*f,?Yd*r ,!o   ,?r,?m,?r,?r,v,v,v,m,*x,*x,*x,m ,r ,Yi")
3056         (match_operand:DF 1 "general_operand"
3057     "Yf*fm,Yf*f,G   ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,v,m,v,C ,*x,m ,*x,Yj,r"))]
3058   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3059    && (!can_create_pseudo_p ()
3060        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3061        || GET_CODE (operands[1]) != CONST_DOUBLE
3062        || (optimize_function_for_size_p (cfun)
3063            && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3064                 && standard_80387_constant_p (operands[1]) > 0)
3065                || (TARGET_SSE2 && TARGET_SSE_MATH
3066                    && standard_sse_constant_p (operands[1])))
3067            && !memory_operand (operands[0], DFmode))
3068        || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
3069            && memory_operand (operands[0], DFmode)))"
3071   switch (get_attr_type (insn))
3072     {
3073     case TYPE_FMOV:
3074       if (which_alternative == 2)
3075         return standard_80387_constant_opcode (operands[1]);
3076       return output_387_reg_move (insn, operands);
3078     case TYPE_MULTI:
3079       return "#";
3081     case TYPE_IMOV:
3082       if (get_attr_mode (insn) == MODE_SI)
3083         return "mov{l}\t{%1, %k0|%k0, %1}";
3084       else if (which_alternative == 8)
3085         return "movabs{q}\t{%1, %0|%0, %1}";
3086       else
3087         return "mov{q}\t{%1, %0|%0, %1}";
3089     case TYPE_SSELOG1:
3090       return standard_sse_constant_opcode (insn, operands[1]);
3092     case TYPE_SSEMOV:
3093       switch (get_attr_mode (insn))
3094         {
3095         case MODE_DF:
3096           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3097             return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3098           return "%vmovsd\t{%1, %0|%0, %1}";
3100         case MODE_V4SF:
3101           return "%vmovaps\t{%1, %0|%0, %1}";
3102         case MODE_V8DF:
3103           return "vmovapd\t{%g1, %g0|%g0, %g1}";
3104         case MODE_V2DF:
3105           return "%vmovapd\t{%1, %0|%0, %1}";
3107         case MODE_V2SF:
3108           gcc_assert (!TARGET_AVX);
3109           return "movlps\t{%1, %0|%0, %1}";
3110         case MODE_V1DF:
3111           gcc_assert (!TARGET_AVX);
3112           return "movlpd\t{%1, %0|%0, %1}";
3114         case MODE_DI:
3115           /* Handle broken assemblers that require movd instead of movq.  */
3116           if (!HAVE_AS_IX86_INTERUNIT_MOVQ
3117               && (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1])))
3118             return "%vmovd\t{%1, %0|%0, %1}";
3119           return "%vmovq\t{%1, %0|%0, %1}";
3121         default:
3122           gcc_unreachable ();
3123         }
3125     default:
3126       gcc_unreachable ();
3127     }
3129   [(set (attr "isa")
3130         (cond [(eq_attr "alternative" "3,4")
3131                  (const_string "nox64")
3132                (eq_attr "alternative" "5,6,7,8,17,18")
3133                  (const_string "x64")
3134                (eq_attr "alternative" "9,10,11,12")
3135                  (const_string "sse2")
3136               ]
3137               (const_string "*")))
3138    (set (attr "type")
3139         (cond [(eq_attr "alternative" "0,1,2")
3140                  (const_string "fmov")
3141                (eq_attr "alternative" "3,4")
3142                  (const_string "multi")
3143                (eq_attr "alternative" "5,6,7,8")
3144                  (const_string "imov")
3145                (eq_attr "alternative" "9,13")
3146                  (const_string "sselog1")
3147               ]
3148               (const_string "ssemov")))
3149    (set (attr "modrm")
3150      (if_then_else (eq_attr "alternative" "8")
3151        (const_string "0")
3152        (const_string "*")))
3153    (set (attr "length_immediate")
3154      (if_then_else (eq_attr "alternative" "8")
3155        (const_string "8")
3156        (const_string "*")))
3157    (set (attr "prefix")
3158      (if_then_else (eq_attr "type" "sselog1,ssemov")
3159        (const_string "maybe_vex")
3160        (const_string "orig")))
3161    (set (attr "prefix_data16")
3162      (if_then_else
3163        (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
3164             (eq_attr "mode" "V1DF"))
3165        (const_string "1")
3166        (const_string "*")))
3167    (set (attr "mode")
3168         (cond [(eq_attr "alternative" "3,4,7")
3169                  (const_string "SI")
3170                (eq_attr "alternative" "5,6,8,17,18")
3171                  (const_string "DI")
3173                /* xorps is one byte shorter for non-AVX targets.  */
3174                (eq_attr "alternative" "9,13")
3175                  (cond [(not (match_test "TARGET_SSE2"))
3176                           (const_string "V4SF")
3177                         (match_test "TARGET_AVX512F")
3178                           (const_string "XI")
3179                         (match_test "TARGET_AVX")
3180                           (const_string "V2DF")
3181                         (match_test "optimize_function_for_size_p (cfun)")
3182                           (const_string "V4SF")
3183                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3184                           (const_string "TI")
3185                        ]
3186                        (const_string "V2DF"))
3188                /* For architectures resolving dependencies on
3189                   whole SSE registers use movapd to break dependency
3190                   chains, otherwise use short move to avoid extra work.  */
3192                /* movaps is one byte shorter for non-AVX targets.  */
3193                (eq_attr "alternative" "10,14")
3194                  (cond [(ior (match_operand 0 "ext_sse_reg_operand")
3195                              (match_operand 1 "ext_sse_reg_operand"))
3196                           (const_string "V8DF")
3197                         (ior (not (match_test "TARGET_SSE2"))
3198                              (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
3199                           (const_string "V4SF")
3200                         (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3201                           (const_string "V2DF")
3202                         (match_test "TARGET_AVX")
3203                           (const_string "DF")
3204                         (match_test "optimize_function_for_size_p (cfun)")
3205                           (const_string "V4SF")
3206                        ]
3207                        (const_string "DF"))
3209                /* For architectures resolving dependencies on register
3210                   parts we may avoid extra work to zero out upper part
3211                   of register.  */
3212                (eq_attr "alternative" "11,15")
3213                  (cond [(not (match_test "TARGET_SSE2"))
3214                           (const_string "V2SF")
3215                         (match_test "TARGET_AVX")
3216                           (const_string "DF")
3217                         (match_test "TARGET_SSE_SPLIT_REGS")
3218                           (const_string "V1DF")
3219                        ]
3220                        (const_string "DF"))
3222                (and (eq_attr "alternative" "12,16")
3223                     (not (match_test "TARGET_SSE2")))
3224                  (const_string "V2SF")
3225               ]
3226               (const_string "DF")))])
3228 (define_insn "*movsf_internal"
3229   [(set (match_operand:SF 0 "nonimmediate_operand"
3230           "=Yf*f,m   ,Yf*f,?r ,?m,v,v,v,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
3231         (match_operand:SF 1 "general_operand"
3232           "Yf*fm,Yf*f,G   ,rmF,rF,C,v,m,v,Yj,r  ,*y ,m  ,*y,*Yn,r"))]
3233   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3234    && (!can_create_pseudo_p ()
3235        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3236        || GET_CODE (operands[1]) != CONST_DOUBLE
3237        || (optimize_function_for_size_p (cfun)
3238            && ((!TARGET_SSE_MATH
3239                 && standard_80387_constant_p (operands[1]) > 0)
3240                || (TARGET_SSE_MATH
3241                    && standard_sse_constant_p (operands[1]))))
3242        || memory_operand (operands[0], SFmode))"
3244   switch (get_attr_type (insn))
3245     {
3246     case TYPE_FMOV:
3247       if (which_alternative == 2)
3248         return standard_80387_constant_opcode (operands[1]);
3249       return output_387_reg_move (insn, operands);
3251     case TYPE_IMOV:
3252       return "mov{l}\t{%1, %0|%0, %1}";
3254     case TYPE_SSELOG1:
3255       return standard_sse_constant_opcode (insn, operands[1]);
3257     case TYPE_SSEMOV:
3258       switch (get_attr_mode (insn))
3259         {
3260         case MODE_SF:
3261           if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3262             return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3263           return "%vmovss\t{%1, %0|%0, %1}";
3265         case MODE_V16SF:
3266           return "vmovaps\t{%g1, %g0|%g0, %g1}";
3267         case MODE_V4SF:
3268           return "%vmovaps\t{%1, %0|%0, %1}";
3270         case MODE_SI:
3271           return "%vmovd\t{%1, %0|%0, %1}";
3273         default:
3274           gcc_unreachable ();
3275         }
3277     case TYPE_MMXMOV:
3278       switch (get_attr_mode (insn))
3279         {
3280         case MODE_DI:
3281           return "movq\t{%1, %0|%0, %1}";
3282         case MODE_SI:
3283           return "movd\t{%1, %0|%0, %1}";
3285         default:
3286           gcc_unreachable ();
3287         }
3289     default:
3290       gcc_unreachable ();
3291     }
3293   [(set (attr "type")
3294         (cond [(eq_attr "alternative" "0,1,2")
3295                  (const_string "fmov")
3296                (eq_attr "alternative" "3,4")
3297                  (const_string "imov")
3298                (eq_attr "alternative" "5")
3299                  (const_string "sselog1")
3300                (eq_attr "alternative" "11,12,13,14,15")
3301                  (const_string "mmxmov")
3302               ]
3303               (const_string "ssemov")))
3304    (set (attr "prefix")
3305      (if_then_else (eq_attr "type" "sselog1,ssemov")
3306        (const_string "maybe_vex")
3307        (const_string "orig")))
3308    (set (attr "prefix_data16")
3309      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
3310        (const_string "1")
3311        (const_string "*")))
3312    (set (attr "mode")
3313         (cond [(eq_attr "alternative" "3,4,9,10,12,13,14,15")
3314                  (const_string "SI")
3315                (eq_attr "alternative" "11")
3316                  (const_string "DI")
3317                (eq_attr "alternative" "5")
3318                  (cond [(not (match_test "TARGET_SSE2"))
3319                           (const_string "V4SF")
3320                         (match_test "TARGET_AVX512F")
3321                           (const_string "V16SF")
3322                         (match_test "TARGET_AVX")
3323                           (const_string "V4SF")
3324                         (match_test "optimize_function_for_size_p (cfun)")
3325                           (const_string "V4SF")
3326                         (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3327                           (const_string "TI")
3328                        ]
3329                        (const_string "V4SF"))
3331                /* For architectures resolving dependencies on
3332                   whole SSE registers use APS move to break dependency
3333                   chains, otherwise use short move to avoid extra work.
3335                   Do the same for architectures resolving dependencies on
3336                   the parts.  While in DF mode it is better to always handle
3337                   just register parts, the SF mode is different due to lack
3338                   of instructions to load just part of the register.  It is
3339                   better to maintain the whole registers in single format
3340                   to avoid problems on using packed logical operations.  */
3341                (eq_attr "alternative" "6")
3342                  (cond [(ior  (match_operand 0 "ext_sse_reg_operand")
3343                               (match_operand 1 "ext_sse_reg_operand"))
3344                           (const_string "V16SF")
3345                         (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3346                              (match_test "TARGET_SSE_SPLIT_REGS"))
3347                           (const_string "V4SF")
3348                        ]
3349                        (const_string "SF"))
3350               ]
3351               (const_string "SF")))])
3353 (define_split
3354   [(set (match_operand 0 "any_fp_register_operand")
3355         (match_operand 1 "memory_operand"))]
3356   "reload_completed
3357    && (GET_MODE (operands[0]) == TFmode
3358        || GET_MODE (operands[0]) == XFmode
3359        || GET_MODE (operands[0]) == DFmode
3360        || GET_MODE (operands[0]) == SFmode)
3361    && (operands[2] = find_constant_src (insn))"
3362   [(set (match_dup 0) (match_dup 2))]
3364   rtx c = operands[2];
3365   int r = REGNO (operands[0]);
3367   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3368       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3369     FAIL;
3372 (define_split
3373   [(set (match_operand 0 "any_fp_register_operand")
3374         (float_extend (match_operand 1 "memory_operand")))]
3375   "reload_completed
3376    && (GET_MODE (operands[0]) == TFmode
3377        || GET_MODE (operands[0]) == XFmode
3378        || GET_MODE (operands[0]) == DFmode)
3379    && (operands[2] = find_constant_src (insn))"
3380   [(set (match_dup 0) (match_dup 2))]
3382   rtx c = operands[2];
3383   int r = REGNO (operands[0]);
3385   if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3386       || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3387     FAIL;
3390 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3391 (define_split
3392   [(set (match_operand:X87MODEF 0 "fp_register_operand")
3393         (match_operand:X87MODEF 1 "immediate_operand"))]
3394   "reload_completed
3395    && (standard_80387_constant_p (operands[1]) == 8
3396        || standard_80387_constant_p (operands[1]) == 9)"
3397   [(set (match_dup 0)(match_dup 1))
3398    (set (match_dup 0)
3399         (neg:X87MODEF (match_dup 0)))]
3401   REAL_VALUE_TYPE r;
3403   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3404   if (real_isnegzero (&r))
3405     operands[1] = CONST0_RTX (<MODE>mode);
3406   else
3407     operands[1] = CONST1_RTX (<MODE>mode);
3410 (define_split
3411   [(set (match_operand 0 "nonimmediate_operand")
3412         (match_operand 1 "general_operand"))]
3413   "reload_completed
3414    && (GET_MODE (operands[0]) == TFmode
3415        || GET_MODE (operands[0]) == XFmode
3416        || GET_MODE (operands[0]) == DFmode)
3417    && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3418   [(const_int 0)]
3419   "ix86_split_long_move (operands); DONE;")
3421 (define_insn "swapxf"
3422   [(set (match_operand:XF 0 "register_operand" "+f")
3423         (match_operand:XF 1 "register_operand" "+f"))
3424    (set (match_dup 1)
3425         (match_dup 0))]
3426   "TARGET_80387"
3428   if (STACK_TOP_P (operands[0]))
3429     return "fxch\t%1";
3430   else
3431     return "fxch\t%0";
3433   [(set_attr "type" "fxch")
3434    (set_attr "mode" "XF")])
3436 (define_insn "*swap<mode>"
3437   [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3438         (match_operand:MODEF 1 "fp_register_operand" "+f"))
3439    (set (match_dup 1)
3440         (match_dup 0))]
3441   "TARGET_80387 || reload_completed"
3443   if (STACK_TOP_P (operands[0]))
3444     return "fxch\t%1";
3445   else
3446     return "fxch\t%0";
3448   [(set_attr "type" "fxch")
3449    (set_attr "mode" "<MODE>")])
3451 ;; Zero extension instructions
3453 (define_expand "zero_extendsidi2"
3454   [(set (match_operand:DI 0 "nonimmediate_operand")
3455         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3457 (define_insn "*zero_extendsidi2"
3458   [(set (match_operand:DI 0 "nonimmediate_operand"
3459                         "=r,?r,?o,r   ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3460         (zero_extend:DI
3461          (match_operand:SI 1 "x86_64_zext_operand"
3462                         "0 ,rm,r ,rmWz,0,r   ,m   ,*Yj,*x,r   ,m")))]
3463   ""
3465   switch (get_attr_type (insn))
3466     {
3467     case TYPE_IMOVX:
3468       if (ix86_use_lea_for_mov (insn, operands))
3469         return "lea{l}\t{%E1, %k0|%k0, %E1}";
3470       else
3471         return "mov{l}\t{%1, %k0|%k0, %1}";
3473     case TYPE_MULTI:
3474       return "#";
3476     case TYPE_MMXMOV:
3477       return "movd\t{%1, %0|%0, %1}";
3479     case TYPE_SSELOG1:
3480       return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3482     case TYPE_SSEMOV:
3483       if (GENERAL_REG_P (operands[0]))
3484         return "%vmovd\t{%1, %k0|%k0, %1}";
3486       return "%vmovd\t{%1, %0|%0, %1}";
3488     default:
3489       gcc_unreachable ();
3490     }
3492   [(set (attr "isa")
3493      (cond [(eq_attr "alternative" "0,1,2")
3494               (const_string "nox64")
3495             (eq_attr "alternative" "3,7")
3496               (const_string "x64")
3497             (eq_attr "alternative" "8")
3498               (const_string "x64_sse4")
3499             (eq_attr "alternative" "10")
3500               (const_string "sse2")
3501            ]
3502            (const_string "*")))
3503    (set (attr "type")
3504      (cond [(eq_attr "alternative" "0,1,2,4")
3505               (const_string "multi")
3506             (eq_attr "alternative" "5,6")
3507               (const_string "mmxmov")
3508             (eq_attr "alternative" "7,9,10")
3509               (const_string "ssemov")
3510             (eq_attr "alternative" "8")
3511               (const_string "sselog1")
3512            ]
3513            (const_string "imovx")))
3514    (set (attr "prefix_extra")
3515      (if_then_else (eq_attr "alternative" "8")
3516        (const_string "1")
3517        (const_string "*")))
3518    (set (attr "length_immediate")
3519      (if_then_else (eq_attr "alternative" "8")
3520        (const_string "1")
3521        (const_string "*")))
3522    (set (attr "prefix")
3523      (if_then_else (eq_attr "type" "ssemov,sselog1")
3524        (const_string "maybe_vex")
3525        (const_string "orig")))
3526    (set (attr "prefix_0f")
3527      (if_then_else (eq_attr "type" "imovx")
3528        (const_string "0")
3529        (const_string "*")))
3530    (set (attr "mode")
3531      (cond [(eq_attr "alternative" "5,6")
3532               (const_string "DI")
3533             (eq_attr "alternative" "7,8,9")
3534               (const_string "TI")
3535            ]
3536            (const_string "SI")))])
3538 (define_split
3539   [(set (match_operand:DI 0 "memory_operand")
3540         (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3541   "reload_completed"
3542   [(set (match_dup 4) (const_int 0))]
3543   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3545 (define_split
3546   [(set (match_operand:DI 0 "register_operand")
3547         (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3548   "!TARGET_64BIT && reload_completed
3549    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3550    && true_regnum (operands[0]) == true_regnum (operands[1])"
3551   [(set (match_dup 4) (const_int 0))]
3552   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3554 (define_split
3555   [(set (match_operand:DI 0 "nonimmediate_operand")
3556         (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3557   "!TARGET_64BIT && reload_completed
3558    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3559    && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3560   [(set (match_dup 3) (match_dup 1))
3561    (set (match_dup 4) (const_int 0))]
3562   "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3564 (define_insn "zero_extend<mode>di2"
3565   [(set (match_operand:DI 0 "register_operand" "=r")
3566         (zero_extend:DI
3567          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3568   "TARGET_64BIT"
3569   "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3570   [(set_attr "type" "imovx")
3571    (set_attr "mode" "SI")])
3573 (define_expand "zero_extend<mode>si2"
3574   [(set (match_operand:SI 0 "register_operand")
3575         (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3576   ""
3578   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3579     {
3580       operands[1] = force_reg (<MODE>mode, operands[1]);
3581       emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3582       DONE;
3583     }
3586 (define_insn_and_split "zero_extend<mode>si2_and"
3587   [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3588         (zero_extend:SI
3589           (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3590    (clobber (reg:CC FLAGS_REG))]
3591   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3592   "#"
3593   "&& reload_completed"
3594   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3595               (clobber (reg:CC FLAGS_REG))])]
3597   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3598     {
3599       ix86_expand_clear (operands[0]);
3601       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3602       emit_insn (gen_movstrict<mode>
3603                   (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3604       DONE;
3605     }
3607   operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3609   [(set_attr "type" "alu1")
3610    (set_attr "mode" "SI")])
3612 (define_insn "*zero_extend<mode>si2"
3613   [(set (match_operand:SI 0 "register_operand" "=r")
3614         (zero_extend:SI
3615           (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3616   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3617   "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3618   [(set_attr "type" "imovx")
3619    (set_attr "mode" "SI")])
3621 (define_expand "zero_extendqihi2"
3622   [(set (match_operand:HI 0 "register_operand")
3623         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3624   ""
3626   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3627     {
3628       operands[1] = force_reg (QImode, operands[1]);
3629       emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3630       DONE;
3631     }
3634 (define_insn_and_split "zero_extendqihi2_and"
3635   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3636         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3637    (clobber (reg:CC FLAGS_REG))]
3638   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3639   "#"
3640   "&& reload_completed"
3641   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3642               (clobber (reg:CC FLAGS_REG))])]
3644   if (true_regnum (operands[0]) != true_regnum (operands[1]))
3645     {
3646       ix86_expand_clear (operands[0]);
3648       gcc_assert (!TARGET_PARTIAL_REG_STALL);
3649       emit_insn (gen_movstrictqi
3650                   (gen_lowpart (QImode, operands[0]), operands[1]));
3651       DONE;
3652     }
3654   operands[0] = gen_lowpart (SImode, operands[0]);
3656   [(set_attr "type" "alu1")
3657    (set_attr "mode" "SI")])
3659 ; zero extend to SImode to avoid partial register stalls
3660 (define_insn "*zero_extendqihi2"
3661   [(set (match_operand:HI 0 "register_operand" "=r")
3662         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3663   "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3664   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3665   [(set_attr "type" "imovx")
3666    (set_attr "mode" "SI")])
3668 ;; Sign extension instructions
3670 (define_expand "extendsidi2"
3671   [(set (match_operand:DI 0 "register_operand")
3672         (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3673   ""
3675   if (!TARGET_64BIT)
3676     {
3677       emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3678       DONE;
3679     }
3682 (define_insn "*extendsidi2_rex64"
3683   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3684         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3685   "TARGET_64BIT"
3686   "@
3687    {cltq|cdqe}
3688    movs{lq|x}\t{%1, %0|%0, %1}"
3689   [(set_attr "type" "imovx")
3690    (set_attr "mode" "DI")
3691    (set_attr "prefix_0f" "0")
3692    (set_attr "modrm" "0,1")])
3694 (define_insn "extendsidi2_1"
3695   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3696         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3697    (clobber (reg:CC FLAGS_REG))
3698    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3699   "!TARGET_64BIT"
3700   "#")
3702 ;; Split the memory case.  If the source register doesn't die, it will stay
3703 ;; this way, if it does die, following peephole2s take care of it.
3704 (define_split
3705   [(set (match_operand:DI 0 "memory_operand")
3706         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3707    (clobber (reg:CC FLAGS_REG))
3708    (clobber (match_operand:SI 2 "register_operand"))]
3709   "reload_completed"
3710   [(const_int 0)]
3712   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3714   emit_move_insn (operands[3], operands[1]);
3716   /* Generate a cltd if possible and doing so it profitable.  */
3717   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3718       && true_regnum (operands[1]) == AX_REG
3719       && true_regnum (operands[2]) == DX_REG)
3720     {
3721       emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3722     }
3723   else
3724     {
3725       emit_move_insn (operands[2], operands[1]);
3726       emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3727     }
3728   emit_move_insn (operands[4], operands[2]);
3729   DONE;
3732 ;; Peepholes for the case where the source register does die, after
3733 ;; being split with the above splitter.
3734 (define_peephole2
3735   [(set (match_operand:SI 0 "memory_operand")
3736         (match_operand:SI 1 "register_operand"))
3737    (set (match_operand:SI 2 "register_operand") (match_dup 1))
3738    (parallel [(set (match_dup 2)
3739                    (ashiftrt:SI (match_dup 2) (const_int 31)))
3740                (clobber (reg:CC FLAGS_REG))])
3741    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3742   "REGNO (operands[1]) != REGNO (operands[2])
3743    && peep2_reg_dead_p (2, operands[1])
3744    && peep2_reg_dead_p (4, operands[2])
3745    && !reg_mentioned_p (operands[2], operands[3])"
3746   [(set (match_dup 0) (match_dup 1))
3747    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3748               (clobber (reg:CC FLAGS_REG))])
3749    (set (match_dup 3) (match_dup 1))])
3751 (define_peephole2
3752   [(set (match_operand:SI 0 "memory_operand")
3753         (match_operand:SI 1 "register_operand"))
3754    (parallel [(set (match_operand:SI 2 "register_operand")
3755                    (ashiftrt:SI (match_dup 1) (const_int 31)))
3756                (clobber (reg:CC FLAGS_REG))])
3757    (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3758   "/* cltd is shorter than sarl $31, %eax */
3759    !optimize_function_for_size_p (cfun)
3760    && true_regnum (operands[1]) == AX_REG
3761    && true_regnum (operands[2]) == DX_REG
3762    && peep2_reg_dead_p (2, operands[1])
3763    && peep2_reg_dead_p (3, operands[2])
3764    && !reg_mentioned_p (operands[2], operands[3])"
3765   [(set (match_dup 0) (match_dup 1))
3766    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3767               (clobber (reg:CC FLAGS_REG))])
3768    (set (match_dup 3) (match_dup 1))])
3770 ;; Extend to register case.  Optimize case where source and destination
3771 ;; registers match and cases where we can use cltd.
3772 (define_split
3773   [(set (match_operand:DI 0 "register_operand")
3774         (sign_extend:DI (match_operand:SI 1 "register_operand")))
3775    (clobber (reg:CC FLAGS_REG))
3776    (clobber (match_scratch:SI 2))]
3777   "reload_completed"
3778   [(const_int 0)]
3780   split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3782   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3783     emit_move_insn (operands[3], operands[1]);
3785   /* Generate a cltd if possible and doing so it profitable.  */
3786   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3787       && true_regnum (operands[3]) == AX_REG
3788       && true_regnum (operands[4]) == DX_REG)
3789     {
3790       emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3791       DONE;
3792     }
3794   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3795     emit_move_insn (operands[4], operands[1]);
3797   emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3798   DONE;
3801 (define_insn "extend<mode>di2"
3802   [(set (match_operand:DI 0 "register_operand" "=r")
3803         (sign_extend:DI
3804          (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3805   "TARGET_64BIT"
3806   "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3807   [(set_attr "type" "imovx")
3808    (set_attr "mode" "DI")])
3810 (define_insn "extendhisi2"
3811   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3812         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3813   ""
3815   switch (get_attr_prefix_0f (insn))
3816     {
3817     case 0:
3818       return "{cwtl|cwde}";
3819     default:
3820       return "movs{wl|x}\t{%1, %0|%0, %1}";
3821     }
3823   [(set_attr "type" "imovx")
3824    (set_attr "mode" "SI")
3825    (set (attr "prefix_0f")
3826      ;; movsx is short decodable while cwtl is vector decoded.
3827      (if_then_else (and (eq_attr "cpu" "!k6")
3828                         (eq_attr "alternative" "0"))
3829         (const_string "0")
3830         (const_string "1")))
3831    (set (attr "modrm")
3832      (if_then_else (eq_attr "prefix_0f" "0")
3833         (const_string "0")
3834         (const_string "1")))])
3836 (define_insn "*extendhisi2_zext"
3837   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3838         (zero_extend:DI
3839          (sign_extend:SI
3840           (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3841   "TARGET_64BIT"
3843   switch (get_attr_prefix_0f (insn))
3844     {
3845     case 0:
3846       return "{cwtl|cwde}";
3847     default:
3848       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3849     }
3851   [(set_attr "type" "imovx")
3852    (set_attr "mode" "SI")
3853    (set (attr "prefix_0f")
3854      ;; movsx is short decodable while cwtl is vector decoded.
3855      (if_then_else (and (eq_attr "cpu" "!k6")
3856                         (eq_attr "alternative" "0"))
3857         (const_string "0")
3858         (const_string "1")))
3859    (set (attr "modrm")
3860      (if_then_else (eq_attr "prefix_0f" "0")
3861         (const_string "0")
3862         (const_string "1")))])
3864 (define_insn "extendqisi2"
3865   [(set (match_operand:SI 0 "register_operand" "=r")
3866         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3867   ""
3868   "movs{bl|x}\t{%1, %0|%0, %1}"
3869    [(set_attr "type" "imovx")
3870     (set_attr "mode" "SI")])
3872 (define_insn "*extendqisi2_zext"
3873   [(set (match_operand:DI 0 "register_operand" "=r")
3874         (zero_extend:DI
3875           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3876   "TARGET_64BIT"
3877   "movs{bl|x}\t{%1, %k0|%k0, %1}"
3878    [(set_attr "type" "imovx")
3879     (set_attr "mode" "SI")])
3881 (define_insn "extendqihi2"
3882   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3883         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3884   ""
3886   switch (get_attr_prefix_0f (insn))
3887     {
3888     case 0:
3889       return "{cbtw|cbw}";
3890     default:
3891       return "movs{bw|x}\t{%1, %0|%0, %1}";
3892     }
3894   [(set_attr "type" "imovx")
3895    (set_attr "mode" "HI")
3896    (set (attr "prefix_0f")
3897      ;; movsx is short decodable while cwtl is vector decoded.
3898      (if_then_else (and (eq_attr "cpu" "!k6")
3899                         (eq_attr "alternative" "0"))
3900         (const_string "0")
3901         (const_string "1")))
3902    (set (attr "modrm")
3903      (if_then_else (eq_attr "prefix_0f" "0")
3904         (const_string "0")
3905         (const_string "1")))])
3907 ;; Conversions between float and double.
3909 ;; These are all no-ops in the model used for the 80387.
3910 ;; So just emit moves.
3912 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3913 (define_split
3914   [(set (match_operand:DF 0 "push_operand")
3915         (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3916   "reload_completed"
3917   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3918    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3920 (define_split
3921   [(set (match_operand:XF 0 "push_operand")
3922         (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3923   "reload_completed"
3924   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3925    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3926   "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3928 (define_expand "extendsfdf2"
3929   [(set (match_operand:DF 0 "nonimmediate_operand")
3930         (float_extend:DF (match_operand:SF 1 "general_operand")))]
3931   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3933   /* ??? Needed for compress_float_constant since all fp constants
3934      are TARGET_LEGITIMATE_CONSTANT_P.  */
3935   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3936     {
3937       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3938           && standard_80387_constant_p (operands[1]) > 0)
3939         {
3940           operands[1] = simplify_const_unary_operation
3941             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3942           emit_move_insn_1 (operands[0], operands[1]);
3943           DONE;
3944         }
3945       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3946     }
3949 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3950    cvtss2sd:
3951       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3952       cvtps2pd xmm2,xmm1
3953    We do the conversion post reload to avoid producing of 128bit spills
3954    that might lead to ICE on 32bit target.  The sequence unlikely combine
3955    anyway.  */
3956 (define_split
3957   [(set (match_operand:DF 0 "register_operand")
3958         (float_extend:DF
3959           (match_operand:SF 1 "nonimmediate_operand")))]
3960   "TARGET_USE_VECTOR_FP_CONVERTS
3961    && optimize_insn_for_speed_p ()
3962    && reload_completed && SSE_REG_P (operands[0])"
3963    [(set (match_dup 2)
3964          (float_extend:V2DF
3965            (vec_select:V2SF
3966              (match_dup 3)
3967              (parallel [(const_int 0) (const_int 1)]))))]
3969   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3970   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3971   /* Use movss for loading from memory, unpcklps reg, reg for registers.
3972      Try to avoid move when unpacking can be done in source.  */
3973   if (REG_P (operands[1]))
3974     {
3975       /* If it is unsafe to overwrite upper half of source, we need
3976          to move to destination and unpack there.  */
3977       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3978            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3979           && true_regnum (operands[0]) != true_regnum (operands[1]))
3980         {
3981           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3982           emit_move_insn (tmp, operands[1]);
3983         }
3984       else
3985         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3986       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3987                                              operands[3]));
3988     }
3989   else
3990     emit_insn (gen_vec_setv4sf_0 (operands[3],
3991                                   CONST0_RTX (V4SFmode), operands[1]));
3994 ;; It's more profitable to split and then extend in the same register.
3995 (define_peephole2
3996   [(set (match_operand:DF 0 "register_operand")
3997         (float_extend:DF
3998           (match_operand:SF 1 "memory_operand")))]
3999   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4000    && optimize_insn_for_speed_p ()
4001    && SSE_REG_P (operands[0])"
4002   [(set (match_dup 2) (match_dup 1))
4003    (set (match_dup 0) (float_extend:DF (match_dup 2)))]
4004   "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
4006 (define_insn "*extendsfdf2_mixed"
4007   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4008         (float_extend:DF
4009           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4010   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4012   switch (which_alternative)
4013     {
4014     case 0:
4015     case 1:
4016       return output_387_reg_move (insn, operands);
4018     case 2:
4019       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4021     default:
4022       gcc_unreachable ();
4023     }
4025   [(set_attr "type" "fmov,fmov,ssecvt")
4026    (set_attr "prefix" "orig,orig,maybe_vex")
4027    (set_attr "mode" "SF,XF,DF")])
4029 (define_insn "*extendsfdf2_sse"
4030   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4031         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4032   "TARGET_SSE2 && TARGET_SSE_MATH"
4033   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4034   [(set_attr "type" "ssecvt")
4035    (set_attr "prefix" "maybe_vex")
4036    (set_attr "mode" "DF")])
4038 (define_insn "*extendsfdf2_i387"
4039   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4040         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4041   "TARGET_80387"
4042   "* return output_387_reg_move (insn, operands);"
4043   [(set_attr "type" "fmov")
4044    (set_attr "mode" "SF,XF")])
4046 (define_expand "extend<mode>xf2"
4047   [(set (match_operand:XF 0 "nonimmediate_operand")
4048         (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4049   "TARGET_80387"
4051   /* ??? Needed for compress_float_constant since all fp constants
4052      are TARGET_LEGITIMATE_CONSTANT_P.  */
4053   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4054     {
4055       if (standard_80387_constant_p (operands[1]) > 0)
4056         {
4057           operands[1] = simplify_const_unary_operation
4058             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4059           emit_move_insn_1 (operands[0], operands[1]);
4060           DONE;
4061         }
4062       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4063     }
4066 (define_insn "*extend<mode>xf2_i387"
4067   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4068         (float_extend:XF
4069           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4070   "TARGET_80387"
4071   "* return output_387_reg_move (insn, operands);"
4072   [(set_attr "type" "fmov")
4073    (set_attr "mode" "<MODE>,XF")])
4075 ;; %%% This seems bad bad news.
4076 ;; This cannot output into an f-reg because there is no way to be sure
4077 ;; of truncating in that case.  Otherwise this is just like a simple move
4078 ;; insn.  So we pretend we can output to a reg in order to get better
4079 ;; register preferencing, but we really use a stack slot.
4081 ;; Conversion from DFmode to SFmode.
4083 (define_expand "truncdfsf2"
4084   [(set (match_operand:SF 0 "nonimmediate_operand")
4085         (float_truncate:SF
4086           (match_operand:DF 1 "nonimmediate_operand")))]
4087   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4089   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4090     ;
4091   else if (flag_unsafe_math_optimizations)
4092     ;
4093   else
4094     {
4095       rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4096       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4097       DONE;
4098     }
4101 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4102    cvtsd2ss:
4103       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4104       cvtpd2ps xmm2,xmm1
4105    We do the conversion post reload to avoid producing of 128bit spills
4106    that might lead to ICE on 32bit target.  The sequence unlikely combine
4107    anyway.  */
4108 (define_split
4109   [(set (match_operand:SF 0 "register_operand")
4110         (float_truncate:SF
4111           (match_operand:DF 1 "nonimmediate_operand")))]
4112   "TARGET_USE_VECTOR_FP_CONVERTS
4113    && optimize_insn_for_speed_p ()
4114    && reload_completed && SSE_REG_P (operands[0])"
4115    [(set (match_dup 2)
4116          (vec_concat:V4SF
4117            (float_truncate:V2SF
4118              (match_dup 4))
4119            (match_dup 3)))]
4121   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4122   operands[3] = CONST0_RTX (V2SFmode);
4123   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4124   /* Use movsd for loading from memory, unpcklpd for registers.
4125      Try to avoid move when unpacking can be done in source, or SSE3
4126      movddup is available.  */
4127   if (REG_P (operands[1]))
4128     {
4129       if (!TARGET_SSE3
4130           && true_regnum (operands[0]) != true_regnum (operands[1])
4131           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4132               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4133         {
4134           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4135           emit_move_insn (tmp, operands[1]);
4136           operands[1] = tmp;
4137         }
4138       else if (!TARGET_SSE3)
4139         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4140       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4141     }
4142   else
4143     emit_insn (gen_sse2_loadlpd (operands[4],
4144                                  CONST0_RTX (V2DFmode), operands[1]));
4147 ;; It's more profitable to split and then extend in the same register.
4148 (define_peephole2
4149   [(set (match_operand:SF 0 "register_operand")
4150         (float_truncate:SF
4151           (match_operand:DF 1 "memory_operand")))]
4152   "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
4153    && optimize_insn_for_speed_p ()
4154    && SSE_REG_P (operands[0])"
4155   [(set (match_dup 2) (match_dup 1))
4156    (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
4157   "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
4159 (define_expand "truncdfsf2_with_temp"
4160   [(parallel [(set (match_operand:SF 0)
4161                    (float_truncate:SF (match_operand:DF 1)))
4162               (clobber (match_operand:SF 2))])])
4164 (define_insn "*truncdfsf_fast_mixed"
4165   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4166         (float_truncate:SF
4167           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4168   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4170   switch (which_alternative)
4171     {
4172     case 0:
4173       return output_387_reg_move (insn, operands);
4174     case 1:
4175       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4176     default:
4177       gcc_unreachable ();
4178     }
4180   [(set_attr "type" "fmov,ssecvt")
4181    (set_attr "prefix" "orig,maybe_vex")
4182    (set_attr "mode" "SF")])
4184 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4185 ;; because nothing we do here is unsafe.
4186 (define_insn "*truncdfsf_fast_sse"
4187   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4188         (float_truncate:SF
4189           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4190   "TARGET_SSE2 && TARGET_SSE_MATH"
4191   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4192   [(set_attr "type" "ssecvt")
4193    (set_attr "prefix" "maybe_vex")
4194    (set_attr "mode" "SF")])
4196 (define_insn "*truncdfsf_fast_i387"
4197   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4198         (float_truncate:SF
4199           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4200   "TARGET_80387 && flag_unsafe_math_optimizations"
4201   "* return output_387_reg_move (insn, operands);"
4202   [(set_attr "type" "fmov")
4203    (set_attr "mode" "SF")])
4205 (define_insn "*truncdfsf_mixed"
4206   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,x ,?f,?x,?*r")
4207         (float_truncate:SF
4208           (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4209    (clobber (match_operand:SF 2 "memory_operand"     "=X,X ,m ,m ,m"))]
4210   "TARGET_MIX_SSE_I387"
4212   switch (which_alternative)
4213     {
4214     case 0:
4215       return output_387_reg_move (insn, operands);
4216     case 1:
4217       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4219     default:
4220       return "#";
4221     }
4223   [(set_attr "isa" "*,sse2,*,*,*")
4224    (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4225    (set_attr "unit" "*,*,i387,i387,i387")
4226    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4227    (set_attr "mode" "SF")])
4229 (define_insn "*truncdfsf_i387"
4230   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4231         (float_truncate:SF
4232           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4233    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4234   "TARGET_80387"
4236   switch (which_alternative)
4237     {
4238     case 0:
4239       return output_387_reg_move (insn, operands);
4241     default:
4242       return "#";
4243     }
4245   [(set_attr "type" "fmov,multi,multi,multi")
4246    (set_attr "unit" "*,i387,i387,i387")
4247    (set_attr "mode" "SF")])
4249 (define_insn "*truncdfsf2_i387_1"
4250   [(set (match_operand:SF 0 "memory_operand" "=m")
4251         (float_truncate:SF
4252           (match_operand:DF 1 "register_operand" "f")))]
4253   "TARGET_80387
4254    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4255    && !TARGET_MIX_SSE_I387"
4256   "* return output_387_reg_move (insn, operands);"
4257   [(set_attr "type" "fmov")
4258    (set_attr "mode" "SF")])
4260 (define_split
4261   [(set (match_operand:SF 0 "register_operand")
4262         (float_truncate:SF
4263          (match_operand:DF 1 "fp_register_operand")))
4264    (clobber (match_operand 2))]
4265   "reload_completed"
4266   [(set (match_dup 2) (match_dup 1))
4267    (set (match_dup 0) (match_dup 2))]
4268   "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4270 ;; Conversion from XFmode to {SF,DF}mode
4272 (define_expand "truncxf<mode>2"
4273   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4274                    (float_truncate:MODEF
4275                      (match_operand:XF 1 "register_operand")))
4276               (clobber (match_dup 2))])]
4277   "TARGET_80387"
4279   if (flag_unsafe_math_optimizations)
4280     {
4281       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4282       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4283       if (reg != operands[0])
4284         emit_move_insn (operands[0], reg);
4285       DONE;
4286     }
4287   else
4288     operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4291 (define_insn "*truncxfsf2_mixed"
4292   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4293         (float_truncate:SF
4294           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4295    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4296   "TARGET_80387"
4298   gcc_assert (!which_alternative);
4299   return output_387_reg_move (insn, operands);
4301   [(set_attr "type" "fmov,multi,multi,multi")
4302    (set_attr "unit" "*,i387,i387,i387")
4303    (set_attr "mode" "SF")])
4305 (define_insn "*truncxfdf2_mixed"
4306   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4307         (float_truncate:DF
4308           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4309    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4310   "TARGET_80387"
4312   gcc_assert (!which_alternative);
4313   return output_387_reg_move (insn, operands);
4315   [(set_attr "isa" "*,*,sse2,*")
4316    (set_attr "type" "fmov,multi,multi,multi")
4317    (set_attr "unit" "*,i387,i387,i387")
4318    (set_attr "mode" "DF")])
4320 (define_insn "truncxf<mode>2_i387_noop"
4321   [(set (match_operand:MODEF 0 "register_operand" "=f")
4322         (float_truncate:MODEF
4323           (match_operand:XF 1 "register_operand" "f")))]
4324   "TARGET_80387 && flag_unsafe_math_optimizations"
4325   "* return output_387_reg_move (insn, operands);"
4326   [(set_attr "type" "fmov")
4327    (set_attr "mode" "<MODE>")])
4329 (define_insn "*truncxf<mode>2_i387"
4330   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4331         (float_truncate:MODEF
4332           (match_operand:XF 1 "register_operand" "f")))]
4333   "TARGET_80387"
4334   "* return output_387_reg_move (insn, operands);"
4335   [(set_attr "type" "fmov")
4336    (set_attr "mode" "<MODE>")])
4338 (define_split
4339   [(set (match_operand:MODEF 0 "register_operand")
4340         (float_truncate:MODEF
4341           (match_operand:XF 1 "register_operand")))
4342    (clobber (match_operand:MODEF 2 "memory_operand"))]
4343   "TARGET_80387 && reload_completed"
4344   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4345    (set (match_dup 0) (match_dup 2))])
4347 (define_split
4348   [(set (match_operand:MODEF 0 "memory_operand")
4349         (float_truncate:MODEF
4350           (match_operand:XF 1 "register_operand")))
4351    (clobber (match_operand:MODEF 2 "memory_operand"))]
4352   "TARGET_80387"
4353   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4355 ;; Signed conversion to DImode.
4357 (define_expand "fix_truncxfdi2"
4358   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4359                    (fix:DI (match_operand:XF 1 "register_operand")))
4360               (clobber (reg:CC FLAGS_REG))])]
4361   "TARGET_80387"
4363   if (TARGET_FISTTP)
4364    {
4365      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4366      DONE;
4367    }
4370 (define_expand "fix_trunc<mode>di2"
4371   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4372                    (fix:DI (match_operand:MODEF 1 "register_operand")))
4373               (clobber (reg:CC FLAGS_REG))])]
4374   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4376   if (TARGET_FISTTP
4377       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4378    {
4379      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4380      DONE;
4381    }
4382   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4383    {
4384      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4385      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4386      if (out != operands[0])
4387         emit_move_insn (operands[0], out);
4388      DONE;
4389    }
4392 ;; Signed conversion to SImode.
4394 (define_expand "fix_truncxfsi2"
4395   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4396                    (fix:SI (match_operand:XF 1 "register_operand")))
4397               (clobber (reg:CC FLAGS_REG))])]
4398   "TARGET_80387"
4400   if (TARGET_FISTTP)
4401    {
4402      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4403      DONE;
4404    }
4407 (define_expand "fix_trunc<mode>si2"
4408   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4409                    (fix:SI (match_operand:MODEF 1 "register_operand")))
4410               (clobber (reg:CC FLAGS_REG))])]
4411   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4413   if (TARGET_FISTTP
4414       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4415    {
4416      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4417      DONE;
4418    }
4419   if (SSE_FLOAT_MODE_P (<MODE>mode))
4420    {
4421      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4422      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4423      if (out != operands[0])
4424         emit_move_insn (operands[0], out);
4425      DONE;
4426    }
4429 ;; Signed conversion to HImode.
4431 (define_expand "fix_trunc<mode>hi2"
4432   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4433                    (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4434               (clobber (reg:CC FLAGS_REG))])]
4435   "TARGET_80387
4436    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4438   if (TARGET_FISTTP)
4439    {
4440      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4441      DONE;
4442    }
4445 ;; Unsigned conversion to SImode.
4447 (define_expand "fixuns_trunc<mode>si2"
4448   [(parallel
4449     [(set (match_operand:SI 0 "register_operand")
4450           (unsigned_fix:SI
4451             (match_operand:MODEF 1 "nonimmediate_operand")))
4452      (use (match_dup 2))
4453      (clobber (match_scratch:<ssevecmode> 3))
4454      (clobber (match_scratch:<ssevecmode> 4))])]
4455   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4457   machine_mode mode = <MODE>mode;
4458   machine_mode vecmode = <ssevecmode>mode;
4459   REAL_VALUE_TYPE TWO31r;
4460   rtx two31;
4462   if (optimize_insn_for_size_p ())
4463     FAIL;
4465   real_ldexp (&TWO31r, &dconst1, 31);
4466   two31 = const_double_from_real_value (TWO31r, mode);
4467   two31 = ix86_build_const_vector (vecmode, true, two31);
4468   operands[2] = force_reg (vecmode, two31);
4471 (define_insn_and_split "*fixuns_trunc<mode>_1"
4472   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4473         (unsigned_fix:SI
4474           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4475    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4476    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4477    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4478   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4479    && optimize_function_for_speed_p (cfun)"
4480   "#"
4481   "&& reload_completed"
4482   [(const_int 0)]
4484   ix86_split_convert_uns_si_sse (operands);
4485   DONE;
4488 ;; Unsigned conversion to HImode.
4489 ;; Without these patterns, we'll try the unsigned SI conversion which
4490 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4492 (define_expand "fixuns_trunc<mode>hi2"
4493   [(set (match_dup 2)
4494         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4495    (set (match_operand:HI 0 "nonimmediate_operand")
4496         (subreg:HI (match_dup 2) 0))]
4497   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4498   "operands[2] = gen_reg_rtx (SImode);")
4500 ;; When SSE is available, it is always faster to use it!
4501 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4502   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4503         (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4504   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4505    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4506   "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4507   [(set_attr "type" "sseicvt")
4508    (set_attr "prefix" "maybe_vex")
4509    (set (attr "prefix_rex")
4510         (if_then_else
4511           (match_test "<SWI48:MODE>mode == DImode")
4512           (const_string "1")
4513           (const_string "*")))
4514    (set_attr "mode" "<MODEF:MODE>")
4515    (set_attr "athlon_decode" "double,vector")
4516    (set_attr "amdfam10_decode" "double,double")
4517    (set_attr "bdver1_decode" "double,double")])
4519 ;; Avoid vector decoded forms of the instruction.
4520 (define_peephole2
4521   [(match_scratch:MODEF 2 "x")
4522    (set (match_operand:SWI48 0 "register_operand")
4523         (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4524   "TARGET_AVOID_VECTOR_DECODE
4525    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4526    && optimize_insn_for_speed_p ()"
4527   [(set (match_dup 2) (match_dup 1))
4528    (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4530 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4531   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4532         (fix:SWI248x (match_operand 1 "register_operand")))]
4533   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4534    && TARGET_FISTTP
4535    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4536          && (TARGET_64BIT || <MODE>mode != DImode))
4537         && TARGET_SSE_MATH)
4538    && can_create_pseudo_p ()"
4539   "#"
4540   "&& 1"
4541   [(const_int 0)]
4543   if (memory_operand (operands[0], VOIDmode))
4544     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4545   else
4546     {
4547       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4548       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4549                                                             operands[1],
4550                                                             operands[2]));
4551     }
4552   DONE;
4554   [(set_attr "type" "fisttp")
4555    (set_attr "mode" "<MODE>")])
4557 (define_insn "fix_trunc<mode>_i387_fisttp"
4558   [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4559         (fix:SWI248x (match_operand 1 "register_operand" "f")))
4560    (clobber (match_scratch:XF 2 "=&1f"))]
4561   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4562    && TARGET_FISTTP
4563    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4564          && (TARGET_64BIT || <MODE>mode != DImode))
4565         && TARGET_SSE_MATH)"
4566   "* return output_fix_trunc (insn, operands, true);"
4567   [(set_attr "type" "fisttp")
4568    (set_attr "mode" "<MODE>")])
4570 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4571   [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4572         (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4573    (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4574    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4575   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4576    && TARGET_FISTTP
4577    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4578         && (TARGET_64BIT || <MODE>mode != DImode))
4579         && TARGET_SSE_MATH)"
4580   "#"
4581   [(set_attr "type" "fisttp")
4582    (set_attr "mode" "<MODE>")])
4584 (define_split
4585   [(set (match_operand:SWI248x 0 "register_operand")
4586         (fix:SWI248x (match_operand 1 "register_operand")))
4587    (clobber (match_operand:SWI248x 2 "memory_operand"))
4588    (clobber (match_scratch 3))]
4589   "reload_completed"
4590   [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4591               (clobber (match_dup 3))])
4592    (set (match_dup 0) (match_dup 2))])
4594 (define_split
4595   [(set (match_operand:SWI248x 0 "memory_operand")
4596         (fix:SWI248x (match_operand 1 "register_operand")))
4597    (clobber (match_operand:SWI248x 2 "memory_operand"))
4598    (clobber (match_scratch 3))]
4599   "reload_completed"
4600   [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4601               (clobber (match_dup 3))])])
4603 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4604 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4605 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4606 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4607 ;; function in i386.c.
4608 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4609   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4610         (fix:SWI248x (match_operand 1 "register_operand")))
4611    (clobber (reg:CC FLAGS_REG))]
4612   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4613    && !TARGET_FISTTP
4614    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4615          && (TARGET_64BIT || <MODE>mode != DImode))
4616    && can_create_pseudo_p ()"
4617   "#"
4618   "&& 1"
4619   [(const_int 0)]
4621   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4623   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4624   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4625   if (memory_operand (operands[0], VOIDmode))
4626     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4627                                          operands[2], operands[3]));
4628   else
4629     {
4630       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4631       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4632                                                      operands[2], operands[3],
4633                                                      operands[4]));
4634     }
4635   DONE;
4637   [(set_attr "type" "fistp")
4638    (set_attr "i387_cw" "trunc")
4639    (set_attr "mode" "<MODE>")])
4641 (define_insn "fix_truncdi_i387"
4642   [(set (match_operand:DI 0 "memory_operand" "=m")
4643         (fix:DI (match_operand 1 "register_operand" "f")))
4644    (use (match_operand:HI 2 "memory_operand" "m"))
4645    (use (match_operand:HI 3 "memory_operand" "m"))
4646    (clobber (match_scratch:XF 4 "=&1f"))]
4647   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4648    && !TARGET_FISTTP
4649    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4650   "* return output_fix_trunc (insn, operands, false);"
4651   [(set_attr "type" "fistp")
4652    (set_attr "i387_cw" "trunc")
4653    (set_attr "mode" "DI")])
4655 (define_insn "fix_truncdi_i387_with_temp"
4656   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4657         (fix:DI (match_operand 1 "register_operand" "f,f")))
4658    (use (match_operand:HI 2 "memory_operand" "m,m"))
4659    (use (match_operand:HI 3 "memory_operand" "m,m"))
4660    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4661    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4662   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4663    && !TARGET_FISTTP
4664    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4665   "#"
4666   [(set_attr "type" "fistp")
4667    (set_attr "i387_cw" "trunc")
4668    (set_attr "mode" "DI")])
4670 (define_split
4671   [(set (match_operand:DI 0 "register_operand")
4672         (fix:DI (match_operand 1 "register_operand")))
4673    (use (match_operand:HI 2 "memory_operand"))
4674    (use (match_operand:HI 3 "memory_operand"))
4675    (clobber (match_operand:DI 4 "memory_operand"))
4676    (clobber (match_scratch 5))]
4677   "reload_completed"
4678   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4679               (use (match_dup 2))
4680               (use (match_dup 3))
4681               (clobber (match_dup 5))])
4682    (set (match_dup 0) (match_dup 4))])
4684 (define_split
4685   [(set (match_operand:DI 0 "memory_operand")
4686         (fix:DI (match_operand 1 "register_operand")))
4687    (use (match_operand:HI 2 "memory_operand"))
4688    (use (match_operand:HI 3 "memory_operand"))
4689    (clobber (match_operand:DI 4 "memory_operand"))
4690    (clobber (match_scratch 5))]
4691   "reload_completed"
4692   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4693               (use (match_dup 2))
4694               (use (match_dup 3))
4695               (clobber (match_dup 5))])])
4697 (define_insn "fix_trunc<mode>_i387"
4698   [(set (match_operand:SWI24 0 "memory_operand" "=m")
4699         (fix:SWI24 (match_operand 1 "register_operand" "f")))
4700    (use (match_operand:HI 2 "memory_operand" "m"))
4701    (use (match_operand:HI 3 "memory_operand" "m"))]
4702   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4703    && !TARGET_FISTTP
4704    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4705   "* return output_fix_trunc (insn, operands, false);"
4706   [(set_attr "type" "fistp")
4707    (set_attr "i387_cw" "trunc")
4708    (set_attr "mode" "<MODE>")])
4710 (define_insn "fix_trunc<mode>_i387_with_temp"
4711   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4712         (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4713    (use (match_operand:HI 2 "memory_operand" "m,m"))
4714    (use (match_operand:HI 3 "memory_operand" "m,m"))
4715    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4716   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4717    && !TARGET_FISTTP
4718    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4719   "#"
4720   [(set_attr "type" "fistp")
4721    (set_attr "i387_cw" "trunc")
4722    (set_attr "mode" "<MODE>")])
4724 (define_split
4725   [(set (match_operand:SWI24 0 "register_operand")
4726         (fix:SWI24 (match_operand 1 "register_operand")))
4727    (use (match_operand:HI 2 "memory_operand"))
4728    (use (match_operand:HI 3 "memory_operand"))
4729    (clobber (match_operand:SWI24 4 "memory_operand"))]
4730   "reload_completed"
4731   [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4732               (use (match_dup 2))
4733               (use (match_dup 3))])
4734    (set (match_dup 0) (match_dup 4))])
4736 (define_split
4737   [(set (match_operand:SWI24 0 "memory_operand")
4738         (fix:SWI24 (match_operand 1 "register_operand")))
4739    (use (match_operand:HI 2 "memory_operand"))
4740    (use (match_operand:HI 3 "memory_operand"))
4741    (clobber (match_operand:SWI24 4 "memory_operand"))]
4742   "reload_completed"
4743   [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4744               (use (match_dup 2))
4745               (use (match_dup 3))])])
4747 (define_insn "x86_fnstcw_1"
4748   [(set (match_operand:HI 0 "memory_operand" "=m")
4749         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4750   "TARGET_80387"
4751   "fnstcw\t%0"
4752   [(set (attr "length")
4753         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4754    (set_attr "mode" "HI")
4755    (set_attr "unit" "i387")
4756    (set_attr "bdver1_decode" "vector")])
4758 (define_insn "x86_fldcw_1"
4759   [(set (reg:HI FPCR_REG)
4760         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4761   "TARGET_80387"
4762   "fldcw\t%0"
4763   [(set (attr "length")
4764         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4765    (set_attr "mode" "HI")
4766    (set_attr "unit" "i387")
4767    (set_attr "athlon_decode" "vector")
4768    (set_attr "amdfam10_decode" "vector")
4769    (set_attr "bdver1_decode" "vector")])
4771 ;; Conversion between fixed point and floating point.
4773 ;; Even though we only accept memory inputs, the backend _really_
4774 ;; wants to be able to do this between registers.  Thankfully, LRA
4775 ;; will fix this up for us during register allocation.
4777 (define_insn "floathi<mode>2"
4778   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4779         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m")))]
4780   "TARGET_80387
4781    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4782        || TARGET_MIX_SSE_I387)"
4783   "fild%Z1\t%1"
4784   [(set_attr "type" "fmov")
4785    (set_attr "mode" "<MODE>")
4786    (set_attr "fp_int_src" "true")])
4788 (define_insn "float<SWI48x:mode>xf2"
4789   [(set (match_operand:XF 0 "register_operand" "=f")
4790         (float:XF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4791   "TARGET_80387"
4792   "fild%Z1\t%1"
4793   [(set_attr "type" "fmov")
4794    (set_attr "mode" "XF")
4795    (set_attr "fp_int_src" "true")])
4797 (define_expand "float<SWI48:mode><MODEF:mode>2"
4798   [(set (match_operand:MODEF 0 "register_operand")
4799         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4800   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)"
4802   if (!(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
4803       && !X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48:MODE>mode))
4804     {
4805       rtx reg = gen_reg_rtx (XFmode);
4806       rtx (*insn)(rtx, rtx);
4808       emit_insn (gen_float<SWI48:mode>xf2 (reg, operands[1]));
4810       if (<MODEF:MODE>mode == SFmode)
4811         insn = gen_truncxfsf2;
4812       else if (<MODEF:MODE>mode == DFmode)
4813         insn = gen_truncxfdf2;
4814       else
4815         gcc_unreachable ();
4817       emit_insn (insn (operands[0], reg));
4818       DONE;
4819     }
4822 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse"
4823   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4824         (float:MODEF
4825           (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4826   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4827   "@
4828    fild%Z1\t%1
4829    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4830    %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4831   [(set_attr "type" "fmov,sseicvt,sseicvt")
4832    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4833    (set_attr "mode" "<MODEF:MODE>")
4834    (set (attr "prefix_rex")
4835      (if_then_else
4836        (and (eq_attr "prefix" "maybe_vex")
4837             (match_test "<SWI48:MODE>mode == DImode"))
4838        (const_string "1")
4839        (const_string "*")))
4840    (set_attr "unit" "i387,*,*")
4841    (set_attr "athlon_decode" "*,double,direct")
4842    (set_attr "amdfam10_decode" "*,vector,double")
4843    (set_attr "bdver1_decode" "*,double,direct")
4844    (set_attr "fp_int_src" "true")
4845    (set (attr "enabled")
4846      (cond [(eq_attr "alternative" "0")
4847               (symbol_ref "TARGET_MIX_SSE_I387
4848                            && X87_ENABLE_FLOAT (<MODEF:MODE>mode,
4849                                                 <SWI48:MODE>mode)")
4850            ]
4851            (symbol_ref "true")))
4852    (set (attr "preferred_for_speed")
4853      (cond [(eq_attr "alternative" "1")
4854               (symbol_ref "TARGET_INTER_UNIT_CONVERSIONS")]
4855            (symbol_ref "true")))
4856    ])
4858 (define_insn "*float<SWI48x:mode><MODEF:mode>2_i387"
4859   [(set (match_operand:MODEF 0 "register_operand" "=f")
4860         (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "m")))]
4861   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI48x:MODE>mode)"
4862   "fild%Z1\t%1"
4863   [(set_attr "type" "fmov")
4864    (set_attr "mode" "<MODEF:MODE>")
4865    (set_attr "fp_int_src" "true")])
4867 ;; Try TARGET_USE_VECTOR_CONVERTS, but not so hard as to require extra memory
4868 ;; slots when !TARGET_INTER_UNIT_MOVES_TO_VEC disables the general_regs
4869 ;; alternative in sse2_loadld.
4870 (define_split
4871   [(set (match_operand:MODEF 0 "register_operand")
4872         (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4873   "TARGET_SSE2 && TARGET_SSE_MATH
4874    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4875    && reload_completed && SSE_REG_P (operands[0])
4876    && (MEM_P (operands[1]) || TARGET_INTER_UNIT_MOVES_TO_VEC)"
4877   [(const_int 0)]
4879   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4880                                      <MODE>mode, 0);
4881   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4883   emit_insn (gen_sse2_loadld (operands[4],
4884                               CONST0_RTX (V4SImode), operands[1]));
4886   if (<ssevecmode>mode == V4SFmode)
4887     emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4888   else
4889     emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4890   DONE;
4893 ;; Avoid partial SSE register dependency stalls
4894 (define_split
4895   [(set (match_operand:MODEF 0 "register_operand")
4896         (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))]
4897   "TARGET_SSE2 && TARGET_SSE_MATH
4898    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4899    && optimize_function_for_speed_p (cfun)
4900    && reload_completed && SSE_REG_P (operands[0])"
4901   [(const_int 0)]
4903   const machine_mode vmode = <MODEF:ssevecmode>mode;
4904   const machine_mode mode = <MODEF:MODE>mode;
4905   rtx t, op0 = simplify_gen_subreg (vmode, operands[0], mode, 0);
4907   emit_move_insn (op0, CONST0_RTX (vmode));
4909   t = gen_rtx_FLOAT (mode, operands[1]);
4910   t = gen_rtx_VEC_DUPLICATE (vmode, t);
4911   t = gen_rtx_VEC_MERGE (vmode, t, op0, const1_rtx);
4912   emit_insn (gen_rtx_SET (VOIDmode, op0, t));
4913   DONE;
4916 ;; Break partial reg stall for cvtsd2ss.
4918 (define_peephole2
4919   [(set (match_operand:SF 0 "register_operand")
4920         (float_truncate:SF
4921           (match_operand:DF 1 "nonimmediate_operand")))]
4922   "TARGET_SSE2 && TARGET_SSE_MATH
4923    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4924    && optimize_function_for_speed_p (cfun)
4925    && SSE_REG_P (operands[0])
4926    && (!SSE_REG_P (operands[1])
4927        || REGNO (operands[0]) != REGNO (operands[1]))"
4928   [(set (match_dup 0)
4929         (vec_merge:V4SF
4930           (vec_duplicate:V4SF
4931             (float_truncate:V2SF
4932               (match_dup 1)))
4933           (match_dup 0)
4934           (const_int 1)))]
4936   operands[0] = simplify_gen_subreg (V4SFmode, operands[0],
4937                                      SFmode, 0);
4938   operands[1] = simplify_gen_subreg (V2DFmode, operands[1],
4939                                      DFmode, 0);
4940   emit_move_insn (operands[0], CONST0_RTX (V4SFmode));
4943 ;; Break partial reg stall for cvtss2sd.
4945 (define_peephole2
4946   [(set (match_operand:DF 0 "register_operand")
4947         (float_extend:DF
4948           (match_operand:SF 1 "nonimmediate_operand")))]
4949   "TARGET_SSE2 && TARGET_SSE_MATH
4950    && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4951    && optimize_function_for_speed_p (cfun)
4952    && SSE_REG_P (operands[0])
4953    && (!SSE_REG_P (operands[1])
4954        || REGNO (operands[0]) != REGNO (operands[1]))"
4955   [(set (match_dup 0)
4956         (vec_merge:V2DF
4957           (float_extend:V2DF
4958             (vec_select:V2SF
4959               (match_dup 1)
4960               (parallel [(const_int 0) (const_int 1)])))
4961           (match_dup 0)
4962           (const_int 1)))]
4964   operands[0] = simplify_gen_subreg (V2DFmode, operands[0],
4965                                      DFmode, 0);
4966   operands[1] = simplify_gen_subreg (V4SFmode, operands[1],
4967                                      SFmode, 0);
4968   emit_move_insn (operands[0], CONST0_RTX (V2DFmode));
4971 ;; Avoid store forwarding (partial memory) stall penalty
4972 ;; by passing DImode value through XMM registers.  */
4974 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4975   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4976         (float:X87MODEF
4977           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4978    (clobber (match_scratch:V4SI 3 "=X,x"))
4979    (clobber (match_scratch:V4SI 4 "=X,x"))
4980    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4981   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4982    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4983    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4984   "#"
4985   [(set_attr "type" "multi")
4986    (set_attr "mode" "<X87MODEF:MODE>")
4987    (set_attr "unit" "i387")
4988    (set_attr "fp_int_src" "true")])
4990 (define_split
4991   [(set (match_operand:X87MODEF 0 "fp_register_operand")
4992         (float:X87MODEF (match_operand:DI 1 "register_operand")))
4993    (clobber (match_scratch:V4SI 3))
4994    (clobber (match_scratch:V4SI 4))
4995    (clobber (match_operand:DI 2 "memory_operand"))]
4996   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4997    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4998    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4999    && reload_completed"
5000   [(set (match_dup 2) (match_dup 3))
5001    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5003   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5004      Assemble the 64-bit DImode value in an xmm register.  */
5005   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5006                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5007   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5008                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5009   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5010                                          operands[4]));
5012   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5015 (define_split
5016   [(set (match_operand:X87MODEF 0 "fp_register_operand")
5017         (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5018    (clobber (match_scratch:V4SI 3))
5019    (clobber (match_scratch:V4SI 4))
5020    (clobber (match_operand:DI 2 "memory_operand"))]
5021   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5022    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5023    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5024    && reload_completed"
5025   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5027 (define_expand "floatuns<SWI12:mode><MODEF:mode>2"
5028   [(set (match_operand:MODEF 0 "register_operand")
5029         (unsigned_float:MODEF
5030           (match_operand:SWI12 1 "nonimmediate_operand")))]
5031   "!TARGET_64BIT
5032    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5034   operands[1] = convert_to_mode (SImode, operands[1], 1);
5035   emit_insn (gen_floatsi<MODEF:mode>2 (operands[0], operands[1]));
5036   DONE;
5039 ;; Avoid store forwarding (partial memory) stall penalty by extending
5040 ;; SImode value to DImode through XMM register instead of pushing two
5041 ;; SImode values to stack. Also note that fild loads from memory only.
5043 (define_insn_and_split "*floatunssi<mode>2_i387_with_xmm"
5044   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5045         (unsigned_float:X87MODEF
5046           (match_operand:SI 1 "nonimmediate_operand" "rm")))
5047    (clobber (match_scratch:DI 3 "=x"))
5048    (clobber (match_operand:DI 2 "memory_operand" "=m"))]
5049   "!TARGET_64BIT
5050    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5051    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC"
5052   "#"
5053   "&& reload_completed"
5054   [(set (match_dup 3) (zero_extend:DI (match_dup 1)))
5055    (set (match_dup 2) (match_dup 3))
5056    (set (match_dup 0)
5057         (float:X87MODEF (match_dup 2)))]
5058   ""
5059   [(set_attr "type" "multi")
5060    (set_attr "mode" "<MODE>")])
5062 (define_expand "floatunssi<mode>2"
5063   [(parallel
5064      [(set (match_operand:X87MODEF 0 "register_operand")
5065            (unsigned_float:X87MODEF
5066              (match_operand:SI 1 "nonimmediate_operand")))
5067       (clobber (match_scratch:DI 3))
5068       (clobber (match_dup 2))])]
5069   "!TARGET_64BIT
5070    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5071         && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC)
5072        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5074   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5075     {
5076       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5077       DONE;
5078     }
5079   else
5080     operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5083 (define_expand "floatunsdisf2"
5084   [(use (match_operand:SF 0 "register_operand"))
5085    (use (match_operand:DI 1 "nonimmediate_operand"))]
5086   "TARGET_64BIT && TARGET_SSE_MATH"
5087   "x86_emit_floatuns (operands); DONE;")
5089 (define_expand "floatunsdidf2"
5090   [(use (match_operand:DF 0 "register_operand"))
5091    (use (match_operand:DI 1 "nonimmediate_operand"))]
5092   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5093    && TARGET_SSE2 && TARGET_SSE_MATH"
5095   if (TARGET_64BIT)
5096     x86_emit_floatuns (operands);
5097   else
5098     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5099   DONE;
5102 ;; Load effective address instructions
5104 (define_insn_and_split "*lea<mode>"
5105   [(set (match_operand:SWI48 0 "register_operand" "=r")
5106         (match_operand:SWI48 1 "address_no_seg_operand" "Ts"))]
5107   ""
5109   if (SImode_address_operand (operands[1], VOIDmode))
5110     {
5111       gcc_assert (TARGET_64BIT);
5112       return "lea{l}\t{%E1, %k0|%k0, %E1}";
5113     }
5114   else 
5115     return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5117   "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5118   [(const_int 0)]
5120   machine_mode mode = <MODE>mode;
5121   rtx pat;
5123   /* ix86_avoid_lea_for_addr re-recognizes insn and may
5124      change operands[] array behind our back.  */
5125   pat = PATTERN (curr_insn);
5127   operands[0] = SET_DEST (pat);
5128   operands[1] = SET_SRC (pat);
5130   /* Emit all operations in SImode for zero-extended addresses.  */
5131   if (SImode_address_operand (operands[1], VOIDmode))
5132     mode = SImode;
5134   ix86_split_lea_for_addr (curr_insn, operands, mode);
5136   /* Zero-extend return register to DImode for zero-extended addresses.  */
5137   if (mode != <MODE>mode)
5138     emit_insn (gen_zero_extendsidi2
5139                (operands[0], gen_lowpart (mode, operands[0])));
5141   DONE;
5143   [(set_attr "type" "lea")
5144    (set (attr "mode")
5145      (if_then_else
5146        (match_operand 1 "SImode_address_operand")
5147        (const_string "SI")
5148        (const_string "<MODE>")))])
5150 ;; Add instructions
5152 (define_expand "add<mode>3"
5153   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5154         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5155                     (match_operand:SDWIM 2 "<general_operand>")))]
5156   ""
5157   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5159 (define_insn_and_split "*add<dwi>3_doubleword"
5160   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5161         (plus:<DWI>
5162           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5163           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5164    (clobber (reg:CC FLAGS_REG))]
5165   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5166   "#"
5167   "reload_completed"
5168   [(parallel [(set (reg:CC FLAGS_REG)
5169                    (unspec:CC [(match_dup 1) (match_dup 2)]
5170                               UNSPEC_ADD_CARRY))
5171               (set (match_dup 0)
5172                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5173    (parallel [(set (match_dup 3)
5174                    (plus:DWIH
5175                      (match_dup 4)
5176                      (plus:DWIH
5177                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5178                        (match_dup 5))))
5179               (clobber (reg:CC FLAGS_REG))])]
5180   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5182 (define_insn "*add<mode>3_cc"
5183   [(set (reg:CC FLAGS_REG)
5184         (unspec:CC
5185           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5186            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5187           UNSPEC_ADD_CARRY))
5188    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5189         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5190   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5191   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5192   [(set_attr "type" "alu")
5193    (set_attr "mode" "<MODE>")])
5195 (define_insn "addqi3_cc"
5196   [(set (reg:CC FLAGS_REG)
5197         (unspec:CC
5198           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5199            (match_operand:QI 2 "general_operand" "qn,qm")]
5200           UNSPEC_ADD_CARRY))
5201    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5202         (plus:QI (match_dup 1) (match_dup 2)))]
5203   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5204   "add{b}\t{%2, %0|%0, %2}"
5205   [(set_attr "type" "alu")
5206    (set_attr "mode" "QI")])
5208 (define_insn "*add<mode>_1"
5209   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5210         (plus:SWI48
5211           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5212           (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5213    (clobber (reg:CC FLAGS_REG))]
5214   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5216   switch (get_attr_type (insn))
5217     {
5218     case TYPE_LEA:
5219       return "#";
5221     case TYPE_INCDEC:
5222       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5223       if (operands[2] == const1_rtx)
5224         return "inc{<imodesuffix>}\t%0";
5225       else
5226         {
5227           gcc_assert (operands[2] == constm1_rtx);
5228           return "dec{<imodesuffix>}\t%0";
5229         }
5231     default:
5232       /* For most processors, ADD is faster than LEA.  This alternative
5233          was added to use ADD as much as possible.  */
5234       if (which_alternative == 2)
5235         std::swap (operands[1], operands[2]);
5236         
5237       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5238       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5239         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5241       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5242     }
5244   [(set (attr "type")
5245      (cond [(eq_attr "alternative" "3")
5246               (const_string "lea")
5247             (match_operand:SWI48 2 "incdec_operand")
5248               (const_string "incdec")
5249            ]
5250            (const_string "alu")))
5251    (set (attr "length_immediate")
5252       (if_then_else
5253         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5254         (const_string "1")
5255         (const_string "*")))
5256    (set_attr "mode" "<MODE>")])
5258 ;; It may seem that nonimmediate operand is proper one for operand 1.
5259 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5260 ;; we take care in ix86_binary_operator_ok to not allow two memory
5261 ;; operands so proper swapping will be done in reload.  This allow
5262 ;; patterns constructed from addsi_1 to match.
5264 (define_insn "addsi_1_zext"
5265   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5266         (zero_extend:DI
5267           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5268                    (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5269    (clobber (reg:CC FLAGS_REG))]
5270   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5272   switch (get_attr_type (insn))
5273     {
5274     case TYPE_LEA:
5275       return "#";
5277     case TYPE_INCDEC:
5278       if (operands[2] == const1_rtx)
5279         return "inc{l}\t%k0";
5280       else
5281         {
5282           gcc_assert (operands[2] == constm1_rtx);
5283           return "dec{l}\t%k0";
5284         }
5286     default:
5287       /* For most processors, ADD is faster than LEA.  This alternative
5288          was added to use ADD as much as possible.  */
5289       if (which_alternative == 1)
5290         std::swap (operands[1], operands[2]);
5292       if (x86_maybe_negate_const_int (&operands[2], SImode))
5293         return "sub{l}\t{%2, %k0|%k0, %2}";
5295       return "add{l}\t{%2, %k0|%k0, %2}";
5296     }
5298   [(set (attr "type")
5299      (cond [(eq_attr "alternative" "2")
5300               (const_string "lea")
5301             (match_operand:SI 2 "incdec_operand")
5302               (const_string "incdec")
5303            ]
5304            (const_string "alu")))
5305    (set (attr "length_immediate")
5306       (if_then_else
5307         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5308         (const_string "1")
5309         (const_string "*")))
5310    (set_attr "mode" "SI")])
5312 (define_insn "*addhi_1"
5313   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5314         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5315                  (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5316    (clobber (reg:CC FLAGS_REG))]
5317   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5319   switch (get_attr_type (insn))
5320     {
5321     case TYPE_LEA:
5322       return "#";
5324     case TYPE_INCDEC:
5325       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5326       if (operands[2] == const1_rtx)
5327         return "inc{w}\t%0";
5328       else
5329         {
5330           gcc_assert (operands[2] == constm1_rtx);
5331           return "dec{w}\t%0";
5332         }
5334     default:
5335       /* For most processors, ADD is faster than LEA.  This alternative
5336          was added to use ADD as much as possible.  */
5337       if (which_alternative == 2)
5338         std::swap (operands[1], operands[2]);
5340       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5341       if (x86_maybe_negate_const_int (&operands[2], HImode))
5342         return "sub{w}\t{%2, %0|%0, %2}";
5344       return "add{w}\t{%2, %0|%0, %2}";
5345     }
5347   [(set (attr "type")
5348      (cond [(eq_attr "alternative" "3")
5349               (const_string "lea")
5350             (match_operand:HI 2 "incdec_operand")
5351               (const_string "incdec")
5352            ]
5353            (const_string "alu")))
5354    (set (attr "length_immediate")
5355       (if_then_else
5356         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5357         (const_string "1")
5358         (const_string "*")))
5359    (set_attr "mode" "HI,HI,HI,SI")])
5361 ;; %%% Potential partial reg stall on alternatives 3 and 4.  What to do?
5362 (define_insn "*addqi_1"
5363   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5364         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5365                  (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5366    (clobber (reg:CC FLAGS_REG))]
5367   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5369   bool widen = (which_alternative == 3 || which_alternative == 4);
5371   switch (get_attr_type (insn))
5372     {
5373     case TYPE_LEA:
5374       return "#";
5376     case TYPE_INCDEC:
5377       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5378       if (operands[2] == const1_rtx)
5379         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5380       else
5381         {
5382           gcc_assert (operands[2] == constm1_rtx);
5383           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5384         }
5386     default:
5387       /* For most processors, ADD is faster than LEA.  These alternatives
5388          were added to use ADD as much as possible.  */
5389       if (which_alternative == 2 || which_alternative == 4)
5390         std::swap (operands[1], operands[2]);
5392       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5393       if (x86_maybe_negate_const_int (&operands[2], QImode))
5394         {
5395           if (widen)
5396             return "sub{l}\t{%2, %k0|%k0, %2}";
5397           else
5398             return "sub{b}\t{%2, %0|%0, %2}";
5399         }
5400       if (widen)
5401         return "add{l}\t{%k2, %k0|%k0, %k2}";
5402       else
5403         return "add{b}\t{%2, %0|%0, %2}";
5404     }
5406   [(set (attr "type")
5407      (cond [(eq_attr "alternative" "5")
5408               (const_string "lea")
5409             (match_operand:QI 2 "incdec_operand")
5410               (const_string "incdec")
5411            ]
5412            (const_string "alu")))
5413    (set (attr "length_immediate")
5414       (if_then_else
5415         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5416         (const_string "1")
5417         (const_string "*")))
5418    (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5420 (define_insn "*addqi_1_slp"
5421   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5422         (plus:QI (match_dup 0)
5423                  (match_operand:QI 1 "general_operand" "qn,qm")))
5424    (clobber (reg:CC FLAGS_REG))]
5425   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5426    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5428   switch (get_attr_type (insn))
5429     {
5430     case TYPE_INCDEC:
5431       if (operands[1] == const1_rtx)
5432         return "inc{b}\t%0";
5433       else
5434         {
5435           gcc_assert (operands[1] == constm1_rtx);
5436           return "dec{b}\t%0";
5437         }
5439     default:
5440       if (x86_maybe_negate_const_int (&operands[1], QImode))
5441         return "sub{b}\t{%1, %0|%0, %1}";
5443       return "add{b}\t{%1, %0|%0, %1}";
5444     }
5446   [(set (attr "type")
5447      (if_then_else (match_operand:QI 1 "incdec_operand")
5448         (const_string "incdec")
5449         (const_string "alu1")))
5450    (set (attr "memory")
5451      (if_then_else (match_operand 1 "memory_operand")
5452         (const_string "load")
5453         (const_string "none")))
5454    (set_attr "mode" "QI")])
5456 ;; Split non destructive adds if we cannot use lea.
5457 (define_split
5458   [(set (match_operand:SWI48 0 "register_operand")
5459         (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5460                     (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5461    (clobber (reg:CC FLAGS_REG))]
5462   "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5463   [(set (match_dup 0) (match_dup 1))
5464    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5465               (clobber (reg:CC FLAGS_REG))])])
5467 ;; Convert add to the lea pattern to avoid flags dependency.
5468 (define_split
5469   [(set (match_operand:SWI 0 "register_operand")
5470         (plus:SWI (match_operand:SWI 1 "register_operand")
5471                   (match_operand:SWI 2 "<nonmemory_operand>")))
5472    (clobber (reg:CC FLAGS_REG))]
5473   "reload_completed && ix86_lea_for_add_ok (insn, operands)" 
5474   [(const_int 0)]
5476   machine_mode mode = <MODE>mode;
5477   rtx pat;
5479   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
5480     { 
5481       mode = SImode; 
5482       operands[0] = gen_lowpart (mode, operands[0]);
5483       operands[1] = gen_lowpart (mode, operands[1]);
5484       operands[2] = gen_lowpart (mode, operands[2]);
5485     }
5487   pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5489   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5490   DONE;
5493 ;; Split non destructive adds if we cannot use lea.
5494 (define_split
5495   [(set (match_operand:DI 0 "register_operand")
5496         (zero_extend:DI
5497           (plus:SI (match_operand:SI 1 "register_operand")
5498                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5499    (clobber (reg:CC FLAGS_REG))]
5500   "TARGET_64BIT
5501    && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5502   [(set (match_dup 3) (match_dup 1))
5503    (parallel [(set (match_dup 0)
5504                    (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5505               (clobber (reg:CC FLAGS_REG))])]
5506   "operands[3] = gen_lowpart (SImode, operands[0]);")
5508 ;; Convert add to the lea pattern to avoid flags dependency.
5509 (define_split
5510   [(set (match_operand:DI 0 "register_operand")
5511         (zero_extend:DI
5512           (plus:SI (match_operand:SI 1 "register_operand")
5513                    (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5514    (clobber (reg:CC FLAGS_REG))]
5515   "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5516   [(set (match_dup 0)
5517         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5519 (define_insn "*add<mode>_2"
5520   [(set (reg FLAGS_REG)
5521         (compare
5522           (plus:SWI
5523             (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5524             (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5525           (const_int 0)))
5526    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5527         (plus:SWI (match_dup 1) (match_dup 2)))]
5528   "ix86_match_ccmode (insn, CCGOCmode)
5529    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5531   switch (get_attr_type (insn))
5532     {
5533     case TYPE_INCDEC:
5534       if (operands[2] == const1_rtx)
5535         return "inc{<imodesuffix>}\t%0";
5536       else
5537         {
5538           gcc_assert (operands[2] == constm1_rtx);
5539           return "dec{<imodesuffix>}\t%0";
5540         }
5542     default:
5543       if (which_alternative == 2)
5544         std::swap (operands[1], operands[2]);
5545         
5546       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5547       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5548         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5550       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5551     }
5553   [(set (attr "type")
5554      (if_then_else (match_operand:SWI 2 "incdec_operand")
5555         (const_string "incdec")
5556         (const_string "alu")))
5557    (set (attr "length_immediate")
5558       (if_then_else
5559         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5560         (const_string "1")
5561         (const_string "*")))
5562    (set_attr "mode" "<MODE>")])
5564 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5565 (define_insn "*addsi_2_zext"
5566   [(set (reg FLAGS_REG)
5567         (compare
5568           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5569                    (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5570           (const_int 0)))
5571    (set (match_operand:DI 0 "register_operand" "=r,r")
5572         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5573   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5574    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5576   switch (get_attr_type (insn))
5577     {
5578     case TYPE_INCDEC:
5579       if (operands[2] == const1_rtx)
5580         return "inc{l}\t%k0";
5581       else
5582         {
5583           gcc_assert (operands[2] == constm1_rtx);
5584           return "dec{l}\t%k0";
5585         }
5587     default:
5588       if (which_alternative == 1)
5589         std::swap (operands[1], operands[2]);
5591       if (x86_maybe_negate_const_int (&operands[2], SImode))
5592         return "sub{l}\t{%2, %k0|%k0, %2}";
5594       return "add{l}\t{%2, %k0|%k0, %2}";
5595     }
5597   [(set (attr "type")
5598      (if_then_else (match_operand:SI 2 "incdec_operand")
5599         (const_string "incdec")
5600         (const_string "alu")))
5601    (set (attr "length_immediate")
5602       (if_then_else
5603         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5604         (const_string "1")
5605         (const_string "*")))
5606    (set_attr "mode" "SI")])
5608 (define_insn "*add<mode>_3"
5609   [(set (reg FLAGS_REG)
5610         (compare
5611           (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5612           (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5613    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5614   "ix86_match_ccmode (insn, CCZmode)
5615    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5617   switch (get_attr_type (insn))
5618     {
5619     case TYPE_INCDEC:
5620       if (operands[2] == const1_rtx)
5621         return "inc{<imodesuffix>}\t%0";
5622       else
5623         {
5624           gcc_assert (operands[2] == constm1_rtx);
5625           return "dec{<imodesuffix>}\t%0";
5626         }
5628     default:
5629       if (which_alternative == 1)
5630         std::swap (operands[1], operands[2]);
5632       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5633       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5634         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5636       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5637     }
5639   [(set (attr "type")
5640      (if_then_else (match_operand:SWI 2 "incdec_operand")
5641         (const_string "incdec")
5642         (const_string "alu")))
5643    (set (attr "length_immediate")
5644       (if_then_else
5645         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5646         (const_string "1")
5647         (const_string "*")))
5648    (set_attr "mode" "<MODE>")])
5650 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5651 (define_insn "*addsi_3_zext"
5652   [(set (reg FLAGS_REG)
5653         (compare
5654           (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5655           (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5656    (set (match_operand:DI 0 "register_operand" "=r,r")
5657         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5658   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5659    && ix86_binary_operator_ok (PLUS, SImode, operands)"
5661   switch (get_attr_type (insn))
5662     {
5663     case TYPE_INCDEC:
5664       if (operands[2] == const1_rtx)
5665         return "inc{l}\t%k0";
5666       else
5667         {
5668           gcc_assert (operands[2] == constm1_rtx);
5669           return "dec{l}\t%k0";
5670         }
5672     default:
5673       if (which_alternative == 1)
5674         std::swap (operands[1], operands[2]);
5676       if (x86_maybe_negate_const_int (&operands[2], SImode))
5677         return "sub{l}\t{%2, %k0|%k0, %2}";
5679       return "add{l}\t{%2, %k0|%k0, %2}";
5680     }
5682   [(set (attr "type")
5683      (if_then_else (match_operand:SI 2 "incdec_operand")
5684         (const_string "incdec")
5685         (const_string "alu")))
5686    (set (attr "length_immediate")
5687       (if_then_else
5688         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5689         (const_string "1")
5690         (const_string "*")))
5691    (set_attr "mode" "SI")])
5693 ; For comparisons against 1, -1 and 128, we may generate better code
5694 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5695 ; is matched then.  We can't accept general immediate, because for
5696 ; case of overflows,  the result is messed up.
5697 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5698 ; only for comparisons not depending on it.
5700 (define_insn "*adddi_4"
5701   [(set (reg FLAGS_REG)
5702         (compare
5703           (match_operand:DI 1 "nonimmediate_operand" "0")
5704           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5705    (clobber (match_scratch:DI 0 "=rm"))]
5706   "TARGET_64BIT
5707    && ix86_match_ccmode (insn, CCGCmode)"
5709   switch (get_attr_type (insn))
5710     {
5711     case TYPE_INCDEC:
5712       if (operands[2] == constm1_rtx)
5713         return "inc{q}\t%0";
5714       else
5715         {
5716           gcc_assert (operands[2] == const1_rtx);
5717           return "dec{q}\t%0";
5718         }
5720     default:
5721       if (x86_maybe_negate_const_int (&operands[2], DImode))
5722         return "add{q}\t{%2, %0|%0, %2}";
5724       return "sub{q}\t{%2, %0|%0, %2}";
5725     }
5727   [(set (attr "type")
5728      (if_then_else (match_operand:DI 2 "incdec_operand")
5729         (const_string "incdec")
5730         (const_string "alu")))
5731    (set (attr "length_immediate")
5732       (if_then_else
5733         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5734         (const_string "1")
5735         (const_string "*")))
5736    (set_attr "mode" "DI")])
5738 ; For comparisons against 1, -1 and 128, we may generate better code
5739 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
5740 ; is matched then.  We can't accept general immediate, because for
5741 ; case of overflows,  the result is messed up.
5742 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5743 ; only for comparisons not depending on it.
5745 (define_insn "*add<mode>_4"
5746   [(set (reg FLAGS_REG)
5747         (compare
5748           (match_operand:SWI124 1 "nonimmediate_operand" "0")
5749           (match_operand:SWI124 2 "const_int_operand" "n")))
5750    (clobber (match_scratch:SWI124 0 "=<r>m"))]
5751   "ix86_match_ccmode (insn, CCGCmode)"
5753   switch (get_attr_type (insn))
5754     {
5755     case TYPE_INCDEC:
5756       if (operands[2] == constm1_rtx)
5757         return "inc{<imodesuffix>}\t%0";
5758       else
5759         {
5760           gcc_assert (operands[2] == const1_rtx);
5761           return "dec{<imodesuffix>}\t%0";
5762         }
5764     default:
5765       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5766         return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5768       return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5769     }
5771   [(set (attr "type")
5772      (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5773         (const_string "incdec")
5774         (const_string "alu")))
5775    (set (attr "length_immediate")
5776       (if_then_else
5777         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5778         (const_string "1")
5779         (const_string "*")))
5780    (set_attr "mode" "<MODE>")])
5782 (define_insn "*add<mode>_5"
5783   [(set (reg FLAGS_REG)
5784         (compare
5785           (plus:SWI
5786             (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5787             (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5788           (const_int 0)))
5789    (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5790   "ix86_match_ccmode (insn, CCGOCmode)
5791    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5793   switch (get_attr_type (insn))
5794     {
5795     case TYPE_INCDEC:
5796       if (operands[2] == const1_rtx)
5797         return "inc{<imodesuffix>}\t%0";
5798       else
5799         {
5800           gcc_assert (operands[2] == constm1_rtx);
5801           return "dec{<imodesuffix>}\t%0";
5802         }
5804     default:
5805       if (which_alternative == 1)
5806         std::swap (operands[1], operands[2]);
5808       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5809       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5810         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5812       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5813     }
5815   [(set (attr "type")
5816      (if_then_else (match_operand:SWI 2 "incdec_operand")
5817         (const_string "incdec")
5818         (const_string "alu")))
5819    (set (attr "length_immediate")
5820       (if_then_else
5821         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5822         (const_string "1")
5823         (const_string "*")))
5824    (set_attr "mode" "<MODE>")])
5826 (define_insn "addqi_ext_1"
5827   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5828                          (const_int 8)
5829                          (const_int 8))
5830         (plus:SI
5831           (zero_extract:SI
5832             (match_operand 1 "ext_register_operand" "0,0")
5833             (const_int 8)
5834             (const_int 8))
5835           (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5836    (clobber (reg:CC FLAGS_REG))]
5837   ""
5839   switch (get_attr_type (insn))
5840     {
5841     case TYPE_INCDEC:
5842       if (operands[2] == const1_rtx)
5843         return "inc{b}\t%h0";
5844       else
5845         {
5846           gcc_assert (operands[2] == constm1_rtx);
5847           return "dec{b}\t%h0";
5848         }
5850     default:
5851       return "add{b}\t{%2, %h0|%h0, %2}";
5852     }
5854   [(set_attr "isa" "*,nox64")
5855    (set (attr "type")
5856      (if_then_else (match_operand:QI 2 "incdec_operand")
5857         (const_string "incdec")
5858         (const_string "alu")))
5859    (set_attr "modrm" "1")
5860    (set_attr "mode" "QI")])
5862 (define_insn "*addqi_ext_2"
5863   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5864                          (const_int 8)
5865                          (const_int 8))
5866         (plus:SI
5867           (zero_extract:SI
5868             (match_operand 1 "ext_register_operand" "%0")
5869             (const_int 8)
5870             (const_int 8))
5871           (zero_extract:SI
5872             (match_operand 2 "ext_register_operand" "Q")
5873             (const_int 8)
5874             (const_int 8))))
5875    (clobber (reg:CC FLAGS_REG))]
5876   ""
5877   "add{b}\t{%h2, %h0|%h0, %h2}"
5878   [(set_attr "type" "alu")
5879    (set_attr "mode" "QI")])
5881 ;; Add with jump on overflow.
5882 (define_expand "addv<mode>4"
5883   [(parallel [(set (reg:CCO FLAGS_REG)
5884                    (eq:CCO (plus:<DWI>
5885                               (sign_extend:<DWI>
5886                                  (match_operand:SWI 1 "nonimmediate_operand"))
5887                               (match_dup 4))
5888                            (sign_extend:<DWI>
5889                               (plus:SWI (match_dup 1)
5890                                         (match_operand:SWI 2
5891                                            "<general_operand>")))))
5892               (set (match_operand:SWI 0 "register_operand")
5893                    (plus:SWI (match_dup 1) (match_dup 2)))])
5894    (set (pc) (if_then_else
5895                (eq (reg:CCO FLAGS_REG) (const_int 0))
5896                (label_ref (match_operand 3))
5897                (pc)))]
5898   ""
5900   ix86_fixup_binary_operands_no_copy (PLUS, <MODE>mode, operands);
5901   if (CONST_INT_P (operands[2]))
5902     operands[4] = operands[2];
5903   else
5904     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
5907 (define_insn "*addv<mode>4"
5908   [(set (reg:CCO FLAGS_REG)
5909         (eq:CCO (plus:<DWI>
5910                    (sign_extend:<DWI>
5911                       (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5912                    (sign_extend:<DWI>
5913                       (match_operand:SWI 2 "<general_sext_operand>"
5914                                            "<r>mWe,<r>We")))
5915                 (sign_extend:<DWI>
5916                    (plus:SWI (match_dup 1) (match_dup 2)))))
5917    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5918         (plus:SWI (match_dup 1) (match_dup 2)))]
5919   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5920   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5921   [(set_attr "type" "alu")
5922    (set_attr "mode" "<MODE>")])
5924 (define_insn "*addv<mode>4_1"
5925   [(set (reg:CCO FLAGS_REG)
5926         (eq:CCO (plus:<DWI>
5927                    (sign_extend:<DWI>
5928                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
5929                    (match_operand:<DWI> 3 "const_int_operand" "i"))
5930                 (sign_extend:<DWI>
5931                    (plus:SWI (match_dup 1)
5932                              (match_operand:SWI 2 "x86_64_immediate_operand"
5933                                                   "<i>")))))
5934    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
5935         (plus:SWI (match_dup 1) (match_dup 2)))]
5936   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
5937    && CONST_INT_P (operands[2])
5938    && INTVAL (operands[2]) == INTVAL (operands[3])"
5939   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5940   [(set_attr "type" "alu")
5941    (set_attr "mode" "<MODE>")
5942    (set (attr "length_immediate")
5943         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
5944                   (const_string "1")
5945                (match_test "<MODE_SIZE> == 8")
5946                   (const_string "4")]
5947               (const_string "<MODE_SIZE>")))])
5949 ;; The lea patterns for modes less than 32 bits need to be matched by
5950 ;; several insns converted to real lea by splitters.
5952 (define_insn_and_split "*lea_general_1"
5953   [(set (match_operand 0 "register_operand" "=r")
5954         (plus (plus (match_operand 1 "index_register_operand" "l")
5955                     (match_operand 2 "register_operand" "r"))
5956               (match_operand 3 "immediate_operand" "i")))]
5957   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5958    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5959    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5960    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5961    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5962        || GET_MODE (operands[3]) == VOIDmode)"
5963   "#"
5964   "&& reload_completed"
5965   [(const_int 0)]
5967   machine_mode mode = SImode;
5968   rtx pat;
5970   operands[0] = gen_lowpart (mode, operands[0]);
5971   operands[1] = gen_lowpart (mode, operands[1]);
5972   operands[2] = gen_lowpart (mode, operands[2]);
5973   operands[3] = gen_lowpart (mode, operands[3]);
5975   pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5976                       operands[3]);
5978   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5979   DONE;
5981   [(set_attr "type" "lea")
5982    (set_attr "mode" "SI")])
5984 (define_insn_and_split "*lea_general_2"
5985   [(set (match_operand 0 "register_operand" "=r")
5986         (plus (mult (match_operand 1 "index_register_operand" "l")
5987                     (match_operand 2 "const248_operand" "n"))
5988               (match_operand 3 "nonmemory_operand" "ri")))]
5989   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5990    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5991    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5992    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5993        || GET_MODE (operands[3]) == VOIDmode)"
5994   "#"
5995   "&& reload_completed"
5996   [(const_int 0)]
5998   machine_mode mode = SImode;
5999   rtx pat;
6001   operands[0] = gen_lowpart (mode, operands[0]);
6002   operands[1] = gen_lowpart (mode, operands[1]);
6003   operands[3] = gen_lowpart (mode, operands[3]);
6005   pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6006                       operands[3]);
6008   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6009   DONE;
6011   [(set_attr "type" "lea")
6012    (set_attr "mode" "SI")])
6014 (define_insn_and_split "*lea_general_3"
6015   [(set (match_operand 0 "register_operand" "=r")
6016         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6017                           (match_operand 2 "const248_operand" "n"))
6018                     (match_operand 3 "register_operand" "r"))
6019               (match_operand 4 "immediate_operand" "i")))]
6020   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6021    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6022    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6023    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6024   "#"
6025   "&& reload_completed"
6026   [(const_int 0)]
6028   machine_mode mode = SImode;
6029   rtx pat;
6031   operands[0] = gen_lowpart (mode, operands[0]);
6032   operands[1] = gen_lowpart (mode, operands[1]);
6033   operands[3] = gen_lowpart (mode, operands[3]);
6034   operands[4] = gen_lowpart (mode, operands[4]);
6036   pat = gen_rtx_PLUS (mode,
6037                       gen_rtx_PLUS (mode,
6038                                     gen_rtx_MULT (mode, operands[1],
6039                                                         operands[2]),
6040                                     operands[3]),
6041                       operands[4]);
6043   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6044   DONE;
6046   [(set_attr "type" "lea")
6047    (set_attr "mode" "SI")])
6049 (define_insn_and_split "*lea_general_4"
6050   [(set (match_operand 0 "register_operand" "=r")
6051         (any_or (ashift
6052                   (match_operand 1 "index_register_operand" "l")
6053                   (match_operand 2 "const_int_operand" "n"))
6054                 (match_operand 3 "const_int_operand" "n")))]
6055   "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6056       && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6057     || GET_MODE (operands[0]) == SImode
6058     || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6059    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6060    && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6061    && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6062        < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6063   "#"
6064   "&& reload_completed"
6065   [(const_int 0)]
6067   machine_mode mode = GET_MODE (operands[0]);
6068   rtx pat;
6070   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6071     { 
6072       mode = SImode; 
6073       operands[0] = gen_lowpart (mode, operands[0]);
6074       operands[1] = gen_lowpart (mode, operands[1]);
6075     }
6077   operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6079   pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6080                        INTVAL (operands[3]));
6082   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6083   DONE;
6085   [(set_attr "type" "lea")
6086    (set (attr "mode")
6087       (if_then_else (match_operand:DI 0)
6088         (const_string "DI")
6089         (const_string "SI")))])
6091 ;; Subtract instructions
6093 (define_expand "sub<mode>3"
6094   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6095         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6096                      (match_operand:SDWIM 2 "<general_operand>")))]
6097   ""
6098   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6100 (define_insn_and_split "*sub<dwi>3_doubleword"
6101   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6102         (minus:<DWI>
6103           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6104           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6105    (clobber (reg:CC FLAGS_REG))]
6106   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6107   "#"
6108   "reload_completed"
6109   [(parallel [(set (reg:CC FLAGS_REG)
6110                    (compare:CC (match_dup 1) (match_dup 2)))
6111               (set (match_dup 0)
6112                    (minus:DWIH (match_dup 1) (match_dup 2)))])
6113    (parallel [(set (match_dup 3)
6114                    (minus:DWIH
6115                      (match_dup 4)
6116                      (plus:DWIH
6117                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6118                        (match_dup 5))))
6119               (clobber (reg:CC FLAGS_REG))])]
6120   "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6122 (define_insn "*sub<mode>_1"
6123   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6124         (minus:SWI
6125           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6126           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6127    (clobber (reg:CC FLAGS_REG))]
6128   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6129   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6130   [(set_attr "type" "alu")
6131    (set_attr "mode" "<MODE>")])
6133 (define_insn "*subsi_1_zext"
6134   [(set (match_operand:DI 0 "register_operand" "=r")
6135         (zero_extend:DI
6136           (minus:SI (match_operand:SI 1 "register_operand" "0")
6137                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6138    (clobber (reg:CC FLAGS_REG))]
6139   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6140   "sub{l}\t{%2, %k0|%k0, %2}"
6141   [(set_attr "type" "alu")
6142    (set_attr "mode" "SI")])
6144 (define_insn "*subqi_1_slp"
6145   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6146         (minus:QI (match_dup 0)
6147                   (match_operand:QI 1 "general_operand" "qn,qm")))
6148    (clobber (reg:CC FLAGS_REG))]
6149   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6150    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6151   "sub{b}\t{%1, %0|%0, %1}"
6152   [(set_attr "type" "alu1")
6153    (set_attr "mode" "QI")])
6155 (define_insn "*sub<mode>_2"
6156   [(set (reg FLAGS_REG)
6157         (compare
6158           (minus:SWI
6159             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6160             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6161           (const_int 0)))
6162    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6163         (minus:SWI (match_dup 1) (match_dup 2)))]
6164   "ix86_match_ccmode (insn, CCGOCmode)
6165    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6166   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6167   [(set_attr "type" "alu")
6168    (set_attr "mode" "<MODE>")])
6170 (define_insn "*subsi_2_zext"
6171   [(set (reg FLAGS_REG)
6172         (compare
6173           (minus:SI (match_operand:SI 1 "register_operand" "0")
6174                     (match_operand:SI 2 "x86_64_general_operand" "rme"))
6175           (const_int 0)))
6176    (set (match_operand:DI 0 "register_operand" "=r")
6177         (zero_extend:DI
6178           (minus:SI (match_dup 1)
6179                     (match_dup 2))))]
6180   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6181    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6182   "sub{l}\t{%2, %k0|%k0, %2}"
6183   [(set_attr "type" "alu")
6184    (set_attr "mode" "SI")])
6186 ;; Subtract with jump on overflow.
6187 (define_expand "subv<mode>4"
6188   [(parallel [(set (reg:CCO FLAGS_REG)
6189                    (eq:CCO (minus:<DWI>
6190                               (sign_extend:<DWI>
6191                                  (match_operand:SWI 1 "nonimmediate_operand"))
6192                               (match_dup 4))
6193                            (sign_extend:<DWI>
6194                               (minus:SWI (match_dup 1)
6195                                          (match_operand:SWI 2
6196                                             "<general_operand>")))))
6197               (set (match_operand:SWI 0 "register_operand")
6198                    (minus:SWI (match_dup 1) (match_dup 2)))])
6199    (set (pc) (if_then_else
6200                (eq (reg:CCO FLAGS_REG) (const_int 0))
6201                (label_ref (match_operand 3))
6202                (pc)))]
6203   ""
6205   ix86_fixup_binary_operands_no_copy (MINUS, <MODE>mode, operands);
6206   if (CONST_INT_P (operands[2]))
6207     operands[4] = operands[2];
6208   else
6209     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6212 (define_insn "*subv<mode>4"
6213   [(set (reg:CCO FLAGS_REG)
6214         (eq:CCO (minus:<DWI>
6215                    (sign_extend:<DWI>
6216                       (match_operand:SWI 1 "nonimmediate_operand" "0,0"))
6217                    (sign_extend:<DWI>
6218                       (match_operand:SWI 2 "<general_sext_operand>"
6219                                            "<r>We,<r>m")))
6220                 (sign_extend:<DWI>
6221                    (minus:SWI (match_dup 1) (match_dup 2)))))
6222    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6223         (minus:SWI (match_dup 1) (match_dup 2)))]
6224   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6225   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6226   [(set_attr "type" "alu")
6227    (set_attr "mode" "<MODE>")])
6229 (define_insn "*subv<mode>4_1"
6230   [(set (reg:CCO FLAGS_REG)
6231         (eq:CCO (minus:<DWI>
6232                    (sign_extend:<DWI>
6233                       (match_operand:SWI 1 "nonimmediate_operand" "0"))
6234                    (match_operand:<DWI> 3 "const_int_operand" "i"))
6235                 (sign_extend:<DWI>
6236                    (minus:SWI (match_dup 1)
6237                               (match_operand:SWI 2 "x86_64_immediate_operand"
6238                                                    "<i>")))))
6239    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
6240         (minus:SWI (match_dup 1) (match_dup 2)))]
6241   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)
6242    && CONST_INT_P (operands[2])
6243    && INTVAL (operands[2]) == INTVAL (operands[3])"
6244   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6245   [(set_attr "type" "alu")
6246    (set_attr "mode" "<MODE>")
6247    (set (attr "length_immediate")
6248         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6249                   (const_string "1")
6250                (match_test "<MODE_SIZE> == 8")
6251                   (const_string "4")]
6252               (const_string "<MODE_SIZE>")))])
6254 (define_insn "*sub<mode>_3"
6255   [(set (reg FLAGS_REG)
6256         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6257                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6258    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6259         (minus:SWI (match_dup 1) (match_dup 2)))]
6260   "ix86_match_ccmode (insn, CCmode)
6261    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6262   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6263   [(set_attr "type" "alu")
6264    (set_attr "mode" "<MODE>")])
6266 (define_insn "*subsi_3_zext"
6267   [(set (reg FLAGS_REG)
6268         (compare (match_operand:SI 1 "register_operand" "0")
6269                  (match_operand:SI 2 "x86_64_general_operand" "rme")))
6270    (set (match_operand:DI 0 "register_operand" "=r")
6271         (zero_extend:DI
6272           (minus:SI (match_dup 1)
6273                     (match_dup 2))))]
6274   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6275    && ix86_binary_operator_ok (MINUS, SImode, operands)"
6276   "sub{l}\t{%2, %1|%1, %2}"
6277   [(set_attr "type" "alu")
6278    (set_attr "mode" "SI")])
6280 ;; Add with carry and subtract with borrow
6282 (define_expand "<plusminus_insn><mode>3_carry"
6283   [(parallel
6284     [(set (match_operand:SWI 0 "nonimmediate_operand")
6285           (plusminus:SWI
6286             (match_operand:SWI 1 "nonimmediate_operand")
6287             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6288                        [(match_operand 3 "flags_reg_operand")
6289                         (const_int 0)])
6290                       (match_operand:SWI 2 "<general_operand>"))))
6291      (clobber (reg:CC FLAGS_REG))])]
6292   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6294 (define_insn "*<plusminus_insn><mode>3_carry"
6295   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6296         (plusminus:SWI
6297           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6298           (plus:SWI
6299             (match_operator 3 "ix86_carry_flag_operator"
6300              [(reg FLAGS_REG) (const_int 0)])
6301             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6302    (clobber (reg:CC FLAGS_REG))]
6303   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6304   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6305   [(set_attr "type" "alu")
6306    (set_attr "use_carry" "1")
6307    (set_attr "pent_pair" "pu")
6308    (set_attr "mode" "<MODE>")])
6310 (define_insn "*addsi3_carry_zext"
6311   [(set (match_operand:DI 0 "register_operand" "=r")
6312         (zero_extend:DI
6313           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6314                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6315                              [(reg FLAGS_REG) (const_int 0)])
6316                             (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6317    (clobber (reg:CC FLAGS_REG))]
6318   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6319   "adc{l}\t{%2, %k0|%k0, %2}"
6320   [(set_attr "type" "alu")
6321    (set_attr "use_carry" "1")
6322    (set_attr "pent_pair" "pu")
6323    (set_attr "mode" "SI")])
6325 (define_insn "*subsi3_carry_zext"
6326   [(set (match_operand:DI 0 "register_operand" "=r")
6327         (zero_extend:DI
6328           (minus:SI (match_operand:SI 1 "register_operand" "0")
6329                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6330                               [(reg FLAGS_REG) (const_int 0)])
6331                              (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6332    (clobber (reg:CC FLAGS_REG))]
6333   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6334   "sbb{l}\t{%2, %k0|%k0, %2}"
6335   [(set_attr "type" "alu")
6336    (set_attr "pent_pair" "pu")
6337    (set_attr "mode" "SI")])
6339 ;; ADCX instruction
6341 (define_insn "adcx<mode>3"
6342   [(set (reg:CCC FLAGS_REG)
6343         (compare:CCC
6344           (plus:SWI48
6345             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6346             (plus:SWI48
6347               (match_operator 4 "ix86_carry_flag_operator"
6348                [(match_operand 3 "flags_reg_operand") (const_int 0)])
6349               (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6350           (const_int 0)))
6351    (set (match_operand:SWI48 0 "register_operand" "=r")
6352         (plus:SWI48 (match_dup 1)
6353                     (plus:SWI48 (match_op_dup 4
6354                                  [(match_dup 3) (const_int 0)])
6355                                 (match_dup 2))))]
6356   "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6357   "adcx\t{%2, %0|%0, %2}"
6358   [(set_attr "type" "alu")
6359    (set_attr "use_carry" "1")
6360    (set_attr "mode" "<MODE>")])
6362 ;; Overflow setting add instructions
6364 (define_insn "*add<mode>3_cconly_overflow"
6365   [(set (reg:CCC FLAGS_REG)
6366         (compare:CCC
6367           (plus:SWI
6368             (match_operand:SWI 1 "nonimmediate_operand" "%0")
6369             (match_operand:SWI 2 "<general_operand>" "<g>"))
6370           (match_dup 1)))
6371    (clobber (match_scratch:SWI 0 "=<r>"))]
6372   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6373   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6374   [(set_attr "type" "alu")
6375    (set_attr "mode" "<MODE>")])
6377 (define_insn "*add<mode>3_cc_overflow"
6378   [(set (reg:CCC FLAGS_REG)
6379         (compare:CCC
6380             (plus:SWI
6381                 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6382                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6383             (match_dup 1)))
6384    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6385         (plus:SWI (match_dup 1) (match_dup 2)))]
6386   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6387   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6388   [(set_attr "type" "alu")
6389    (set_attr "mode" "<MODE>")])
6391 (define_insn "*addsi3_zext_cc_overflow"
6392   [(set (reg:CCC FLAGS_REG)
6393         (compare:CCC
6394           (plus:SI
6395             (match_operand:SI 1 "nonimmediate_operand" "%0")
6396             (match_operand:SI 2 "x86_64_general_operand" "rme"))
6397           (match_dup 1)))
6398    (set (match_operand:DI 0 "register_operand" "=r")
6399         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6400   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6401   "add{l}\t{%2, %k0|%k0, %2}"
6402   [(set_attr "type" "alu")
6403    (set_attr "mode" "SI")])
6405 ;; The patterns that match these are at the end of this file.
6407 (define_expand "<plusminus_insn>xf3"
6408   [(set (match_operand:XF 0 "register_operand")
6409         (plusminus:XF
6410           (match_operand:XF 1 "register_operand")
6411           (match_operand:XF 2 "register_operand")))]
6412   "TARGET_80387")
6414 (define_expand "<plusminus_insn><mode>3"
6415   [(set (match_operand:MODEF 0 "register_operand")
6416         (plusminus:MODEF
6417           (match_operand:MODEF 1 "register_operand")
6418           (match_operand:MODEF 2 "nonimmediate_operand")))]
6419   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6420     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6422 ;; Multiply instructions
6424 (define_expand "mul<mode>3"
6425   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6426                    (mult:SWIM248
6427                      (match_operand:SWIM248 1 "register_operand")
6428                      (match_operand:SWIM248 2 "<general_operand>")))
6429               (clobber (reg:CC FLAGS_REG))])])
6431 (define_expand "mulqi3"
6432   [(parallel [(set (match_operand:QI 0 "register_operand")
6433                    (mult:QI
6434                      (match_operand:QI 1 "register_operand")
6435                      (match_operand:QI 2 "nonimmediate_operand")))
6436               (clobber (reg:CC FLAGS_REG))])]
6437   "TARGET_QIMODE_MATH")
6439 ;; On AMDFAM10
6440 ;; IMUL reg32/64, reg32/64, imm8        Direct
6441 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
6442 ;; IMUL reg32/64, reg32/64, imm32       Direct
6443 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
6444 ;; IMUL reg32/64, reg32/64              Direct
6445 ;; IMUL reg32/64, mem32/64              Direct
6447 ;; On BDVER1, all above IMULs use DirectPath
6449 (define_insn "*mul<mode>3_1"
6450   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6451         (mult:SWI48
6452           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6453           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6454    (clobber (reg:CC FLAGS_REG))]
6455   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6456   "@
6457    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6458    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6459    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6460   [(set_attr "type" "imul")
6461    (set_attr "prefix_0f" "0,0,1")
6462    (set (attr "athlon_decode")
6463         (cond [(eq_attr "cpu" "athlon")
6464                   (const_string "vector")
6465                (eq_attr "alternative" "1")
6466                   (const_string "vector")
6467                (and (eq_attr "alternative" "2")
6468                     (match_operand 1 "memory_operand"))
6469                   (const_string "vector")]
6470               (const_string "direct")))
6471    (set (attr "amdfam10_decode")
6472         (cond [(and (eq_attr "alternative" "0,1")
6473                     (match_operand 1 "memory_operand"))
6474                   (const_string "vector")]
6475               (const_string "direct")))
6476    (set_attr "bdver1_decode" "direct")
6477    (set_attr "mode" "<MODE>")])
6479 (define_insn "*mulsi3_1_zext"
6480   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6481         (zero_extend:DI
6482           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6483                    (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6484    (clobber (reg:CC FLAGS_REG))]
6485   "TARGET_64BIT
6486    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6487   "@
6488    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6489    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6490    imul{l}\t{%2, %k0|%k0, %2}"
6491   [(set_attr "type" "imul")
6492    (set_attr "prefix_0f" "0,0,1")
6493    (set (attr "athlon_decode")
6494         (cond [(eq_attr "cpu" "athlon")
6495                   (const_string "vector")
6496                (eq_attr "alternative" "1")
6497                   (const_string "vector")
6498                (and (eq_attr "alternative" "2")
6499                     (match_operand 1 "memory_operand"))
6500                   (const_string "vector")]
6501               (const_string "direct")))
6502    (set (attr "amdfam10_decode")
6503         (cond [(and (eq_attr "alternative" "0,1")
6504                     (match_operand 1 "memory_operand"))
6505                   (const_string "vector")]
6506               (const_string "direct")))
6507    (set_attr "bdver1_decode" "direct")
6508    (set_attr "mode" "SI")])
6510 ;; On AMDFAM10
6511 ;; IMUL reg16, reg16, imm8      VectorPath
6512 ;; IMUL reg16, mem16, imm8      VectorPath
6513 ;; IMUL reg16, reg16, imm16     VectorPath
6514 ;; IMUL reg16, mem16, imm16     VectorPath
6515 ;; IMUL reg16, reg16            Direct
6516 ;; IMUL reg16, mem16            Direct
6518 ;; On BDVER1, all HI MULs use DoublePath
6520 (define_insn "*mulhi3_1"
6521   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6522         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6523                  (match_operand:HI 2 "general_operand" "K,n,mr")))
6524    (clobber (reg:CC FLAGS_REG))]
6525   "TARGET_HIMODE_MATH
6526    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6527   "@
6528    imul{w}\t{%2, %1, %0|%0, %1, %2}
6529    imul{w}\t{%2, %1, %0|%0, %1, %2}
6530    imul{w}\t{%2, %0|%0, %2}"
6531   [(set_attr "type" "imul")
6532    (set_attr "prefix_0f" "0,0,1")
6533    (set (attr "athlon_decode")
6534         (cond [(eq_attr "cpu" "athlon")
6535                   (const_string "vector")
6536                (eq_attr "alternative" "1,2")
6537                   (const_string "vector")]
6538               (const_string "direct")))
6539    (set (attr "amdfam10_decode")
6540         (cond [(eq_attr "alternative" "0,1")
6541                   (const_string "vector")]
6542               (const_string "direct")))
6543    (set_attr "bdver1_decode" "double")
6544    (set_attr "mode" "HI")])
6546 ;;On AMDFAM10 and BDVER1
6547 ;; MUL reg8     Direct
6548 ;; MUL mem8     Direct
6550 (define_insn "*mulqi3_1"
6551   [(set (match_operand:QI 0 "register_operand" "=a")
6552         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6553                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
6554    (clobber (reg:CC FLAGS_REG))]
6555   "TARGET_QIMODE_MATH
6556    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6557   "mul{b}\t%2"
6558   [(set_attr "type" "imul")
6559    (set_attr "length_immediate" "0")
6560    (set (attr "athlon_decode")
6561      (if_then_else (eq_attr "cpu" "athlon")
6562         (const_string "vector")
6563         (const_string "direct")))
6564    (set_attr "amdfam10_decode" "direct")
6565    (set_attr "bdver1_decode" "direct")
6566    (set_attr "mode" "QI")])
6568 ;; Multiply with jump on overflow.
6569 (define_expand "mulv<mode>4"
6570   [(parallel [(set (reg:CCO FLAGS_REG)
6571                    (eq:CCO (mult:<DWI>
6572                               (sign_extend:<DWI>
6573                                  (match_operand:SWI48 1 "register_operand"))
6574                               (match_dup 4))
6575                            (sign_extend:<DWI>
6576                               (mult:SWI48 (match_dup 1)
6577                                           (match_operand:SWI48 2
6578                                              "<general_operand>")))))
6579               (set (match_operand:SWI48 0 "register_operand")
6580                    (mult:SWI48 (match_dup 1) (match_dup 2)))])
6581    (set (pc) (if_then_else
6582                (eq (reg:CCO FLAGS_REG) (const_int 0))
6583                (label_ref (match_operand 3))
6584                (pc)))]
6585   ""
6587   if (CONST_INT_P (operands[2]))
6588     operands[4] = operands[2];
6589   else
6590     operands[4] = gen_rtx_SIGN_EXTEND (<DWI>mode, operands[2]);
6593 (define_insn "*mulv<mode>4"
6594   [(set (reg:CCO FLAGS_REG)
6595         (eq:CCO (mult:<DWI>
6596                    (sign_extend:<DWI>
6597                       (match_operand:SWI48 1 "nonimmediate_operand" "%rm,0"))
6598                    (sign_extend:<DWI>
6599                       (match_operand:SWI48 2 "<general_sext_operand>"
6600                                              "We,mr")))
6601                 (sign_extend:<DWI>
6602                    (mult:SWI48 (match_dup 1) (match_dup 2)))))
6603    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6604         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6605   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6606   "@
6607    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6608    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6609   [(set_attr "type" "imul")
6610    (set_attr "prefix_0f" "0,1")
6611    (set (attr "athlon_decode")
6612         (cond [(eq_attr "cpu" "athlon")
6613                   (const_string "vector")
6614                (eq_attr "alternative" "0")
6615                   (const_string "vector")
6616                (and (eq_attr "alternative" "1")
6617                     (match_operand 1 "memory_operand"))
6618                   (const_string "vector")]
6619               (const_string "direct")))
6620    (set (attr "amdfam10_decode")
6621         (cond [(and (eq_attr "alternative" "1")
6622                     (match_operand 1 "memory_operand"))
6623                   (const_string "vector")]
6624               (const_string "direct")))
6625    (set_attr "bdver1_decode" "direct")
6626    (set_attr "mode" "<MODE>")])
6628 (define_insn "*mulv<mode>4_1"
6629   [(set (reg:CCO FLAGS_REG)
6630         (eq:CCO (mult:<DWI>
6631                    (sign_extend:<DWI>
6632                       (match_operand:SWI48 1 "nonimmediate_operand" "rm,rm"))
6633                    (match_operand:<DWI> 3 "const_int_operand" "K,i"))
6634                 (sign_extend:<DWI>
6635                    (mult:SWI48 (match_dup 1)
6636                                (match_operand:SWI 2 "x86_64_immediate_operand"
6637                                                     "K,<i>")))))
6638    (set (match_operand:SWI48 0 "register_operand" "=r,r")
6639         (mult:SWI48 (match_dup 1) (match_dup 2)))]
6640   "!(MEM_P (operands[1]) && MEM_P (operands[2]))
6641    && CONST_INT_P (operands[2])
6642    && INTVAL (operands[2]) == INTVAL (operands[3])"
6643   "@
6644    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6645    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}"
6646   [(set_attr "type" "imul")
6647    (set (attr "athlon_decode")
6648         (cond [(eq_attr "cpu" "athlon")
6649                   (const_string "vector")
6650                (eq_attr "alternative" "1")
6651                   (const_string "vector")]
6652               (const_string "direct")))
6653    (set (attr "amdfam10_decode")
6654         (cond [(match_operand 1 "memory_operand")
6655                   (const_string "vector")]
6656               (const_string "direct")))
6657    (set_attr "bdver1_decode" "direct")
6658    (set_attr "mode" "<MODE>")
6659    (set (attr "length_immediate")
6660         (cond [(match_test "IN_RANGE (INTVAL (operands[2]), -128, 127)")
6661                   (const_string "1")
6662                (match_test "<MODE_SIZE> == 8")
6663                   (const_string "4")]
6664               (const_string "<MODE_SIZE>")))])
6666 (define_expand "<u>mul<mode><dwi>3"
6667   [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6668                    (mult:<DWI>
6669                      (any_extend:<DWI>
6670                        (match_operand:DWIH 1 "nonimmediate_operand"))
6671                      (any_extend:<DWI>
6672                        (match_operand:DWIH 2 "register_operand"))))
6673               (clobber (reg:CC FLAGS_REG))])])
6675 (define_expand "<u>mulqihi3"
6676   [(parallel [(set (match_operand:HI 0 "register_operand")
6677                    (mult:HI
6678                      (any_extend:HI
6679                        (match_operand:QI 1 "nonimmediate_operand"))
6680                      (any_extend:HI
6681                        (match_operand:QI 2 "register_operand"))))
6682               (clobber (reg:CC FLAGS_REG))])]
6683   "TARGET_QIMODE_MATH")
6685 (define_insn "*bmi2_umulditi3_1"
6686   [(set (match_operand:DI 0 "register_operand" "=r")
6687         (mult:DI
6688           (match_operand:DI 2 "nonimmediate_operand" "%d")
6689           (match_operand:DI 3 "nonimmediate_operand" "rm")))
6690    (set (match_operand:DI 1 "register_operand" "=r")
6691         (truncate:DI
6692           (lshiftrt:TI
6693             (mult:TI (zero_extend:TI (match_dup 2))
6694                      (zero_extend:TI (match_dup 3)))
6695             (const_int 64))))]
6696   "TARGET_64BIT && TARGET_BMI2
6697    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6698   "mulx\t{%3, %0, %1|%1, %0, %3}"
6699   [(set_attr "type" "imulx")
6700    (set_attr "prefix" "vex")
6701    (set_attr "mode" "DI")])
6703 (define_insn "*bmi2_umulsidi3_1"
6704   [(set (match_operand:SI 0 "register_operand" "=r")
6705         (mult:SI
6706           (match_operand:SI 2 "nonimmediate_operand" "%d")
6707           (match_operand:SI 3 "nonimmediate_operand" "rm")))
6708    (set (match_operand:SI 1 "register_operand" "=r")
6709         (truncate:SI
6710           (lshiftrt:DI
6711             (mult:DI (zero_extend:DI (match_dup 2))
6712                      (zero_extend:DI (match_dup 3)))
6713             (const_int 32))))]
6714   "!TARGET_64BIT && TARGET_BMI2
6715    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6716   "mulx\t{%3, %0, %1|%1, %0, %3}"
6717   [(set_attr "type" "imulx")
6718    (set_attr "prefix" "vex")
6719    (set_attr "mode" "SI")])
6721 (define_insn "*umul<mode><dwi>3_1"
6722   [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6723         (mult:<DWI>
6724           (zero_extend:<DWI>
6725             (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6726           (zero_extend:<DWI>
6727             (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6728    (clobber (reg:CC FLAGS_REG))]
6729   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6730   "@
6731    #
6732    mul{<imodesuffix>}\t%2"
6733   [(set_attr "isa" "bmi2,*")
6734    (set_attr "type" "imulx,imul")
6735    (set_attr "length_immediate" "*,0")
6736    (set (attr "athlon_decode")
6737         (cond [(eq_attr "alternative" "1")
6738                  (if_then_else (eq_attr "cpu" "athlon")
6739                    (const_string "vector")
6740                    (const_string "double"))]
6741               (const_string "*")))
6742    (set_attr "amdfam10_decode" "*,double")
6743    (set_attr "bdver1_decode" "*,direct")
6744    (set_attr "prefix" "vex,orig")
6745    (set_attr "mode" "<MODE>")])
6747 ;; Convert mul to the mulx pattern to avoid flags dependency.
6748 (define_split
6749  [(set (match_operand:<DWI> 0 "register_operand")
6750        (mult:<DWI>
6751          (zero_extend:<DWI>
6752            (match_operand:DWIH 1 "register_operand"))
6753          (zero_extend:<DWI>
6754            (match_operand:DWIH 2 "nonimmediate_operand"))))
6755   (clobber (reg:CC FLAGS_REG))]
6756  "TARGET_BMI2 && reload_completed
6757   && true_regnum (operands[1]) == DX_REG"
6758   [(parallel [(set (match_dup 3)
6759                    (mult:DWIH (match_dup 1) (match_dup 2)))
6760               (set (match_dup 4)
6761                    (truncate:DWIH
6762                      (lshiftrt:<DWI>
6763                        (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6764                                    (zero_extend:<DWI> (match_dup 2)))
6765                        (match_dup 5))))])]
6767   split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6769   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6772 (define_insn "*mul<mode><dwi>3_1"
6773   [(set (match_operand:<DWI> 0 "register_operand" "=A")
6774         (mult:<DWI>
6775           (sign_extend:<DWI>
6776             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6777           (sign_extend:<DWI>
6778             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6779    (clobber (reg:CC FLAGS_REG))]
6780   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6781   "imul{<imodesuffix>}\t%2"
6782   [(set_attr "type" "imul")
6783    (set_attr "length_immediate" "0")
6784    (set (attr "athlon_decode")
6785      (if_then_else (eq_attr "cpu" "athlon")
6786         (const_string "vector")
6787         (const_string "double")))
6788    (set_attr "amdfam10_decode" "double")
6789    (set_attr "bdver1_decode" "direct")
6790    (set_attr "mode" "<MODE>")])
6792 (define_insn "*<u>mulqihi3_1"
6793   [(set (match_operand:HI 0 "register_operand" "=a")
6794         (mult:HI
6795           (any_extend:HI
6796             (match_operand:QI 1 "nonimmediate_operand" "%0"))
6797           (any_extend:HI
6798             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6799    (clobber (reg:CC FLAGS_REG))]
6800   "TARGET_QIMODE_MATH
6801    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6802   "<sgnprefix>mul{b}\t%2"
6803   [(set_attr "type" "imul")
6804    (set_attr "length_immediate" "0")
6805    (set (attr "athlon_decode")
6806      (if_then_else (eq_attr "cpu" "athlon")
6807         (const_string "vector")
6808         (const_string "direct")))
6809    (set_attr "amdfam10_decode" "direct")
6810    (set_attr "bdver1_decode" "direct")
6811    (set_attr "mode" "QI")])
6813 (define_expand "<s>mul<mode>3_highpart"
6814   [(parallel [(set (match_operand:SWI48 0 "register_operand")
6815                    (truncate:SWI48
6816                      (lshiftrt:<DWI>
6817                        (mult:<DWI>
6818                          (any_extend:<DWI>
6819                            (match_operand:SWI48 1 "nonimmediate_operand"))
6820                          (any_extend:<DWI>
6821                            (match_operand:SWI48 2 "register_operand")))
6822                        (match_dup 4))))
6823               (clobber (match_scratch:SWI48 3))
6824               (clobber (reg:CC FLAGS_REG))])]
6825   ""
6826   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6828 (define_insn "*<s>muldi3_highpart_1"
6829   [(set (match_operand:DI 0 "register_operand" "=d")
6830         (truncate:DI
6831           (lshiftrt:TI
6832             (mult:TI
6833               (any_extend:TI
6834                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6835               (any_extend:TI
6836                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6837             (const_int 64))))
6838    (clobber (match_scratch:DI 3 "=1"))
6839    (clobber (reg:CC FLAGS_REG))]
6840   "TARGET_64BIT
6841    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6842   "<sgnprefix>mul{q}\t%2"
6843   [(set_attr "type" "imul")
6844    (set_attr "length_immediate" "0")
6845    (set (attr "athlon_decode")
6846      (if_then_else (eq_attr "cpu" "athlon")
6847         (const_string "vector")
6848         (const_string "double")))
6849    (set_attr "amdfam10_decode" "double")
6850    (set_attr "bdver1_decode" "direct")
6851    (set_attr "mode" "DI")])
6853 (define_insn "*<s>mulsi3_highpart_1"
6854   [(set (match_operand:SI 0 "register_operand" "=d")
6855         (truncate:SI
6856           (lshiftrt:DI
6857             (mult:DI
6858               (any_extend:DI
6859                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6860               (any_extend:DI
6861                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6862             (const_int 32))))
6863    (clobber (match_scratch:SI 3 "=1"))
6864    (clobber (reg:CC FLAGS_REG))]
6865   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6866   "<sgnprefix>mul{l}\t%2"
6867   [(set_attr "type" "imul")
6868    (set_attr "length_immediate" "0")
6869    (set (attr "athlon_decode")
6870      (if_then_else (eq_attr "cpu" "athlon")
6871         (const_string "vector")
6872         (const_string "double")))
6873    (set_attr "amdfam10_decode" "double")
6874    (set_attr "bdver1_decode" "direct")
6875    (set_attr "mode" "SI")])
6877 (define_insn "*<s>mulsi3_highpart_zext"
6878   [(set (match_operand:DI 0 "register_operand" "=d")
6879         (zero_extend:DI (truncate:SI
6880           (lshiftrt:DI
6881             (mult:DI (any_extend:DI
6882                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
6883                      (any_extend:DI
6884                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
6885             (const_int 32)))))
6886    (clobber (match_scratch:SI 3 "=1"))
6887    (clobber (reg:CC FLAGS_REG))]
6888   "TARGET_64BIT
6889    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6890   "<sgnprefix>mul{l}\t%2"
6891   [(set_attr "type" "imul")
6892    (set_attr "length_immediate" "0")
6893    (set (attr "athlon_decode")
6894      (if_then_else (eq_attr "cpu" "athlon")
6895         (const_string "vector")
6896         (const_string "double")))
6897    (set_attr "amdfam10_decode" "double")
6898    (set_attr "bdver1_decode" "direct")
6899    (set_attr "mode" "SI")])
6901 ;; The patterns that match these are at the end of this file.
6903 (define_expand "mulxf3"
6904   [(set (match_operand:XF 0 "register_operand")
6905         (mult:XF (match_operand:XF 1 "register_operand")
6906                  (match_operand:XF 2 "register_operand")))]
6907   "TARGET_80387")
6909 (define_expand "mul<mode>3"
6910   [(set (match_operand:MODEF 0 "register_operand")
6911         (mult:MODEF (match_operand:MODEF 1 "register_operand")
6912                     (match_operand:MODEF 2 "nonimmediate_operand")))]
6913   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6914     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6916 ;; Divide instructions
6918 ;; The patterns that match these are at the end of this file.
6920 (define_expand "divxf3"
6921   [(set (match_operand:XF 0 "register_operand")
6922         (div:XF (match_operand:XF 1 "register_operand")
6923                 (match_operand:XF 2 "register_operand")))]
6924   "TARGET_80387")
6926 (define_expand "divdf3"
6927   [(set (match_operand:DF 0 "register_operand")
6928         (div:DF (match_operand:DF 1 "register_operand")
6929                 (match_operand:DF 2 "nonimmediate_operand")))]
6930    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6931     || (TARGET_SSE2 && TARGET_SSE_MATH)")
6933 (define_expand "divsf3"
6934   [(set (match_operand:SF 0 "register_operand")
6935         (div:SF (match_operand:SF 1 "register_operand")
6936                 (match_operand:SF 2 "nonimmediate_operand")))]
6937   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6938     || TARGET_SSE_MATH"
6940   if (TARGET_SSE_MATH
6941       && TARGET_RECIP_DIV
6942       && optimize_insn_for_speed_p ()
6943       && flag_finite_math_only && !flag_trapping_math
6944       && flag_unsafe_math_optimizations)
6945     {
6946       ix86_emit_swdivsf (operands[0], operands[1],
6947                          operands[2], SFmode);
6948       DONE;
6949     }
6952 ;; Divmod instructions.
6954 (define_expand "divmod<mode>4"
6955   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6956                    (div:SWIM248
6957                      (match_operand:SWIM248 1 "register_operand")
6958                      (match_operand:SWIM248 2 "nonimmediate_operand")))
6959               (set (match_operand:SWIM248 3 "register_operand")
6960                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
6961               (clobber (reg:CC FLAGS_REG))])])
6963 ;; Split with 8bit unsigned divide:
6964 ;;      if (dividend an divisor are in [0-255])
6965 ;;         use 8bit unsigned integer divide
6966 ;;       else
6967 ;;         use original integer divide
6968 (define_split
6969   [(set (match_operand:SWI48 0 "register_operand")
6970         (div:SWI48 (match_operand:SWI48 2 "register_operand")
6971                     (match_operand:SWI48 3 "nonimmediate_operand")))
6972    (set (match_operand:SWI48 1 "register_operand")
6973         (mod:SWI48 (match_dup 2) (match_dup 3)))
6974    (clobber (reg:CC FLAGS_REG))]
6975   "TARGET_USE_8BIT_IDIV
6976    && TARGET_QIMODE_MATH
6977    && can_create_pseudo_p ()
6978    && !optimize_insn_for_size_p ()"
6979   [(const_int 0)]
6980   "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6982 (define_insn_and_split "divmod<mode>4_1"
6983   [(set (match_operand:SWI48 0 "register_operand" "=a")
6984         (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6985                    (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6986    (set (match_operand:SWI48 1 "register_operand" "=&d")
6987         (mod:SWI48 (match_dup 2) (match_dup 3)))
6988    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6989    (clobber (reg:CC FLAGS_REG))]
6990   ""
6991   "#"
6992   "reload_completed"
6993   [(parallel [(set (match_dup 1)
6994                    (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6995               (clobber (reg:CC FLAGS_REG))])
6996    (parallel [(set (match_dup 0)
6997                    (div:SWI48 (match_dup 2) (match_dup 3)))
6998               (set (match_dup 1)
6999                    (mod:SWI48 (match_dup 2) (match_dup 3)))
7000               (use (match_dup 1))
7001               (clobber (reg:CC FLAGS_REG))])]
7003   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7005   if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7006     operands[4] = operands[2];
7007   else
7008     {
7009       /* Avoid use of cltd in favor of a mov+shift.  */
7010       emit_move_insn (operands[1], operands[2]);
7011       operands[4] = operands[1];
7012     }
7014   [(set_attr "type" "multi")
7015    (set_attr "mode" "<MODE>")])
7017 (define_insn_and_split "*divmod<mode>4"
7018   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7019         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7020                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7021    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7022         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7023    (clobber (reg:CC FLAGS_REG))]
7024   ""
7025   "#"
7026   "reload_completed"
7027   [(parallel [(set (match_dup 1)
7028                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7029               (clobber (reg:CC FLAGS_REG))])
7030    (parallel [(set (match_dup 0)
7031                    (div:SWIM248 (match_dup 2) (match_dup 3)))
7032               (set (match_dup 1)
7033                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
7034               (use (match_dup 1))
7035               (clobber (reg:CC FLAGS_REG))])]
7037   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7039   if (<MODE>mode != HImode
7040       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7041     operands[4] = operands[2];
7042   else
7043     {
7044       /* Avoid use of cltd in favor of a mov+shift.  */
7045       emit_move_insn (operands[1], operands[2]);
7046       operands[4] = operands[1];
7047     }
7049   [(set_attr "type" "multi")
7050    (set_attr "mode" "<MODE>")])
7052 (define_insn "*divmod<mode>4_noext"
7053   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7054         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7055                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7056    (set (match_operand:SWIM248 1 "register_operand" "=d")
7057         (mod:SWIM248 (match_dup 2) (match_dup 3)))
7058    (use (match_operand:SWIM248 4 "register_operand" "1"))
7059    (clobber (reg:CC FLAGS_REG))]
7060   ""
7061   "idiv{<imodesuffix>}\t%3"
7062   [(set_attr "type" "idiv")
7063    (set_attr "mode" "<MODE>")])
7065 (define_expand "divmodqi4"
7066   [(parallel [(set (match_operand:QI 0 "register_operand")
7067                    (div:QI
7068                      (match_operand:QI 1 "register_operand")
7069                      (match_operand:QI 2 "nonimmediate_operand")))
7070               (set (match_operand:QI 3 "register_operand")
7071                    (mod:QI (match_dup 1) (match_dup 2)))
7072               (clobber (reg:CC FLAGS_REG))])]
7073   "TARGET_QIMODE_MATH"
7075   rtx div, mod, insn;
7076   rtx tmp0, tmp1;
7077   
7078   tmp0 = gen_reg_rtx (HImode);
7079   tmp1 = gen_reg_rtx (HImode);
7081   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7082      in AX.  */
7083   emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7084   emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7086   /* Extract remainder from AH.  */
7087   tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7088   insn = emit_move_insn (operands[3], tmp1);
7090   mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7091   set_unique_reg_note (insn, REG_EQUAL, mod);
7093   /* Extract quotient from AL.  */
7094   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7096   div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7097   set_unique_reg_note (insn, REG_EQUAL, div);
7099   DONE;
7102 ;; Divide AX by r/m8, with result stored in
7103 ;; AL <- Quotient
7104 ;; AH <- Remainder
7105 ;; Change div/mod to HImode and extend the second argument to HImode
7106 ;; so that mode of div/mod matches with mode of arguments.  Otherwise
7107 ;; combine may fail.
7108 (define_insn "divmodhiqi3"
7109   [(set (match_operand:HI 0 "register_operand" "=a")
7110         (ior:HI
7111           (ashift:HI
7112             (zero_extend:HI
7113               (truncate:QI
7114                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7115                         (sign_extend:HI
7116                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7117             (const_int 8))
7118           (zero_extend:HI
7119             (truncate:QI
7120               (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7121    (clobber (reg:CC FLAGS_REG))]
7122   "TARGET_QIMODE_MATH"
7123   "idiv{b}\t%2"
7124   [(set_attr "type" "idiv")
7125    (set_attr "mode" "QI")])
7127 (define_expand "udivmod<mode>4"
7128   [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7129                    (udiv:SWIM248
7130                      (match_operand:SWIM248 1 "register_operand")
7131                      (match_operand:SWIM248 2 "nonimmediate_operand")))
7132               (set (match_operand:SWIM248 3 "register_operand")
7133                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
7134               (clobber (reg:CC FLAGS_REG))])])
7136 ;; Split with 8bit unsigned divide:
7137 ;;      if (dividend an divisor are in [0-255])
7138 ;;         use 8bit unsigned integer divide
7139 ;;       else
7140 ;;         use original integer divide
7141 (define_split
7142   [(set (match_operand:SWI48 0 "register_operand")
7143         (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7144                     (match_operand:SWI48 3 "nonimmediate_operand")))
7145    (set (match_operand:SWI48 1 "register_operand")
7146         (umod:SWI48 (match_dup 2) (match_dup 3)))
7147    (clobber (reg:CC FLAGS_REG))]
7148   "TARGET_USE_8BIT_IDIV
7149    && TARGET_QIMODE_MATH
7150    && can_create_pseudo_p ()
7151    && !optimize_insn_for_size_p ()"
7152   [(const_int 0)]
7153   "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7155 (define_insn_and_split "udivmod<mode>4_1"
7156   [(set (match_operand:SWI48 0 "register_operand" "=a")
7157         (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7158                     (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7159    (set (match_operand:SWI48 1 "register_operand" "=&d")
7160         (umod:SWI48 (match_dup 2) (match_dup 3)))
7161    (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7162    (clobber (reg:CC FLAGS_REG))]
7163   ""
7164   "#"
7165   "reload_completed"
7166   [(set (match_dup 1) (const_int 0))
7167    (parallel [(set (match_dup 0)
7168                    (udiv:SWI48 (match_dup 2) (match_dup 3)))
7169               (set (match_dup 1)
7170                    (umod:SWI48 (match_dup 2) (match_dup 3)))
7171               (use (match_dup 1))
7172               (clobber (reg:CC FLAGS_REG))])]
7173   ""
7174   [(set_attr "type" "multi")
7175    (set_attr "mode" "<MODE>")])
7177 (define_insn_and_split "*udivmod<mode>4"
7178   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7179         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7180                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7181    (set (match_operand:SWIM248 1 "register_operand" "=&d")
7182         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7183    (clobber (reg:CC FLAGS_REG))]
7184   ""
7185   "#"
7186   "reload_completed"
7187   [(set (match_dup 1) (const_int 0))
7188    (parallel [(set (match_dup 0)
7189                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7190               (set (match_dup 1)
7191                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
7192               (use (match_dup 1))
7193               (clobber (reg:CC FLAGS_REG))])]
7194   ""
7195   [(set_attr "type" "multi")
7196    (set_attr "mode" "<MODE>")])
7198 (define_insn "*udivmod<mode>4_noext"
7199   [(set (match_operand:SWIM248 0 "register_operand" "=a")
7200         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7201                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7202    (set (match_operand:SWIM248 1 "register_operand" "=d")
7203         (umod:SWIM248 (match_dup 2) (match_dup 3)))
7204    (use (match_operand:SWIM248 4 "register_operand" "1"))
7205    (clobber (reg:CC FLAGS_REG))]
7206   ""
7207   "div{<imodesuffix>}\t%3"
7208   [(set_attr "type" "idiv")
7209    (set_attr "mode" "<MODE>")])
7211 (define_expand "udivmodqi4"
7212   [(parallel [(set (match_operand:QI 0 "register_operand")
7213                    (udiv:QI
7214                      (match_operand:QI 1 "register_operand")
7215                      (match_operand:QI 2 "nonimmediate_operand")))
7216               (set (match_operand:QI 3 "register_operand")
7217                    (umod:QI (match_dup 1) (match_dup 2)))
7218               (clobber (reg:CC FLAGS_REG))])]
7219   "TARGET_QIMODE_MATH"
7221   rtx div, mod, insn;
7222   rtx tmp0, tmp1;
7223   
7224   tmp0 = gen_reg_rtx (HImode);
7225   tmp1 = gen_reg_rtx (HImode);
7227   /* Extend operands[1] to HImode.  Generate 8bit divide.  Result is
7228      in AX.  */
7229   emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7230   emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7232   /* Extract remainder from AH.  */
7233   tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7234   tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7235   insn = emit_move_insn (operands[3], tmp1);
7237   mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7238   set_unique_reg_note (insn, REG_EQUAL, mod);
7240   /* Extract quotient from AL.  */
7241   insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7243   div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7244   set_unique_reg_note (insn, REG_EQUAL, div);
7246   DONE;
7249 (define_insn "udivmodhiqi3"
7250   [(set (match_operand:HI 0 "register_operand" "=a")
7251         (ior:HI
7252           (ashift:HI
7253             (zero_extend:HI
7254               (truncate:QI
7255                 (mod:HI (match_operand:HI 1 "register_operand" "0")
7256                         (zero_extend:HI
7257                           (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7258             (const_int 8))
7259           (zero_extend:HI
7260             (truncate:QI
7261               (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7262    (clobber (reg:CC FLAGS_REG))]
7263   "TARGET_QIMODE_MATH"
7264   "div{b}\t%2"
7265   [(set_attr "type" "idiv")
7266    (set_attr "mode" "QI")])
7268 ;; We cannot use div/idiv for double division, because it causes
7269 ;; "division by zero" on the overflow and that's not what we expect
7270 ;; from truncate.  Because true (non truncating) double division is
7271 ;; never generated, we can't create this insn anyway.
7273 ;(define_insn ""
7274 ;  [(set (match_operand:SI 0 "register_operand" "=a")
7275 ;       (truncate:SI
7276 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
7277 ;                  (zero_extend:DI
7278 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7279 ;   (set (match_operand:SI 3 "register_operand" "=d")
7280 ;       (truncate:SI
7281 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7282 ;   (clobber (reg:CC FLAGS_REG))]
7283 ;  ""
7284 ;  "div{l}\t{%2, %0|%0, %2}"
7285 ;  [(set_attr "type" "idiv")])
7287 ;;- Logical AND instructions
7289 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7290 ;; Note that this excludes ah.
7292 (define_expand "testsi_ccno_1"
7293   [(set (reg:CCNO FLAGS_REG)
7294         (compare:CCNO
7295           (and:SI (match_operand:SI 0 "nonimmediate_operand")
7296                   (match_operand:SI 1 "x86_64_nonmemory_operand"))
7297           (const_int 0)))])
7299 (define_expand "testqi_ccz_1"
7300   [(set (reg:CCZ FLAGS_REG)
7301         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7302                              (match_operand:QI 1 "nonmemory_operand"))
7303                  (const_int 0)))])
7305 (define_expand "testdi_ccno_1"
7306   [(set (reg:CCNO FLAGS_REG)
7307         (compare:CCNO
7308           (and:DI (match_operand:DI 0 "nonimmediate_operand")
7309                   (match_operand:DI 1 "x86_64_szext_general_operand"))
7310           (const_int 0)))]
7311   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7313 (define_insn "*testdi_1"
7314   [(set (reg FLAGS_REG)
7315         (compare
7316          (and:DI
7317           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7318           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7319          (const_int 0)))]
7320   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7321    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7322   "@
7323    test{l}\t{%k1, %k0|%k0, %k1}
7324    test{l}\t{%k1, %k0|%k0, %k1}
7325    test{q}\t{%1, %0|%0, %1}
7326    test{q}\t{%1, %0|%0, %1}
7327    test{q}\t{%1, %0|%0, %1}"
7328   [(set_attr "type" "test")
7329    (set_attr "modrm" "0,1,0,1,1")
7330    (set_attr "mode" "SI,SI,DI,DI,DI")])
7332 (define_insn "*testqi_1_maybe_si"
7333   [(set (reg FLAGS_REG)
7334         (compare
7335           (and:QI
7336             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7337             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7338           (const_int 0)))]
7339    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7340     && ix86_match_ccmode (insn,
7341                          CONST_INT_P (operands[1])
7342                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7344   if (which_alternative == 3)
7345     {
7346       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7347         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7348       return "test{l}\t{%1, %k0|%k0, %1}";
7349     }
7350   return "test{b}\t{%1, %0|%0, %1}";
7352   [(set_attr "type" "test")
7353    (set_attr "modrm" "0,1,1,1")
7354    (set_attr "mode" "QI,QI,QI,SI")
7355    (set_attr "pent_pair" "uv,np,uv,np")])
7357 (define_insn "*test<mode>_1"
7358   [(set (reg FLAGS_REG)
7359         (compare
7360          (and:SWI124
7361           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7362           (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7363          (const_int 0)))]
7364   "ix86_match_ccmode (insn, CCNOmode)
7365    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7366   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7367   [(set_attr "type" "test")
7368    (set_attr "modrm" "0,1,1")
7369    (set_attr "mode" "<MODE>")
7370    (set_attr "pent_pair" "uv,np,uv")])
7372 (define_expand "testqi_ext_ccno_0"
7373   [(set (reg:CCNO FLAGS_REG)
7374         (compare:CCNO
7375           (and:SI
7376             (zero_extract:SI
7377               (match_operand 0 "ext_register_operand")
7378               (const_int 8)
7379               (const_int 8))
7380             (match_operand 1 "const_int_operand"))
7381           (const_int 0)))])
7383 (define_insn "*testqi_ext_0"
7384   [(set (reg FLAGS_REG)
7385         (compare
7386           (and:SI
7387             (zero_extract:SI
7388               (match_operand 0 "ext_register_operand" "Q")
7389               (const_int 8)
7390               (const_int 8))
7391             (match_operand 1 "const_int_operand" "n"))
7392           (const_int 0)))]
7393   "ix86_match_ccmode (insn, CCNOmode)"
7394   "test{b}\t{%1, %h0|%h0, %1}"
7395   [(set_attr "type" "test")
7396    (set_attr "mode" "QI")
7397    (set_attr "length_immediate" "1")
7398    (set_attr "modrm" "1")
7399    (set_attr "pent_pair" "np")])
7401 (define_insn "*testqi_ext_1"
7402   [(set (reg FLAGS_REG)
7403         (compare
7404           (and:SI
7405             (zero_extract:SI
7406               (match_operand 0 "ext_register_operand" "Q,Q")
7407               (const_int 8)
7408               (const_int 8))
7409             (zero_extend:SI
7410               (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7411           (const_int 0)))]
7412   "ix86_match_ccmode (insn, CCNOmode)"
7413   "test{b}\t{%1, %h0|%h0, %1}"
7414   [(set_attr "isa" "*,nox64")
7415    (set_attr "type" "test")
7416    (set_attr "mode" "QI")])
7418 (define_insn "*testqi_ext_2"
7419   [(set (reg FLAGS_REG)
7420         (compare
7421           (and:SI
7422             (zero_extract:SI
7423               (match_operand 0 "ext_register_operand" "Q")
7424               (const_int 8)
7425               (const_int 8))
7426             (zero_extract:SI
7427               (match_operand 1 "ext_register_operand" "Q")
7428               (const_int 8)
7429               (const_int 8)))
7430           (const_int 0)))]
7431   "ix86_match_ccmode (insn, CCNOmode)"
7432   "test{b}\t{%h1, %h0|%h0, %h1}"
7433   [(set_attr "type" "test")
7434    (set_attr "mode" "QI")])
7436 ;; Combine likes to form bit extractions for some tests.  Humor it.
7437 (define_insn "*testqi_ext_3"
7438   [(set (reg FLAGS_REG)
7439         (compare (zero_extract:SWI48
7440                    (match_operand 0 "nonimmediate_operand" "rm")
7441                    (match_operand:SWI48 1 "const_int_operand")
7442                    (match_operand:SWI48 2 "const_int_operand"))
7443                  (const_int 0)))]
7444   "ix86_match_ccmode (insn, CCNOmode)
7445    && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7446        || GET_MODE (operands[0]) == SImode
7447        || GET_MODE (operands[0]) == HImode
7448        || GET_MODE (operands[0]) == QImode)
7449    /* Ensure that resulting mask is zero or sign extended operand.  */
7450    && INTVAL (operands[2]) >= 0
7451    && ((INTVAL (operands[1]) > 0
7452         && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7453        || (<MODE>mode == DImode
7454            && INTVAL (operands[1]) > 32
7455            && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7456   "#")
7458 (define_split
7459   [(set (match_operand 0 "flags_reg_operand")
7460         (match_operator 1 "compare_operator"
7461           [(zero_extract
7462              (match_operand 2 "nonimmediate_operand")
7463              (match_operand 3 "const_int_operand")
7464              (match_operand 4 "const_int_operand"))
7465            (const_int 0)]))]
7466   "ix86_match_ccmode (insn, CCNOmode)"
7467   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7469   rtx val = operands[2];
7470   HOST_WIDE_INT len = INTVAL (operands[3]);
7471   HOST_WIDE_INT pos = INTVAL (operands[4]);
7472   HOST_WIDE_INT mask;
7473   machine_mode mode, submode;
7475   mode = GET_MODE (val);
7476   if (MEM_P (val))
7477     {
7478       /* ??? Combine likes to put non-volatile mem extractions in QImode
7479          no matter the size of the test.  So find a mode that works.  */
7480       if (! MEM_VOLATILE_P (val))
7481         {
7482           mode = smallest_mode_for_size (pos + len, MODE_INT);
7483           val = adjust_address (val, mode, 0);
7484         }
7485     }
7486   else if (GET_CODE (val) == SUBREG
7487            && (submode = GET_MODE (SUBREG_REG (val)),
7488                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7489            && pos + len <= GET_MODE_BITSIZE (submode)
7490            && GET_MODE_CLASS (submode) == MODE_INT)
7491     {
7492       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
7493       mode = submode;
7494       val = SUBREG_REG (val);
7495     }
7496   else if (mode == HImode && pos + len <= 8)
7497     {
7498       /* Small HImode tests can be converted to QImode.  */
7499       mode = QImode;
7500       val = gen_lowpart (QImode, val);
7501     }
7503   if (len == HOST_BITS_PER_WIDE_INT)
7504     mask = -1;
7505   else
7506     mask = ((HOST_WIDE_INT)1 << len) - 1;
7507   mask <<= pos;
7509   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7512 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7513 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7514 ;; this is relatively important trick.
7515 ;; Do the conversion only post-reload to avoid limiting of the register class
7516 ;; to QI regs.
7517 (define_split
7518   [(set (match_operand 0 "flags_reg_operand")
7519         (match_operator 1 "compare_operator"
7520           [(and (match_operand 2 "register_operand")
7521                 (match_operand 3 "const_int_operand"))
7522            (const_int 0)]))]
7523    "reload_completed
7524     && QI_REG_P (operands[2])
7525     && GET_MODE (operands[2]) != QImode
7526     && ((ix86_match_ccmode (insn, CCZmode)
7527          && !(INTVAL (operands[3]) & ~(255 << 8)))
7528         || (ix86_match_ccmode (insn, CCNOmode)
7529             && !(INTVAL (operands[3]) & ~(127 << 8))))"
7530   [(set (match_dup 0)
7531         (match_op_dup 1
7532           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7533                    (match_dup 3))
7534            (const_int 0)]))]
7536   operands[2] = gen_lowpart (SImode, operands[2]);
7537   operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7540 (define_split
7541   [(set (match_operand 0 "flags_reg_operand")
7542         (match_operator 1 "compare_operator"
7543           [(and (match_operand 2 "nonimmediate_operand")
7544                 (match_operand 3 "const_int_operand"))
7545            (const_int 0)]))]
7546    "reload_completed
7547     && GET_MODE (operands[2]) != QImode
7548     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7549     && ((ix86_match_ccmode (insn, CCZmode)
7550          && !(INTVAL (operands[3]) & ~255))
7551         || (ix86_match_ccmode (insn, CCNOmode)
7552             && !(INTVAL (operands[3]) & ~127)))"
7553   [(set (match_dup 0)
7554         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7555                          (const_int 0)]))]
7557   operands[2] = gen_lowpart (QImode, operands[2]);
7558   operands[3] = gen_lowpart (QImode, operands[3]);
7561 (define_split
7562   [(set (match_operand:SWI1248x 0 "mask_reg_operand")
7563         (any_logic:SWI1248x (match_operand:SWI1248x 1 "mask_reg_operand")
7564                             (match_operand:SWI1248x 2 "mask_reg_operand")))
7565    (clobber (reg:CC FLAGS_REG))]
7566   "TARGET_AVX512F && reload_completed"
7567   [(set (match_dup 0)
7568         (any_logic:SWI1248x (match_dup 1)
7569                             (match_dup 2)))])
7571 (define_insn "*k<logic><mode>"
7572   [(set (match_operand:SWI1248_AVX512BW 0 "mask_reg_operand" "=k")
7573         (any_logic:SWI1248_AVX512BW (match_operand:SWI1248_AVX512BW 1 "mask_reg_operand" "k")
7574                           (match_operand:SWI1248_AVX512BW 2 "mask_reg_operand" "k")))]
7575   "TARGET_AVX512F"
7576   {
7577     if (!TARGET_AVX512DQ && <MODE>mode == QImode)
7578       return "k<logic>w\t{%2, %1, %0|%0, %1, %2}";
7579     else
7580       return "k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}";
7581   }
7582   [(set_attr "mode" "<MODE>")
7583    (set_attr "type" "msklog")
7584    (set_attr "prefix" "vex")])
7586 ;; %%% This used to optimize known byte-wide and operations to memory,
7587 ;; and sometimes to QImode registers.  If this is considered useful,
7588 ;; it should be done with splitters.
7590 (define_expand "and<mode>3"
7591   [(set (match_operand:SWIM 0 "nonimmediate_operand")
7592         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7593                   (match_operand:SWIM 2 "<general_szext_operand>")))]
7594   ""
7596   machine_mode mode = <MODE>mode;
7597   rtx (*insn) (rtx, rtx);
7599   if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7600     {
7601       HOST_WIDE_INT ival = INTVAL (operands[2]);
7603       if (ival == (HOST_WIDE_INT) 0xffffffff)
7604         mode = SImode;
7605       else if (ival == 0xffff)
7606         mode = HImode;
7607       else if (ival == 0xff)
7608         mode = QImode;
7609       }
7611   if (mode == <MODE>mode)
7612     {
7613       ix86_expand_binary_operator (AND, <MODE>mode, operands);
7614       DONE;
7615     }
7617   if (<MODE>mode == DImode)
7618     insn = (mode == SImode)
7619            ? gen_zero_extendsidi2
7620            : (mode == HImode)
7621            ? gen_zero_extendhidi2
7622            : gen_zero_extendqidi2;
7623   else if (<MODE>mode == SImode)
7624     insn = (mode == HImode)
7625            ? gen_zero_extendhisi2
7626            : gen_zero_extendqisi2;
7627   else if (<MODE>mode == HImode)
7628     insn = gen_zero_extendqihi2;
7629   else
7630     gcc_unreachable ();
7632   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7633   DONE;
7636 (define_insn "*anddi_1"
7637   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r,!k")
7638         (and:DI
7639          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm,k")
7640          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L,k")))
7641    (clobber (reg:CC FLAGS_REG))]
7642   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7644   switch (get_attr_type (insn))
7645     {
7646     case TYPE_IMOVX:
7647       return "#";
7649     case TYPE_MSKLOG:
7650       return "kandq\t{%2, %1, %0|%0, %1, %2}";
7652     default:
7653       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7654       if (get_attr_mode (insn) == MODE_SI)
7655         return "and{l}\t{%k2, %k0|%k0, %k2}";
7656       else
7657         return "and{q}\t{%2, %0|%0, %2}";
7658     }
7660   [(set_attr "type" "alu,alu,alu,imovx,msklog")
7661    (set_attr "length_immediate" "*,*,*,0,0")
7662    (set (attr "prefix_rex")
7663      (if_then_else
7664        (and (eq_attr "type" "imovx")
7665             (and (match_test "INTVAL (operands[2]) == 0xff")
7666                  (match_operand 1 "ext_QIreg_operand")))
7667        (const_string "1")
7668        (const_string "*")))
7669    (set_attr "mode" "SI,DI,DI,SI,DI")])
7671 (define_insn "*andsi_1"
7672   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7673         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm,k")
7674                 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L,k")))
7675    (clobber (reg:CC FLAGS_REG))]
7676   "ix86_binary_operator_ok (AND, SImode, operands)"
7678   switch (get_attr_type (insn))
7679     {
7680     case TYPE_IMOVX:
7681       return "#";
7683     case TYPE_MSKLOG:
7684       return "kandd\t{%2, %1, %0|%0, %1, %2}";
7686     default:
7687       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7688       return "and{l}\t{%2, %0|%0, %2}";
7689     }
7691   [(set_attr "type" "alu,alu,imovx,msklog")
7692    (set (attr "prefix_rex")
7693      (if_then_else
7694        (and (eq_attr "type" "imovx")
7695             (and (match_test "INTVAL (operands[2]) == 0xff")
7696                  (match_operand 1 "ext_QIreg_operand")))
7697        (const_string "1")
7698        (const_string "*")))
7699    (set_attr "length_immediate" "*,*,0,0")
7700    (set_attr "mode" "SI")])
7702 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7703 (define_insn "*andsi_1_zext"
7704   [(set (match_operand:DI 0 "register_operand" "=r")
7705         (zero_extend:DI
7706           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7707                   (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7708    (clobber (reg:CC FLAGS_REG))]
7709   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7710   "and{l}\t{%2, %k0|%k0, %2}"
7711   [(set_attr "type" "alu")
7712    (set_attr "mode" "SI")])
7714 (define_insn "*andhi_1"
7715   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya,!k")
7716         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm,k")
7717                 (match_operand:HI 2 "general_operand" "rn,rm,L,k")))
7718    (clobber (reg:CC FLAGS_REG))]
7719   "ix86_binary_operator_ok (AND, HImode, operands)"
7721   switch (get_attr_type (insn))
7722     {
7723     case TYPE_IMOVX:
7724       return "#";
7726     case TYPE_MSKLOG:
7727       return "kandw\t{%2, %1, %0|%0, %1, %2}";
7729     default:
7730       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7731       return "and{w}\t{%2, %0|%0, %2}";
7732     }
7734   [(set_attr "type" "alu,alu,imovx,msklog")
7735    (set_attr "length_immediate" "*,*,0,*")
7736    (set (attr "prefix_rex")
7737      (if_then_else
7738        (and (eq_attr "type" "imovx")
7739             (match_operand 1 "ext_QIreg_operand"))
7740        (const_string "1")
7741        (const_string "*")))
7742    (set_attr "mode" "HI,HI,SI,HI")])
7744 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7745 (define_insn "*andqi_1"
7746   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,!k")
7747         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
7748                 (match_operand:QI 2 "general_operand" "qn,qmn,rn,k")))
7749    (clobber (reg:CC FLAGS_REG))]
7750   "ix86_binary_operator_ok (AND, QImode, operands)"
7752   switch (which_alternative)
7753     {
7754     case 0:
7755     case 1:
7756       return "and{b}\t{%2, %0|%0, %2}";
7757     case 2:
7758       return "and{l}\t{%k2, %k0|%k0, %k2}";
7759     case 3:
7760       return TARGET_AVX512DQ ? "kandb\t{%2, %1, %0|%0, %1, %2}"
7761                              : "kandw\t{%2, %1, %0|%0, %1, %2}";
7762     default:
7763       gcc_unreachable ();
7764     }
7766   [(set_attr "type" "alu,alu,alu,msklog")
7767    (set_attr "mode" "QI,QI,SI,HI")])
7769 (define_insn "*andqi_1_slp"
7770   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7771         (and:QI (match_dup 0)
7772                 (match_operand:QI 1 "general_operand" "qn,qmn")))
7773    (clobber (reg:CC FLAGS_REG))]
7774   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7775    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7776   "and{b}\t{%1, %0|%0, %1}"
7777   [(set_attr "type" "alu1")
7778    (set_attr "mode" "QI")])
7780 (define_insn "kandn<mode>"
7781   [(set (match_operand:SWI12 0 "register_operand" "=r,&r,!k")
7782         (and:SWI12
7783           (not:SWI12
7784             (match_operand:SWI12 1 "register_operand" "r,0,k"))
7785           (match_operand:SWI12 2 "register_operand" "r,r,k")))
7786    (clobber (reg:CC FLAGS_REG))]
7787   "TARGET_AVX512F"
7789   switch (which_alternative)
7790     {
7791     case 0:
7792       return "andn\t{%k2, %k1, %k0|%k0, %k1, %k2}";
7793     case 1:
7794       return "#";
7795     case 2:
7796       if (TARGET_AVX512DQ && <MODE>mode == QImode)
7797         return "kandnb\t{%2, %1, %0|%0, %1, %2}";
7798       else
7799         return "kandnw\t{%2, %1, %0|%0, %1, %2}";
7800     default:
7801       gcc_unreachable ();
7802     }
7804   [(set_attr "isa" "bmi,*,avx512f")
7805    (set_attr "type" "bitmanip,*,msklog")
7806    (set_attr "prefix" "*,*,vex")
7807    (set_attr "btver2_decode" "direct,*,*")
7808    (set_attr "mode" "<MODE>")])
7810 (define_split
7811   [(set (match_operand:SWI12 0 "general_reg_operand")
7812         (and:SWI12
7813           (not:SWI12
7814             (match_dup 0))
7815           (match_operand:SWI12 1 "general_reg_operand")))
7816    (clobber (reg:CC FLAGS_REG))]
7817   "TARGET_AVX512F && !TARGET_BMI && reload_completed"
7818   [(set (match_dup 0)
7819         (not:HI (match_dup 0)))
7820    (parallel [(set (match_dup 0)
7821                    (and:HI (match_dup 0)
7822                            (match_dup 1)))
7823               (clobber (reg:CC FLAGS_REG))])])
7825 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7826 (define_split
7827   [(set (match_operand:DI 0 "register_operand")
7828         (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7829                 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7830    (clobber (reg:CC FLAGS_REG))]
7831   "TARGET_64BIT"
7832   [(parallel [(set (match_dup 0)
7833                    (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7834               (clobber (reg:CC FLAGS_REG))])]
7835   "operands[2] = gen_lowpart (SImode, operands[2]);")
7837 (define_split
7838   [(set (match_operand:SWI248 0 "register_operand")
7839         (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7840                     (match_operand:SWI248 2 "const_int_operand")))
7841    (clobber (reg:CC FLAGS_REG))]
7842   "reload_completed
7843    && true_regnum (operands[0]) != true_regnum (operands[1])"
7844   [(const_int 0)]
7846   HOST_WIDE_INT ival = INTVAL (operands[2]);
7847   machine_mode mode;
7848   rtx (*insn) (rtx, rtx);
7850   if (ival == (HOST_WIDE_INT) 0xffffffff)
7851     mode = SImode;
7852   else if (ival == 0xffff)
7853     mode = HImode;
7854   else
7855     {
7856       gcc_assert (ival == 0xff);
7857       mode = QImode;
7858     }
7860   if (<MODE>mode == DImode)
7861     insn = (mode == SImode)
7862            ? gen_zero_extendsidi2
7863            : (mode == HImode)
7864            ? gen_zero_extendhidi2
7865            : gen_zero_extendqidi2;
7866   else
7867     {
7868       if (<MODE>mode != SImode)
7869         /* Zero extend to SImode to avoid partial register stalls.  */
7870         operands[0] = gen_lowpart (SImode, operands[0]);
7872       insn = (mode == HImode)
7873              ? gen_zero_extendhisi2
7874              : gen_zero_extendqisi2;
7875     }
7876   emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7877   DONE;
7880 (define_split
7881   [(set (match_operand 0 "register_operand")
7882         (and (match_dup 0)
7883              (const_int -65536)))
7884    (clobber (reg:CC FLAGS_REG))]
7885   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7886     || optimize_function_for_size_p (cfun)"
7887   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7888   "operands[1] = gen_lowpart (HImode, operands[0]);")
7890 (define_split
7891   [(set (match_operand 0 "ext_register_operand")
7892         (and (match_dup 0)
7893              (const_int -256)))
7894    (clobber (reg:CC FLAGS_REG))]
7895   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7896    && reload_completed"
7897   [(set (strict_low_part (match_dup 1)) (const_int 0))]
7898   "operands[1] = gen_lowpart (QImode, operands[0]);")
7900 (define_split
7901   [(set (match_operand 0 "ext_register_operand")
7902         (and (match_dup 0)
7903              (const_int -65281)))
7904    (clobber (reg:CC FLAGS_REG))]
7905   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7906    && reload_completed"
7907   [(parallel [(set (zero_extract:SI (match_dup 0)
7908                                     (const_int 8)
7909                                     (const_int 8))
7910                    (xor:SI
7911                      (zero_extract:SI (match_dup 0)
7912                                       (const_int 8)
7913                                       (const_int 8))
7914                      (zero_extract:SI (match_dup 0)
7915                                       (const_int 8)
7916                                       (const_int 8))))
7917               (clobber (reg:CC FLAGS_REG))])]
7918   "operands[0] = gen_lowpart (SImode, operands[0]);")
7920 (define_insn "*anddi_2"
7921   [(set (reg FLAGS_REG)
7922         (compare
7923          (and:DI
7924           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7925           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7926          (const_int 0)))
7927    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7928         (and:DI (match_dup 1) (match_dup 2)))]
7929   "TARGET_64BIT
7930    && ix86_match_ccmode
7931         (insn,
7932          /* If we are going to emit andl instead of andq, and the operands[2]
7933             constant might have the SImode sign bit set, make sure the sign
7934             flag isn't tested, because the instruction will set the sign flag
7935             based on bit 31 rather than bit 63.  If it isn't CONST_INT,
7936             conservatively assume it might have bit 31 set.  */
7937          (satisfies_constraint_Z (operands[2])
7938           && (!CONST_INT_P (operands[2])
7939               || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
7940          ? CCZmode : CCNOmode)
7941    && ix86_binary_operator_ok (AND, DImode, operands)"
7942   "@
7943    and{l}\t{%k2, %k0|%k0, %k2}
7944    and{q}\t{%2, %0|%0, %2}
7945    and{q}\t{%2, %0|%0, %2}"
7946   [(set_attr "type" "alu")
7947    (set_attr "mode" "SI,DI,DI")])
7949 (define_insn "*andqi_2_maybe_si"
7950   [(set (reg FLAGS_REG)
7951         (compare (and:QI
7952                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7953                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7954                  (const_int 0)))
7955    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7956         (and:QI (match_dup 1) (match_dup 2)))]
7957   "ix86_binary_operator_ok (AND, QImode, operands)
7958    && ix86_match_ccmode (insn,
7959                          CONST_INT_P (operands[2])
7960                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7962   if (which_alternative == 2)
7963     {
7964       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7965         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7966       return "and{l}\t{%2, %k0|%k0, %2}";
7967     }
7968   return "and{b}\t{%2, %0|%0, %2}";
7970   [(set_attr "type" "alu")
7971    (set_attr "mode" "QI,QI,SI")])
7973 (define_insn "*and<mode>_2"
7974   [(set (reg FLAGS_REG)
7975         (compare (and:SWI124
7976                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7977                   (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7978                  (const_int 0)))
7979    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7980         (and:SWI124 (match_dup 1) (match_dup 2)))]
7981   "ix86_match_ccmode (insn, CCNOmode)
7982    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7983   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7984   [(set_attr "type" "alu")
7985    (set_attr "mode" "<MODE>")])
7987 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7988 (define_insn "*andsi_2_zext"
7989   [(set (reg FLAGS_REG)
7990         (compare (and:SI
7991                   (match_operand:SI 1 "nonimmediate_operand" "%0")
7992                   (match_operand:SI 2 "x86_64_general_operand" "rme"))
7993                  (const_int 0)))
7994    (set (match_operand:DI 0 "register_operand" "=r")
7995         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7996   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7997    && ix86_binary_operator_ok (AND, SImode, operands)"
7998   "and{l}\t{%2, %k0|%k0, %2}"
7999   [(set_attr "type" "alu")
8000    (set_attr "mode" "SI")])
8002 (define_insn "*andqi_2_slp"
8003   [(set (reg FLAGS_REG)
8004         (compare (and:QI
8005                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8006                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8007                  (const_int 0)))
8008    (set (strict_low_part (match_dup 0))
8009         (and:QI (match_dup 0) (match_dup 1)))]
8010   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8011    && ix86_match_ccmode (insn, CCNOmode)
8012    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8013   "and{b}\t{%1, %0|%0, %1}"
8014   [(set_attr "type" "alu1")
8015    (set_attr "mode" "QI")])
8017 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8018 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8019 ;; for a QImode operand, which of course failed.
8020 (define_insn "andqi_ext_0"
8021   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8022                          (const_int 8)
8023                          (const_int 8))
8024         (and:SI
8025           (zero_extract:SI
8026             (match_operand 1 "ext_register_operand" "0")
8027             (const_int 8)
8028             (const_int 8))
8029           (match_operand 2 "const_int_operand" "n")))
8030    (clobber (reg:CC FLAGS_REG))]
8031   ""
8032   "and{b}\t{%2, %h0|%h0, %2}"
8033   [(set_attr "type" "alu")
8034    (set_attr "length_immediate" "1")
8035    (set_attr "modrm" "1")
8036    (set_attr "mode" "QI")])
8038 ;; Generated by peephole translating test to and.  This shows up
8039 ;; often in fp comparisons.
8040 (define_insn "*andqi_ext_0_cc"
8041   [(set (reg FLAGS_REG)
8042         (compare
8043           (and:SI
8044             (zero_extract:SI
8045               (match_operand 1 "ext_register_operand" "0")
8046               (const_int 8)
8047               (const_int 8))
8048             (match_operand 2 "const_int_operand" "n"))
8049           (const_int 0)))
8050    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8051                          (const_int 8)
8052                          (const_int 8))
8053         (and:SI
8054           (zero_extract:SI
8055             (match_dup 1)
8056             (const_int 8)
8057             (const_int 8))
8058           (match_dup 2)))]
8059   "ix86_match_ccmode (insn, CCNOmode)"
8060   "and{b}\t{%2, %h0|%h0, %2}"
8061   [(set_attr "type" "alu")
8062    (set_attr "length_immediate" "1")
8063    (set_attr "modrm" "1")
8064    (set_attr "mode" "QI")])
8066 (define_insn "*andqi_ext_1"
8067   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8068                          (const_int 8)
8069                          (const_int 8))
8070         (and:SI
8071           (zero_extract:SI
8072             (match_operand 1 "ext_register_operand" "0,0")
8073             (const_int 8)
8074             (const_int 8))
8075           (zero_extend:SI
8076             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8077    (clobber (reg:CC FLAGS_REG))]
8078   ""
8079   "and{b}\t{%2, %h0|%h0, %2}"
8080   [(set_attr "isa" "*,nox64")
8081    (set_attr "type" "alu")
8082    (set_attr "length_immediate" "0")
8083    (set_attr "mode" "QI")])
8085 (define_insn "*andqi_ext_2"
8086   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8087                          (const_int 8)
8088                          (const_int 8))
8089         (and:SI
8090           (zero_extract:SI
8091             (match_operand 1 "ext_register_operand" "%0")
8092             (const_int 8)
8093             (const_int 8))
8094           (zero_extract:SI
8095             (match_operand 2 "ext_register_operand" "Q")
8096             (const_int 8)
8097             (const_int 8))))
8098    (clobber (reg:CC FLAGS_REG))]
8099   ""
8100   "and{b}\t{%h2, %h0|%h0, %h2}"
8101   [(set_attr "type" "alu")
8102    (set_attr "length_immediate" "0")
8103    (set_attr "mode" "QI")])
8105 ;; Convert wide AND instructions with immediate operand to shorter QImode
8106 ;; equivalents when possible.
8107 ;; Don't do the splitting with memory operands, since it introduces risk
8108 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8109 ;; for size, but that can (should?) be handled by generic code instead.
8110 (define_split
8111   [(set (match_operand 0 "register_operand")
8112         (and (match_operand 1 "register_operand")
8113              (match_operand 2 "const_int_operand")))
8114    (clobber (reg:CC FLAGS_REG))]
8115    "reload_completed
8116     && QI_REG_P (operands[0])
8117     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8118     && !(~INTVAL (operands[2]) & ~(255 << 8))
8119     && GET_MODE (operands[0]) != QImode"
8120   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8121                    (and:SI (zero_extract:SI (match_dup 1)
8122                                             (const_int 8) (const_int 8))
8123                            (match_dup 2)))
8124               (clobber (reg:CC FLAGS_REG))])]
8126   operands[0] = gen_lowpart (SImode, operands[0]);
8127   operands[1] = gen_lowpart (SImode, operands[1]);
8128   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8131 ;; Since AND can be encoded with sign extended immediate, this is only
8132 ;; profitable when 7th bit is not set.
8133 (define_split
8134   [(set (match_operand 0 "register_operand")
8135         (and (match_operand 1 "general_operand")
8136              (match_operand 2 "const_int_operand")))
8137    (clobber (reg:CC FLAGS_REG))]
8138    "reload_completed
8139     && ANY_QI_REG_P (operands[0])
8140     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8141     && !(~INTVAL (operands[2]) & ~255)
8142     && !(INTVAL (operands[2]) & 128)
8143     && GET_MODE (operands[0]) != QImode"
8144   [(parallel [(set (strict_low_part (match_dup 0))
8145                    (and:QI (match_dup 1)
8146                            (match_dup 2)))
8147               (clobber (reg:CC FLAGS_REG))])]
8149   operands[0] = gen_lowpart (QImode, operands[0]);
8150   operands[1] = gen_lowpart (QImode, operands[1]);
8151   operands[2] = gen_lowpart (QImode, operands[2]);
8154 ;; Logical inclusive and exclusive OR instructions
8156 ;; %%% This used to optimize known byte-wide and operations to memory.
8157 ;; If this is considered useful, it should be done with splitters.
8159 (define_expand "<code><mode>3"
8160   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8161         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8162                      (match_operand:SWIM 2 "<general_operand>")))]
8163   ""
8164   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8166 (define_insn "*<code><mode>_1"
8167   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,k")
8168         (any_or:SWI48
8169          (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,k")
8170          (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,k")))
8171    (clobber (reg:CC FLAGS_REG))]
8172   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8173   "@
8174    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8175    <logic>{<imodesuffix>}\t{%2, %0|%0, %2}
8176    k<logic><mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8177   [(set_attr "type" "alu,alu,msklog")
8178    (set_attr "mode" "<MODE>")])
8180 (define_insn "*<code>hi_1"
8181   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,!k")
8182         (any_or:HI
8183          (match_operand:HI 1 "nonimmediate_operand" "%0,0,k")
8184          (match_operand:HI 2 "general_operand" "<g>,r<i>,k")))
8185    (clobber (reg:CC FLAGS_REG))]
8186   "ix86_binary_operator_ok (<CODE>, HImode, operands)"
8187   "@
8188   <logic>{w}\t{%2, %0|%0, %2}
8189   <logic>{w}\t{%2, %0|%0, %2}
8190   k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8191   [(set_attr "type" "alu,alu,msklog")
8192    (set_attr "mode" "HI")])
8194 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8195 (define_insn "*<code>qi_1"
8196   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r,!k")
8197         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,k")
8198                    (match_operand:QI 2 "general_operand" "qmn,qn,rn,k")))
8199    (clobber (reg:CC FLAGS_REG))]
8200   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8201   "@
8202    <logic>{b}\t{%2, %0|%0, %2}
8203    <logic>{b}\t{%2, %0|%0, %2}
8204    <logic>{l}\t{%k2, %k0|%k0, %k2}
8205    k<logic>w\t{%2, %1, %0|%0, %1, %2}"
8206   [(set_attr "type" "alu,alu,alu,msklog")
8207    (set_attr "mode" "QI,QI,SI,HI")])
8209 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8210 (define_insn "*<code>si_1_zext"
8211   [(set (match_operand:DI 0 "register_operand" "=r")
8212         (zero_extend:DI
8213          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8214                     (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8215    (clobber (reg:CC FLAGS_REG))]
8216   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8217   "<logic>{l}\t{%2, %k0|%k0, %2}"
8218   [(set_attr "type" "alu")
8219    (set_attr "mode" "SI")])
8221 (define_insn "*<code>si_1_zext_imm"
8222   [(set (match_operand:DI 0 "register_operand" "=r")
8223         (any_or:DI
8224          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8225          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8226    (clobber (reg:CC FLAGS_REG))]
8227   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8228   "<logic>{l}\t{%2, %k0|%k0, %2}"
8229   [(set_attr "type" "alu")
8230    (set_attr "mode" "SI")])
8232 (define_insn "*<code>qi_1_slp"
8233   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8234         (any_or:QI (match_dup 0)
8235                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8236    (clobber (reg:CC FLAGS_REG))]
8237   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8238    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8239   "<logic>{b}\t{%1, %0|%0, %1}"
8240   [(set_attr "type" "alu1")
8241    (set_attr "mode" "QI")])
8243 (define_insn "*<code><mode>_2"
8244   [(set (reg FLAGS_REG)
8245         (compare (any_or:SWI
8246                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8247                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8248                  (const_int 0)))
8249    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8250         (any_or:SWI (match_dup 1) (match_dup 2)))]
8251   "ix86_match_ccmode (insn, CCNOmode)
8252    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8253   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8254   [(set_attr "type" "alu")
8255    (set_attr "mode" "<MODE>")])
8257 (define_insn "kxnor<mode>"
8258   [(set (match_operand:SWI12 0 "register_operand" "=r,!k")
8259         (not:SWI12
8260           (xor:SWI12
8261             (match_operand:SWI12 1 "register_operand" "0,k")
8262             (match_operand:SWI12 2 "register_operand" "r,k"))))
8263    (clobber (reg:CC FLAGS_REG))]
8264   "TARGET_AVX512F"
8266   if (which_alternative == 1 && <MODE>mode == QImode && TARGET_AVX512DQ)
8267     return "kxnorb\t{%2, %1, %0|%0, %1, %2}";
8268   return "kxnorw\t{%2, %1, %0|%0, %1, %2}";
8270   [(set_attr "type" "*,msklog")
8271    (set_attr "prefix" "*,vex")
8272    (set_attr "mode" "<MODE>")])
8274 (define_insn "kxnor<mode>"
8275   [(set (match_operand:SWI48x 0 "register_operand" "=r,!k")
8276         (not:SWI48x
8277           (xor:SWI48x
8278             (match_operand:SWI48x 1 "register_operand" "0,k")
8279             (match_operand:SWI48x 2 "register_operand" "r,k"))))
8280    (clobber (reg:CC FLAGS_REG))]
8281   "TARGET_AVX512BW"
8282   "@
8283    #
8284    kxnor<mskmodesuffix>\t{%2, %1, %0|%0, %1, %2}"
8285   [(set_attr "type" "*,msklog")
8286    (set_attr "prefix" "*,vex")
8287    (set_attr "mode" "<MODE>")])
8289 (define_split
8290   [(set (match_operand:SWI1248x 0 "general_reg_operand")
8291         (not:SWI1248x
8292           (xor:SWI1248x
8293             (match_dup 0)
8294             (match_operand:SWI1248x 1 "general_reg_operand"))))
8295    (clobber (reg:CC FLAGS_REG))]
8296   "TARGET_AVX512F && reload_completed"
8297    [(parallel [(set (match_dup 0)
8298                     (xor:HI (match_dup 0)
8299                             (match_dup 1)))
8300                (clobber (reg:CC FLAGS_REG))])
8301     (set (match_dup 0)
8302          (not:HI (match_dup 0)))])
8304 ;;There are kortrest[bdq] but no intrinsics for them.
8305 ;;We probably don't need to implement them.
8306 (define_insn "kortestzhi"
8307   [(set (reg:CCZ FLAGS_REG)
8308         (compare:CCZ
8309           (ior:HI
8310             (match_operand:HI 0 "register_operand" "k")
8311             (match_operand:HI 1 "register_operand" "k"))
8312           (const_int 0)))]
8313   "TARGET_AVX512F && ix86_match_ccmode (insn, CCZmode)"
8314   "kortestw\t{%1, %0|%0, %1}"
8315   [(set_attr "mode" "HI")
8316    (set_attr "type" "msklog")
8317    (set_attr "prefix" "vex")])
8319 (define_insn "kortestchi"
8320   [(set (reg:CCC FLAGS_REG)
8321         (compare:CCC
8322           (ior:HI
8323             (match_operand:HI 0 "register_operand" "k")
8324             (match_operand:HI 1 "register_operand" "k"))
8325           (const_int -1)))]
8326   "TARGET_AVX512F && ix86_match_ccmode (insn, CCCmode)"
8327   "kortestw\t{%1, %0|%0, %1}"
8328   [(set_attr "mode" "HI")
8329    (set_attr "type" "msklog")
8330    (set_attr "prefix" "vex")])
8332 (define_insn "kunpckhi"
8333   [(set (match_operand:HI 0 "register_operand" "=k")
8334         (ior:HI
8335           (ashift:HI
8336             (match_operand:HI 1 "register_operand" "k")
8337             (const_int 8))
8338           (zero_extend:HI (match_operand:QI 2 "register_operand" "k"))))]
8339   "TARGET_AVX512F"
8340   "kunpckbw\t{%2, %1, %0|%0, %1, %2}"
8341   [(set_attr "mode" "HI")
8342    (set_attr "type" "msklog")
8343    (set_attr "prefix" "vex")])
8345 (define_insn "kunpcksi"
8346   [(set (match_operand:SI 0 "register_operand" "=k")
8347         (ior:SI
8348           (ashift:SI
8349             (match_operand:SI 1 "register_operand" "k")
8350             (const_int 16))
8351           (zero_extend:SI (subreg:HI (match_operand:SI 2 "register_operand" "k") 0))))]
8352   "TARGET_AVX512BW"
8353   "kunpckwd\t{%2, %1, %0|%0, %1, %2}"
8354   [(set_attr "mode" "SI")])
8356 (define_insn "kunpckdi"
8357   [(set (match_operand:DI 0 "register_operand" "=k")
8358         (ior:DI
8359           (ashift:DI
8360             (match_operand:DI 1 "register_operand" "k")
8361             (const_int 32))
8362           (zero_extend:DI (subreg:SI (match_operand:DI 2 "register_operand" "k") 0))))]
8363   "TARGET_AVX512BW"
8364   "kunpckdq\t{%2, %1, %0|%0, %1, %2}"
8365   [(set_attr "mode" "DI")])
8367 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8368 ;; ??? Special case for immediate operand is missing - it is tricky.
8369 (define_insn "*<code>si_2_zext"
8370   [(set (reg FLAGS_REG)
8371         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8372                             (match_operand:SI 2 "x86_64_general_operand" "rme"))
8373                  (const_int 0)))
8374    (set (match_operand:DI 0 "register_operand" "=r")
8375         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8376   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8377    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8378   "<logic>{l}\t{%2, %k0|%k0, %2}"
8379   [(set_attr "type" "alu")
8380    (set_attr "mode" "SI")])
8382 (define_insn "*<code>si_2_zext_imm"
8383   [(set (reg FLAGS_REG)
8384         (compare (any_or:SI
8385                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8386                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8387                  (const_int 0)))
8388    (set (match_operand:DI 0 "register_operand" "=r")
8389         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8390   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8391    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8392   "<logic>{l}\t{%2, %k0|%k0, %2}"
8393   [(set_attr "type" "alu")
8394    (set_attr "mode" "SI")])
8396 (define_insn "*<code>qi_2_slp"
8397   [(set (reg FLAGS_REG)
8398         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8399                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8400                  (const_int 0)))
8401    (set (strict_low_part (match_dup 0))
8402         (any_or:QI (match_dup 0) (match_dup 1)))]
8403   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8404    && ix86_match_ccmode (insn, CCNOmode)
8405    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8406   "<logic>{b}\t{%1, %0|%0, %1}"
8407   [(set_attr "type" "alu1")
8408    (set_attr "mode" "QI")])
8410 (define_insn "*<code><mode>_3"
8411   [(set (reg FLAGS_REG)
8412         (compare (any_or:SWI
8413                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8414                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8415                  (const_int 0)))
8416    (clobber (match_scratch:SWI 0 "=<r>"))]
8417   "ix86_match_ccmode (insn, CCNOmode)
8418    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8419   "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8420   [(set_attr "type" "alu")
8421    (set_attr "mode" "<MODE>")])
8423 (define_insn "*<code>qi_ext_0"
8424   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8425                          (const_int 8)
8426                          (const_int 8))
8427         (any_or:SI
8428           (zero_extract:SI
8429             (match_operand 1 "ext_register_operand" "0")
8430             (const_int 8)
8431             (const_int 8))
8432           (match_operand 2 "const_int_operand" "n")))
8433    (clobber (reg:CC FLAGS_REG))]
8434   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8435   "<logic>{b}\t{%2, %h0|%h0, %2}"
8436   [(set_attr "type" "alu")
8437    (set_attr "length_immediate" "1")
8438    (set_attr "modrm" "1")
8439    (set_attr "mode" "QI")])
8441 (define_insn "*<code>qi_ext_1"
8442   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8443                          (const_int 8)
8444                          (const_int 8))
8445         (any_or:SI
8446           (zero_extract:SI
8447             (match_operand 1 "ext_register_operand" "0,0")
8448             (const_int 8)
8449             (const_int 8))
8450           (zero_extend:SI
8451             (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8452    (clobber (reg:CC FLAGS_REG))]
8453   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8454   "<logic>{b}\t{%2, %h0|%h0, %2}"
8455   [(set_attr "isa" "*,nox64")
8456    (set_attr "type" "alu")
8457    (set_attr "length_immediate" "0")
8458    (set_attr "mode" "QI")])
8460 (define_insn "*<code>qi_ext_2"
8461   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8462                          (const_int 8)
8463                          (const_int 8))
8464         (any_or:SI
8465           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8466                            (const_int 8)
8467                            (const_int 8))
8468           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8469                            (const_int 8)
8470                            (const_int 8))))
8471    (clobber (reg:CC FLAGS_REG))]
8472   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8473   "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8474   [(set_attr "type" "alu")
8475    (set_attr "length_immediate" "0")
8476    (set_attr "mode" "QI")])
8478 (define_split
8479   [(set (match_operand 0 "register_operand")
8480         (any_or (match_operand 1 "register_operand")
8481                 (match_operand 2 "const_int_operand")))
8482    (clobber (reg:CC FLAGS_REG))]
8483    "reload_completed
8484     && QI_REG_P (operands[0])
8485     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8486     && !(INTVAL (operands[2]) & ~(255 << 8))
8487     && GET_MODE (operands[0]) != QImode"
8488   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8489                    (any_or:SI (zero_extract:SI (match_dup 1)
8490                                                (const_int 8) (const_int 8))
8491                               (match_dup 2)))
8492               (clobber (reg:CC FLAGS_REG))])]
8494   operands[0] = gen_lowpart (SImode, operands[0]);
8495   operands[1] = gen_lowpart (SImode, operands[1]);
8496   operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8499 ;; Since OR can be encoded with sign extended immediate, this is only
8500 ;; profitable when 7th bit is set.
8501 (define_split
8502   [(set (match_operand 0 "register_operand")
8503         (any_or (match_operand 1 "general_operand")
8504                 (match_operand 2 "const_int_operand")))
8505    (clobber (reg:CC FLAGS_REG))]
8506    "reload_completed
8507     && ANY_QI_REG_P (operands[0])
8508     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8509     && !(INTVAL (operands[2]) & ~255)
8510     && (INTVAL (operands[2]) & 128)
8511     && GET_MODE (operands[0]) != QImode"
8512   [(parallel [(set (strict_low_part (match_dup 0))
8513                    (any_or:QI (match_dup 1)
8514                               (match_dup 2)))
8515               (clobber (reg:CC FLAGS_REG))])]
8517   operands[0] = gen_lowpart (QImode, operands[0]);
8518   operands[1] = gen_lowpart (QImode, operands[1]);
8519   operands[2] = gen_lowpart (QImode, operands[2]);
8522 (define_expand "xorqi_cc_ext_1"
8523   [(parallel [
8524      (set (reg:CCNO FLAGS_REG)
8525           (compare:CCNO
8526             (xor:SI
8527               (zero_extract:SI
8528                 (match_operand 1 "ext_register_operand")
8529                 (const_int 8)
8530                 (const_int 8))
8531               (match_operand:QI 2 "const_int_operand"))
8532             (const_int 0)))
8533      (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8534                            (const_int 8)
8535                            (const_int 8))
8536           (xor:SI
8537             (zero_extract:SI
8538              (match_dup 1)
8539              (const_int 8)
8540              (const_int 8))
8541             (match_dup 2)))])])
8543 (define_insn "*xorqi_cc_ext_1"
8544   [(set (reg FLAGS_REG)
8545         (compare
8546           (xor:SI
8547             (zero_extract:SI
8548               (match_operand 1 "ext_register_operand" "0,0")
8549               (const_int 8)
8550               (const_int 8))
8551             (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8552           (const_int 0)))
8553    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8554                          (const_int 8)
8555                          (const_int 8))
8556         (xor:SI
8557           (zero_extract:SI
8558            (match_dup 1)
8559            (const_int 8)
8560            (const_int 8))
8561           (match_dup 2)))]
8562   "ix86_match_ccmode (insn, CCNOmode)"
8563   "xor{b}\t{%2, %h0|%h0, %2}"
8564   [(set_attr "isa" "*,nox64")
8565    (set_attr "type" "alu")
8566    (set_attr "modrm" "1")
8567    (set_attr "mode" "QI")])
8569 ;; Negation instructions
8571 (define_expand "neg<mode>2"
8572   [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8573         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8574   ""
8575   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8577 (define_insn_and_split "*neg<dwi>2_doubleword"
8578   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8579         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8580    (clobber (reg:CC FLAGS_REG))]
8581   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8582   "#"
8583   "reload_completed"
8584   [(parallel
8585     [(set (reg:CCZ FLAGS_REG)
8586           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8587      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8588    (parallel
8589     [(set (match_dup 2)
8590           (plus:DWIH (match_dup 3)
8591                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8592                                 (const_int 0))))
8593      (clobber (reg:CC FLAGS_REG))])
8594    (parallel
8595     [(set (match_dup 2)
8596           (neg:DWIH (match_dup 2)))
8597      (clobber (reg:CC FLAGS_REG))])]
8598   "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8600 (define_insn "*neg<mode>2_1"
8601   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8602         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8603    (clobber (reg:CC FLAGS_REG))]
8604   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8605   "neg{<imodesuffix>}\t%0"
8606   [(set_attr "type" "negnot")
8607    (set_attr "mode" "<MODE>")])
8609 ;; Combine is quite creative about this pattern.
8610 (define_insn "*negsi2_1_zext"
8611   [(set (match_operand:DI 0 "register_operand" "=r")
8612         (lshiftrt:DI
8613           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8614                              (const_int 32)))
8615         (const_int 32)))
8616    (clobber (reg:CC FLAGS_REG))]
8617   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8618   "neg{l}\t%k0"
8619   [(set_attr "type" "negnot")
8620    (set_attr "mode" "SI")])
8622 ;; The problem with neg is that it does not perform (compare x 0),
8623 ;; it really performs (compare 0 x), which leaves us with the zero
8624 ;; flag being the only useful item.
8626 (define_insn "*neg<mode>2_cmpz"
8627   [(set (reg:CCZ FLAGS_REG)
8628         (compare:CCZ
8629           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8630                    (const_int 0)))
8631    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8632         (neg:SWI (match_dup 1)))]
8633   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8634   "neg{<imodesuffix>}\t%0"
8635   [(set_attr "type" "negnot")
8636    (set_attr "mode" "<MODE>")])
8638 (define_insn "*negsi2_cmpz_zext"
8639   [(set (reg:CCZ FLAGS_REG)
8640         (compare:CCZ
8641           (lshiftrt:DI
8642             (neg:DI (ashift:DI
8643                       (match_operand:DI 1 "register_operand" "0")
8644                       (const_int 32)))
8645             (const_int 32))
8646           (const_int 0)))
8647    (set (match_operand:DI 0 "register_operand" "=r")
8648         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8649                                         (const_int 32)))
8650                      (const_int 32)))]
8651   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8652   "neg{l}\t%k0"
8653   [(set_attr "type" "negnot")
8654    (set_attr "mode" "SI")])
8656 ;; Negate with jump on overflow.
8657 (define_expand "negv<mode>3"
8658   [(parallel [(set (reg:CCO FLAGS_REG)
8659                    (ne:CCO (match_operand:SWI 1 "register_operand")
8660                            (match_dup 3)))
8661               (set (match_operand:SWI 0 "register_operand")
8662                    (neg:SWI (match_dup 1)))])
8663    (set (pc) (if_then_else
8664                (eq (reg:CCO FLAGS_REG) (const_int 0))
8665                (label_ref (match_operand 2))
8666                (pc)))]
8667   ""
8669   operands[3]
8670     = gen_int_mode (HOST_WIDE_INT_1U << (GET_MODE_BITSIZE (<MODE>mode) - 1),
8671                     <MODE>mode);
8674 (define_insn "*negv<mode>3"
8675   [(set (reg:CCO FLAGS_REG)
8676         (ne:CCO (match_operand:SWI 1 "nonimmediate_operand" "0")
8677                 (match_operand:SWI 2 "const_int_operand")))
8678    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8679         (neg:SWI (match_dup 1)))]
8680   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)
8681    && mode_signbit_p (<MODE>mode, operands[2])"
8682   "neg{<imodesuffix>}\t%0"
8683   [(set_attr "type" "negnot")
8684    (set_attr "mode" "<MODE>")])
8686 ;; Changing of sign for FP values is doable using integer unit too.
8688 (define_expand "<code><mode>2"
8689   [(set (match_operand:X87MODEF 0 "register_operand")
8690         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8691   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8692   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8694 (define_insn "*absneg<mode>2_mixed"
8695   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8696         (match_operator:MODEF 3 "absneg_operator"
8697           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8698    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8699    (clobber (reg:CC FLAGS_REG))]
8700   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8701   "#")
8703 (define_insn "*absneg<mode>2_sse"
8704   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8705         (match_operator:MODEF 3 "absneg_operator"
8706           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8707    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8708    (clobber (reg:CC FLAGS_REG))]
8709   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8710   "#")
8712 (define_insn "*absneg<mode>2_i387"
8713   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8714         (match_operator:X87MODEF 3 "absneg_operator"
8715           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8716    (use (match_operand 2))
8717    (clobber (reg:CC FLAGS_REG))]
8718   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8719   "#")
8721 (define_expand "<code>tf2"
8722   [(set (match_operand:TF 0 "register_operand")
8723         (absneg:TF (match_operand:TF 1 "register_operand")))]
8724   "TARGET_SSE"
8725   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8727 (define_insn "*absnegtf2_sse"
8728   [(set (match_operand:TF 0 "register_operand" "=x,x")
8729         (match_operator:TF 3 "absneg_operator"
8730           [(match_operand:TF 1 "register_operand" "0,x")]))
8731    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8732    (clobber (reg:CC FLAGS_REG))]
8733   "TARGET_SSE"
8734   "#")
8736 ;; Splitters for fp abs and neg.
8738 (define_split
8739   [(set (match_operand 0 "fp_register_operand")
8740         (match_operator 1 "absneg_operator" [(match_dup 0)]))
8741    (use (match_operand 2))
8742    (clobber (reg:CC FLAGS_REG))]
8743   "reload_completed"
8744   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8746 (define_split
8747   [(set (match_operand 0 "register_operand")
8748         (match_operator 3 "absneg_operator"
8749           [(match_operand 1 "register_operand")]))
8750    (use (match_operand 2 "nonimmediate_operand"))
8751    (clobber (reg:CC FLAGS_REG))]
8752   "reload_completed && SSE_REG_P (operands[0])"
8753   [(set (match_dup 0) (match_dup 3))]
8755   machine_mode mode = GET_MODE (operands[0]);
8756   machine_mode vmode = GET_MODE (operands[2]);
8757   rtx tmp;
8759   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8760   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8761   if (operands_match_p (operands[0], operands[2]))
8762     std::swap (operands[1], operands[2]);
8763   if (GET_CODE (operands[3]) == ABS)
8764     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8765   else
8766     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8767   operands[3] = tmp;
8770 (define_split
8771   [(set (match_operand:SF 0 "register_operand")
8772         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8773    (use (match_operand:V4SF 2))
8774    (clobber (reg:CC FLAGS_REG))]
8775   "reload_completed"
8776   [(parallel [(set (match_dup 0) (match_dup 1))
8777               (clobber (reg:CC FLAGS_REG))])]
8779   rtx tmp;
8780   operands[0] = gen_lowpart (SImode, operands[0]);
8781   if (GET_CODE (operands[1]) == ABS)
8782     {
8783       tmp = gen_int_mode (0x7fffffff, SImode);
8784       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8785     }
8786   else
8787     {
8788       tmp = gen_int_mode (0x80000000, SImode);
8789       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8790     }
8791   operands[1] = tmp;
8794 (define_split
8795   [(set (match_operand:DF 0 "register_operand")
8796         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8797    (use (match_operand 2))
8798    (clobber (reg:CC FLAGS_REG))]
8799   "reload_completed"
8800   [(parallel [(set (match_dup 0) (match_dup 1))
8801               (clobber (reg:CC FLAGS_REG))])]
8803   rtx tmp;
8804   if (TARGET_64BIT)
8805     {
8806       tmp = gen_lowpart (DImode, operands[0]);
8807       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8808       operands[0] = tmp;
8810       if (GET_CODE (operands[1]) == ABS)
8811         tmp = const0_rtx;
8812       else
8813         tmp = gen_rtx_NOT (DImode, tmp);
8814     }
8815   else
8816     {
8817       operands[0] = gen_highpart (SImode, operands[0]);
8818       if (GET_CODE (operands[1]) == ABS)
8819         {
8820           tmp = gen_int_mode (0x7fffffff, SImode);
8821           tmp = gen_rtx_AND (SImode, operands[0], tmp);
8822         }
8823       else
8824         {
8825           tmp = gen_int_mode (0x80000000, SImode);
8826           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8827         }
8828     }
8829   operands[1] = tmp;
8832 (define_split
8833   [(set (match_operand:XF 0 "register_operand")
8834         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8835    (use (match_operand 2))
8836    (clobber (reg:CC FLAGS_REG))]
8837   "reload_completed"
8838   [(parallel [(set (match_dup 0) (match_dup 1))
8839               (clobber (reg:CC FLAGS_REG))])]
8841   rtx tmp;
8842   operands[0] = gen_rtx_REG (SImode,
8843                              true_regnum (operands[0])
8844                              + (TARGET_64BIT ? 1 : 2));
8845   if (GET_CODE (operands[1]) == ABS)
8846     {
8847       tmp = GEN_INT (0x7fff);
8848       tmp = gen_rtx_AND (SImode, operands[0], tmp);
8849     }
8850   else
8851     {
8852       tmp = GEN_INT (0x8000);
8853       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8854     }
8855   operands[1] = tmp;
8858 ;; Conditionalize these after reload. If they match before reload, we
8859 ;; lose the clobber and ability to use integer instructions.
8861 (define_insn "*<code><mode>2_1"
8862   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8863         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8864   "TARGET_80387
8865    && (reload_completed
8866        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8867   "f<absneg_mnemonic>"
8868   [(set_attr "type" "fsgn")
8869    (set_attr "mode" "<MODE>")])
8871 (define_insn "*<code>extendsfdf2"
8872   [(set (match_operand:DF 0 "register_operand" "=f")
8873         (absneg:DF (float_extend:DF
8874                      (match_operand:SF 1 "register_operand" "0"))))]
8875   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8876   "f<absneg_mnemonic>"
8877   [(set_attr "type" "fsgn")
8878    (set_attr "mode" "DF")])
8880 (define_insn "*<code>extendsfxf2"
8881   [(set (match_operand:XF 0 "register_operand" "=f")
8882         (absneg:XF (float_extend:XF
8883                      (match_operand:SF 1 "register_operand" "0"))))]
8884   "TARGET_80387"
8885   "f<absneg_mnemonic>"
8886   [(set_attr "type" "fsgn")
8887    (set_attr "mode" "XF")])
8889 (define_insn "*<code>extenddfxf2"
8890   [(set (match_operand:XF 0 "register_operand" "=f")
8891         (absneg:XF (float_extend:XF
8892                      (match_operand:DF 1 "register_operand" "0"))))]
8893   "TARGET_80387"
8894   "f<absneg_mnemonic>"
8895   [(set_attr "type" "fsgn")
8896    (set_attr "mode" "XF")])
8898 ;; Copysign instructions
8900 (define_mode_iterator CSGNMODE [SF DF TF])
8901 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8903 (define_expand "copysign<mode>3"
8904   [(match_operand:CSGNMODE 0 "register_operand")
8905    (match_operand:CSGNMODE 1 "nonmemory_operand")
8906    (match_operand:CSGNMODE 2 "register_operand")]
8907   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8908    || (TARGET_SSE && (<MODE>mode == TFmode))"
8909   "ix86_expand_copysign (operands); DONE;")
8911 (define_insn_and_split "copysign<mode>3_const"
8912   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8913         (unspec:CSGNMODE
8914           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8915            (match_operand:CSGNMODE 2 "register_operand" "0")
8916            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8917           UNSPEC_COPYSIGN))]
8918   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8919    || (TARGET_SSE && (<MODE>mode == TFmode))"
8920   "#"
8921   "&& reload_completed"
8922   [(const_int 0)]
8923   "ix86_split_copysign_const (operands); DONE;")
8925 (define_insn "copysign<mode>3_var"
8926   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8927         (unspec:CSGNMODE
8928           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8929            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8930            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8931            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8932           UNSPEC_COPYSIGN))
8933    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8934   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8935    || (TARGET_SSE && (<MODE>mode == TFmode))"
8936   "#")
8938 (define_split
8939   [(set (match_operand:CSGNMODE 0 "register_operand")
8940         (unspec:CSGNMODE
8941           [(match_operand:CSGNMODE 2 "register_operand")
8942            (match_operand:CSGNMODE 3 "register_operand")
8943            (match_operand:<CSGNVMODE> 4)
8944            (match_operand:<CSGNVMODE> 5)]
8945           UNSPEC_COPYSIGN))
8946    (clobber (match_scratch:<CSGNVMODE> 1))]
8947   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8948     || (TARGET_SSE && (<MODE>mode == TFmode)))
8949    && reload_completed"
8950   [(const_int 0)]
8951   "ix86_split_copysign_var (operands); DONE;")
8953 ;; One complement instructions
8955 (define_expand "one_cmpl<mode>2"
8956   [(set (match_operand:SWIM 0 "nonimmediate_operand")
8957         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8958   ""
8959   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8961 (define_insn "*one_cmpl<mode>2_1"
8962   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,k")
8963         (not:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,k")))]
8964   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8965   "@
8966    not{<imodesuffix>}\t%0
8967    knot<mskmodesuffix>\t{%1, %0|%0, %1}"
8968   [(set_attr "isa" "*,avx512bw")
8969    (set_attr "type" "negnot,msklog")
8970    (set_attr "prefix" "*,vex")
8971    (set_attr "mode" "<MODE>")])
8973 (define_insn "*one_cmplhi2_1"
8974   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,!k")
8975         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0,k")))]
8976   "ix86_unary_operator_ok (NOT, HImode, operands)"
8977   "@
8978    not{w}\t%0
8979    knotw\t{%1, %0|%0, %1}"
8980   [(set_attr "isa" "*,avx512f")
8981    (set_attr "type" "negnot,msklog")
8982    (set_attr "prefix" "*,vex")
8983    (set_attr "mode" "HI")])
8985 ;; %%% Potential partial reg stall on alternative 1.  What to do?
8986 (define_insn "*one_cmplqi2_1"
8987   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,!k")
8988         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,k")))]
8989   "ix86_unary_operator_ok (NOT, QImode, operands)"
8991   switch (which_alternative)
8992     {
8993     case 0:
8994       return "not{b}\t%0";
8995     case 1:
8996       return "not{l}\t%k0";
8997     case 2:
8998       if (TARGET_AVX512DQ)
8999         return "knotb\t{%1, %0|%0, %1}";
9000       return "knotw\t{%1, %0|%0, %1}";
9001     default:
9002       gcc_unreachable ();
9003     }
9005   [(set_attr "isa" "*,*,avx512f")
9006    (set_attr "type" "negnot,negnot,msklog")
9007    (set_attr "prefix" "*,*,vex")
9008    (set_attr "mode" "QI,SI,QI")])
9010 ;; ??? Currently never generated - xor is used instead.
9011 (define_insn "*one_cmplsi2_1_zext"
9012   [(set (match_operand:DI 0 "register_operand" "=r")
9013         (zero_extend:DI
9014           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9015   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9016   "not{l}\t%k0"
9017   [(set_attr "type" "negnot")
9018    (set_attr "mode" "SI")])
9020 (define_insn "*one_cmpl<mode>2_2"
9021   [(set (reg FLAGS_REG)
9022         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9023                  (const_int 0)))
9024    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9025         (not:SWI (match_dup 1)))]
9026   "ix86_match_ccmode (insn, CCNOmode)
9027    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9028   "#"
9029   [(set_attr "type" "alu1")
9030    (set_attr "mode" "<MODE>")])
9032 (define_split
9033   [(set (match_operand 0 "flags_reg_operand")
9034         (match_operator 2 "compare_operator"
9035           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9036            (const_int 0)]))
9037    (set (match_operand:SWI 1 "nonimmediate_operand")
9038         (not:SWI (match_dup 3)))]
9039   "ix86_match_ccmode (insn, CCNOmode)"
9040   [(parallel [(set (match_dup 0)
9041                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9042                                     (const_int 0)]))
9043               (set (match_dup 1)
9044                    (xor:SWI (match_dup 3) (const_int -1)))])])
9046 ;; ??? Currently never generated - xor is used instead.
9047 (define_insn "*one_cmplsi2_2_zext"
9048   [(set (reg FLAGS_REG)
9049         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9050                  (const_int 0)))
9051    (set (match_operand:DI 0 "register_operand" "=r")
9052         (zero_extend:DI (not:SI (match_dup 1))))]
9053   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9054    && ix86_unary_operator_ok (NOT, SImode, operands)"
9055   "#"
9056   [(set_attr "type" "alu1")
9057    (set_attr "mode" "SI")])
9059 (define_split
9060   [(set (match_operand 0 "flags_reg_operand")
9061         (match_operator 2 "compare_operator"
9062           [(not:SI (match_operand:SI 3 "register_operand"))
9063            (const_int 0)]))
9064    (set (match_operand:DI 1 "register_operand")
9065         (zero_extend:DI (not:SI (match_dup 3))))]
9066   "ix86_match_ccmode (insn, CCNOmode)"
9067   [(parallel [(set (match_dup 0)
9068                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9069                                     (const_int 0)]))
9070               (set (match_dup 1)
9071                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9073 ;; Shift instructions
9075 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9076 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9077 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9078 ;; from the assembler input.
9080 ;; This instruction shifts the target reg/mem as usual, but instead of
9081 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9082 ;; is a left shift double, bits are taken from the high order bits of
9083 ;; reg, else if the insn is a shift right double, bits are taken from the
9084 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9085 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9087 ;; Since sh[lr]d does not change the `reg' operand, that is done
9088 ;; separately, making all shifts emit pairs of shift double and normal
9089 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9090 ;; support a 63 bit shift, each shift where the count is in a reg expands
9091 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9093 ;; If the shift count is a constant, we need never emit more than one
9094 ;; shift pair, instead using moves and sign extension for counts greater
9095 ;; than 31.
9097 (define_expand "ashl<mode>3"
9098   [(set (match_operand:SDWIM 0 "<shift_operand>")
9099         (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9100                       (match_operand:QI 2 "nonmemory_operand")))]
9101   ""
9102   "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9104 (define_insn "*ashl<mode>3_doubleword"
9105   [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9106         (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9107                     (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9108    (clobber (reg:CC FLAGS_REG))]
9109   ""
9110   "#"
9111   [(set_attr "type" "multi")])
9113 (define_split
9114   [(set (match_operand:DWI 0 "register_operand")
9115         (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9116                     (match_operand:QI 2 "nonmemory_operand")))
9117    (clobber (reg:CC FLAGS_REG))]
9118   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9119   [(const_int 0)]
9120   "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9122 ;; By default we don't ask for a scratch register, because when DWImode
9123 ;; values are manipulated, registers are already at a premium.  But if
9124 ;; we have one handy, we won't turn it away.
9126 (define_peephole2
9127   [(match_scratch:DWIH 3 "r")
9128    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9129                    (ashift:<DWI>
9130                      (match_operand:<DWI> 1 "nonmemory_operand")
9131                      (match_operand:QI 2 "nonmemory_operand")))
9132               (clobber (reg:CC FLAGS_REG))])
9133    (match_dup 3)]
9134   "TARGET_CMOVE"
9135   [(const_int 0)]
9136   "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9138 (define_insn "x86_64_shld"
9139   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9140         (ior:DI (ashift:DI (match_dup 0)
9141                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9142                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9143                   (minus:QI (const_int 64) (match_dup 2)))))
9144    (clobber (reg:CC FLAGS_REG))]
9145   "TARGET_64BIT"
9146   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9147   [(set_attr "type" "ishift")
9148    (set_attr "prefix_0f" "1")
9149    (set_attr "mode" "DI")
9150    (set_attr "athlon_decode" "vector")
9151    (set_attr "amdfam10_decode" "vector")
9152    (set_attr "bdver1_decode" "vector")])
9154 (define_insn "x86_shld"
9155   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9156         (ior:SI (ashift:SI (match_dup 0)
9157                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9158                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9159                   (minus:QI (const_int 32) (match_dup 2)))))
9160    (clobber (reg:CC FLAGS_REG))]
9161   ""
9162   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9163   [(set_attr "type" "ishift")
9164    (set_attr "prefix_0f" "1")
9165    (set_attr "mode" "SI")
9166    (set_attr "pent_pair" "np")
9167    (set_attr "athlon_decode" "vector")
9168    (set_attr "amdfam10_decode" "vector")
9169    (set_attr "bdver1_decode" "vector")])
9171 (define_expand "x86_shift<mode>_adj_1"
9172   [(set (reg:CCZ FLAGS_REG)
9173         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9174                              (match_dup 4))
9175                      (const_int 0)))
9176    (set (match_operand:SWI48 0 "register_operand")
9177         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9178                             (match_operand:SWI48 1 "register_operand")
9179                             (match_dup 0)))
9180    (set (match_dup 1)
9181         (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9182                             (match_operand:SWI48 3 "register_operand")
9183                             (match_dup 1)))]
9184   "TARGET_CMOVE"
9185   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9187 (define_expand "x86_shift<mode>_adj_2"
9188   [(use (match_operand:SWI48 0 "register_operand"))
9189    (use (match_operand:SWI48 1 "register_operand"))
9190    (use (match_operand:QI 2 "register_operand"))]
9191   ""
9193   rtx_code_label *label = gen_label_rtx ();
9194   rtx tmp;
9196   emit_insn (gen_testqi_ccz_1 (operands[2],
9197                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9199   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9200   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9201   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9202                               gen_rtx_LABEL_REF (VOIDmode, label),
9203                               pc_rtx);
9204   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9205   JUMP_LABEL (tmp) = label;
9207   emit_move_insn (operands[0], operands[1]);
9208   ix86_expand_clear (operands[1]);
9210   emit_label (label);
9211   LABEL_NUSES (label) = 1;
9213   DONE;
9216 ;; Avoid useless masking of count operand.
9217 (define_insn "*ashl<mode>3_mask"
9218   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9219         (ashift:SWI48
9220           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9221           (subreg:QI
9222             (and:SI
9223               (match_operand:SI 2 "register_operand" "c")
9224               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9225    (clobber (reg:CC FLAGS_REG))]
9226   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9227    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9228       == GET_MODE_BITSIZE (<MODE>mode)-1"
9230   return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9232   [(set_attr "type" "ishift")
9233    (set_attr "mode" "<MODE>")])
9235 (define_insn "*bmi2_ashl<mode>3_1"
9236   [(set (match_operand:SWI48 0 "register_operand" "=r")
9237         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9238                       (match_operand:SWI48 2 "register_operand" "r")))]
9239   "TARGET_BMI2"
9240   "shlx\t{%2, %1, %0|%0, %1, %2}"
9241   [(set_attr "type" "ishiftx")
9242    (set_attr "mode" "<MODE>")])
9244 (define_insn "*ashl<mode>3_1"
9245   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9246         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9247                       (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9248    (clobber (reg:CC FLAGS_REG))]
9249   "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9251   switch (get_attr_type (insn))
9252     {
9253     case TYPE_LEA:
9254     case TYPE_ISHIFTX:
9255       return "#";
9257     case TYPE_ALU:
9258       gcc_assert (operands[2] == const1_rtx);
9259       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9260       return "add{<imodesuffix>}\t%0, %0";
9262     default:
9263       if (operands[2] == const1_rtx
9264           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9265         return "sal{<imodesuffix>}\t%0";
9266       else
9267         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9268     }
9270   [(set_attr "isa" "*,*,bmi2")
9271    (set (attr "type")
9272      (cond [(eq_attr "alternative" "1")
9273               (const_string "lea")
9274             (eq_attr "alternative" "2")
9275               (const_string "ishiftx")
9276             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9277                       (match_operand 0 "register_operand"))
9278                  (match_operand 2 "const1_operand"))
9279               (const_string "alu")
9280            ]
9281            (const_string "ishift")))
9282    (set (attr "length_immediate")
9283      (if_then_else
9284        (ior (eq_attr "type" "alu")
9285             (and (eq_attr "type" "ishift")
9286                  (and (match_operand 2 "const1_operand")
9287                       (ior (match_test "TARGET_SHIFT1")
9288                            (match_test "optimize_function_for_size_p (cfun)")))))
9289        (const_string "0")
9290        (const_string "*")))
9291    (set_attr "mode" "<MODE>")])
9293 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9294 (define_split
9295   [(set (match_operand:SWI48 0 "register_operand")
9296         (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9297                       (match_operand:QI 2 "register_operand")))
9298    (clobber (reg:CC FLAGS_REG))]
9299   "TARGET_BMI2 && reload_completed"
9300   [(set (match_dup 0)
9301         (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9302   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9304 (define_insn "*bmi2_ashlsi3_1_zext"
9305   [(set (match_operand:DI 0 "register_operand" "=r")
9306         (zero_extend:DI
9307           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9308                      (match_operand:SI 2 "register_operand" "r"))))]
9309   "TARGET_64BIT && TARGET_BMI2"
9310   "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9311   [(set_attr "type" "ishiftx")
9312    (set_attr "mode" "SI")])
9314 (define_insn "*ashlsi3_1_zext"
9315   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9316         (zero_extend:DI
9317           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9318                      (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9319    (clobber (reg:CC FLAGS_REG))]
9320   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9322   switch (get_attr_type (insn))
9323     {
9324     case TYPE_LEA:
9325     case TYPE_ISHIFTX:
9326       return "#";
9328     case TYPE_ALU:
9329       gcc_assert (operands[2] == const1_rtx);
9330       return "add{l}\t%k0, %k0";
9332     default:
9333       if (operands[2] == const1_rtx
9334           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9335         return "sal{l}\t%k0";
9336       else
9337         return "sal{l}\t{%2, %k0|%k0, %2}";
9338     }
9340   [(set_attr "isa" "*,*,bmi2")
9341    (set (attr "type")
9342      (cond [(eq_attr "alternative" "1")
9343               (const_string "lea")
9344             (eq_attr "alternative" "2")
9345               (const_string "ishiftx")
9346             (and (match_test "TARGET_DOUBLE_WITH_ADD")
9347                  (match_operand 2 "const1_operand"))
9348               (const_string "alu")
9349            ]
9350            (const_string "ishift")))
9351    (set (attr "length_immediate")
9352      (if_then_else
9353        (ior (eq_attr "type" "alu")
9354             (and (eq_attr "type" "ishift")
9355                  (and (match_operand 2 "const1_operand")
9356                       (ior (match_test "TARGET_SHIFT1")
9357                            (match_test "optimize_function_for_size_p (cfun)")))))
9358        (const_string "0")
9359        (const_string "*")))
9360    (set_attr "mode" "SI")])
9362 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9363 (define_split
9364   [(set (match_operand:DI 0 "register_operand")
9365         (zero_extend:DI
9366           (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9367                      (match_operand:QI 2 "register_operand"))))
9368    (clobber (reg:CC FLAGS_REG))]
9369   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9370   [(set (match_dup 0)
9371         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9372   "operands[2] = gen_lowpart (SImode, operands[2]);")
9374 (define_insn "*ashlhi3_1"
9375   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9376         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9377                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9378    (clobber (reg:CC FLAGS_REG))]
9379   "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9381   switch (get_attr_type (insn))
9382     {
9383     case TYPE_LEA:
9384       return "#";
9386     case TYPE_ALU:
9387       gcc_assert (operands[2] == const1_rtx);
9388       return "add{w}\t%0, %0";
9390     default:
9391       if (operands[2] == const1_rtx
9392           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9393         return "sal{w}\t%0";
9394       else
9395         return "sal{w}\t{%2, %0|%0, %2}";
9396     }
9398   [(set (attr "type")
9399      (cond [(eq_attr "alternative" "1")
9400               (const_string "lea")
9401             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9402                       (match_operand 0 "register_operand"))
9403                  (match_operand 2 "const1_operand"))
9404               (const_string "alu")
9405            ]
9406            (const_string "ishift")))
9407    (set (attr "length_immediate")
9408      (if_then_else
9409        (ior (eq_attr "type" "alu")
9410             (and (eq_attr "type" "ishift")
9411                  (and (match_operand 2 "const1_operand")
9412                       (ior (match_test "TARGET_SHIFT1")
9413                            (match_test "optimize_function_for_size_p (cfun)")))))
9414        (const_string "0")
9415        (const_string "*")))
9416    (set_attr "mode" "HI,SI")])
9418 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9419 (define_insn "*ashlqi3_1"
9420   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9421         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9422                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9423    (clobber (reg:CC FLAGS_REG))]
9424   "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9426   switch (get_attr_type (insn))
9427     {
9428     case TYPE_LEA:
9429       return "#";
9431     case TYPE_ALU:
9432       gcc_assert (operands[2] == const1_rtx);
9433       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9434         return "add{l}\t%k0, %k0";
9435       else
9436         return "add{b}\t%0, %0";
9438     default:
9439       if (operands[2] == const1_rtx
9440           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9441         {
9442           if (get_attr_mode (insn) == MODE_SI)
9443             return "sal{l}\t%k0";
9444           else
9445             return "sal{b}\t%0";
9446         }
9447       else
9448         {
9449           if (get_attr_mode (insn) == MODE_SI)
9450             return "sal{l}\t{%2, %k0|%k0, %2}";
9451           else
9452             return "sal{b}\t{%2, %0|%0, %2}";
9453         }
9454     }
9456   [(set (attr "type")
9457      (cond [(eq_attr "alternative" "2")
9458               (const_string "lea")
9459             (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9460                       (match_operand 0 "register_operand"))
9461                  (match_operand 2 "const1_operand"))
9462               (const_string "alu")
9463            ]
9464            (const_string "ishift")))
9465    (set (attr "length_immediate")
9466      (if_then_else
9467        (ior (eq_attr "type" "alu")
9468             (and (eq_attr "type" "ishift")
9469                  (and (match_operand 2 "const1_operand")
9470                       (ior (match_test "TARGET_SHIFT1")
9471                            (match_test "optimize_function_for_size_p (cfun)")))))
9472        (const_string "0")
9473        (const_string "*")))
9474    (set_attr "mode" "QI,SI,SI")])
9476 (define_insn "*ashlqi3_1_slp"
9477   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9478         (ashift:QI (match_dup 0)
9479                    (match_operand:QI 1 "nonmemory_operand" "cI")))
9480    (clobber (reg:CC FLAGS_REG))]
9481   "(optimize_function_for_size_p (cfun)
9482     || !TARGET_PARTIAL_FLAG_REG_STALL
9483     || (operands[1] == const1_rtx
9484         && (TARGET_SHIFT1
9485             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9487   switch (get_attr_type (insn))
9488     {
9489     case TYPE_ALU:
9490       gcc_assert (operands[1] == const1_rtx);
9491       return "add{b}\t%0, %0";
9493     default:
9494       if (operands[1] == const1_rtx
9495           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9496         return "sal{b}\t%0";
9497       else
9498         return "sal{b}\t{%1, %0|%0, %1}";
9499     }
9501   [(set (attr "type")
9502      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9503                       (match_operand 0 "register_operand"))
9504                  (match_operand 1 "const1_operand"))
9505               (const_string "alu")
9506            ]
9507            (const_string "ishift1")))
9508    (set (attr "length_immediate")
9509      (if_then_else
9510        (ior (eq_attr "type" "alu")
9511             (and (eq_attr "type" "ishift1")
9512                  (and (match_operand 1 "const1_operand")
9513                       (ior (match_test "TARGET_SHIFT1")
9514                            (match_test "optimize_function_for_size_p (cfun)")))))
9515        (const_string "0")
9516        (const_string "*")))
9517    (set_attr "mode" "QI")])
9519 ;; Convert ashift to the lea pattern to avoid flags dependency.
9520 (define_split
9521   [(set (match_operand 0 "register_operand")
9522         (ashift (match_operand 1 "index_register_operand")
9523                 (match_operand:QI 2 "const_int_operand")))
9524    (clobber (reg:CC FLAGS_REG))]
9525   "GET_MODE (operands[0]) == GET_MODE (operands[1])
9526    && reload_completed
9527    && true_regnum (operands[0]) != true_regnum (operands[1])"
9528   [(const_int 0)]
9530   machine_mode mode = GET_MODE (operands[0]);
9531   rtx pat;
9533   if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9534     { 
9535       mode = SImode; 
9536       operands[0] = gen_lowpart (mode, operands[0]);
9537       operands[1] = gen_lowpart (mode, operands[1]);
9538     }
9540   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9542   pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9544   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9545   DONE;
9548 ;; Convert ashift to the lea pattern to avoid flags dependency.
9549 (define_split
9550   [(set (match_operand:DI 0 "register_operand")
9551         (zero_extend:DI
9552           (ashift:SI (match_operand:SI 1 "index_register_operand")
9553                      (match_operand:QI 2 "const_int_operand"))))
9554    (clobber (reg:CC FLAGS_REG))]
9555   "TARGET_64BIT && reload_completed
9556    && true_regnum (operands[0]) != true_regnum (operands[1])"
9557   [(set (match_dup 0)
9558         (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9560   operands[1] = gen_lowpart (SImode, operands[1]);
9561   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9564 ;; This pattern can't accept a variable shift count, since shifts by
9565 ;; zero don't affect the flags.  We assume that shifts by constant
9566 ;; zero are optimized away.
9567 (define_insn "*ashl<mode>3_cmp"
9568   [(set (reg FLAGS_REG)
9569         (compare
9570           (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9571                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9572           (const_int 0)))
9573    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9574         (ashift:SWI (match_dup 1) (match_dup 2)))]
9575   "(optimize_function_for_size_p (cfun)
9576     || !TARGET_PARTIAL_FLAG_REG_STALL
9577     || (operands[2] == const1_rtx
9578         && (TARGET_SHIFT1
9579             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9580    && ix86_match_ccmode (insn, CCGOCmode)
9581    && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9583   switch (get_attr_type (insn))
9584     {
9585     case TYPE_ALU:
9586       gcc_assert (operands[2] == const1_rtx);
9587       return "add{<imodesuffix>}\t%0, %0";
9589     default:
9590       if (operands[2] == const1_rtx
9591           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9592         return "sal{<imodesuffix>}\t%0";
9593       else
9594         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9595     }
9597   [(set (attr "type")
9598      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9599                       (match_operand 0 "register_operand"))
9600                  (match_operand 2 "const1_operand"))
9601               (const_string "alu")
9602            ]
9603            (const_string "ishift")))
9604    (set (attr "length_immediate")
9605      (if_then_else
9606        (ior (eq_attr "type" "alu")
9607             (and (eq_attr "type" "ishift")
9608                  (and (match_operand 2 "const1_operand")
9609                       (ior (match_test "TARGET_SHIFT1")
9610                            (match_test "optimize_function_for_size_p (cfun)")))))
9611        (const_string "0")
9612        (const_string "*")))
9613    (set_attr "mode" "<MODE>")])
9615 (define_insn "*ashlsi3_cmp_zext"
9616   [(set (reg FLAGS_REG)
9617         (compare
9618           (ashift:SI (match_operand:SI 1 "register_operand" "0")
9619                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
9620           (const_int 0)))
9621    (set (match_operand:DI 0 "register_operand" "=r")
9622         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9623   "TARGET_64BIT
9624    && (optimize_function_for_size_p (cfun)
9625        || !TARGET_PARTIAL_FLAG_REG_STALL
9626        || (operands[2] == const1_rtx
9627            && (TARGET_SHIFT1
9628                || TARGET_DOUBLE_WITH_ADD)))
9629    && ix86_match_ccmode (insn, CCGOCmode)
9630    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9632   switch (get_attr_type (insn))
9633     {
9634     case TYPE_ALU:
9635       gcc_assert (operands[2] == const1_rtx);
9636       return "add{l}\t%k0, %k0";
9638     default:
9639       if (operands[2] == const1_rtx
9640           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9641         return "sal{l}\t%k0";
9642       else
9643         return "sal{l}\t{%2, %k0|%k0, %2}";
9644     }
9646   [(set (attr "type")
9647      (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9648                  (match_operand 2 "const1_operand"))
9649               (const_string "alu")
9650            ]
9651            (const_string "ishift")))
9652    (set (attr "length_immediate")
9653      (if_then_else
9654        (ior (eq_attr "type" "alu")
9655             (and (eq_attr "type" "ishift")
9656                  (and (match_operand 2 "const1_operand")
9657                       (ior (match_test "TARGET_SHIFT1")
9658                            (match_test "optimize_function_for_size_p (cfun)")))))
9659        (const_string "0")
9660        (const_string "*")))
9661    (set_attr "mode" "SI")])
9663 (define_insn "*ashl<mode>3_cconly"
9664   [(set (reg FLAGS_REG)
9665         (compare
9666           (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9667                       (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9668           (const_int 0)))
9669    (clobber (match_scratch:SWI 0 "=<r>"))]
9670   "(optimize_function_for_size_p (cfun)
9671     || !TARGET_PARTIAL_FLAG_REG_STALL
9672     || (operands[2] == const1_rtx
9673         && (TARGET_SHIFT1
9674             || TARGET_DOUBLE_WITH_ADD)))
9675    && ix86_match_ccmode (insn, CCGOCmode)"
9677   switch (get_attr_type (insn))
9678     {
9679     case TYPE_ALU:
9680       gcc_assert (operands[2] == const1_rtx);
9681       return "add{<imodesuffix>}\t%0, %0";
9683     default:
9684       if (operands[2] == const1_rtx
9685           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9686         return "sal{<imodesuffix>}\t%0";
9687       else
9688         return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9689     }
9691   [(set (attr "type")
9692      (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9693                       (match_operand 0 "register_operand"))
9694                  (match_operand 2 "const1_operand"))
9695               (const_string "alu")
9696            ]
9697            (const_string "ishift")))
9698    (set (attr "length_immediate")
9699      (if_then_else
9700        (ior (eq_attr "type" "alu")
9701             (and (eq_attr "type" "ishift")
9702                  (and (match_operand 2 "const1_operand")
9703                       (ior (match_test "TARGET_SHIFT1")
9704                            (match_test "optimize_function_for_size_p (cfun)")))))
9705        (const_string "0")
9706        (const_string "*")))
9707    (set_attr "mode" "<MODE>")])
9709 ;; See comment above `ashl<mode>3' about how this works.
9711 (define_expand "<shift_insn><mode>3"
9712   [(set (match_operand:SDWIM 0 "<shift_operand>")
9713         (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9714                            (match_operand:QI 2 "nonmemory_operand")))]
9715   ""
9716   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9718 ;; Avoid useless masking of count operand.
9719 (define_insn "*<shift_insn><mode>3_mask"
9720   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9721         (any_shiftrt:SWI48
9722           (match_operand:SWI48 1 "nonimmediate_operand" "0")
9723           (subreg:QI
9724             (and:SI
9725               (match_operand:SI 2 "register_operand" "c")
9726               (match_operand:SI 3 "const_int_operand" "n")) 0)))
9727    (clobber (reg:CC FLAGS_REG))]
9728   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9729    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9730       == GET_MODE_BITSIZE (<MODE>mode)-1"
9732   return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9734   [(set_attr "type" "ishift")
9735    (set_attr "mode" "<MODE>")])
9737 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9738   [(set (match_operand:DWI 0 "register_operand" "=r")
9739         (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9740                          (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9741    (clobber (reg:CC FLAGS_REG))]
9742   ""
9743   "#"
9744   "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9745   [(const_int 0)]
9746   "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9747   [(set_attr "type" "multi")])
9749 ;; By default we don't ask for a scratch register, because when DWImode
9750 ;; values are manipulated, registers are already at a premium.  But if
9751 ;; we have one handy, we won't turn it away.
9753 (define_peephole2
9754   [(match_scratch:DWIH 3 "r")
9755    (parallel [(set (match_operand:<DWI> 0 "register_operand")
9756                    (any_shiftrt:<DWI>
9757                      (match_operand:<DWI> 1 "register_operand")
9758                      (match_operand:QI 2 "nonmemory_operand")))
9759               (clobber (reg:CC FLAGS_REG))])
9760    (match_dup 3)]
9761   "TARGET_CMOVE"
9762   [(const_int 0)]
9763   "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9765 (define_insn "x86_64_shrd"
9766   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9767         (ior:DI (lshiftrt:DI (match_dup 0)
9768                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9769                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9770                   (minus:QI (const_int 64) (match_dup 2)))))
9771    (clobber (reg:CC FLAGS_REG))]
9772   "TARGET_64BIT"
9773   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9774   [(set_attr "type" "ishift")
9775    (set_attr "prefix_0f" "1")
9776    (set_attr "mode" "DI")
9777    (set_attr "athlon_decode" "vector")
9778    (set_attr "amdfam10_decode" "vector")
9779    (set_attr "bdver1_decode" "vector")])
9781 (define_insn "x86_shrd"
9782   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9783         (ior:SI (lshiftrt:SI (match_dup 0)
9784                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9785                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9786                   (minus:QI (const_int 32) (match_dup 2)))))
9787    (clobber (reg:CC FLAGS_REG))]
9788   ""
9789   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9790   [(set_attr "type" "ishift")
9791    (set_attr "prefix_0f" "1")
9792    (set_attr "mode" "SI")
9793    (set_attr "pent_pair" "np")
9794    (set_attr "athlon_decode" "vector")
9795    (set_attr "amdfam10_decode" "vector")
9796    (set_attr "bdver1_decode" "vector")])
9798 (define_insn "ashrdi3_cvt"
9799   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9800         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9801                      (match_operand:QI 2 "const_int_operand")))
9802    (clobber (reg:CC FLAGS_REG))]
9803   "TARGET_64BIT && INTVAL (operands[2]) == 63
9804    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9805    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9806   "@
9807    {cqto|cqo}
9808    sar{q}\t{%2, %0|%0, %2}"
9809   [(set_attr "type" "imovx,ishift")
9810    (set_attr "prefix_0f" "0,*")
9811    (set_attr "length_immediate" "0,*")
9812    (set_attr "modrm" "0,1")
9813    (set_attr "mode" "DI")])
9815 (define_insn "ashrsi3_cvt"
9816   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9817         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9818                      (match_operand:QI 2 "const_int_operand")))
9819    (clobber (reg:CC FLAGS_REG))]
9820   "INTVAL (operands[2]) == 31
9821    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9822    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9823   "@
9824    {cltd|cdq}
9825    sar{l}\t{%2, %0|%0, %2}"
9826   [(set_attr "type" "imovx,ishift")
9827    (set_attr "prefix_0f" "0,*")
9828    (set_attr "length_immediate" "0,*")
9829    (set_attr "modrm" "0,1")
9830    (set_attr "mode" "SI")])
9832 (define_insn "*ashrsi3_cvt_zext"
9833   [(set (match_operand:DI 0 "register_operand" "=*d,r")
9834         (zero_extend:DI
9835           (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9836                        (match_operand:QI 2 "const_int_operand"))))
9837    (clobber (reg:CC FLAGS_REG))]
9838   "TARGET_64BIT && INTVAL (operands[2]) == 31
9839    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9840    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9841   "@
9842    {cltd|cdq}
9843    sar{l}\t{%2, %k0|%k0, %2}"
9844   [(set_attr "type" "imovx,ishift")
9845    (set_attr "prefix_0f" "0,*")
9846    (set_attr "length_immediate" "0,*")
9847    (set_attr "modrm" "0,1")
9848    (set_attr "mode" "SI")])
9850 (define_expand "x86_shift<mode>_adj_3"
9851   [(use (match_operand:SWI48 0 "register_operand"))
9852    (use (match_operand:SWI48 1 "register_operand"))
9853    (use (match_operand:QI 2 "register_operand"))]
9854   ""
9856   rtx_code_label *label = gen_label_rtx ();
9857   rtx tmp;
9859   emit_insn (gen_testqi_ccz_1 (operands[2],
9860                                GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9862   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9863   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9864   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9865                               gen_rtx_LABEL_REF (VOIDmode, label),
9866                               pc_rtx);
9867   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9868   JUMP_LABEL (tmp) = label;
9870   emit_move_insn (operands[0], operands[1]);
9871   emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9872                                   GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9873   emit_label (label);
9874   LABEL_NUSES (label) = 1;
9876   DONE;
9879 (define_insn "*bmi2_<shift_insn><mode>3_1"
9880   [(set (match_operand:SWI48 0 "register_operand" "=r")
9881         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9882                            (match_operand:SWI48 2 "register_operand" "r")))]
9883   "TARGET_BMI2"
9884   "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9885   [(set_attr "type" "ishiftx")
9886    (set_attr "mode" "<MODE>")])
9888 (define_insn "*<shift_insn><mode>3_1"
9889   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9890         (any_shiftrt:SWI48
9891           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9892           (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9893    (clobber (reg:CC FLAGS_REG))]
9894   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9896   switch (get_attr_type (insn))
9897     {
9898     case TYPE_ISHIFTX:
9899       return "#";
9901     default:
9902       if (operands[2] == const1_rtx
9903           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9904         return "<shift>{<imodesuffix>}\t%0";
9905       else
9906         return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9907     }
9909   [(set_attr "isa" "*,bmi2")
9910    (set_attr "type" "ishift,ishiftx")
9911    (set (attr "length_immediate")
9912      (if_then_else
9913        (and (match_operand 2 "const1_operand")
9914             (ior (match_test "TARGET_SHIFT1")
9915                  (match_test "optimize_function_for_size_p (cfun)")))
9916        (const_string "0")
9917        (const_string "*")))
9918    (set_attr "mode" "<MODE>")])
9920 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9921 (define_split
9922   [(set (match_operand:SWI48 0 "register_operand")
9923         (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9924                            (match_operand:QI 2 "register_operand")))
9925    (clobber (reg:CC FLAGS_REG))]
9926   "TARGET_BMI2 && reload_completed"
9927   [(set (match_dup 0)
9928         (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9929   "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9931 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9932   [(set (match_operand:DI 0 "register_operand" "=r")
9933         (zero_extend:DI
9934           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9935                           (match_operand:SI 2 "register_operand" "r"))))]
9936   "TARGET_64BIT && TARGET_BMI2"
9937   "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9938   [(set_attr "type" "ishiftx")
9939    (set_attr "mode" "SI")])
9941 (define_insn "*<shift_insn>si3_1_zext"
9942   [(set (match_operand:DI 0 "register_operand" "=r,r")
9943         (zero_extend:DI
9944           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9945                           (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9946    (clobber (reg:CC FLAGS_REG))]
9947   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9949   switch (get_attr_type (insn))
9950     {
9951     case TYPE_ISHIFTX:
9952       return "#";
9954     default:
9955       if (operands[2] == const1_rtx
9956           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9957         return "<shift>{l}\t%k0";
9958       else
9959         return "<shift>{l}\t{%2, %k0|%k0, %2}";
9960     }
9962   [(set_attr "isa" "*,bmi2")
9963    (set_attr "type" "ishift,ishiftx")
9964    (set (attr "length_immediate")
9965      (if_then_else
9966        (and (match_operand 2 "const1_operand")
9967             (ior (match_test "TARGET_SHIFT1")
9968                  (match_test "optimize_function_for_size_p (cfun)")))
9969        (const_string "0")
9970        (const_string "*")))
9971    (set_attr "mode" "SI")])
9973 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9974 (define_split
9975   [(set (match_operand:DI 0 "register_operand")
9976         (zero_extend:DI
9977           (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9978                           (match_operand:QI 2 "register_operand"))))
9979    (clobber (reg:CC FLAGS_REG))]
9980   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9981   [(set (match_dup 0)
9982         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9983   "operands[2] = gen_lowpart (SImode, operands[2]);")
9985 (define_insn "*<shift_insn><mode>3_1"
9986   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9987         (any_shiftrt:SWI12
9988           (match_operand:SWI12 1 "nonimmediate_operand" "0")
9989           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9990    (clobber (reg:CC FLAGS_REG))]
9991   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9993   if (operands[2] == const1_rtx
9994       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9995     return "<shift>{<imodesuffix>}\t%0";
9996   else
9997     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9999   [(set_attr "type" "ishift")
10000    (set (attr "length_immediate")
10001      (if_then_else
10002        (and (match_operand 2 "const1_operand")
10003             (ior (match_test "TARGET_SHIFT1")
10004                  (match_test "optimize_function_for_size_p (cfun)")))
10005        (const_string "0")
10006        (const_string "*")))
10007    (set_attr "mode" "<MODE>")])
10009 (define_insn "*<shift_insn>qi3_1_slp"
10010   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10011         (any_shiftrt:QI (match_dup 0)
10012                         (match_operand:QI 1 "nonmemory_operand" "cI")))
10013    (clobber (reg:CC FLAGS_REG))]
10014   "(optimize_function_for_size_p (cfun)
10015     || !TARGET_PARTIAL_REG_STALL
10016     || (operands[1] == const1_rtx
10017         && TARGET_SHIFT1))"
10019   if (operands[1] == const1_rtx
10020       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10021     return "<shift>{b}\t%0";
10022   else
10023     return "<shift>{b}\t{%1, %0|%0, %1}";
10025   [(set_attr "type" "ishift1")
10026    (set (attr "length_immediate")
10027      (if_then_else
10028        (and (match_operand 1 "const1_operand")
10029             (ior (match_test "TARGET_SHIFT1")
10030                  (match_test "optimize_function_for_size_p (cfun)")))
10031        (const_string "0")
10032        (const_string "*")))
10033    (set_attr "mode" "QI")])
10035 ;; This pattern can't accept a variable shift count, since shifts by
10036 ;; zero don't affect the flags.  We assume that shifts by constant
10037 ;; zero are optimized away.
10038 (define_insn "*<shift_insn><mode>3_cmp"
10039   [(set (reg FLAGS_REG)
10040         (compare
10041           (any_shiftrt:SWI
10042             (match_operand:SWI 1 "nonimmediate_operand" "0")
10043             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10044           (const_int 0)))
10045    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10046         (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10047   "(optimize_function_for_size_p (cfun)
10048     || !TARGET_PARTIAL_FLAG_REG_STALL
10049     || (operands[2] == const1_rtx
10050         && TARGET_SHIFT1))
10051    && ix86_match_ccmode (insn, CCGOCmode)
10052    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10054   if (operands[2] == const1_rtx
10055       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10056     return "<shift>{<imodesuffix>}\t%0";
10057   else
10058     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10060   [(set_attr "type" "ishift")
10061    (set (attr "length_immediate")
10062      (if_then_else
10063        (and (match_operand 2 "const1_operand")
10064             (ior (match_test "TARGET_SHIFT1")
10065                  (match_test "optimize_function_for_size_p (cfun)")))
10066        (const_string "0")
10067        (const_string "*")))
10068    (set_attr "mode" "<MODE>")])
10070 (define_insn "*<shift_insn>si3_cmp_zext"
10071   [(set (reg FLAGS_REG)
10072         (compare
10073           (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10074                           (match_operand:QI 2 "const_1_to_31_operand" "I"))
10075           (const_int 0)))
10076    (set (match_operand:DI 0 "register_operand" "=r")
10077         (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10078   "TARGET_64BIT
10079    && (optimize_function_for_size_p (cfun)
10080        || !TARGET_PARTIAL_FLAG_REG_STALL
10081        || (operands[2] == const1_rtx
10082            && TARGET_SHIFT1))
10083    && ix86_match_ccmode (insn, CCGOCmode)
10084    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10086   if (operands[2] == const1_rtx
10087       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10088     return "<shift>{l}\t%k0";
10089   else
10090     return "<shift>{l}\t{%2, %k0|%k0, %2}";
10092   [(set_attr "type" "ishift")
10093    (set (attr "length_immediate")
10094      (if_then_else
10095        (and (match_operand 2 "const1_operand")
10096             (ior (match_test "TARGET_SHIFT1")
10097                  (match_test "optimize_function_for_size_p (cfun)")))
10098        (const_string "0")
10099        (const_string "*")))
10100    (set_attr "mode" "SI")])
10102 (define_insn "*<shift_insn><mode>3_cconly"
10103   [(set (reg FLAGS_REG)
10104         (compare
10105           (any_shiftrt:SWI
10106             (match_operand:SWI 1 "register_operand" "0")
10107             (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10108           (const_int 0)))
10109    (clobber (match_scratch:SWI 0 "=<r>"))]
10110   "(optimize_function_for_size_p (cfun)
10111     || !TARGET_PARTIAL_FLAG_REG_STALL
10112     || (operands[2] == const1_rtx
10113         && TARGET_SHIFT1))
10114    && ix86_match_ccmode (insn, CCGOCmode)"
10116   if (operands[2] == const1_rtx
10117       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10118     return "<shift>{<imodesuffix>}\t%0";
10119   else
10120     return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10122   [(set_attr "type" "ishift")
10123    (set (attr "length_immediate")
10124      (if_then_else
10125        (and (match_operand 2 "const1_operand")
10126             (ior (match_test "TARGET_SHIFT1")
10127                  (match_test "optimize_function_for_size_p (cfun)")))
10128        (const_string "0")
10129        (const_string "*")))
10130    (set_attr "mode" "<MODE>")])
10132 ;; Rotate instructions
10134 (define_expand "<rotate_insn>ti3"
10135   [(set (match_operand:TI 0 "register_operand")
10136         (any_rotate:TI (match_operand:TI 1 "register_operand")
10137                        (match_operand:QI 2 "nonmemory_operand")))]
10138   "TARGET_64BIT"
10140   if (const_1_to_63_operand (operands[2], VOIDmode))
10141     emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10142                 (operands[0], operands[1], operands[2]));
10143   else
10144     FAIL;
10146   DONE;
10149 (define_expand "<rotate_insn>di3"
10150   [(set (match_operand:DI 0 "shiftdi_operand")
10151         (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10152                        (match_operand:QI 2 "nonmemory_operand")))]
10153  ""
10155   if (TARGET_64BIT)
10156     ix86_expand_binary_operator (<CODE>, DImode, operands);
10157   else if (const_1_to_31_operand (operands[2], VOIDmode))
10158     emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10159                 (operands[0], operands[1], operands[2]));
10160   else
10161     FAIL;
10163   DONE;
10166 (define_expand "<rotate_insn><mode>3"
10167   [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10168         (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10169                             (match_operand:QI 2 "nonmemory_operand")))]
10170   ""
10171   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10173 ;; Avoid useless masking of count operand.
10174 (define_insn "*<rotate_insn><mode>3_mask"
10175   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10176         (any_rotate:SWI48
10177           (match_operand:SWI48 1 "nonimmediate_operand" "0")
10178           (subreg:QI
10179             (and:SI
10180               (match_operand:SI 2 "register_operand" "c")
10181               (match_operand:SI 3 "const_int_operand" "n")) 0)))
10182    (clobber (reg:CC FLAGS_REG))]
10183   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10184    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10185       == GET_MODE_BITSIZE (<MODE>mode)-1"
10187   return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10189   [(set_attr "type" "rotate")
10190    (set_attr "mode" "<MODE>")])
10192 ;; Implement rotation using two double-precision
10193 ;; shift instructions and a scratch register.
10195 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10196  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10197        (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10198                      (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10199   (clobber (reg:CC FLAGS_REG))
10200   (clobber (match_scratch:DWIH 3 "=&r"))]
10201  ""
10202  "#"
10203  "reload_completed"
10204  [(set (match_dup 3) (match_dup 4))
10205   (parallel
10206    [(set (match_dup 4)
10207          (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10208                    (lshiftrt:DWIH (match_dup 5)
10209                                   (minus:QI (match_dup 6) (match_dup 2)))))
10210     (clobber (reg:CC FLAGS_REG))])
10211   (parallel
10212    [(set (match_dup 5)
10213          (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10214                    (lshiftrt:DWIH (match_dup 3)
10215                                   (minus:QI (match_dup 6) (match_dup 2)))))
10216     (clobber (reg:CC FLAGS_REG))])]
10218   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10220   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10223 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10224  [(set (match_operand:<DWI> 0 "register_operand" "=r")
10225        (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10226                        (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10227   (clobber (reg:CC FLAGS_REG))
10228   (clobber (match_scratch:DWIH 3 "=&r"))]
10229  ""
10230  "#"
10231  "reload_completed"
10232  [(set (match_dup 3) (match_dup 4))
10233   (parallel
10234    [(set (match_dup 4)
10235          (ior:DWIH (lshiftrt:DWIH (match_dup 4) (match_dup 2))
10236                    (ashift:DWIH (match_dup 5)
10237                                 (minus:QI (match_dup 6) (match_dup 2)))))
10238     (clobber (reg:CC FLAGS_REG))])
10239   (parallel
10240    [(set (match_dup 5)
10241          (ior:DWIH (lshiftrt:DWIH (match_dup 5) (match_dup 2))
10242                    (ashift:DWIH (match_dup 3)
10243                                 (minus:QI (match_dup 6) (match_dup 2)))))
10244     (clobber (reg:CC FLAGS_REG))])]
10246   operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10248   split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10251 (define_insn "*bmi2_rorx<mode>3_1"
10252   [(set (match_operand:SWI48 0 "register_operand" "=r")
10253         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10254                         (match_operand:QI 2 "immediate_operand" "<S>")))]
10255   "TARGET_BMI2"
10256   "rorx\t{%2, %1, %0|%0, %1, %2}"
10257   [(set_attr "type" "rotatex")
10258    (set_attr "mode" "<MODE>")])
10260 (define_insn "*<rotate_insn><mode>3_1"
10261   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10262         (any_rotate:SWI48
10263           (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10264           (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10265    (clobber (reg:CC FLAGS_REG))]
10266   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10268   switch (get_attr_type (insn))
10269     {
10270     case TYPE_ROTATEX:
10271       return "#";
10273     default:
10274       if (operands[2] == const1_rtx
10275           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10276         return "<rotate>{<imodesuffix>}\t%0";
10277       else
10278         return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10279     }
10281   [(set_attr "isa" "*,bmi2")
10282    (set_attr "type" "rotate,rotatex")
10283    (set (attr "length_immediate")
10284      (if_then_else
10285        (and (eq_attr "type" "rotate")
10286             (and (match_operand 2 "const1_operand")
10287                  (ior (match_test "TARGET_SHIFT1")
10288                       (match_test "optimize_function_for_size_p (cfun)"))))
10289        (const_string "0")
10290        (const_string "*")))
10291    (set_attr "mode" "<MODE>")])
10293 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10294 (define_split
10295   [(set (match_operand:SWI48 0 "register_operand")
10296         (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10297                       (match_operand:QI 2 "immediate_operand")))
10298    (clobber (reg:CC FLAGS_REG))]
10299   "TARGET_BMI2 && reload_completed"
10300   [(set (match_dup 0)
10301         (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10303   operands[2]
10304     = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10307 (define_split
10308   [(set (match_operand:SWI48 0 "register_operand")
10309         (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10310                         (match_operand:QI 2 "immediate_operand")))
10311    (clobber (reg:CC FLAGS_REG))]
10312   "TARGET_BMI2 && reload_completed"
10313   [(set (match_dup 0)
10314         (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10316 (define_insn "*bmi2_rorxsi3_1_zext"
10317   [(set (match_operand:DI 0 "register_operand" "=r")
10318         (zero_extend:DI
10319           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10320                        (match_operand:QI 2 "immediate_operand" "I"))))]
10321   "TARGET_64BIT && TARGET_BMI2"
10322   "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10323   [(set_attr "type" "rotatex")
10324    (set_attr "mode" "SI")])
10326 (define_insn "*<rotate_insn>si3_1_zext"
10327   [(set (match_operand:DI 0 "register_operand" "=r,r")
10328         (zero_extend:DI
10329           (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10330                          (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10331    (clobber (reg:CC FLAGS_REG))]
10332   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10334   switch (get_attr_type (insn))
10335     {
10336     case TYPE_ROTATEX:
10337       return "#";
10339     default:
10340       if (operands[2] == const1_rtx
10341           && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10342         return "<rotate>{l}\t%k0";
10343       else
10344         return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10345     }
10347   [(set_attr "isa" "*,bmi2")
10348    (set_attr "type" "rotate,rotatex")
10349    (set (attr "length_immediate")
10350      (if_then_else
10351        (and (eq_attr "type" "rotate")
10352             (and (match_operand 2 "const1_operand")
10353                  (ior (match_test "TARGET_SHIFT1")
10354                       (match_test "optimize_function_for_size_p (cfun)"))))
10355        (const_string "0")
10356        (const_string "*")))
10357    (set_attr "mode" "SI")])
10359 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10360 (define_split
10361   [(set (match_operand:DI 0 "register_operand")
10362         (zero_extend:DI
10363           (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10364                      (match_operand:QI 2 "immediate_operand"))))
10365    (clobber (reg:CC FLAGS_REG))]
10366   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10367   [(set (match_dup 0)
10368         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10370   operands[2]
10371     = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10374 (define_split
10375   [(set (match_operand:DI 0 "register_operand")
10376         (zero_extend:DI
10377           (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10378                        (match_operand:QI 2 "immediate_operand"))))
10379    (clobber (reg:CC FLAGS_REG))]
10380   "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10381   [(set (match_dup 0)
10382         (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10384 (define_insn "*<rotate_insn><mode>3_1"
10385   [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10386         (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10387                           (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10388    (clobber (reg:CC FLAGS_REG))]
10389   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10391   if (operands[2] == const1_rtx
10392       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10393     return "<rotate>{<imodesuffix>}\t%0";
10394   else
10395     return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10397   [(set_attr "type" "rotate")
10398    (set (attr "length_immediate")
10399      (if_then_else
10400        (and (match_operand 2 "const1_operand")
10401             (ior (match_test "TARGET_SHIFT1")
10402                  (match_test "optimize_function_for_size_p (cfun)")))
10403        (const_string "0")
10404        (const_string "*")))
10405    (set_attr "mode" "<MODE>")])
10407 (define_insn "*<rotate_insn>qi3_1_slp"
10408   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10409         (any_rotate:QI (match_dup 0)
10410                        (match_operand:QI 1 "nonmemory_operand" "cI")))
10411    (clobber (reg:CC FLAGS_REG))]
10412   "(optimize_function_for_size_p (cfun)
10413     || !TARGET_PARTIAL_REG_STALL
10414     || (operands[1] == const1_rtx
10415         && TARGET_SHIFT1))"
10417   if (operands[1] == const1_rtx
10418       && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10419     return "<rotate>{b}\t%0";
10420   else
10421     return "<rotate>{b}\t{%1, %0|%0, %1}";
10423   [(set_attr "type" "rotate1")
10424    (set (attr "length_immediate")
10425      (if_then_else
10426        (and (match_operand 1 "const1_operand")
10427             (ior (match_test "TARGET_SHIFT1")
10428                  (match_test "optimize_function_for_size_p (cfun)")))
10429        (const_string "0")
10430        (const_string "*")))
10431    (set_attr "mode" "QI")])
10433 (define_split
10434  [(set (match_operand:HI 0 "register_operand")
10435        (any_rotate:HI (match_dup 0) (const_int 8)))
10436   (clobber (reg:CC FLAGS_REG))]
10437  "reload_completed
10438   && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10439  [(parallel [(set (strict_low_part (match_dup 0))
10440                   (bswap:HI (match_dup 0)))
10441              (clobber (reg:CC FLAGS_REG))])])
10443 ;; Bit set / bit test instructions
10445 (define_expand "extv"
10446   [(set (match_operand:SI 0 "register_operand")
10447         (sign_extract:SI (match_operand:SI 1 "register_operand")
10448                          (match_operand:SI 2 "const8_operand")
10449                          (match_operand:SI 3 "const8_operand")))]
10450   ""
10452   /* Handle extractions from %ah et al.  */
10453   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10454     FAIL;
10456   /* From mips.md: extract_bit_field doesn't verify that our source
10457      matches the predicate, so check it again here.  */
10458   if (! ext_register_operand (operands[1], VOIDmode))
10459     FAIL;
10462 (define_expand "extzv"
10463   [(set (match_operand:SI 0 "register_operand")
10464         (zero_extract:SI (match_operand 1 "ext_register_operand")
10465                          (match_operand:SI 2 "const8_operand")
10466                          (match_operand:SI 3 "const8_operand")))]
10467   ""
10469   /* Handle extractions from %ah et al.  */
10470   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10471     FAIL;
10473   /* From mips.md: extract_bit_field doesn't verify that our source
10474      matches the predicate, so check it again here.  */
10475   if (! ext_register_operand (operands[1], VOIDmode))
10476     FAIL;
10479 (define_expand "insv"
10480   [(set (zero_extract (match_operand 0 "register_operand")
10481                       (match_operand 1 "const_int_operand")
10482                       (match_operand 2 "const_int_operand"))
10483         (match_operand 3 "register_operand"))]
10484   ""
10486   rtx (*gen_mov_insv_1) (rtx, rtx);
10488   if (ix86_expand_pinsr (operands))
10489     DONE;
10491   /* Handle insertions to %ah et al.  */
10492   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10493     FAIL;
10495   /* From mips.md: insert_bit_field doesn't verify that our source
10496      matches the predicate, so check it again here.  */
10497   if (! ext_register_operand (operands[0], VOIDmode))
10498     FAIL;
10500   gen_mov_insv_1 = (TARGET_64BIT
10501                     ? gen_movdi_insv_1 : gen_movsi_insv_1);
10503   emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10504   DONE;
10507 ;; %%% bts, btr, btc, bt.
10508 ;; In general these instructions are *slow* when applied to memory,
10509 ;; since they enforce atomic operation.  When applied to registers,
10510 ;; it depends on the cpu implementation.  They're never faster than
10511 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10512 ;; no point.  But in 64-bit, we can't hold the relevant immediates
10513 ;; within the instruction itself, so operating on bits in the high
10514 ;; 32-bits of a register becomes easier.
10516 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
10517 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10518 ;; negdf respectively, so they can never be disabled entirely.
10520 (define_insn "*btsq"
10521   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10522                          (const_int 1)
10523                          (match_operand:DI 1 "const_0_to_63_operand"))
10524         (const_int 1))
10525    (clobber (reg:CC FLAGS_REG))]
10526   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10527   "bts{q}\t{%1, %0|%0, %1}"
10528   [(set_attr "type" "alu1")
10529    (set_attr "prefix_0f" "1")
10530    (set_attr "mode" "DI")])
10532 (define_insn "*btrq"
10533   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10534                          (const_int 1)
10535                          (match_operand:DI 1 "const_0_to_63_operand"))
10536         (const_int 0))
10537    (clobber (reg:CC FLAGS_REG))]
10538   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10539   "btr{q}\t{%1, %0|%0, %1}"
10540   [(set_attr "type" "alu1")
10541    (set_attr "prefix_0f" "1")
10542    (set_attr "mode" "DI")])
10544 (define_insn "*btcq"
10545   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10546                          (const_int 1)
10547                          (match_operand:DI 1 "const_0_to_63_operand"))
10548         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10549    (clobber (reg:CC FLAGS_REG))]
10550   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10551   "btc{q}\t{%1, %0|%0, %1}"
10552   [(set_attr "type" "alu1")
10553    (set_attr "prefix_0f" "1")
10554    (set_attr "mode" "DI")])
10556 ;; Allow Nocona to avoid these instructions if a register is available.
10558 (define_peephole2
10559   [(match_scratch:DI 2 "r")
10560    (parallel [(set (zero_extract:DI
10561                      (match_operand:DI 0 "register_operand")
10562                      (const_int 1)
10563                      (match_operand:DI 1 "const_0_to_63_operand"))
10564                    (const_int 1))
10565               (clobber (reg:CC FLAGS_REG))])]
10566   "TARGET_64BIT && !TARGET_USE_BT"
10567   [(const_int 0)]
10569   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10570   rtx op1;
10572   if (HOST_BITS_PER_WIDE_INT >= 64)
10573     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10574   else if (i < HOST_BITS_PER_WIDE_INT)
10575     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10576   else
10577     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10579   op1 = immed_double_const (lo, hi, DImode);
10580   if (i >= 31)
10581     {
10582       emit_move_insn (operands[2], op1);
10583       op1 = operands[2];
10584     }
10586   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10587   DONE;
10590 (define_peephole2
10591   [(match_scratch:DI 2 "r")
10592    (parallel [(set (zero_extract:DI
10593                      (match_operand:DI 0 "register_operand")
10594                      (const_int 1)
10595                      (match_operand:DI 1 "const_0_to_63_operand"))
10596                    (const_int 0))
10597               (clobber (reg:CC FLAGS_REG))])]
10598   "TARGET_64BIT && !TARGET_USE_BT"
10599   [(const_int 0)]
10601   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10602   rtx op1;
10604   if (HOST_BITS_PER_WIDE_INT >= 64)
10605     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10606   else if (i < HOST_BITS_PER_WIDE_INT)
10607     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10608   else
10609     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10611   op1 = immed_double_const (~lo, ~hi, DImode);
10612   if (i >= 32)
10613     {
10614       emit_move_insn (operands[2], op1);
10615       op1 = operands[2];
10616     }
10618   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10619   DONE;
10622 (define_peephole2
10623   [(match_scratch:DI 2 "r")
10624    (parallel [(set (zero_extract:DI
10625                      (match_operand:DI 0 "register_operand")
10626                      (const_int 1)
10627                      (match_operand:DI 1 "const_0_to_63_operand"))
10628               (not:DI (zero_extract:DI
10629                         (match_dup 0) (const_int 1) (match_dup 1))))
10630               (clobber (reg:CC FLAGS_REG))])]
10631   "TARGET_64BIT && !TARGET_USE_BT"
10632   [(const_int 0)]
10634   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10635   rtx op1;
10637   if (HOST_BITS_PER_WIDE_INT >= 64)
10638     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10639   else if (i < HOST_BITS_PER_WIDE_INT)
10640     lo = (HOST_WIDE_INT)1 << i, hi = 0;
10641   else
10642     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10644   op1 = immed_double_const (lo, hi, DImode);
10645   if (i >= 31)
10646     {
10647       emit_move_insn (operands[2], op1);
10648       op1 = operands[2];
10649     }
10651   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10652   DONE;
10655 (define_insn "*bt<mode>"
10656   [(set (reg:CCC FLAGS_REG)
10657         (compare:CCC
10658           (zero_extract:SWI48
10659             (match_operand:SWI48 0 "register_operand" "r")
10660             (const_int 1)
10661             (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10662           (const_int 0)))]
10663   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10664   "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10665   [(set_attr "type" "alu1")
10666    (set_attr "prefix_0f" "1")
10667    (set_attr "mode" "<MODE>")])
10669 ;; Store-flag instructions.
10671 ;; For all sCOND expanders, also expand the compare or test insn that
10672 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
10674 (define_insn_and_split "*setcc_di_1"
10675   [(set (match_operand:DI 0 "register_operand" "=q")
10676         (match_operator:DI 1 "ix86_comparison_operator"
10677           [(reg FLAGS_REG) (const_int 0)]))]
10678   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10679   "#"
10680   "&& reload_completed"
10681   [(set (match_dup 2) (match_dup 1))
10682    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10684   PUT_MODE (operands[1], QImode);
10685   operands[2] = gen_lowpart (QImode, operands[0]);
10688 (define_insn_and_split "*setcc_si_1_and"
10689   [(set (match_operand:SI 0 "register_operand" "=q")
10690         (match_operator:SI 1 "ix86_comparison_operator"
10691           [(reg FLAGS_REG) (const_int 0)]))
10692    (clobber (reg:CC FLAGS_REG))]
10693   "!TARGET_PARTIAL_REG_STALL
10694    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10695   "#"
10696   "&& reload_completed"
10697   [(set (match_dup 2) (match_dup 1))
10698    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10699               (clobber (reg:CC FLAGS_REG))])]
10701   PUT_MODE (operands[1], QImode);
10702   operands[2] = gen_lowpart (QImode, operands[0]);
10705 (define_insn_and_split "*setcc_si_1_movzbl"
10706   [(set (match_operand:SI 0 "register_operand" "=q")
10707         (match_operator:SI 1 "ix86_comparison_operator"
10708           [(reg FLAGS_REG) (const_int 0)]))]
10709   "!TARGET_PARTIAL_REG_STALL
10710    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10711   "#"
10712   "&& reload_completed"
10713   [(set (match_dup 2) (match_dup 1))
10714    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10716   PUT_MODE (operands[1], QImode);
10717   operands[2] = gen_lowpart (QImode, operands[0]);
10720 (define_insn "*setcc_qi"
10721   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10722         (match_operator:QI 1 "ix86_comparison_operator"
10723           [(reg FLAGS_REG) (const_int 0)]))]
10724   ""
10725   "set%C1\t%0"
10726   [(set_attr "type" "setcc")
10727    (set_attr "mode" "QI")])
10729 (define_insn "*setcc_qi_slp"
10730   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10731         (match_operator:QI 1 "ix86_comparison_operator"
10732           [(reg FLAGS_REG) (const_int 0)]))]
10733   ""
10734   "set%C1\t%0"
10735   [(set_attr "type" "setcc")
10736    (set_attr "mode" "QI")])
10738 ;; In general it is not safe to assume too much about CCmode registers,
10739 ;; so simplify-rtx stops when it sees a second one.  Under certain
10740 ;; conditions this is safe on x86, so help combine not create
10742 ;;      seta    %al
10743 ;;      testb   %al, %al
10744 ;;      sete    %al
10746 (define_split
10747   [(set (match_operand:QI 0 "nonimmediate_operand")
10748         (ne:QI (match_operator 1 "ix86_comparison_operator"
10749                  [(reg FLAGS_REG) (const_int 0)])
10750             (const_int 0)))]
10751   ""
10752   [(set (match_dup 0) (match_dup 1))]
10753   "PUT_MODE (operands[1], QImode);")
10755 (define_split
10756   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10757         (ne:QI (match_operator 1 "ix86_comparison_operator"
10758                  [(reg FLAGS_REG) (const_int 0)])
10759             (const_int 0)))]
10760   ""
10761   [(set (match_dup 0) (match_dup 1))]
10762   "PUT_MODE (operands[1], QImode);")
10764 (define_split
10765   [(set (match_operand:QI 0 "nonimmediate_operand")
10766         (eq:QI (match_operator 1 "ix86_comparison_operator"
10767                  [(reg FLAGS_REG) (const_int 0)])
10768             (const_int 0)))]
10769   ""
10770   [(set (match_dup 0) (match_dup 1))]
10772   rtx new_op1 = copy_rtx (operands[1]);
10773   operands[1] = new_op1;
10774   PUT_MODE (new_op1, QImode);
10775   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10776                                              GET_MODE (XEXP (new_op1, 0))));
10778   /* Make sure that (a) the CCmode we have for the flags is strong
10779      enough for the reversed compare or (b) we have a valid FP compare.  */
10780   if (! ix86_comparison_operator (new_op1, VOIDmode))
10781     FAIL;
10784 (define_split
10785   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10786         (eq:QI (match_operator 1 "ix86_comparison_operator"
10787                  [(reg FLAGS_REG) (const_int 0)])
10788             (const_int 0)))]
10789   ""
10790   [(set (match_dup 0) (match_dup 1))]
10792   rtx new_op1 = copy_rtx (operands[1]);
10793   operands[1] = new_op1;
10794   PUT_MODE (new_op1, QImode);
10795   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10796                                              GET_MODE (XEXP (new_op1, 0))));
10798   /* Make sure that (a) the CCmode we have for the flags is strong
10799      enough for the reversed compare or (b) we have a valid FP compare.  */
10800   if (! ix86_comparison_operator (new_op1, VOIDmode))
10801     FAIL;
10804 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10805 ;; subsequent logical operations are used to imitate conditional moves.
10806 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10807 ;; it directly.
10809 (define_insn "setcc_<mode>_sse"
10810   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10811         (match_operator:MODEF 3 "sse_comparison_operator"
10812           [(match_operand:MODEF 1 "register_operand" "0,x")
10813            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10814   "SSE_FLOAT_MODE_P (<MODE>mode)"
10815   "@
10816    cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10817    vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10818   [(set_attr "isa" "noavx,avx")
10819    (set_attr "type" "ssecmp")
10820    (set_attr "length_immediate" "1")
10821    (set_attr "prefix" "orig,vex")
10822    (set_attr "mode" "<MODE>")])
10824 ;; Basic conditional jump instructions.
10825 ;; We ignore the overflow flag for signed branch instructions.
10827 (define_insn "*jcc_1"
10828   [(set (pc)
10829         (if_then_else (match_operator 1 "ix86_comparison_operator"
10830                                       [(reg FLAGS_REG) (const_int 0)])
10831                       (label_ref (match_operand 0))
10832                       (pc)))]
10833   ""
10834   "%!%+j%C1\t%l0"
10835   [(set_attr "type" "ibr")
10836    (set_attr "modrm" "0")
10837    (set (attr "length_nobnd")
10838            (if_then_else (and (ge (minus (match_dup 0) (pc))
10839                                   (const_int -126))
10840                               (lt (minus (match_dup 0) (pc))
10841                                   (const_int 128)))
10842              (const_int 2)
10843              (const_int 6)))])
10845 (define_insn "*jcc_2"
10846   [(set (pc)
10847         (if_then_else (match_operator 1 "ix86_comparison_operator"
10848                                       [(reg FLAGS_REG) (const_int 0)])
10849                       (pc)
10850                       (label_ref (match_operand 0))))]
10851   ""
10852   "%!%+j%c1\t%l0"
10853   [(set_attr "type" "ibr")
10854    (set_attr "modrm" "0")
10855    (set (attr "length_nobnd")
10856            (if_then_else (and (ge (minus (match_dup 0) (pc))
10857                                   (const_int -126))
10858                               (lt (minus (match_dup 0) (pc))
10859                                   (const_int 128)))
10860              (const_int 2)
10861              (const_int 6)))])
10863 ;; In general it is not safe to assume too much about CCmode registers,
10864 ;; so simplify-rtx stops when it sees a second one.  Under certain
10865 ;; conditions this is safe on x86, so help combine not create
10867 ;;      seta    %al
10868 ;;      testb   %al, %al
10869 ;;      je      Lfoo
10871 (define_split
10872   [(set (pc)
10873         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10874                                       [(reg FLAGS_REG) (const_int 0)])
10875                           (const_int 0))
10876                       (label_ref (match_operand 1))
10877                       (pc)))]
10878   ""
10879   [(set (pc)
10880         (if_then_else (match_dup 0)
10881                       (label_ref (match_dup 1))
10882                       (pc)))]
10883   "PUT_MODE (operands[0], VOIDmode);")
10885 (define_split
10886   [(set (pc)
10887         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10888                                       [(reg FLAGS_REG) (const_int 0)])
10889                           (const_int 0))
10890                       (label_ref (match_operand 1))
10891                       (pc)))]
10892   ""
10893   [(set (pc)
10894         (if_then_else (match_dup 0)
10895                       (label_ref (match_dup 1))
10896                       (pc)))]
10898   rtx new_op0 = copy_rtx (operands[0]);
10899   operands[0] = new_op0;
10900   PUT_MODE (new_op0, VOIDmode);
10901   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10902                                              GET_MODE (XEXP (new_op0, 0))));
10904   /* Make sure that (a) the CCmode we have for the flags is strong
10905      enough for the reversed compare or (b) we have a valid FP compare.  */
10906   if (! ix86_comparison_operator (new_op0, VOIDmode))
10907     FAIL;
10910 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10911 ;; pass generates from shift insn with QImode operand.  Actually, the mode
10912 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10913 ;; appropriate modulo of the bit offset value.
10915 (define_insn_and_split "*jcc_bt<mode>"
10916   [(set (pc)
10917         (if_then_else (match_operator 0 "bt_comparison_operator"
10918                         [(zero_extract:SWI48
10919                            (match_operand:SWI48 1 "register_operand" "r")
10920                            (const_int 1)
10921                            (zero_extend:SI
10922                              (match_operand:QI 2 "register_operand" "r")))
10923                          (const_int 0)])
10924                       (label_ref (match_operand 3))
10925                       (pc)))
10926    (clobber (reg:CC FLAGS_REG))]
10927   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10928   "#"
10929   "&& 1"
10930   [(set (reg:CCC FLAGS_REG)
10931         (compare:CCC
10932           (zero_extract:SWI48
10933             (match_dup 1)
10934             (const_int 1)
10935             (match_dup 2))
10936           (const_int 0)))
10937    (set (pc)
10938         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10939                       (label_ref (match_dup 3))
10940                       (pc)))]
10942   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10944   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10947 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
10948 ;; zero extended to SImode.
10949 (define_insn_and_split "*jcc_bt<mode>_1"
10950   [(set (pc)
10951         (if_then_else (match_operator 0 "bt_comparison_operator"
10952                         [(zero_extract:SWI48
10953                            (match_operand:SWI48 1 "register_operand" "r")
10954                            (const_int 1)
10955                            (match_operand:SI 2 "register_operand" "r"))
10956                          (const_int 0)])
10957                       (label_ref (match_operand 3))
10958                       (pc)))
10959    (clobber (reg:CC FLAGS_REG))]
10960   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10961   "#"
10962   "&& 1"
10963   [(set (reg:CCC FLAGS_REG)
10964         (compare:CCC
10965           (zero_extract:SWI48
10966             (match_dup 1)
10967             (const_int 1)
10968             (match_dup 2))
10969           (const_int 0)))
10970    (set (pc)
10971         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10972                       (label_ref (match_dup 3))
10973                       (pc)))]
10975   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10977   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10980 ;; Avoid useless masking of bit offset operand.  "and" in SImode is correct
10981 ;; also for DImode, this is what combine produces.
10982 (define_insn_and_split "*jcc_bt<mode>_mask"
10983   [(set (pc)
10984         (if_then_else (match_operator 0 "bt_comparison_operator"
10985                         [(zero_extract:SWI48
10986                            (match_operand:SWI48 1 "register_operand" "r")
10987                            (const_int 1)
10988                            (and:SI
10989                              (match_operand:SI 2 "register_operand" "r")
10990                              (match_operand:SI 3 "const_int_operand" "n")))])
10991                       (label_ref (match_operand 4))
10992                       (pc)))
10993    (clobber (reg:CC FLAGS_REG))]
10994   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10995    && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10996       == GET_MODE_BITSIZE (<MODE>mode)-1"
10997   "#"
10998   "&& 1"
10999   [(set (reg:CCC FLAGS_REG)
11000         (compare:CCC
11001           (zero_extract:SWI48
11002             (match_dup 1)
11003             (const_int 1)
11004             (match_dup 2))
11005           (const_int 0)))
11006    (set (pc)
11007         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11008                       (label_ref (match_dup 4))
11009                       (pc)))]
11011   operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
11013   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11016 (define_insn_and_split "*jcc_btsi_1"
11017   [(set (pc)
11018         (if_then_else (match_operator 0 "bt_comparison_operator"
11019                         [(and:SI
11020                            (lshiftrt:SI
11021                              (match_operand:SI 1 "register_operand" "r")
11022                              (match_operand:QI 2 "register_operand" "r"))
11023                            (const_int 1))
11024                          (const_int 0)])
11025                       (label_ref (match_operand 3))
11026                       (pc)))
11027    (clobber (reg:CC FLAGS_REG))]
11028   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
11029   "#"
11030   "&& 1"
11031   [(set (reg:CCC FLAGS_REG)
11032         (compare:CCC
11033           (zero_extract:SI
11034             (match_dup 1)
11035             (const_int 1)
11036             (match_dup 2))
11037           (const_int 0)))
11038    (set (pc)
11039         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11040                       (label_ref (match_dup 3))
11041                       (pc)))]
11043   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11045   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11048 ;; avoid useless masking of bit offset operand
11049 (define_insn_and_split "*jcc_btsi_mask_1"
11050   [(set (pc)
11051         (if_then_else
11052           (match_operator 0 "bt_comparison_operator"
11053             [(and:SI
11054                (lshiftrt:SI
11055                  (match_operand:SI 1 "register_operand" "r")
11056                  (subreg:QI
11057                    (and:SI
11058                      (match_operand:SI 2 "register_operand" "r")
11059                      (match_operand:SI 3 "const_int_operand" "n")) 0))
11060                (const_int 1))
11061              (const_int 0)])
11062           (label_ref (match_operand 4))
11063           (pc)))
11064    (clobber (reg:CC FLAGS_REG))]
11065   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11066    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11067   "#"
11068   "&& 1"
11069   [(set (reg:CCC FLAGS_REG)
11070         (compare:CCC
11071           (zero_extract:SI
11072             (match_dup 1)
11073             (const_int 1)
11074             (match_dup 2))
11075           (const_int 0)))
11076    (set (pc)
11077         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11078                       (label_ref (match_dup 4))
11079                       (pc)))]
11080   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11082 ;; Define combination compare-and-branch fp compare instructions to help
11083 ;; combine.
11085 (define_insn "*jcc<mode>_0_i387"
11086   [(set (pc)
11087         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11088                         [(match_operand:X87MODEF 1 "register_operand" "f")
11089                          (match_operand:X87MODEF 2 "const0_operand")])
11090           (label_ref (match_operand 3))
11091           (pc)))
11092    (clobber (reg:CCFP FPSR_REG))
11093    (clobber (reg:CCFP FLAGS_REG))
11094    (clobber (match_scratch:HI 4 "=a"))]
11095   "TARGET_80387 && !TARGET_CMOVE"
11096   "#")
11098 (define_insn "*jcc<mode>_0_r_i387"
11099   [(set (pc)
11100         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11101                         [(match_operand:X87MODEF 1 "register_operand" "f")
11102                          (match_operand:X87MODEF 2 "const0_operand")])
11103           (pc)
11104           (label_ref (match_operand 3))))
11105    (clobber (reg:CCFP FPSR_REG))
11106    (clobber (reg:CCFP FLAGS_REG))
11107    (clobber (match_scratch:HI 4 "=a"))]
11108   "TARGET_80387 && !TARGET_CMOVE"
11109   "#")
11111 (define_insn "*jccxf_i387"
11112   [(set (pc)
11113         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11114                         [(match_operand:XF 1 "register_operand" "f")
11115                          (match_operand:XF 2 "register_operand" "f")])
11116           (label_ref (match_operand 3))
11117           (pc)))
11118    (clobber (reg:CCFP FPSR_REG))
11119    (clobber (reg:CCFP FLAGS_REG))
11120    (clobber (match_scratch:HI 4 "=a"))]
11121   "TARGET_80387 && !TARGET_CMOVE"
11122   "#")
11124 (define_insn "*jccxf_r_i387"
11125   [(set (pc)
11126         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11127                         [(match_operand:XF 1 "register_operand" "f")
11128                          (match_operand:XF 2 "register_operand" "f")])
11129           (pc)
11130           (label_ref (match_operand 3))))
11131    (clobber (reg:CCFP FPSR_REG))
11132    (clobber (reg:CCFP FLAGS_REG))
11133    (clobber (match_scratch:HI 4 "=a"))]
11134   "TARGET_80387 && !TARGET_CMOVE"
11135   "#")
11137 (define_insn "*jcc<mode>_i387"
11138   [(set (pc)
11139         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11140                         [(match_operand:MODEF 1 "register_operand" "f")
11141                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11142           (label_ref (match_operand 3))
11143           (pc)))
11144    (clobber (reg:CCFP FPSR_REG))
11145    (clobber (reg:CCFP FLAGS_REG))
11146    (clobber (match_scratch:HI 4 "=a"))]
11147   "TARGET_80387 && !TARGET_CMOVE"
11148   "#")
11150 (define_insn "*jcc<mode>_r_i387"
11151   [(set (pc)
11152         (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11153                         [(match_operand:MODEF 1 "register_operand" "f")
11154                          (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11155           (pc)
11156           (label_ref (match_operand 3))))
11157    (clobber (reg:CCFP FPSR_REG))
11158    (clobber (reg:CCFP FLAGS_REG))
11159    (clobber (match_scratch:HI 4 "=a"))]
11160   "TARGET_80387 && !TARGET_CMOVE"
11161   "#")
11163 (define_insn "*jccu<mode>_i387"
11164   [(set (pc)
11165         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11166                         [(match_operand:X87MODEF 1 "register_operand" "f")
11167                          (match_operand:X87MODEF 2 "register_operand" "f")])
11168           (label_ref (match_operand 3))
11169           (pc)))
11170    (clobber (reg:CCFP FPSR_REG))
11171    (clobber (reg:CCFP FLAGS_REG))
11172    (clobber (match_scratch:HI 4 "=a"))]
11173   "TARGET_80387 && !TARGET_CMOVE"
11174   "#")
11176 (define_insn "*jccu<mode>_r_i387"
11177   [(set (pc)
11178         (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11179                         [(match_operand:X87MODEF 1 "register_operand" "f")
11180                          (match_operand:X87MODEF 2 "register_operand" "f")])
11181           (pc)
11182           (label_ref (match_operand 3))))
11183    (clobber (reg:CCFP FPSR_REG))
11184    (clobber (reg:CCFP FLAGS_REG))
11185    (clobber (match_scratch:HI 4 "=a"))]
11186   "TARGET_80387 && !TARGET_CMOVE"
11187   "#")
11189 (define_split
11190   [(set (pc)
11191         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11192                         [(match_operand:X87MODEF 1 "register_operand")
11193                          (match_operand:X87MODEF 2 "nonimmediate_operand")])
11194           (match_operand 3)
11195           (match_operand 4)))
11196    (clobber (reg:CCFP FPSR_REG))
11197    (clobber (reg:CCFP FLAGS_REG))]
11198   "TARGET_80387 && !TARGET_CMOVE
11199    && reload_completed"
11200   [(const_int 0)]
11202   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11203                         operands[3], operands[4], NULL_RTX);
11204   DONE;
11207 (define_split
11208   [(set (pc)
11209         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11210                         [(match_operand:X87MODEF 1 "register_operand")
11211                          (match_operand:X87MODEF 2 "general_operand")])
11212           (match_operand 3)
11213           (match_operand 4)))
11214    (clobber (reg:CCFP FPSR_REG))
11215    (clobber (reg:CCFP FLAGS_REG))
11216    (clobber (match_scratch:HI 5))]
11217   "TARGET_80387 && !TARGET_CMOVE
11218    && reload_completed"
11219   [(const_int 0)]
11221   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11222                         operands[3], operands[4], operands[5]);
11223   DONE;
11226 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11227 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11228 ;; with a precedence over other operators and is always put in the first
11229 ;; place. Swap condition and operands to match ficom instruction.
11231 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11232   [(set (pc)
11233         (if_then_else
11234           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11235             [(match_operator:X87MODEF 1 "float_operator"
11236               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11237              (match_operand:X87MODEF 3 "register_operand" "f")])
11238           (label_ref (match_operand 4))
11239           (pc)))
11240    (clobber (reg:CCFP FPSR_REG))
11241    (clobber (reg:CCFP FLAGS_REG))
11242    (clobber (match_scratch:HI 5 "=a"))]
11243   "TARGET_80387 && !TARGET_CMOVE
11244    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11245        || optimize_function_for_size_p (cfun))"
11246   "#")
11248 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11249   [(set (pc)
11250         (if_then_else
11251           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11252             [(match_operator:X87MODEF 1 "float_operator"
11253               [(match_operand:SWI24 2 "nonimmediate_operand" "m")])
11254              (match_operand:X87MODEF 3 "register_operand" "f")])
11255           (pc)
11256           (label_ref (match_operand 4))))
11257    (clobber (reg:CCFP FPSR_REG))
11258    (clobber (reg:CCFP FLAGS_REG))
11259    (clobber (match_scratch:HI 5 "=a"))]
11260   "TARGET_80387 && !TARGET_CMOVE
11261    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11262        || optimize_function_for_size_p (cfun))"
11263   "#")
11265 (define_split
11266   [(set (pc)
11267         (if_then_else
11268           (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11269             [(match_operator:X87MODEF 1 "float_operator"
11270               [(match_operand:SWI24 2 "memory_operand")])
11271              (match_operand:X87MODEF 3 "register_operand")])
11272           (match_operand 4)
11273           (match_operand 5)))
11274    (clobber (reg:CCFP FPSR_REG))
11275    (clobber (reg:CCFP FLAGS_REG))
11276    (clobber (match_scratch:HI 6))]
11277   "TARGET_80387 && !TARGET_CMOVE
11278    && reload_completed"
11279   [(const_int 0)]
11281   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11282                         gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11283                         operands[4], operands[5], operands[6]);
11284   DONE;
11287 ;; Unconditional and other jump instructions
11289 (define_insn "jump"
11290   [(set (pc)
11291         (label_ref (match_operand 0)))]
11292   ""
11293   "%!jmp\t%l0"
11294   [(set_attr "type" "ibr")
11295    (set (attr "length_nobnd")
11296            (if_then_else (and (ge (minus (match_dup 0) (pc))
11297                                   (const_int -126))
11298                               (lt (minus (match_dup 0) (pc))
11299                                   (const_int 128)))
11300              (const_int 2)
11301              (const_int 5)))
11302    (set_attr "modrm" "0")])
11304 (define_expand "indirect_jump"
11305   [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11306   ""
11308   if (TARGET_X32)
11309     operands[0] = convert_memory_address (word_mode, operands[0]);
11312 (define_insn "*indirect_jump"
11313   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))]
11314   ""
11315   "%!jmp\t%A0"
11316   [(set_attr "type" "ibr")
11317    (set_attr "length_immediate" "0")])
11319 (define_expand "tablejump"
11320   [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11321               (use (label_ref (match_operand 1)))])]
11322   ""
11324   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11325      relative.  Convert the relative address to an absolute address.  */
11326   if (flag_pic)
11327     {
11328       rtx op0, op1;
11329       enum rtx_code code;
11331       /* We can't use @GOTOFF for text labels on VxWorks;
11332          see gotoff_operand.  */
11333       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11334         {
11335           code = PLUS;
11336           op0 = operands[0];
11337           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11338         }
11339       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11340         {
11341           code = PLUS;
11342           op0 = operands[0];
11343           op1 = pic_offset_table_rtx;
11344         }
11345       else
11346         {
11347           code = MINUS;
11348           op0 = pic_offset_table_rtx;
11349           op1 = operands[0];
11350         }
11352       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11353                                          OPTAB_DIRECT);
11354     }
11356   if (TARGET_X32)
11357     operands[0] = convert_memory_address (word_mode, operands[0]);
11360 (define_insn "*tablejump_1"
11361   [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rBw"))
11362    (use (label_ref (match_operand 1)))]
11363   ""
11364   "%!jmp\t%A0"
11365   [(set_attr "type" "ibr")
11366    (set_attr "length_immediate" "0")])
11368 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11370 (define_peephole2
11371   [(set (reg FLAGS_REG) (match_operand 0))
11372    (set (match_operand:QI 1 "register_operand")
11373         (match_operator:QI 2 "ix86_comparison_operator"
11374           [(reg FLAGS_REG) (const_int 0)]))
11375    (set (match_operand 3 "q_regs_operand")
11376         (zero_extend (match_dup 1)))]
11377   "(peep2_reg_dead_p (3, operands[1])
11378     || operands_match_p (operands[1], operands[3]))
11379    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11380   [(set (match_dup 4) (match_dup 0))
11381    (set (strict_low_part (match_dup 5))
11382         (match_dup 2))]
11384   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11385   operands[5] = gen_lowpart (QImode, operands[3]);
11386   ix86_expand_clear (operands[3]);
11389 (define_peephole2
11390   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11391               (match_operand 4)])
11392    (set (match_operand:QI 1 "register_operand")
11393         (match_operator:QI 2 "ix86_comparison_operator"
11394           [(reg FLAGS_REG) (const_int 0)]))
11395    (set (match_operand 3 "q_regs_operand")
11396         (zero_extend (match_dup 1)))]
11397   "(peep2_reg_dead_p (3, operands[1])
11398     || operands_match_p (operands[1], operands[3]))
11399    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11400   [(parallel [(set (match_dup 5) (match_dup 0))
11401               (match_dup 4)])
11402    (set (strict_low_part (match_dup 6))
11403         (match_dup 2))]
11405   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11406   operands[6] = gen_lowpart (QImode, operands[3]);
11407   ix86_expand_clear (operands[3]);
11410 ;; Similar, but match zero extend with andsi3.
11412 (define_peephole2
11413   [(set (reg FLAGS_REG) (match_operand 0))
11414    (set (match_operand:QI 1 "register_operand")
11415         (match_operator:QI 2 "ix86_comparison_operator"
11416           [(reg FLAGS_REG) (const_int 0)]))
11417    (parallel [(set (match_operand:SI 3 "q_regs_operand")
11418                    (and:SI (match_dup 3) (const_int 255)))
11419               (clobber (reg:CC FLAGS_REG))])]
11420   "REGNO (operands[1]) == REGNO (operands[3])
11421    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11422   [(set (match_dup 4) (match_dup 0))
11423    (set (strict_low_part (match_dup 5))
11424         (match_dup 2))]
11426   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11427   operands[5] = gen_lowpart (QImode, operands[3]);
11428   ix86_expand_clear (operands[3]);
11431 (define_peephole2
11432   [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11433               (match_operand 4)])
11434    (set (match_operand:QI 1 "register_operand")
11435         (match_operator:QI 2 "ix86_comparison_operator"
11436           [(reg FLAGS_REG) (const_int 0)]))
11437    (parallel [(set (match_operand 3 "q_regs_operand")
11438                    (zero_extend (match_dup 1)))
11439               (clobber (reg:CC FLAGS_REG))])]
11440   "(peep2_reg_dead_p (3, operands[1])
11441     || operands_match_p (operands[1], operands[3]))
11442    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11443   [(parallel [(set (match_dup 5) (match_dup 0))
11444               (match_dup 4)])
11445    (set (strict_low_part (match_dup 6))
11446         (match_dup 2))]
11448   operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11449   operands[6] = gen_lowpart (QImode, operands[3]);
11450   ix86_expand_clear (operands[3]);
11453 ;; Call instructions.
11455 ;; The predicates normally associated with named expanders are not properly
11456 ;; checked for calls.  This is a bug in the generic code, but it isn't that
11457 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
11459 ;; P6 processors will jump to the address after the decrement when %esp
11460 ;; is used as a call operand, so they will execute return address as a code.
11461 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11463 ;; Register constraint for call instruction.
11464 (define_mode_attr c [(SI "l") (DI "r")])
11466 ;; Call subroutine returning no value.
11468 (define_expand "call"
11469   [(call (match_operand:QI 0)
11470          (match_operand 1))
11471    (use (match_operand 2))]
11472   ""
11474   ix86_expand_call (NULL, operands[0], operands[1],
11475                     operands[2], NULL, false);
11476   DONE;
11479 (define_expand "sibcall"
11480   [(call (match_operand:QI 0)
11481          (match_operand 1))
11482    (use (match_operand 2))]
11483   ""
11485   ix86_expand_call (NULL, operands[0], operands[1],
11486                     operands[2], NULL, true);
11487   DONE;
11490 (define_insn "*call"
11491   [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>BwBz"))
11492          (match_operand 1))]
11493   "!SIBLING_CALL_P (insn)"
11494   "* return ix86_output_call_insn (insn, operands[0]);"
11495   [(set_attr "type" "call")])
11497 (define_insn "*sibcall"
11498   [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "UBsBz"))
11499          (match_operand 1))]
11500   "SIBLING_CALL_P (insn)"
11501   "* return ix86_output_call_insn (insn, operands[0]);"
11502   [(set_attr "type" "call")])
11504 (define_insn "*sibcall_memory"
11505   [(call (mem:QI (match_operand:W 0 "memory_operand" "m"))
11506          (match_operand 1))
11507    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11508   "!TARGET_X32"
11509   "* return ix86_output_call_insn (insn, operands[0]);"
11510   [(set_attr "type" "call")])
11512 (define_peephole2
11513   [(set (match_operand:W 0 "register_operand")
11514         (match_operand:W 1 "memory_operand"))
11515    (call (mem:QI (match_dup 0))
11516          (match_operand 3))]
11517   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11518    && peep2_reg_dead_p (2, operands[0])"
11519   [(parallel [(call (mem:QI (match_dup 1))
11520                     (match_dup 3))
11521               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11523 (define_peephole2
11524   [(set (match_operand:W 0 "register_operand")
11525         (match_operand:W 1 "memory_operand"))
11526    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11527    (call (mem:QI (match_dup 0))
11528          (match_operand 3))]
11529   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11530    && peep2_reg_dead_p (3, operands[0])"
11531   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11532    (parallel [(call (mem:QI (match_dup 1))
11533                     (match_dup 3))
11534               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11536 (define_expand "call_pop"
11537   [(parallel [(call (match_operand:QI 0)
11538                     (match_operand:SI 1))
11539               (set (reg:SI SP_REG)
11540                    (plus:SI (reg:SI SP_REG)
11541                             (match_operand:SI 3)))])]
11542   "!TARGET_64BIT"
11544   ix86_expand_call (NULL, operands[0], operands[1],
11545                     operands[2], operands[3], false);
11546   DONE;
11549 (define_insn "*call_pop"
11550   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lmBz"))
11551          (match_operand 1))
11552    (set (reg:SI SP_REG)
11553         (plus:SI (reg:SI SP_REG)
11554                  (match_operand:SI 2 "immediate_operand" "i")))]
11555   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11556   "* return ix86_output_call_insn (insn, operands[0]);"
11557   [(set_attr "type" "call")])
11559 (define_insn "*sibcall_pop"
11560   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "UBsBz"))
11561          (match_operand 1))
11562    (set (reg:SI SP_REG)
11563         (plus:SI (reg:SI SP_REG)
11564                  (match_operand:SI 2 "immediate_operand" "i")))]
11565   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11566   "* return ix86_output_call_insn (insn, operands[0]);"
11567   [(set_attr "type" "call")])
11569 (define_insn "*sibcall_pop_memory"
11570   [(call (mem:QI (match_operand:SI 0 "memory_operand" "m"))
11571          (match_operand 1))
11572    (set (reg:SI SP_REG)
11573         (plus:SI (reg:SI SP_REG)
11574                  (match_operand:SI 2 "immediate_operand" "i")))
11575    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11576   "!TARGET_64BIT"
11577   "* return ix86_output_call_insn (insn, operands[0]);"
11578   [(set_attr "type" "call")])
11580 (define_peephole2
11581   [(set (match_operand:SI 0 "register_operand")
11582         (match_operand:SI 1 "memory_operand"))
11583    (parallel [(call (mem:QI (match_dup 0))
11584                     (match_operand 3))
11585               (set (reg:SI SP_REG)
11586                    (plus:SI (reg:SI SP_REG)
11587                             (match_operand:SI 4 "immediate_operand")))])]
11588   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11589    && peep2_reg_dead_p (2, operands[0])"
11590   [(parallel [(call (mem:QI (match_dup 1))
11591                     (match_dup 3))
11592               (set (reg:SI SP_REG)
11593                    (plus:SI (reg:SI SP_REG)
11594                             (match_dup 4)))
11595               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11597 (define_peephole2
11598   [(set (match_operand:SI 0 "register_operand")
11599         (match_operand:SI 1 "memory_operand"))
11600    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11601    (parallel [(call (mem:QI (match_dup 0))
11602                     (match_operand 3))
11603               (set (reg:SI SP_REG)
11604                    (plus:SI (reg:SI SP_REG)
11605                             (match_operand:SI 4 "immediate_operand")))])]
11606   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11607    && peep2_reg_dead_p (3, operands[0])"
11608   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11609    (parallel [(call (mem:QI (match_dup 1))
11610                     (match_dup 3))
11611               (set (reg:SI SP_REG)
11612                    (plus:SI (reg:SI SP_REG)
11613                             (match_dup 4)))
11614               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11616 ;; Combining simple memory jump instruction
11618 (define_peephole2
11619   [(set (match_operand:W 0 "register_operand")
11620         (match_operand:W 1 "memory_operand"))
11621    (set (pc) (match_dup 0))]
11622   "!TARGET_X32 && peep2_reg_dead_p (2, operands[0])"
11623   [(set (pc) (match_dup 1))])
11625 ;; Call subroutine, returning value in operand 0
11627 (define_expand "call_value"
11628   [(set (match_operand 0)
11629         (call (match_operand:QI 1)
11630               (match_operand 2)))
11631    (use (match_operand 3))]
11632   ""
11634   ix86_expand_call (operands[0], operands[1], operands[2],
11635                     operands[3], NULL, false);
11636   DONE;
11639 (define_expand "sibcall_value"
11640   [(set (match_operand 0)
11641         (call (match_operand:QI 1)
11642               (match_operand 2)))
11643    (use (match_operand 3))]
11644   ""
11646   ix86_expand_call (operands[0], operands[1], operands[2],
11647                     operands[3], NULL, true);
11648   DONE;
11651 (define_insn "*call_value"
11652   [(set (match_operand 0)
11653         (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>BwBz"))
11654               (match_operand 2)))]
11655   "!SIBLING_CALL_P (insn)"
11656   "* return ix86_output_call_insn (insn, operands[1]);"
11657   [(set_attr "type" "callv")])
11659 (define_insn "*sibcall_value"
11660   [(set (match_operand 0)
11661         (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "UBsBz"))
11662               (match_operand 2)))]
11663   "SIBLING_CALL_P (insn)"
11664   "* return ix86_output_call_insn (insn, operands[1]);"
11665   [(set_attr "type" "callv")])
11667 (define_insn "*sibcall_value_memory"
11668   [(set (match_operand 0)
11669         (call (mem:QI (match_operand:W 1 "memory_operand" "m"))
11670               (match_operand 2)))
11671    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11672   "!TARGET_X32"
11673   "* return ix86_output_call_insn (insn, operands[1]);"
11674   [(set_attr "type" "callv")])
11676 (define_peephole2
11677   [(set (match_operand:W 0 "register_operand")
11678         (match_operand:W 1 "memory_operand"))
11679    (set (match_operand 2)
11680    (call (mem:QI (match_dup 0))
11681                  (match_operand 3)))]
11682   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (1))
11683    && peep2_reg_dead_p (2, operands[0])"
11684   [(parallel [(set (match_dup 2)
11685                    (call (mem:QI (match_dup 1))
11686                          (match_dup 3)))
11687               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11689 (define_peephole2
11690   [(set (match_operand:W 0 "register_operand")
11691         (match_operand:W 1 "memory_operand"))
11692    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11693    (set (match_operand 2)
11694         (call (mem:QI (match_dup 0))
11695               (match_operand 3)))]
11696   "!TARGET_X32 && SIBLING_CALL_P (peep2_next_insn (2))
11697    && peep2_reg_dead_p (3, operands[0])"
11698   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11699    (parallel [(set (match_dup 2)
11700                    (call (mem:QI (match_dup 1))
11701                          (match_dup 3)))
11702               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11704 (define_expand "call_value_pop"
11705   [(parallel [(set (match_operand 0)
11706                    (call (match_operand:QI 1)
11707                          (match_operand:SI 2)))
11708               (set (reg:SI SP_REG)
11709                    (plus:SI (reg:SI SP_REG)
11710                             (match_operand:SI 4)))])]
11711   "!TARGET_64BIT"
11713   ix86_expand_call (operands[0], operands[1], operands[2],
11714                     operands[3], operands[4], false);
11715   DONE;
11718 (define_insn "*call_value_pop"
11719   [(set (match_operand 0)
11720         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lmBz"))
11721               (match_operand 2)))
11722    (set (reg:SI SP_REG)
11723         (plus:SI (reg:SI SP_REG)
11724                  (match_operand:SI 3 "immediate_operand" "i")))]
11725   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11726   "* return ix86_output_call_insn (insn, operands[1]);"
11727   [(set_attr "type" "callv")])
11729 (define_insn "*sibcall_value_pop"
11730   [(set (match_operand 0)
11731         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "UBsBz"))
11732               (match_operand 2)))
11733    (set (reg:SI SP_REG)
11734         (plus:SI (reg:SI SP_REG)
11735                  (match_operand:SI 3 "immediate_operand" "i")))]
11736   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11737   "* return ix86_output_call_insn (insn, operands[1]);"
11738   [(set_attr "type" "callv")])
11740 (define_insn "*sibcall_value_pop_memory"
11741   [(set (match_operand 0)
11742         (call (mem:QI (match_operand:SI 1 "memory_operand" "m"))
11743               (match_operand 2)))
11744    (set (reg:SI SP_REG)
11745         (plus:SI (reg:SI SP_REG)
11746                  (match_operand:SI 3 "immediate_operand" "i")))
11747    (unspec [(const_int 0)] UNSPEC_PEEPSIB)]
11748   "!TARGET_64BIT"
11749   "* return ix86_output_call_insn (insn, operands[1]);"
11750   [(set_attr "type" "callv")])
11752 (define_peephole2
11753   [(set (match_operand:SI 0 "register_operand")
11754         (match_operand:SI 1 "memory_operand"))
11755    (parallel [(set (match_operand 2)
11756                    (call (mem:QI (match_dup 0))
11757                          (match_operand 3)))
11758               (set (reg:SI SP_REG)
11759                    (plus:SI (reg:SI SP_REG)
11760                             (match_operand:SI 4 "immediate_operand")))])]
11761   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (1))
11762    && peep2_reg_dead_p (2, operands[0])"
11763   [(parallel [(set (match_dup 2)
11764                    (call (mem:QI (match_dup 1))
11765                          (match_dup 3)))
11766               (set (reg:SI SP_REG)
11767                    (plus:SI (reg:SI SP_REG)
11768                             (match_dup 4)))
11769               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11771 (define_peephole2
11772   [(set (match_operand:SI 0 "register_operand")
11773         (match_operand:SI 1 "memory_operand"))
11774    (unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11775    (parallel [(set (match_operand 2)
11776                    (call (mem:QI (match_dup 0))
11777                          (match_operand 3)))
11778               (set (reg:SI SP_REG)
11779                    (plus:SI (reg:SI SP_REG)
11780                             (match_operand:SI 4 "immediate_operand")))])]
11781   "!TARGET_64BIT && SIBLING_CALL_P (peep2_next_insn (2))
11782    && peep2_reg_dead_p (3, operands[0])"
11783   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)
11784    (parallel [(set (match_dup 2)
11785                    (call (mem:QI (match_dup 1))
11786                          (match_dup 3)))
11787               (set (reg:SI SP_REG)
11788                    (plus:SI (reg:SI SP_REG)
11789                             (match_dup 4)))
11790               (unspec [(const_int 0)] UNSPEC_PEEPSIB)])])
11792 ;; Call subroutine returning any type.
11794 (define_expand "untyped_call"
11795   [(parallel [(call (match_operand 0)
11796                     (const_int 0))
11797               (match_operand 1)
11798               (match_operand 2)])]
11799   ""
11801   int i;
11803   /* In order to give reg-stack an easier job in validating two
11804      coprocessor registers as containing a possible return value,
11805      simply pretend the untyped call returns a complex long double
11806      value. 
11808      We can't use SSE_REGPARM_MAX here since callee is unprototyped
11809      and should have the default ABI.  */
11811   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11812                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11813                     operands[0], const0_rtx,
11814                     GEN_INT ((TARGET_64BIT
11815                               ? (ix86_abi == SYSV_ABI
11816                                  ? X86_64_SSE_REGPARM_MAX
11817                                  : X86_64_MS_SSE_REGPARM_MAX)
11818                               : X86_32_SSE_REGPARM_MAX)
11819                              - 1),
11820                     NULL, false);
11822   for (i = 0; i < XVECLEN (operands[2], 0); i++)
11823     {
11824       rtx set = XVECEXP (operands[2], 0, i);
11825       emit_move_insn (SET_DEST (set), SET_SRC (set));
11826     }
11828   /* The optimizer does not know that the call sets the function value
11829      registers we stored in the result block.  We avoid problems by
11830      claiming that all hard registers are used and clobbered at this
11831      point.  */
11832   emit_insn (gen_blockage ());
11834   DONE;
11837 ;; Prologue and epilogue instructions
11839 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11840 ;; all of memory.  This blocks insns from being moved across this point.
11842 (define_insn "blockage"
11843   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11844   ""
11845   ""
11846   [(set_attr "length" "0")])
11848 ;; Do not schedule instructions accessing memory across this point.
11850 (define_expand "memory_blockage"
11851   [(set (match_dup 0)
11852         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11853   ""
11855   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11856   MEM_VOLATILE_P (operands[0]) = 1;
11859 (define_insn "*memory_blockage"
11860   [(set (match_operand:BLK 0)
11861         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11862   ""
11863   ""
11864   [(set_attr "length" "0")])
11866 ;; As USE insns aren't meaningful after reload, this is used instead
11867 ;; to prevent deleting instructions setting registers for PIC code
11868 (define_insn "prologue_use"
11869   [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11870   ""
11871   ""
11872   [(set_attr "length" "0")])
11874 ;; Insn emitted into the body of a function to return from a function.
11875 ;; This is only done if the function's epilogue is known to be simple.
11876 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11878 (define_expand "return"
11879   [(simple_return)]
11880   "ix86_can_use_return_insn_p ()"
11882   if (crtl->args.pops_args)
11883     {
11884       rtx popc = GEN_INT (crtl->args.pops_args);
11885       emit_jump_insn (gen_simple_return_pop_internal (popc));
11886       DONE;
11887     }
11890 ;; We need to disable this for TARGET_SEH, as otherwise
11891 ;; shrink-wrapped prologue gets enabled too.  This might exceed
11892 ;; the maximum size of prologue in unwind information.
11894 (define_expand "simple_return"
11895   [(simple_return)]
11896   "!TARGET_SEH"
11898   if (crtl->args.pops_args)
11899     {
11900       rtx popc = GEN_INT (crtl->args.pops_args);
11901       emit_jump_insn (gen_simple_return_pop_internal (popc));
11902       DONE;
11903     }
11906 (define_insn "simple_return_internal"
11907   [(simple_return)]
11908   "reload_completed"
11909   "%!ret"
11910   [(set_attr "length_nobnd" "1")
11911    (set_attr "atom_unit" "jeu")
11912    (set_attr "length_immediate" "0")
11913    (set_attr "modrm" "0")])
11915 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11916 ;; instruction Athlon and K8 have.
11918 (define_insn "simple_return_internal_long"
11919   [(simple_return)
11920    (unspec [(const_int 0)] UNSPEC_REP)]
11921   "reload_completed"
11923   if (ix86_bnd_prefixed_insn_p (insn))
11924     return "%!ret";
11926   return "rep%; ret";
11928   [(set_attr "length" "2")
11929    (set_attr "atom_unit" "jeu")
11930    (set_attr "length_immediate" "0")
11931    (set_attr "prefix_rep" "1")
11932    (set_attr "modrm" "0")])
11934 (define_insn "simple_return_pop_internal"
11935   [(simple_return)
11936    (use (match_operand:SI 0 "const_int_operand"))]
11937   "reload_completed"
11938   "%!ret\t%0"
11939   [(set_attr "length_nobnd" "3")
11940    (set_attr "atom_unit" "jeu")
11941    (set_attr "length_immediate" "2")
11942    (set_attr "modrm" "0")])
11944 (define_insn "simple_return_indirect_internal"
11945   [(simple_return)
11946    (use (match_operand:SI 0 "register_operand" "r"))]
11947   "reload_completed"
11948   "%!jmp\t%A0"
11949   [(set_attr "type" "ibr")
11950    (set_attr "length_immediate" "0")])
11952 (define_insn "nop"
11953   [(const_int 0)]
11954   ""
11955   "nop"
11956   [(set_attr "length" "1")
11957    (set_attr "length_immediate" "0")
11958    (set_attr "modrm" "0")])
11960 ;; Generate nops.  Operand 0 is the number of nops, up to 8.
11961 (define_insn "nops"
11962   [(unspec_volatile [(match_operand 0 "const_int_operand")]
11963                     UNSPECV_NOPS)]
11964   "reload_completed"
11966   int num = INTVAL (operands[0]);
11968   gcc_assert (IN_RANGE (num, 1, 8));
11970   while (num--)
11971     fputs ("\tnop\n", asm_out_file);
11973   return "";
11975   [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11976    (set_attr "length_immediate" "0")
11977    (set_attr "modrm" "0")])
11979 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
11980 ;; branch prediction penalty for the third jump in a 16-byte
11981 ;; block on K8.
11983 (define_insn "pad"
11984   [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11985   ""
11987 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11988   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11989 #else
11990   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11991      The align insn is used to avoid 3 jump instructions in the row to improve
11992      branch prediction and the benefits hardly outweigh the cost of extra 8
11993      nops on the average inserted by full alignment pseudo operation.  */
11994 #endif
11995   return "";
11997   [(set_attr "length" "16")])
11999 (define_expand "prologue"
12000   [(const_int 0)]
12001   ""
12002   "ix86_expand_prologue (); DONE;")
12004 (define_insn "set_got"
12005   [(set (match_operand:SI 0 "register_operand" "=r")
12006         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
12007    (clobber (reg:CC FLAGS_REG))]
12008   "!TARGET_64BIT"
12009   "* return output_set_got (operands[0], NULL_RTX);"
12010   [(set_attr "type" "multi")
12011    (set_attr "length" "12")])
12013 (define_insn "set_got_labelled"
12014   [(set (match_operand:SI 0 "register_operand" "=r")
12015         (unspec:SI [(label_ref (match_operand 1))]
12016          UNSPEC_SET_GOT))
12017    (clobber (reg:CC FLAGS_REG))]
12018   "!TARGET_64BIT"
12019   "* return output_set_got (operands[0], operands[1]);"
12020   [(set_attr "type" "multi")
12021    (set_attr "length" "12")])
12023 (define_insn "set_got_rex64"
12024   [(set (match_operand:DI 0 "register_operand" "=r")
12025         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12026   "TARGET_64BIT"
12027   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12028   [(set_attr "type" "lea")
12029    (set_attr "length_address" "4")
12030    (set_attr "mode" "DI")])
12032 (define_insn "set_rip_rex64"
12033   [(set (match_operand:DI 0 "register_operand" "=r")
12034         (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12035   "TARGET_64BIT"
12036   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12037   [(set_attr "type" "lea")
12038    (set_attr "length_address" "4")
12039    (set_attr "mode" "DI")])
12041 (define_insn "set_got_offset_rex64"
12042   [(set (match_operand:DI 0 "register_operand" "=r")
12043         (unspec:DI
12044           [(label_ref (match_operand 1))]
12045           UNSPEC_SET_GOT_OFFSET))]
12046   "TARGET_LP64"
12047   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12048   [(set_attr "type" "imov")
12049    (set_attr "length_immediate" "0")
12050    (set_attr "length_address" "8")
12051    (set_attr "mode" "DI")])
12053 (define_expand "epilogue"
12054   [(const_int 0)]
12055   ""
12056   "ix86_expand_epilogue (1); DONE;")
12058 (define_expand "sibcall_epilogue"
12059   [(const_int 0)]
12060   ""
12061   "ix86_expand_epilogue (0); DONE;")
12063 (define_expand "eh_return"
12064   [(use (match_operand 0 "register_operand"))]
12065   ""
12067   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12069   /* Tricky bit: we write the address of the handler to which we will
12070      be returning into someone else's stack frame, one word below the
12071      stack address we wish to restore.  */
12072   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12073   tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12074   tmp = gen_rtx_MEM (Pmode, tmp);
12075   emit_move_insn (tmp, ra);
12077   emit_jump_insn (gen_eh_return_internal ());
12078   emit_barrier ();
12079   DONE;
12082 (define_insn_and_split "eh_return_internal"
12083   [(eh_return)]
12084   ""
12085   "#"
12086   "epilogue_completed"
12087   [(const_int 0)]
12088   "ix86_expand_epilogue (2); DONE;")
12090 (define_insn "leave"
12091   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12092    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12093    (clobber (mem:BLK (scratch)))]
12094   "!TARGET_64BIT"
12095   "leave"
12096   [(set_attr "type" "leave")])
12098 (define_insn "leave_rex64"
12099   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12100    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12101    (clobber (mem:BLK (scratch)))]
12102   "TARGET_64BIT"
12103   "leave"
12104   [(set_attr "type" "leave")])
12106 ;; Handle -fsplit-stack.
12108 (define_expand "split_stack_prologue"
12109   [(const_int 0)]
12110   ""
12112   ix86_expand_split_stack_prologue ();
12113   DONE;
12116 ;; In order to support the call/return predictor, we use a return
12117 ;; instruction which the middle-end doesn't see.
12118 (define_insn "split_stack_return"
12119   [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12120                      UNSPECV_SPLIT_STACK_RETURN)]
12121   ""
12123   if (operands[0] == const0_rtx)
12124     return "ret";
12125   else
12126     return "ret\t%0";
12128   [(set_attr "atom_unit" "jeu")
12129    (set_attr "modrm" "0")
12130    (set (attr "length")
12131         (if_then_else (match_operand:SI 0 "const0_operand")
12132                       (const_int 1)
12133                       (const_int 3)))
12134    (set (attr "length_immediate")
12135         (if_then_else (match_operand:SI 0 "const0_operand")
12136                       (const_int 0)
12137                       (const_int 2)))])
12139 ;; If there are operand 0 bytes available on the stack, jump to
12140 ;; operand 1.
12142 (define_expand "split_stack_space_check"
12143   [(set (pc) (if_then_else
12144               (ltu (minus (reg SP_REG)
12145                           (match_operand 0 "register_operand"))
12146                    (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12147               (label_ref (match_operand 1))
12148               (pc)))]
12149   ""
12151   rtx reg, size, limit;
12153   reg = gen_reg_rtx (Pmode);
12154   size = force_reg (Pmode, operands[0]);
12155   emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12156   limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12157                           UNSPEC_STACK_CHECK);
12158   limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12159   ix86_expand_branch (GEU, reg, limit, operands[1]);
12161   DONE;
12164 ;; Bit manipulation instructions.
12166 (define_expand "ffs<mode>2"
12167   [(set (match_dup 2) (const_int -1))
12168    (parallel [(set (match_dup 3) (match_dup 4))
12169               (set (match_operand:SWI48 0 "register_operand")
12170                    (ctz:SWI48
12171                      (match_operand:SWI48 1 "nonimmediate_operand")))])
12172    (set (match_dup 0) (if_then_else:SWI48
12173                         (eq (match_dup 3) (const_int 0))
12174                         (match_dup 2)
12175                         (match_dup 0)))
12176    (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12177               (clobber (reg:CC FLAGS_REG))])]
12178   ""
12180   machine_mode flags_mode;
12182   if (<MODE>mode == SImode && !TARGET_CMOVE)
12183     {
12184       emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12185       DONE;
12186     }
12188   flags_mode
12189     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12191   operands[2] = gen_reg_rtx (<MODE>mode);
12192   operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12193   operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12196 (define_insn_and_split "ffssi2_no_cmove"
12197   [(set (match_operand:SI 0 "register_operand" "=r")
12198         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12199    (clobber (match_scratch:SI 2 "=&q"))
12200    (clobber (reg:CC FLAGS_REG))]
12201   "!TARGET_CMOVE"
12202   "#"
12203   "&& reload_completed"
12204   [(parallel [(set (match_dup 4) (match_dup 5))
12205               (set (match_dup 0) (ctz:SI (match_dup 1)))])
12206    (set (strict_low_part (match_dup 3))
12207         (eq:QI (match_dup 4) (const_int 0)))
12208    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12209               (clobber (reg:CC FLAGS_REG))])
12210    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12211               (clobber (reg:CC FLAGS_REG))])
12212    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12213               (clobber (reg:CC FLAGS_REG))])]
12215   machine_mode flags_mode
12216     = (TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI) ? CCCmode : CCZmode;
12218   operands[3] = gen_lowpart (QImode, operands[2]);
12219   operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12220   operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12222   ix86_expand_clear (operands[2]);
12225 (define_insn "*tzcnt<mode>_1"
12226   [(set (reg:CCC FLAGS_REG)
12227         (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12228                      (const_int 0)))
12229    (set (match_operand:SWI48 0 "register_operand" "=r")
12230         (ctz:SWI48 (match_dup 1)))]
12231   "TARGET_BMI && !TARGET_AVOID_FALSE_DEP_FOR_BMI"
12232   "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12233   [(set_attr "type" "alu1")
12234    (set_attr "prefix_0f" "1")
12235    (set_attr "prefix_rep" "1")
12236    (set_attr "btver2_decode" "double")
12237    (set_attr "mode" "<MODE>")])
12239 (define_insn "*bsf<mode>_1"
12240   [(set (reg:CCZ FLAGS_REG)
12241         (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12242                      (const_int 0)))
12243    (set (match_operand:SWI48 0 "register_operand" "=r")
12244         (ctz:SWI48 (match_dup 1)))]
12245   ""
12246   "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12247   [(set_attr "type" "alu1")
12248    (set_attr "prefix_0f" "1")
12249    (set_attr "btver2_decode" "double")
12250    (set_attr "mode" "<MODE>")])
12252 (define_expand "ctz<mode>2"
12253   [(parallel
12254     [(set (match_operand:SWI248 0 "register_operand")
12255           (ctz:SWI248
12256             (match_operand:SWI248 1 "nonimmediate_operand")))
12257      (clobber (reg:CC FLAGS_REG))])])
12259 ; False dependency happens when destination is only updated by tzcnt,
12260 ; lzcnt or popcnt.  There is no false dependency when destination is
12261 ; also used in source.
12262 (define_insn_and_split "*ctz<mode>2_falsedep_1"
12263   [(set (match_operand:SWI48 0 "register_operand" "=r")
12264         (ctz:SWI48
12265           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12266    (clobber (reg:CC FLAGS_REG))]
12267   "(TARGET_BMI || TARGET_GENERIC)
12268    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12269   "#"
12270   "&& reload_completed"
12271   [(parallel
12272     [(set (match_dup 0)
12273           (ctz:SWI48 (match_dup 1)))
12274      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12275      (clobber (reg:CC FLAGS_REG))])]
12277   if (!reg_mentioned_p (operands[0], operands[1]))
12278     ix86_expand_clear (operands[0]);
12281 (define_insn "*ctz<mode>2_falsedep"
12282   [(set (match_operand:SWI48 0 "register_operand" "=r")
12283         (ctz:SWI48
12284           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12285    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12286            UNSPEC_INSN_FALSE_DEP)
12287    (clobber (reg:CC FLAGS_REG))]
12288   ""
12290   if (TARGET_BMI)
12291     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12292   else if (TARGET_GENERIC)
12293     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12294     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12295   else
12296     gcc_unreachable ();
12298   [(set_attr "type" "alu1")
12299    (set_attr "prefix_0f" "1")
12300    (set_attr "prefix_rep" "1")
12301    (set_attr "mode" "<MODE>")])
12303 (define_insn "*ctz<mode>2"
12304   [(set (match_operand:SWI248 0 "register_operand" "=r")
12305         (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12306    (clobber (reg:CC FLAGS_REG))]
12307   ""
12309   if (TARGET_BMI)
12310     return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12311   else if (optimize_function_for_size_p (cfun))
12312     ;
12313   else if (TARGET_GENERIC)
12314     /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI.  */
12315     return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12317   return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12319   [(set_attr "type" "alu1")
12320    (set_attr "prefix_0f" "1")
12321    (set (attr "prefix_rep")
12322      (if_then_else
12323        (ior (match_test "TARGET_BMI")
12324             (and (not (match_test "optimize_function_for_size_p (cfun)"))
12325                  (match_test "TARGET_GENERIC")))
12326        (const_string "1")
12327        (const_string "0")))
12328    (set_attr "mode" "<MODE>")])
12330 (define_expand "clz<mode>2"
12331   [(parallel
12332      [(set (match_operand:SWI248 0 "register_operand")
12333            (minus:SWI248
12334              (match_dup 2)
12335              (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12336       (clobber (reg:CC FLAGS_REG))])
12337    (parallel
12338      [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12339       (clobber (reg:CC FLAGS_REG))])]
12340   ""
12342   if (TARGET_LZCNT)
12343     {
12344       emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12345       DONE;
12346     }
12347   operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12350 (define_expand "clz<mode>2_lzcnt"
12351   [(parallel
12352     [(set (match_operand:SWI248 0 "register_operand")
12353           (clz:SWI248
12354             (match_operand:SWI248 1 "nonimmediate_operand")))
12355      (clobber (reg:CC FLAGS_REG))])]
12356   "TARGET_LZCNT")
12358 (define_insn_and_split "*clz<mode>2_lzcnt_falsedep_1"
12359   [(set (match_operand:SWI48 0 "register_operand" "=r")
12360         (clz:SWI48
12361           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12362    (clobber (reg:CC FLAGS_REG))]
12363   "TARGET_LZCNT
12364    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12365   "#"
12366   "&& reload_completed"
12367   [(parallel
12368     [(set (match_dup 0)
12369           (clz:SWI48 (match_dup 1)))
12370      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12371      (clobber (reg:CC FLAGS_REG))])]
12373   if (!reg_mentioned_p (operands[0], operands[1]))
12374     ix86_expand_clear (operands[0]);
12377 (define_insn "*clz<mode>2_lzcnt_falsedep"
12378   [(set (match_operand:SWI48 0 "register_operand" "=r")
12379         (clz:SWI48
12380           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12381    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12382            UNSPEC_INSN_FALSE_DEP)
12383    (clobber (reg:CC FLAGS_REG))]
12384   "TARGET_LZCNT"
12385   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12386   [(set_attr "prefix_rep" "1")
12387    (set_attr "type" "bitmanip")
12388    (set_attr "mode" "<MODE>")])
12390 (define_insn "*clz<mode>2_lzcnt"
12391   [(set (match_operand:SWI248 0 "register_operand" "=r")
12392         (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12393    (clobber (reg:CC FLAGS_REG))]
12394   "TARGET_LZCNT"
12395   "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12396   [(set_attr "prefix_rep" "1")
12397    (set_attr "type" "bitmanip")
12398    (set_attr "mode" "<MODE>")])
12400 ;; BMI instructions.
12401 (define_insn "*bmi_andn_<mode>"
12402   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12403         (and:SWI48
12404           (not:SWI48
12405             (match_operand:SWI48 1 "register_operand" "r,r"))
12406             (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12407    (clobber (reg:CC FLAGS_REG))]
12408   "TARGET_BMI"
12409   "andn\t{%2, %1, %0|%0, %1, %2}"
12410   [(set_attr "type" "bitmanip")
12411    (set_attr "btver2_decode" "direct, double")
12412    (set_attr "mode" "<MODE>")])
12414 (define_insn "bmi_bextr_<mode>"
12415   [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12416         (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12417                        (match_operand:SWI48 2 "register_operand" "r,r")]
12418                        UNSPEC_BEXTR))
12419    (clobber (reg:CC FLAGS_REG))]
12420   "TARGET_BMI"
12421   "bextr\t{%2, %1, %0|%0, %1, %2}"
12422   [(set_attr "type" "bitmanip")
12423    (set_attr "btver2_decode" "direct, double")
12424    (set_attr "mode" "<MODE>")])
12426 (define_insn "*bmi_blsi_<mode>"
12427   [(set (match_operand:SWI48 0 "register_operand" "=r")
12428         (and:SWI48
12429           (neg:SWI48
12430             (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12431           (match_dup 1)))
12432    (clobber (reg:CC FLAGS_REG))]
12433   "TARGET_BMI"
12434   "blsi\t{%1, %0|%0, %1}"
12435   [(set_attr "type" "bitmanip")
12436    (set_attr "btver2_decode" "double")
12437    (set_attr "mode" "<MODE>")])
12439 (define_insn "*bmi_blsmsk_<mode>"
12440   [(set (match_operand:SWI48 0 "register_operand" "=r")
12441         (xor:SWI48
12442           (plus:SWI48
12443             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12444             (const_int -1))
12445           (match_dup 1)))
12446    (clobber (reg:CC FLAGS_REG))]
12447   "TARGET_BMI"
12448   "blsmsk\t{%1, %0|%0, %1}"
12449   [(set_attr "type" "bitmanip")
12450    (set_attr "btver2_decode" "double")
12451    (set_attr "mode" "<MODE>")])
12453 (define_insn "*bmi_blsr_<mode>"
12454   [(set (match_operand:SWI48 0 "register_operand" "=r")
12455         (and:SWI48
12456           (plus:SWI48
12457             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12458             (const_int -1))
12459           (match_dup 1)))
12460    (clobber (reg:CC FLAGS_REG))]
12461    "TARGET_BMI"
12462    "blsr\t{%1, %0|%0, %1}"
12463   [(set_attr "type" "bitmanip")
12464    (set_attr "btver2_decode" "double")
12465    (set_attr "mode" "<MODE>")])
12467 ;; BMI2 instructions.
12468 (define_insn "bmi2_bzhi_<mode>3"
12469   [(set (match_operand:SWI48 0 "register_operand" "=r")
12470         (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12471                                    (match_operand:SWI48 2 "register_operand" "r"))
12472                    (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12473    (clobber (reg:CC FLAGS_REG))]
12474   "TARGET_BMI2"
12475   "bzhi\t{%2, %1, %0|%0, %1, %2}"
12476   [(set_attr "type" "bitmanip")
12477    (set_attr "prefix" "vex")
12478    (set_attr "mode" "<MODE>")])
12480 (define_insn "bmi2_pdep_<mode>3"
12481   [(set (match_operand:SWI48 0 "register_operand" "=r")
12482         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12483                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12484                        UNSPEC_PDEP))]
12485   "TARGET_BMI2"
12486   "pdep\t{%2, %1, %0|%0, %1, %2}"
12487   [(set_attr "type" "bitmanip")
12488    (set_attr "prefix" "vex")
12489    (set_attr "mode" "<MODE>")])
12491 (define_insn "bmi2_pext_<mode>3"
12492   [(set (match_operand:SWI48 0 "register_operand" "=r")
12493         (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12494                        (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12495                        UNSPEC_PEXT))]
12496   "TARGET_BMI2"
12497   "pext\t{%2, %1, %0|%0, %1, %2}"
12498   [(set_attr "type" "bitmanip")
12499    (set_attr "prefix" "vex")
12500    (set_attr "mode" "<MODE>")])
12502 ;; TBM instructions.
12503 (define_insn "tbm_bextri_<mode>"
12504   [(set (match_operand:SWI48 0 "register_operand" "=r")
12505         (zero_extract:SWI48
12506           (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12507           (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12508           (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12509    (clobber (reg:CC FLAGS_REG))]
12510    "TARGET_TBM"
12512   operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12513   return "bextr\t{%2, %1, %0|%0, %1, %2}";
12515   [(set_attr "type" "bitmanip")
12516    (set_attr "mode" "<MODE>")])
12518 (define_insn "*tbm_blcfill_<mode>"
12519   [(set (match_operand:SWI48 0 "register_operand" "=r")
12520         (and:SWI48
12521           (plus:SWI48
12522             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12523             (const_int 1))
12524           (match_dup 1)))
12525    (clobber (reg:CC FLAGS_REG))]
12526    "TARGET_TBM"
12527    "blcfill\t{%1, %0|%0, %1}"
12528   [(set_attr "type" "bitmanip")
12529    (set_attr "mode" "<MODE>")])
12531 (define_insn "*tbm_blci_<mode>"
12532   [(set (match_operand:SWI48 0 "register_operand" "=r")
12533         (ior:SWI48
12534           (not:SWI48
12535             (plus:SWI48
12536               (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12537               (const_int 1)))
12538           (match_dup 1)))
12539    (clobber (reg:CC FLAGS_REG))]
12540    "TARGET_TBM"
12541    "blci\t{%1, %0|%0, %1}"
12542   [(set_attr "type" "bitmanip")
12543    (set_attr "mode" "<MODE>")])
12545 (define_insn "*tbm_blcic_<mode>"
12546   [(set (match_operand:SWI48 0 "register_operand" "=r")
12547         (and:SWI48
12548           (plus:SWI48
12549             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12550             (const_int 1))
12551           (not:SWI48
12552             (match_dup 1))))
12553    (clobber (reg:CC FLAGS_REG))]
12554    "TARGET_TBM"
12555    "blcic\t{%1, %0|%0, %1}"
12556   [(set_attr "type" "bitmanip")
12557    (set_attr "mode" "<MODE>")])
12559 (define_insn "*tbm_blcmsk_<mode>"
12560   [(set (match_operand:SWI48 0 "register_operand" "=r")
12561         (xor:SWI48
12562           (plus:SWI48
12563             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12564             (const_int 1))
12565           (match_dup 1)))
12566    (clobber (reg:CC FLAGS_REG))]
12567    "TARGET_TBM"
12568    "blcmsk\t{%1, %0|%0, %1}"
12569   [(set_attr "type" "bitmanip")
12570    (set_attr "mode" "<MODE>")])
12572 (define_insn "*tbm_blcs_<mode>"
12573   [(set (match_operand:SWI48 0 "register_operand" "=r")
12574         (ior:SWI48
12575           (plus:SWI48
12576             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12577             (const_int 1))
12578           (match_dup 1)))
12579    (clobber (reg:CC FLAGS_REG))]
12580    "TARGET_TBM"
12581    "blcs\t{%1, %0|%0, %1}"
12582   [(set_attr "type" "bitmanip")
12583    (set_attr "mode" "<MODE>")])
12585 (define_insn "*tbm_blsfill_<mode>"
12586   [(set (match_operand:SWI48 0 "register_operand" "=r")
12587         (ior:SWI48
12588           (plus:SWI48
12589             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12590             (const_int -1))
12591           (match_dup 1)))
12592    (clobber (reg:CC FLAGS_REG))]
12593    "TARGET_TBM"
12594    "blsfill\t{%1, %0|%0, %1}"
12595   [(set_attr "type" "bitmanip")
12596    (set_attr "mode" "<MODE>")])
12598 (define_insn "*tbm_blsic_<mode>"
12599   [(set (match_operand:SWI48 0 "register_operand" "=r")
12600         (ior:SWI48
12601           (plus:SWI48
12602             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12603             (const_int -1))
12604           (not:SWI48
12605             (match_dup 1))))
12606    (clobber (reg:CC FLAGS_REG))]
12607    "TARGET_TBM"
12608    "blsic\t{%1, %0|%0, %1}"
12609   [(set_attr "type" "bitmanip")
12610    (set_attr "mode" "<MODE>")])
12612 (define_insn "*tbm_t1mskc_<mode>"
12613   [(set (match_operand:SWI48 0 "register_operand" "=r")
12614         (ior:SWI48
12615           (plus:SWI48
12616             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12617             (const_int 1))
12618           (not:SWI48
12619             (match_dup 1))))
12620    (clobber (reg:CC FLAGS_REG))]
12621    "TARGET_TBM"
12622    "t1mskc\t{%1, %0|%0, %1}"
12623   [(set_attr "type" "bitmanip")
12624    (set_attr "mode" "<MODE>")])
12626 (define_insn "*tbm_tzmsk_<mode>"
12627   [(set (match_operand:SWI48 0 "register_operand" "=r")
12628         (and:SWI48
12629           (plus:SWI48
12630             (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12631             (const_int -1))
12632           (not:SWI48
12633             (match_dup 1))))
12634    (clobber (reg:CC FLAGS_REG))]
12635    "TARGET_TBM"
12636    "tzmsk\t{%1, %0|%0, %1}"
12637   [(set_attr "type" "bitmanip")
12638    (set_attr "mode" "<MODE>")])
12640 (define_insn "bsr_rex64"
12641   [(set (match_operand:DI 0 "register_operand" "=r")
12642         (minus:DI (const_int 63)
12643                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12644    (clobber (reg:CC FLAGS_REG))]
12645   "TARGET_64BIT"
12646   "bsr{q}\t{%1, %0|%0, %1}"
12647   [(set_attr "type" "alu1")
12648    (set_attr "prefix_0f" "1")
12649    (set_attr "mode" "DI")])
12651 (define_insn "bsr"
12652   [(set (match_operand:SI 0 "register_operand" "=r")
12653         (minus:SI (const_int 31)
12654                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12655    (clobber (reg:CC FLAGS_REG))]
12656   ""
12657   "bsr{l}\t{%1, %0|%0, %1}"
12658   [(set_attr "type" "alu1")
12659    (set_attr "prefix_0f" "1")
12660    (set_attr "mode" "SI")])
12662 (define_insn "*bsrhi"
12663   [(set (match_operand:HI 0 "register_operand" "=r")
12664         (minus:HI (const_int 15)
12665                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12666    (clobber (reg:CC FLAGS_REG))]
12667   ""
12668   "bsr{w}\t{%1, %0|%0, %1}"
12669   [(set_attr "type" "alu1")
12670    (set_attr "prefix_0f" "1")
12671    (set_attr "mode" "HI")])
12673 (define_expand "popcount<mode>2"
12674   [(parallel
12675     [(set (match_operand:SWI248 0 "register_operand")
12676           (popcount:SWI248
12677             (match_operand:SWI248 1 "nonimmediate_operand")))
12678      (clobber (reg:CC FLAGS_REG))])]
12679   "TARGET_POPCNT")
12681 (define_insn_and_split "*popcount<mode>2_falsedep_1"
12682   [(set (match_operand:SWI48 0 "register_operand" "=r")
12683         (popcount:SWI48
12684           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12685    (clobber (reg:CC FLAGS_REG))]
12686   "TARGET_POPCNT
12687    && TARGET_AVOID_FALSE_DEP_FOR_BMI && optimize_function_for_speed_p (cfun)"
12688   "#"
12689   "&& reload_completed"
12690   [(parallel
12691     [(set (match_dup 0)
12692           (popcount:SWI48 (match_dup 1)))
12693      (unspec [(match_dup 0)] UNSPEC_INSN_FALSE_DEP)
12694      (clobber (reg:CC FLAGS_REG))])]
12696   if (!reg_mentioned_p (operands[0], operands[1]))
12697     ix86_expand_clear (operands[0]);
12700 (define_insn "*popcount<mode>2_falsedep"
12701   [(set (match_operand:SWI48 0 "register_operand" "=r")
12702         (popcount:SWI48
12703           (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12704    (unspec [(match_operand:SWI48 2 "register_operand" "0")]
12705            UNSPEC_INSN_FALSE_DEP)
12706    (clobber (reg:CC FLAGS_REG))]
12707   "TARGET_POPCNT"
12709 #if TARGET_MACHO
12710   return "popcnt\t{%1, %0|%0, %1}";
12711 #else
12712   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12713 #endif
12715   [(set_attr "prefix_rep" "1")
12716    (set_attr "type" "bitmanip")
12717    (set_attr "mode" "<MODE>")])
12719 (define_insn "*popcount<mode>2"
12720   [(set (match_operand:SWI248 0 "register_operand" "=r")
12721         (popcount:SWI248
12722           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12723    (clobber (reg:CC FLAGS_REG))]
12724   "TARGET_POPCNT"
12726 #if TARGET_MACHO
12727   return "popcnt\t{%1, %0|%0, %1}";
12728 #else
12729   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12730 #endif
12732   [(set_attr "prefix_rep" "1")
12733    (set_attr "type" "bitmanip")
12734    (set_attr "mode" "<MODE>")])
12736 (define_expand "bswapdi2"
12737   [(set (match_operand:DI 0 "register_operand")
12738         (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12739   "TARGET_64BIT"
12741   if (!TARGET_MOVBE)
12742     operands[1] = force_reg (DImode, operands[1]);
12745 (define_expand "bswapsi2"
12746   [(set (match_operand:SI 0 "register_operand")
12747         (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12748   ""
12750   if (TARGET_MOVBE)
12751     ;
12752   else if (TARGET_BSWAP)
12753     operands[1] = force_reg (SImode, operands[1]);
12754   else
12755     {
12756       rtx x = operands[0];
12758       emit_move_insn (x, operands[1]);
12759       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12760       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12761       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12762       DONE;
12763     }
12766 (define_insn "*bswap<mode>2_movbe"
12767   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12768         (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12769   "TARGET_MOVBE
12770    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12771   "@
12772     bswap\t%0
12773     movbe\t{%1, %0|%0, %1}
12774     movbe\t{%1, %0|%0, %1}"
12775   [(set_attr "type" "bitmanip,imov,imov")
12776    (set_attr "modrm" "0,1,1")
12777    (set_attr "prefix_0f" "*,1,1")
12778    (set_attr "prefix_extra" "*,1,1")
12779    (set_attr "mode" "<MODE>")])
12781 (define_insn "*bswap<mode>2"
12782   [(set (match_operand:SWI48 0 "register_operand" "=r")
12783         (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12784   "TARGET_BSWAP"
12785   "bswap\t%0"
12786   [(set_attr "type" "bitmanip")
12787    (set_attr "modrm" "0")
12788    (set_attr "mode" "<MODE>")])
12790 (define_insn "*bswaphi_lowpart_1"
12791   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12792         (bswap:HI (match_dup 0)))
12793    (clobber (reg:CC FLAGS_REG))]
12794   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12795   "@
12796     xchg{b}\t{%h0, %b0|%b0, %h0}
12797     rol{w}\t{$8, %0|%0, 8}"
12798   [(set_attr "length" "2,4")
12799    (set_attr "mode" "QI,HI")])
12801 (define_insn "bswaphi_lowpart"
12802   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12803         (bswap:HI (match_dup 0)))
12804    (clobber (reg:CC FLAGS_REG))]
12805   ""
12806   "rol{w}\t{$8, %0|%0, 8}"
12807   [(set_attr "length" "4")
12808    (set_attr "mode" "HI")])
12810 (define_expand "paritydi2"
12811   [(set (match_operand:DI 0 "register_operand")
12812         (parity:DI (match_operand:DI 1 "register_operand")))]
12813   "! TARGET_POPCNT"
12815   rtx scratch = gen_reg_rtx (QImode);
12816   rtx cond;
12818   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12819                                 NULL_RTX, operands[1]));
12821   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12822                          gen_rtx_REG (CCmode, FLAGS_REG),
12823                          const0_rtx);
12824   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12826   if (TARGET_64BIT)
12827     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12828   else
12829     {
12830       rtx tmp = gen_reg_rtx (SImode);
12832       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12833       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12834     }
12835   DONE;
12838 (define_expand "paritysi2"
12839   [(set (match_operand:SI 0 "register_operand")
12840         (parity:SI (match_operand:SI 1 "register_operand")))]
12841   "! TARGET_POPCNT"
12843   rtx scratch = gen_reg_rtx (QImode);
12844   rtx cond;
12846   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12848   cond = gen_rtx_fmt_ee (ORDERED, QImode,
12849                          gen_rtx_REG (CCmode, FLAGS_REG),
12850                          const0_rtx);
12851   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12853   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12854   DONE;
12857 (define_insn_and_split "paritydi2_cmp"
12858   [(set (reg:CC FLAGS_REG)
12859         (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12860                    UNSPEC_PARITY))
12861    (clobber (match_scratch:DI 0 "=r"))
12862    (clobber (match_scratch:SI 1 "=&r"))
12863    (clobber (match_scratch:HI 2 "=Q"))]
12864   "! TARGET_POPCNT"
12865   "#"
12866   "&& reload_completed"
12867   [(parallel
12868      [(set (match_dup 1)
12869            (xor:SI (match_dup 1) (match_dup 4)))
12870       (clobber (reg:CC FLAGS_REG))])
12871    (parallel
12872      [(set (reg:CC FLAGS_REG)
12873            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12874       (clobber (match_dup 1))
12875       (clobber (match_dup 2))])]
12877   operands[4] = gen_lowpart (SImode, operands[3]);
12879   if (TARGET_64BIT)
12880     {
12881       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12882       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12883     }
12884   else
12885     operands[1] = gen_highpart (SImode, operands[3]);
12888 (define_insn_and_split "paritysi2_cmp"
12889   [(set (reg:CC FLAGS_REG)
12890         (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12891                    UNSPEC_PARITY))
12892    (clobber (match_scratch:SI 0 "=r"))
12893    (clobber (match_scratch:HI 1 "=&Q"))]
12894   "! TARGET_POPCNT"
12895   "#"
12896   "&& reload_completed"
12897   [(parallel
12898      [(set (match_dup 1)
12899            (xor:HI (match_dup 1) (match_dup 3)))
12900       (clobber (reg:CC FLAGS_REG))])
12901    (parallel
12902      [(set (reg:CC FLAGS_REG)
12903            (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12904       (clobber (match_dup 1))])]
12906   operands[3] = gen_lowpart (HImode, operands[2]);
12908   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12909   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12912 (define_insn "*parityhi2_cmp"
12913   [(set (reg:CC FLAGS_REG)
12914         (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12915                    UNSPEC_PARITY))
12916    (clobber (match_scratch:HI 0 "=Q"))]
12917   "! TARGET_POPCNT"
12918   "xor{b}\t{%h0, %b0|%b0, %h0}"
12919   [(set_attr "length" "2")
12920    (set_attr "mode" "HI")])
12923 ;; Thread-local storage patterns for ELF.
12925 ;; Note that these code sequences must appear exactly as shown
12926 ;; in order to allow linker relaxation.
12928 (define_insn "*tls_global_dynamic_32_gnu"
12929   [(set (match_operand:SI 0 "register_operand" "=a")
12930         (unspec:SI
12931          [(match_operand:SI 1 "register_operand" "b")
12932           (match_operand 2 "tls_symbolic_operand")
12933           (match_operand 3 "constant_call_address_operand" "Bz")
12934           (reg:SI SP_REG)]
12935          UNSPEC_TLS_GD))
12936    (clobber (match_scratch:SI 4 "=d"))
12937    (clobber (match_scratch:SI 5 "=c"))
12938    (clobber (reg:CC FLAGS_REG))]
12939   "!TARGET_64BIT && TARGET_GNU_TLS"
12941   output_asm_insn
12942     ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12943   if (TARGET_SUN_TLS)
12944 #ifdef HAVE_AS_IX86_TLSGDPLT
12945     return "call\t%a2@tlsgdplt";
12946 #else
12947     return "call\t%p3@plt";
12948 #endif
12949   return "call\t%P3";
12951   [(set_attr "type" "multi")
12952    (set_attr "length" "12")])
12954 (define_expand "tls_global_dynamic_32"
12955   [(parallel
12956     [(set (match_operand:SI 0 "register_operand")
12957           (unspec:SI [(match_operand:SI 2 "register_operand")
12958                       (match_operand 1 "tls_symbolic_operand")
12959                       (match_operand 3 "constant_call_address_operand")
12960                       (reg:SI SP_REG)]
12961                      UNSPEC_TLS_GD))
12962      (clobber (match_scratch:SI 4))
12963      (clobber (match_scratch:SI 5))
12964      (clobber (reg:CC FLAGS_REG))])]
12965   ""
12966   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
12968 (define_insn "*tls_global_dynamic_64_<mode>"
12969   [(set (match_operand:P 0 "register_operand" "=a")
12970         (call:P
12971          (mem:QI (match_operand 2 "constant_call_address_operand" "Bz"))
12972          (match_operand 3)))
12973    (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12974              UNSPEC_TLS_GD)]
12975   "TARGET_64BIT"
12977   if (!TARGET_X32)
12978     fputs (ASM_BYTE "0x66\n", asm_out_file);
12979   output_asm_insn
12980     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12981   fputs (ASM_SHORT "0x6666\n", asm_out_file);
12982   fputs ("\trex64\n", asm_out_file);
12983   if (TARGET_SUN_TLS)
12984     return "call\t%p2@plt";
12985   return "call\t%P2";
12987   [(set_attr "type" "multi")
12988    (set (attr "length")
12989         (symbol_ref "TARGET_X32 ? 15 : 16"))])
12991 (define_insn "*tls_global_dynamic_64_largepic"
12992   [(set (match_operand:DI 0 "register_operand" "=a")
12993         (call:DI
12994          (mem:QI (plus:DI (match_operand:DI 2 "register_operand" "b")
12995                           (match_operand:DI 3 "immediate_operand" "i")))
12996          (match_operand 4)))
12997    (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12998              UNSPEC_TLS_GD)]
12999   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13000    && GET_CODE (operands[3]) == CONST
13001    && GET_CODE (XEXP (operands[3], 0)) == UNSPEC
13002    && XINT (XEXP (operands[3], 0), 1) == UNSPEC_PLTOFF"
13004   output_asm_insn
13005     ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
13006   output_asm_insn ("movabs{q}\t{%3, %%rax|rax, %3}", operands);
13007   output_asm_insn ("add{q}\t{%2, %%rax|rax, %2}", operands);
13008   return "call\t{*%%rax|rax}";
13010   [(set_attr "type" "multi")
13011    (set_attr "length" "22")])
13013 (define_expand "tls_global_dynamic_64_<mode>"
13014   [(parallel
13015     [(set (match_operand:P 0 "register_operand")
13016           (call:P
13017            (mem:QI (match_operand 2))
13018            (const_int 0)))
13019      (unspec:P [(match_operand 1 "tls_symbolic_operand")]
13020                UNSPEC_TLS_GD)])]
13021   "TARGET_64BIT"
13022   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13024 (define_insn "*tls_local_dynamic_base_32_gnu"
13025   [(set (match_operand:SI 0 "register_operand" "=a")
13026         (unspec:SI
13027          [(match_operand:SI 1 "register_operand" "b")
13028           (match_operand 2 "constant_call_address_operand" "Bz")
13029           (reg:SI SP_REG)]
13030          UNSPEC_TLS_LD_BASE))
13031    (clobber (match_scratch:SI 3 "=d"))
13032    (clobber (match_scratch:SI 4 "=c"))
13033    (clobber (reg:CC FLAGS_REG))]
13034   "!TARGET_64BIT && TARGET_GNU_TLS"
13036   output_asm_insn
13037     ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
13038   if (TARGET_SUN_TLS)
13039     {
13040       if (HAVE_AS_IX86_TLSLDMPLT)
13041         return "call\t%&@tlsldmplt";
13042       else
13043         return "call\t%p2@plt";
13044     }
13045   return "call\t%P2";
13047   [(set_attr "type" "multi")
13048    (set_attr "length" "11")])
13050 (define_expand "tls_local_dynamic_base_32"
13051   [(parallel
13052      [(set (match_operand:SI 0 "register_operand")
13053            (unspec:SI
13054             [(match_operand:SI 1 "register_operand")
13055              (match_operand 2 "constant_call_address_operand")
13056              (reg:SI SP_REG)]
13057             UNSPEC_TLS_LD_BASE))
13058       (clobber (match_scratch:SI 3))
13059       (clobber (match_scratch:SI 4))
13060       (clobber (reg:CC FLAGS_REG))])]
13061   ""
13062   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13064 (define_insn "*tls_local_dynamic_base_64_<mode>"
13065   [(set (match_operand:P 0 "register_operand" "=a")
13066         (call:P
13067          (mem:QI (match_operand 1 "constant_call_address_operand" "Bz"))
13068          (match_operand 2)))
13069    (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13070   "TARGET_64BIT"
13072   output_asm_insn
13073     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13074   if (TARGET_SUN_TLS)
13075     return "call\t%p1@plt";
13076   return "call\t%P1";
13078   [(set_attr "type" "multi")
13079    (set_attr "length" "12")])
13081 (define_insn "*tls_local_dynamic_base_64_largepic"
13082   [(set (match_operand:DI 0 "register_operand" "=a")
13083         (call:DI
13084          (mem:QI (plus:DI (match_operand:DI 1 "register_operand" "b")
13085                           (match_operand:DI 2 "immediate_operand" "i")))
13086          (match_operand 3)))
13087    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
13088   "TARGET_64BIT && ix86_cmodel == CM_LARGE_PIC && !TARGET_PECOFF
13089    && GET_CODE (operands[2]) == CONST
13090    && GET_CODE (XEXP (operands[2], 0)) == UNSPEC
13091    && XINT (XEXP (operands[2], 0), 1) == UNSPEC_PLTOFF"
13093   output_asm_insn
13094     ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
13095   output_asm_insn ("movabs{q}\t{%2, %%rax|rax, %2}", operands);
13096   output_asm_insn ("add{q}\t{%1, %%rax|rax, %1}", operands);
13097   return "call\t{*%%rax|rax}";
13099   [(set_attr "type" "multi")
13100    (set_attr "length" "22")])
13102 (define_expand "tls_local_dynamic_base_64_<mode>"
13103   [(parallel
13104      [(set (match_operand:P 0 "register_operand")
13105            (call:P
13106             (mem:QI (match_operand 1))
13107             (const_int 0)))
13108       (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
13109   "TARGET_64BIT"
13110   "ix86_tls_descriptor_calls_expanded_in_cfun = true;")
13112 ;; Local dynamic of a single variable is a lose.  Show combine how
13113 ;; to convert that back to global dynamic.
13115 (define_insn_and_split "*tls_local_dynamic_32_once"
13116   [(set (match_operand:SI 0 "register_operand" "=a")
13117         (plus:SI
13118          (unspec:SI [(match_operand:SI 1 "register_operand" "b")
13119                      (match_operand 2 "constant_call_address_operand" "Bz")
13120                      (reg:SI SP_REG)]
13121                     UNSPEC_TLS_LD_BASE)
13122          (const:SI (unspec:SI
13123                     [(match_operand 3 "tls_symbolic_operand")]
13124                     UNSPEC_DTPOFF))))
13125    (clobber (match_scratch:SI 4 "=d"))
13126    (clobber (match_scratch:SI 5 "=c"))
13127    (clobber (reg:CC FLAGS_REG))]
13128   ""
13129   "#"
13130   ""
13131   [(parallel
13132      [(set (match_dup 0)
13133            (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)
13134                        (reg:SI SP_REG)]
13135                       UNSPEC_TLS_GD))
13136       (clobber (match_dup 4))
13137       (clobber (match_dup 5))
13138       (clobber (reg:CC FLAGS_REG))])])
13140 ;; Segment register for the thread base ptr load
13141 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13143 ;; Load and add the thread base pointer from %<tp_seg>:0.
13144 (define_insn "*load_tp_x32"
13145   [(set (match_operand:SI 0 "register_operand" "=r")
13146         (unspec:SI [(const_int 0)] UNSPEC_TP))]
13147   "TARGET_X32"
13148   "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13149   [(set_attr "type" "imov")
13150    (set_attr "modrm" "0")
13151    (set_attr "length" "7")
13152    (set_attr "memory" "load")
13153    (set_attr "imm_disp" "false")])
13155 (define_insn "*load_tp_x32_zext"
13156   [(set (match_operand:DI 0 "register_operand" "=r")
13157         (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13158   "TARGET_X32"
13159   "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13160   [(set_attr "type" "imov")
13161    (set_attr "modrm" "0")
13162    (set_attr "length" "7")
13163    (set_attr "memory" "load")
13164    (set_attr "imm_disp" "false")])
13166 (define_insn "*load_tp_<mode>"
13167   [(set (match_operand:P 0 "register_operand" "=r")
13168         (unspec:P [(const_int 0)] UNSPEC_TP))]
13169   "!TARGET_X32"
13170   "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13171   [(set_attr "type" "imov")
13172    (set_attr "modrm" "0")
13173    (set_attr "length" "7")
13174    (set_attr "memory" "load")
13175    (set_attr "imm_disp" "false")])
13177 (define_insn "*add_tp_x32"
13178   [(set (match_operand:SI 0 "register_operand" "=r")
13179         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13180                  (match_operand:SI 1 "register_operand" "0")))
13181    (clobber (reg:CC FLAGS_REG))]
13182   "TARGET_X32"
13183   "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13184   [(set_attr "type" "alu")
13185    (set_attr "modrm" "0")
13186    (set_attr "length" "7")
13187    (set_attr "memory" "load")
13188    (set_attr "imm_disp" "false")])
13190 (define_insn "*add_tp_x32_zext"
13191   [(set (match_operand:DI 0 "register_operand" "=r")
13192         (zero_extend:DI
13193           (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13194                    (match_operand:SI 1 "register_operand" "0"))))
13195    (clobber (reg:CC FLAGS_REG))]
13196   "TARGET_X32"
13197   "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13198   [(set_attr "type" "alu")
13199    (set_attr "modrm" "0")
13200    (set_attr "length" "7")
13201    (set_attr "memory" "load")
13202    (set_attr "imm_disp" "false")])
13204 (define_insn "*add_tp_<mode>"
13205   [(set (match_operand:P 0 "register_operand" "=r")
13206         (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13207                 (match_operand:P 1 "register_operand" "0")))
13208    (clobber (reg:CC FLAGS_REG))]
13209   "!TARGET_X32"
13210   "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13211   [(set_attr "type" "alu")
13212    (set_attr "modrm" "0")
13213    (set_attr "length" "7")
13214    (set_attr "memory" "load")
13215    (set_attr "imm_disp" "false")])
13217 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13218 ;; %rax as destination of the initial executable code sequence.
13219 (define_insn "tls_initial_exec_64_sun"
13220   [(set (match_operand:DI 0 "register_operand" "=a")
13221         (unspec:DI
13222          [(match_operand 1 "tls_symbolic_operand")]
13223          UNSPEC_TLS_IE_SUN))
13224    (clobber (reg:CC FLAGS_REG))]
13225   "TARGET_64BIT && TARGET_SUN_TLS"
13227   output_asm_insn
13228     ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13229   return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13231   [(set_attr "type" "multi")])
13233 ;; GNU2 TLS patterns can be split.
13235 (define_expand "tls_dynamic_gnu2_32"
13236   [(set (match_dup 3)
13237         (plus:SI (match_operand:SI 2 "register_operand")
13238                  (const:SI
13239                   (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13240                              UNSPEC_TLSDESC))))
13241    (parallel
13242     [(set (match_operand:SI 0 "register_operand")
13243           (unspec:SI [(match_dup 1) (match_dup 3)
13244                       (match_dup 2) (reg:SI SP_REG)]
13245                       UNSPEC_TLSDESC))
13246      (clobber (reg:CC FLAGS_REG))])]
13247   "!TARGET_64BIT && TARGET_GNU2_TLS"
13249   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13250   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13253 (define_insn "*tls_dynamic_gnu2_lea_32"
13254   [(set (match_operand:SI 0 "register_operand" "=r")
13255         (plus:SI (match_operand:SI 1 "register_operand" "b")
13256                  (const:SI
13257                   (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13258                               UNSPEC_TLSDESC))))]
13259   "!TARGET_64BIT && TARGET_GNU2_TLS"
13260   "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13261   [(set_attr "type" "lea")
13262    (set_attr "mode" "SI")
13263    (set_attr "length" "6")
13264    (set_attr "length_address" "4")])
13266 (define_insn "*tls_dynamic_gnu2_call_32"
13267   [(set (match_operand:SI 0 "register_operand" "=a")
13268         (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13269                     (match_operand:SI 2 "register_operand" "0")
13270                     ;; we have to make sure %ebx still points to the GOT
13271                     (match_operand:SI 3 "register_operand" "b")
13272                     (reg:SI SP_REG)]
13273                    UNSPEC_TLSDESC))
13274    (clobber (reg:CC FLAGS_REG))]
13275   "!TARGET_64BIT && TARGET_GNU2_TLS"
13276   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13277   [(set_attr "type" "call")
13278    (set_attr "length" "2")
13279    (set_attr "length_address" "0")])
13281 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13282   [(set (match_operand:SI 0 "register_operand" "=&a")
13283         (plus:SI
13284          (unspec:SI [(match_operand 3 "tls_modbase_operand")
13285                      (match_operand:SI 4)
13286                      (match_operand:SI 2 "register_operand" "b")
13287                      (reg:SI SP_REG)]
13288                     UNSPEC_TLSDESC)
13289          (const:SI (unspec:SI
13290                     [(match_operand 1 "tls_symbolic_operand")]
13291                     UNSPEC_DTPOFF))))
13292    (clobber (reg:CC FLAGS_REG))]
13293   "!TARGET_64BIT && TARGET_GNU2_TLS"
13294   "#"
13295   ""
13296   [(set (match_dup 0) (match_dup 5))]
13298   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13299   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13302 (define_expand "tls_dynamic_gnu2_64"
13303   [(set (match_dup 2)
13304         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13305                    UNSPEC_TLSDESC))
13306    (parallel
13307     [(set (match_operand:DI 0 "register_operand")
13308           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13309                      UNSPEC_TLSDESC))
13310      (clobber (reg:CC FLAGS_REG))])]
13311   "TARGET_64BIT && TARGET_GNU2_TLS"
13313   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13314   ix86_tls_descriptor_calls_expanded_in_cfun = true;
13317 (define_insn "*tls_dynamic_gnu2_lea_64"
13318   [(set (match_operand:DI 0 "register_operand" "=r")
13319         (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13320                    UNSPEC_TLSDESC))]
13321   "TARGET_64BIT && TARGET_GNU2_TLS"
13322   "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13323   [(set_attr "type" "lea")
13324    (set_attr "mode" "DI")
13325    (set_attr "length" "7")
13326    (set_attr "length_address" "4")])
13328 (define_insn "*tls_dynamic_gnu2_call_64"
13329   [(set (match_operand:DI 0 "register_operand" "=a")
13330         (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13331                     (match_operand:DI 2 "register_operand" "0")
13332                     (reg:DI SP_REG)]
13333                    UNSPEC_TLSDESC))
13334    (clobber (reg:CC FLAGS_REG))]
13335   "TARGET_64BIT && TARGET_GNU2_TLS"
13336   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13337   [(set_attr "type" "call")
13338    (set_attr "length" "2")
13339    (set_attr "length_address" "0")])
13341 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13342   [(set (match_operand:DI 0 "register_operand" "=&a")
13343         (plus:DI
13344          (unspec:DI [(match_operand 2 "tls_modbase_operand")
13345                      (match_operand:DI 3)
13346                      (reg:DI SP_REG)]
13347                     UNSPEC_TLSDESC)
13348          (const:DI (unspec:DI
13349                     [(match_operand 1 "tls_symbolic_operand")]
13350                     UNSPEC_DTPOFF))))
13351    (clobber (reg:CC FLAGS_REG))]
13352   "TARGET_64BIT && TARGET_GNU2_TLS"
13353   "#"
13354   ""
13355   [(set (match_dup 0) (match_dup 4))]
13357   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13358   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13361 ;; These patterns match the binary 387 instructions for addM3, subM3,
13362 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
13363 ;; SFmode.  The first is the normal insn, the second the same insn but
13364 ;; with one operand a conversion, and the third the same insn but with
13365 ;; the other operand a conversion.  The conversion may be SFmode or
13366 ;; SImode if the target mode DFmode, but only SImode if the target mode
13367 ;; is SFmode.
13369 ;; Gcc is slightly more smart about handling normal two address instructions
13370 ;; so use special patterns for add and mull.
13372 (define_insn "*fop_<mode>_comm_mixed"
13373   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13374         (match_operator:MODEF 3 "binary_fp_operator"
13375           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13376            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13377   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13378    && COMMUTATIVE_ARITH_P (operands[3])
13379    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13380   "* return output_387_binary_op (insn, operands);"
13381   [(set (attr "type")
13382         (if_then_else (eq_attr "alternative" "1,2")
13383            (if_then_else (match_operand:MODEF 3 "mult_operator")
13384               (const_string "ssemul")
13385               (const_string "sseadd"))
13386            (if_then_else (match_operand:MODEF 3 "mult_operator")
13387               (const_string "fmul")
13388               (const_string "fop"))))
13389    (set_attr "isa" "*,noavx,avx")
13390    (set_attr "prefix" "orig,orig,vex")
13391    (set_attr "mode" "<MODE>")])
13393 (define_insn "*fop_<mode>_comm_sse"
13394   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
13395         (match_operator:MODEF 3 "binary_fp_operator"
13396           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
13397            (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")]))]
13398   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13399    && COMMUTATIVE_ARITH_P (operands[3])
13400    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13401   "* return output_387_binary_op (insn, operands);"
13402   [(set (attr "type")
13403         (if_then_else (match_operand:MODEF 3 "mult_operator")
13404            (const_string "ssemul")
13405            (const_string "sseadd")))
13406    (set_attr "isa" "noavx,avx")
13407    (set_attr "prefix" "orig,vex")
13408    (set_attr "mode" "<MODE>")])
13410 (define_insn "*fop_<mode>_comm_i387"
13411   [(set (match_operand:MODEF 0 "register_operand" "=f")
13412         (match_operator:MODEF 3 "binary_fp_operator"
13413           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13414            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13415   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13416    && COMMUTATIVE_ARITH_P (operands[3])
13417    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13418   "* return output_387_binary_op (insn, operands);"
13419   [(set (attr "type")
13420         (if_then_else (match_operand:MODEF 3 "mult_operator")
13421            (const_string "fmul")
13422            (const_string "fop")))
13423    (set_attr "mode" "<MODE>")])
13425 (define_insn "*fop_<mode>_1_mixed"
13426   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13427         (match_operator:MODEF 3 "binary_fp_operator"
13428           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13429            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13430   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13431    && !COMMUTATIVE_ARITH_P (operands[3])
13432    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13433   "* return output_387_binary_op (insn, operands);"
13434   [(set (attr "type")
13435         (cond [(and (eq_attr "alternative" "2,3")
13436                     (match_operand:MODEF 3 "mult_operator"))
13437                  (const_string "ssemul")
13438                (and (eq_attr "alternative" "2,3")
13439                     (match_operand:MODEF 3 "div_operator"))
13440                  (const_string "ssediv")
13441                (eq_attr "alternative" "2,3")
13442                  (const_string "sseadd")
13443                (match_operand:MODEF 3 "mult_operator")
13444                  (const_string "fmul")
13445                (match_operand:MODEF 3 "div_operator")
13446                  (const_string "fdiv")
13447               ]
13448               (const_string "fop")))
13449    (set_attr "isa" "*,*,noavx,avx")
13450    (set_attr "prefix" "orig,orig,orig,vex")
13451    (set_attr "mode" "<MODE>")])
13453 (define_insn "*rcpsf2_sse"
13454   [(set (match_operand:SF 0 "register_operand" "=x")
13455         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13456                    UNSPEC_RCP))]
13457   "TARGET_SSE_MATH"
13458   "%vrcpss\t{%1, %d0|%d0, %1}"
13459   [(set_attr "type" "sse")
13460    (set_attr "atom_sse_attr" "rcp")
13461    (set_attr "btver2_sse_attr" "rcp")
13462    (set_attr "prefix" "maybe_vex")
13463    (set_attr "mode" "SF")])
13465 (define_insn "*fop_<mode>_1_sse"
13466   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13467         (match_operator:MODEF 3 "binary_fp_operator"
13468           [(match_operand:MODEF 1 "register_operand" "0,x")
13469            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13470   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13471    && !COMMUTATIVE_ARITH_P (operands[3])"
13472   "* return output_387_binary_op (insn, operands);"
13473   [(set (attr "type")
13474         (cond [(match_operand:MODEF 3 "mult_operator")
13475                  (const_string "ssemul")
13476                (match_operand:MODEF 3 "div_operator")
13477                  (const_string "ssediv")
13478               ]
13479               (const_string "sseadd")))
13480    (set_attr "isa" "noavx,avx")
13481    (set_attr "prefix" "orig,vex")
13482    (set_attr "mode" "<MODE>")])
13484 ;; This pattern is not fully shadowed by the pattern above.
13485 (define_insn "*fop_<mode>_1_i387"
13486   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13487         (match_operator:MODEF 3 "binary_fp_operator"
13488           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13489            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13490   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13491    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13492    && !COMMUTATIVE_ARITH_P (operands[3])
13493    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13494   "* return output_387_binary_op (insn, operands);"
13495   [(set (attr "type")
13496         (cond [(match_operand:MODEF 3 "mult_operator")
13497                  (const_string "fmul")
13498                (match_operand:MODEF 3 "div_operator")
13499                  (const_string "fdiv")
13500               ]
13501               (const_string "fop")))
13502    (set_attr "mode" "<MODE>")])
13504 ;; ??? Add SSE splitters for these!
13505 (define_insn "*fop_<MODEF:mode>_2_i387"
13506   [(set (match_operand:MODEF 0 "register_operand" "=f")
13507         (match_operator:MODEF 3 "binary_fp_operator"
13508           [(float:MODEF
13509              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13510            (match_operand:MODEF 2 "register_operand" "0")]))]
13511   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13512    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13513    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13514        || optimize_function_for_size_p (cfun))"
13515   { return output_387_binary_op (insn, operands); }
13516   [(set (attr "type")
13517         (cond [(match_operand:MODEF 3 "mult_operator")
13518                  (const_string "fmul")
13519                (match_operand:MODEF 3 "div_operator")
13520                  (const_string "fdiv")
13521               ]
13522               (const_string "fop")))
13523    (set_attr "fp_int_src" "true")
13524    (set_attr "mode" "<SWI24:MODE>")])
13526 (define_insn "*fop_<MODEF:mode>_3_i387"
13527   [(set (match_operand:MODEF 0 "register_operand" "=f")
13528         (match_operator:MODEF 3 "binary_fp_operator"
13529           [(match_operand:MODEF 1 "register_operand" "0")
13530            (float:MODEF
13531              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13532   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13533    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13534    && (TARGET_USE_<SWI24:MODE>MODE_FIOP
13535        || optimize_function_for_size_p (cfun))"
13536   { return output_387_binary_op (insn, operands); }
13537   [(set (attr "type")
13538         (cond [(match_operand:MODEF 3 "mult_operator")
13539                  (const_string "fmul")
13540                (match_operand:MODEF 3 "div_operator")
13541                  (const_string "fdiv")
13542               ]
13543               (const_string "fop")))
13544    (set_attr "fp_int_src" "true")
13545    (set_attr "mode" "<MODE>")])
13547 (define_insn "*fop_df_4_i387"
13548   [(set (match_operand:DF 0 "register_operand" "=f,f")
13549         (match_operator:DF 3 "binary_fp_operator"
13550            [(float_extend:DF
13551              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13552             (match_operand:DF 2 "register_operand" "0,f")]))]
13553   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13554    && !(TARGET_SSE2 && TARGET_SSE_MATH)
13555    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13556   "* return output_387_binary_op (insn, operands);"
13557   [(set (attr "type")
13558         (cond [(match_operand:DF 3 "mult_operator")
13559                  (const_string "fmul")
13560                (match_operand:DF 3 "div_operator")
13561                  (const_string "fdiv")
13562               ]
13563               (const_string "fop")))
13564    (set_attr "mode" "SF")])
13566 (define_insn "*fop_df_5_i387"
13567   [(set (match_operand:DF 0 "register_operand" "=f,f")
13568         (match_operator:DF 3 "binary_fp_operator"
13569           [(match_operand:DF 1 "register_operand" "0,f")
13570            (float_extend:DF
13571             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13572   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13573    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13574   "* return output_387_binary_op (insn, operands);"
13575   [(set (attr "type")
13576         (cond [(match_operand:DF 3 "mult_operator")
13577                  (const_string "fmul")
13578                (match_operand:DF 3 "div_operator")
13579                  (const_string "fdiv")
13580               ]
13581               (const_string "fop")))
13582    (set_attr "mode" "SF")])
13584 (define_insn "*fop_df_6_i387"
13585   [(set (match_operand:DF 0 "register_operand" "=f,f")
13586         (match_operator:DF 3 "binary_fp_operator"
13587           [(float_extend:DF
13588             (match_operand:SF 1 "register_operand" "0,f"))
13589            (float_extend:DF
13590             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13591   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13592    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13593   "* return output_387_binary_op (insn, operands);"
13594   [(set (attr "type")
13595         (cond [(match_operand:DF 3 "mult_operator")
13596                  (const_string "fmul")
13597                (match_operand:DF 3 "div_operator")
13598                  (const_string "fdiv")
13599               ]
13600               (const_string "fop")))
13601    (set_attr "mode" "SF")])
13603 (define_insn "*fop_xf_comm_i387"
13604   [(set (match_operand:XF 0 "register_operand" "=f")
13605         (match_operator:XF 3 "binary_fp_operator"
13606                         [(match_operand:XF 1 "register_operand" "%0")
13607                          (match_operand:XF 2 "register_operand" "f")]))]
13608   "TARGET_80387
13609    && COMMUTATIVE_ARITH_P (operands[3])"
13610   "* return output_387_binary_op (insn, operands);"
13611   [(set (attr "type")
13612         (if_then_else (match_operand:XF 3 "mult_operator")
13613            (const_string "fmul")
13614            (const_string "fop")))
13615    (set_attr "mode" "XF")])
13617 (define_insn "*fop_xf_1_i387"
13618   [(set (match_operand:XF 0 "register_operand" "=f,f")
13619         (match_operator:XF 3 "binary_fp_operator"
13620                         [(match_operand:XF 1 "register_operand" "0,f")
13621                          (match_operand:XF 2 "register_operand" "f,0")]))]
13622   "TARGET_80387
13623    && !COMMUTATIVE_ARITH_P (operands[3])"
13624   "* return output_387_binary_op (insn, operands);"
13625   [(set (attr "type")
13626         (cond [(match_operand:XF 3 "mult_operator")
13627                  (const_string "fmul")
13628                (match_operand:XF 3 "div_operator")
13629                  (const_string "fdiv")
13630               ]
13631               (const_string "fop")))
13632    (set_attr "mode" "XF")])
13634 (define_insn "*fop_xf_2_i387"
13635   [(set (match_operand:XF 0 "register_operand" "=f")
13636         (match_operator:XF 3 "binary_fp_operator"
13637           [(float:XF
13638              (match_operand:SWI24 1 "nonimmediate_operand" "m"))
13639            (match_operand:XF 2 "register_operand" "0")]))]
13640   "TARGET_80387
13641    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13642   { return output_387_binary_op (insn, operands); }
13643   [(set (attr "type")
13644         (cond [(match_operand:XF 3 "mult_operator")
13645                  (const_string "fmul")
13646                (match_operand:XF 3 "div_operator")
13647                  (const_string "fdiv")
13648               ]
13649               (const_string "fop")))
13650    (set_attr "fp_int_src" "true")
13651    (set_attr "mode" "<MODE>")])
13653 (define_insn "*fop_xf_3_i387"
13654   [(set (match_operand:XF 0 "register_operand" "=f")
13655         (match_operator:XF 3 "binary_fp_operator"
13656           [(match_operand:XF 1 "register_operand" "0")
13657            (float:XF
13658              (match_operand:SWI24 2 "nonimmediate_operand" "m"))]))]
13659   "TARGET_80387
13660    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13661   { return output_387_binary_op (insn, operands); }
13662   [(set (attr "type")
13663         (cond [(match_operand:XF 3 "mult_operator")
13664                  (const_string "fmul")
13665                (match_operand:XF 3 "div_operator")
13666                  (const_string "fdiv")
13667               ]
13668               (const_string "fop")))
13669    (set_attr "fp_int_src" "true")
13670    (set_attr "mode" "<MODE>")])
13672 (define_insn "*fop_xf_4_i387"
13673   [(set (match_operand:XF 0 "register_operand" "=f,f")
13674         (match_operator:XF 3 "binary_fp_operator"
13675            [(float_extend:XF
13676               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13677             (match_operand:XF 2 "register_operand" "0,f")]))]
13678   "TARGET_80387"
13679   "* return output_387_binary_op (insn, operands);"
13680   [(set (attr "type")
13681         (cond [(match_operand:XF 3 "mult_operator")
13682                  (const_string "fmul")
13683                (match_operand:XF 3 "div_operator")
13684                  (const_string "fdiv")
13685               ]
13686               (const_string "fop")))
13687    (set_attr "mode" "<MODE>")])
13689 (define_insn "*fop_xf_5_i387"
13690   [(set (match_operand:XF 0 "register_operand" "=f,f")
13691         (match_operator:XF 3 "binary_fp_operator"
13692           [(match_operand:XF 1 "register_operand" "0,f")
13693            (float_extend:XF
13694              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13695   "TARGET_80387"
13696   "* return output_387_binary_op (insn, operands);"
13697   [(set (attr "type")
13698         (cond [(match_operand:XF 3 "mult_operator")
13699                  (const_string "fmul")
13700                (match_operand:XF 3 "div_operator")
13701                  (const_string "fdiv")
13702               ]
13703               (const_string "fop")))
13704    (set_attr "mode" "<MODE>")])
13706 (define_insn "*fop_xf_6_i387"
13707   [(set (match_operand:XF 0 "register_operand" "=f,f")
13708         (match_operator:XF 3 "binary_fp_operator"
13709           [(float_extend:XF
13710              (match_operand:MODEF 1 "register_operand" "0,f"))
13711            (float_extend:XF
13712              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13713   "TARGET_80387"
13714   "* return output_387_binary_op (insn, operands);"
13715   [(set (attr "type")
13716         (cond [(match_operand:XF 3 "mult_operator")
13717                  (const_string "fmul")
13718                (match_operand:XF 3 "div_operator")
13719                  (const_string "fdiv")
13720               ]
13721               (const_string "fop")))
13722    (set_attr "mode" "<MODE>")])
13724 ;; FPU special functions.
13726 ;; This pattern implements a no-op XFmode truncation for
13727 ;; all fancy i386 XFmode math functions.
13729 (define_insn "truncxf<mode>2_i387_noop_unspec"
13730   [(set (match_operand:MODEF 0 "register_operand" "=f")
13731         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13732         UNSPEC_TRUNC_NOOP))]
13733   "TARGET_USE_FANCY_MATH_387"
13734   "* return output_387_reg_move (insn, operands);"
13735   [(set_attr "type" "fmov")
13736    (set_attr "mode" "<MODE>")])
13738 (define_insn "sqrtxf2"
13739   [(set (match_operand:XF 0 "register_operand" "=f")
13740         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13741   "TARGET_USE_FANCY_MATH_387"
13742   "fsqrt"
13743   [(set_attr "type" "fpspc")
13744    (set_attr "mode" "XF")
13745    (set_attr "athlon_decode" "direct")
13746    (set_attr "amdfam10_decode" "direct")
13747    (set_attr "bdver1_decode" "direct")])
13749 (define_insn "sqrt_extend<mode>xf2_i387"
13750   [(set (match_operand:XF 0 "register_operand" "=f")
13751         (sqrt:XF
13752           (float_extend:XF
13753             (match_operand:MODEF 1 "register_operand" "0"))))]
13754   "TARGET_USE_FANCY_MATH_387"
13755   "fsqrt"
13756   [(set_attr "type" "fpspc")
13757    (set_attr "mode" "XF")
13758    (set_attr "athlon_decode" "direct")
13759    (set_attr "amdfam10_decode" "direct")
13760    (set_attr "bdver1_decode" "direct")])
13762 (define_insn "*rsqrtsf2_sse"
13763   [(set (match_operand:SF 0 "register_operand" "=x")
13764         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13765                    UNSPEC_RSQRT))]
13766   "TARGET_SSE_MATH"
13767   "%vrsqrtss\t{%1, %d0|%d0, %1}"
13768   [(set_attr "type" "sse")
13769    (set_attr "atom_sse_attr" "rcp")
13770    (set_attr "btver2_sse_attr" "rcp")
13771    (set_attr "prefix" "maybe_vex")
13772    (set_attr "mode" "SF")])
13774 (define_expand "rsqrtsf2"
13775   [(set (match_operand:SF 0 "register_operand")
13776         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13777                    UNSPEC_RSQRT))]
13778   "TARGET_SSE_MATH"
13780   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13781   DONE;
13784 (define_insn "*sqrt<mode>2_sse"
13785   [(set (match_operand:MODEF 0 "register_operand" "=x")
13786         (sqrt:MODEF
13787           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13788   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13789   "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13790   [(set_attr "type" "sse")
13791    (set_attr "atom_sse_attr" "sqrt")
13792    (set_attr "btver2_sse_attr" "sqrt")
13793    (set_attr "prefix" "maybe_vex")
13794    (set_attr "mode" "<MODE>")
13795    (set_attr "athlon_decode" "*")
13796    (set_attr "amdfam10_decode" "*")
13797    (set_attr "bdver1_decode" "*")])
13799 (define_expand "sqrt<mode>2"
13800   [(set (match_operand:MODEF 0 "register_operand")
13801         (sqrt:MODEF
13802           (match_operand:MODEF 1 "nonimmediate_operand")))]
13803   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13804    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13806   if (<MODE>mode == SFmode
13807       && TARGET_SSE_MATH
13808       && TARGET_RECIP_SQRT
13809       && !optimize_function_for_size_p (cfun)
13810       && flag_finite_math_only && !flag_trapping_math
13811       && flag_unsafe_math_optimizations)
13812     {
13813       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13814       DONE;
13815     }
13817   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13818     {
13819       rtx op0 = gen_reg_rtx (XFmode);
13820       rtx op1 = force_reg (<MODE>mode, operands[1]);
13822       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13823       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13824       DONE;
13825    }
13828 (define_insn "fpremxf4_i387"
13829   [(set (match_operand:XF 0 "register_operand" "=f")
13830         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13831                     (match_operand:XF 3 "register_operand" "1")]
13832                    UNSPEC_FPREM_F))
13833    (set (match_operand:XF 1 "register_operand" "=u")
13834         (unspec:XF [(match_dup 2) (match_dup 3)]
13835                    UNSPEC_FPREM_U))
13836    (set (reg:CCFP FPSR_REG)
13837         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13838                      UNSPEC_C2_FLAG))]
13839   "TARGET_USE_FANCY_MATH_387
13840    && flag_finite_math_only"
13841   "fprem"
13842   [(set_attr "type" "fpspc")
13843    (set_attr "mode" "XF")])
13845 (define_expand "fmodxf3"
13846   [(use (match_operand:XF 0 "register_operand"))
13847    (use (match_operand:XF 1 "general_operand"))
13848    (use (match_operand:XF 2 "general_operand"))]
13849   "TARGET_USE_FANCY_MATH_387
13850    && flag_finite_math_only"
13852   rtx_code_label *label = gen_label_rtx ();
13854   rtx op1 = gen_reg_rtx (XFmode);
13855   rtx op2 = gen_reg_rtx (XFmode);
13857   emit_move_insn (op2, operands[2]);
13858   emit_move_insn (op1, operands[1]);
13860   emit_label (label);
13861   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13862   ix86_emit_fp_unordered_jump (label);
13863   LABEL_NUSES (label) = 1;
13865   emit_move_insn (operands[0], op1);
13866   DONE;
13869 (define_expand "fmod<mode>3"
13870   [(use (match_operand:MODEF 0 "register_operand"))
13871    (use (match_operand:MODEF 1 "general_operand"))
13872    (use (match_operand:MODEF 2 "general_operand"))]
13873   "TARGET_USE_FANCY_MATH_387
13874    && flag_finite_math_only"
13876   rtx (*gen_truncxf) (rtx, rtx);
13878   rtx_code_label *label = gen_label_rtx ();
13880   rtx op1 = gen_reg_rtx (XFmode);
13881   rtx op2 = gen_reg_rtx (XFmode);
13883   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13884   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13886   emit_label (label);
13887   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13888   ix86_emit_fp_unordered_jump (label);
13889   LABEL_NUSES (label) = 1;
13891   /* Truncate the result properly for strict SSE math.  */
13892   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13893       && !TARGET_MIX_SSE_I387)
13894     gen_truncxf = gen_truncxf<mode>2;
13895   else
13896     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13898   emit_insn (gen_truncxf (operands[0], op1));
13899   DONE;
13902 (define_insn "fprem1xf4_i387"
13903   [(set (match_operand:XF 0 "register_operand" "=f")
13904         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13905                     (match_operand:XF 3 "register_operand" "1")]
13906                    UNSPEC_FPREM1_F))
13907    (set (match_operand:XF 1 "register_operand" "=u")
13908         (unspec:XF [(match_dup 2) (match_dup 3)]
13909                    UNSPEC_FPREM1_U))
13910    (set (reg:CCFP FPSR_REG)
13911         (unspec:CCFP [(match_dup 2) (match_dup 3)]
13912                      UNSPEC_C2_FLAG))]
13913   "TARGET_USE_FANCY_MATH_387
13914    && flag_finite_math_only"
13915   "fprem1"
13916   [(set_attr "type" "fpspc")
13917    (set_attr "mode" "XF")])
13919 (define_expand "remainderxf3"
13920   [(use (match_operand:XF 0 "register_operand"))
13921    (use (match_operand:XF 1 "general_operand"))
13922    (use (match_operand:XF 2 "general_operand"))]
13923   "TARGET_USE_FANCY_MATH_387
13924    && flag_finite_math_only"
13926   rtx_code_label *label = gen_label_rtx ();
13928   rtx op1 = gen_reg_rtx (XFmode);
13929   rtx op2 = gen_reg_rtx (XFmode);
13931   emit_move_insn (op2, operands[2]);
13932   emit_move_insn (op1, operands[1]);
13934   emit_label (label);
13935   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13936   ix86_emit_fp_unordered_jump (label);
13937   LABEL_NUSES (label) = 1;
13939   emit_move_insn (operands[0], op1);
13940   DONE;
13943 (define_expand "remainder<mode>3"
13944   [(use (match_operand:MODEF 0 "register_operand"))
13945    (use (match_operand:MODEF 1 "general_operand"))
13946    (use (match_operand:MODEF 2 "general_operand"))]
13947   "TARGET_USE_FANCY_MATH_387
13948    && flag_finite_math_only"
13950   rtx (*gen_truncxf) (rtx, rtx);
13952   rtx_code_label *label = gen_label_rtx ();
13954   rtx op1 = gen_reg_rtx (XFmode);
13955   rtx op2 = gen_reg_rtx (XFmode);
13957   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13958   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13960   emit_label (label);
13962   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13963   ix86_emit_fp_unordered_jump (label);
13964   LABEL_NUSES (label) = 1;
13966   /* Truncate the result properly for strict SSE math.  */
13967   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13968       && !TARGET_MIX_SSE_I387)
13969     gen_truncxf = gen_truncxf<mode>2;
13970   else
13971     gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13973   emit_insn (gen_truncxf (operands[0], op1));
13974   DONE;
13977 (define_int_iterator SINCOS
13978         [UNSPEC_SIN
13979          UNSPEC_COS])
13981 (define_int_attr sincos
13982         [(UNSPEC_SIN "sin")
13983          (UNSPEC_COS "cos")])
13985 (define_insn "*<sincos>xf2_i387"
13986   [(set (match_operand:XF 0 "register_operand" "=f")
13987         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13988                    SINCOS))]
13989   "TARGET_USE_FANCY_MATH_387
13990    && flag_unsafe_math_optimizations"
13991   "f<sincos>"
13992   [(set_attr "type" "fpspc")
13993    (set_attr "mode" "XF")])
13995 (define_insn "*<sincos>_extend<mode>xf2_i387"
13996   [(set (match_operand:XF 0 "register_operand" "=f")
13997         (unspec:XF [(float_extend:XF
13998                       (match_operand:MODEF 1 "register_operand" "0"))]
13999                    SINCOS))]
14000   "TARGET_USE_FANCY_MATH_387
14001    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14002        || TARGET_MIX_SSE_I387)
14003    && flag_unsafe_math_optimizations"
14004   "f<sincos>"
14005   [(set_attr "type" "fpspc")
14006    (set_attr "mode" "XF")])
14008 ;; When sincos pattern is defined, sin and cos builtin functions will be
14009 ;; expanded to sincos pattern with one of its outputs left unused.
14010 ;; CSE pass will figure out if two sincos patterns can be combined,
14011 ;; otherwise sincos pattern will be split back to sin or cos pattern,
14012 ;; depending on the unused output.
14014 (define_insn "sincosxf3"
14015   [(set (match_operand:XF 0 "register_operand" "=f")
14016         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14017                    UNSPEC_SINCOS_COS))
14018    (set (match_operand:XF 1 "register_operand" "=u")
14019         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14020   "TARGET_USE_FANCY_MATH_387
14021    && flag_unsafe_math_optimizations"
14022   "fsincos"
14023   [(set_attr "type" "fpspc")
14024    (set_attr "mode" "XF")])
14026 (define_split
14027   [(set (match_operand:XF 0 "register_operand")
14028         (unspec:XF [(match_operand:XF 2 "register_operand")]
14029                    UNSPEC_SINCOS_COS))
14030    (set (match_operand:XF 1 "register_operand")
14031         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14032   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14033    && can_create_pseudo_p ()"
14034   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
14036 (define_split
14037   [(set (match_operand:XF 0 "register_operand")
14038         (unspec:XF [(match_operand:XF 2 "register_operand")]
14039                    UNSPEC_SINCOS_COS))
14040    (set (match_operand:XF 1 "register_operand")
14041         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
14042   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14043    && can_create_pseudo_p ()"
14044   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
14046 (define_insn "sincos_extend<mode>xf3_i387"
14047   [(set (match_operand:XF 0 "register_operand" "=f")
14048         (unspec:XF [(float_extend:XF
14049                       (match_operand:MODEF 2 "register_operand" "0"))]
14050                    UNSPEC_SINCOS_COS))
14051    (set (match_operand:XF 1 "register_operand" "=u")
14052         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14053   "TARGET_USE_FANCY_MATH_387
14054    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14055        || TARGET_MIX_SSE_I387)
14056    && flag_unsafe_math_optimizations"
14057   "fsincos"
14058   [(set_attr "type" "fpspc")
14059    (set_attr "mode" "XF")])
14061 (define_split
14062   [(set (match_operand:XF 0 "register_operand")
14063         (unspec:XF [(float_extend:XF
14064                       (match_operand:MODEF 2 "register_operand"))]
14065                    UNSPEC_SINCOS_COS))
14066    (set (match_operand:XF 1 "register_operand")
14067         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14068   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
14069    && can_create_pseudo_p ()"
14070   [(set (match_dup 1)
14071         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
14073 (define_split
14074   [(set (match_operand:XF 0 "register_operand")
14075         (unspec:XF [(float_extend:XF
14076                       (match_operand:MODEF 2 "register_operand"))]
14077                    UNSPEC_SINCOS_COS))
14078    (set (match_operand:XF 1 "register_operand")
14079         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
14080   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
14081    && can_create_pseudo_p ()"
14082   [(set (match_dup 0)
14083         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
14085 (define_expand "sincos<mode>3"
14086   [(use (match_operand:MODEF 0 "register_operand"))
14087    (use (match_operand:MODEF 1 "register_operand"))
14088    (use (match_operand:MODEF 2 "register_operand"))]
14089   "TARGET_USE_FANCY_MATH_387
14090    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14091        || TARGET_MIX_SSE_I387)
14092    && flag_unsafe_math_optimizations"
14094   rtx op0 = gen_reg_rtx (XFmode);
14095   rtx op1 = gen_reg_rtx (XFmode);
14097   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
14098   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14099   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
14100   DONE;
14103 (define_insn "fptanxf4_i387"
14104   [(set (match_operand:XF 0 "register_operand" "=f")
14105         (match_operand:XF 3 "const_double_operand" "F"))
14106    (set (match_operand:XF 1 "register_operand" "=u")
14107         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14108                    UNSPEC_TAN))]
14109   "TARGET_USE_FANCY_MATH_387
14110    && flag_unsafe_math_optimizations
14111    && standard_80387_constant_p (operands[3]) == 2"
14112   "fptan"
14113   [(set_attr "type" "fpspc")
14114    (set_attr "mode" "XF")])
14116 (define_insn "fptan_extend<mode>xf4_i387"
14117   [(set (match_operand:MODEF 0 "register_operand" "=f")
14118         (match_operand:MODEF 3 "const_double_operand" "F"))
14119    (set (match_operand:XF 1 "register_operand" "=u")
14120         (unspec:XF [(float_extend:XF
14121                       (match_operand:MODEF 2 "register_operand" "0"))]
14122                    UNSPEC_TAN))]
14123   "TARGET_USE_FANCY_MATH_387
14124    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14125        || TARGET_MIX_SSE_I387)
14126    && flag_unsafe_math_optimizations
14127    && standard_80387_constant_p (operands[3]) == 2"
14128   "fptan"
14129   [(set_attr "type" "fpspc")
14130    (set_attr "mode" "XF")])
14132 (define_expand "tanxf2"
14133   [(use (match_operand:XF 0 "register_operand"))
14134    (use (match_operand:XF 1 "register_operand"))]
14135   "TARGET_USE_FANCY_MATH_387
14136    && flag_unsafe_math_optimizations"
14138   rtx one = gen_reg_rtx (XFmode);
14139   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14141   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14142   DONE;
14145 (define_expand "tan<mode>2"
14146   [(use (match_operand:MODEF 0 "register_operand"))
14147    (use (match_operand:MODEF 1 "register_operand"))]
14148   "TARGET_USE_FANCY_MATH_387
14149    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14150        || TARGET_MIX_SSE_I387)
14151    && flag_unsafe_math_optimizations"
14153   rtx op0 = gen_reg_rtx (XFmode);
14155   rtx one = gen_reg_rtx (<MODE>mode);
14156   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14158   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14159                                              operands[1], op2));
14160   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14161   DONE;
14164 (define_insn "*fpatanxf3_i387"
14165   [(set (match_operand:XF 0 "register_operand" "=f")
14166         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14167                     (match_operand:XF 2 "register_operand" "u")]
14168                    UNSPEC_FPATAN))
14169    (clobber (match_scratch:XF 3 "=2"))]
14170   "TARGET_USE_FANCY_MATH_387
14171    && flag_unsafe_math_optimizations"
14172   "fpatan"
14173   [(set_attr "type" "fpspc")
14174    (set_attr "mode" "XF")])
14176 (define_insn "fpatan_extend<mode>xf3_i387"
14177   [(set (match_operand:XF 0 "register_operand" "=f")
14178         (unspec:XF [(float_extend:XF
14179                       (match_operand:MODEF 1 "register_operand" "0"))
14180                     (float_extend:XF
14181                       (match_operand:MODEF 2 "register_operand" "u"))]
14182                    UNSPEC_FPATAN))
14183    (clobber (match_scratch:XF 3 "=2"))]
14184   "TARGET_USE_FANCY_MATH_387
14185    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14186        || TARGET_MIX_SSE_I387)
14187    && flag_unsafe_math_optimizations"
14188   "fpatan"
14189   [(set_attr "type" "fpspc")
14190    (set_attr "mode" "XF")])
14192 (define_expand "atan2xf3"
14193   [(parallel [(set (match_operand:XF 0 "register_operand")
14194                    (unspec:XF [(match_operand:XF 2 "register_operand")
14195                                (match_operand:XF 1 "register_operand")]
14196                               UNSPEC_FPATAN))
14197               (clobber (match_scratch:XF 3))])]
14198   "TARGET_USE_FANCY_MATH_387
14199    && flag_unsafe_math_optimizations")
14201 (define_expand "atan2<mode>3"
14202   [(use (match_operand:MODEF 0 "register_operand"))
14203    (use (match_operand:MODEF 1 "register_operand"))
14204    (use (match_operand:MODEF 2 "register_operand"))]
14205   "TARGET_USE_FANCY_MATH_387
14206    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14207        || TARGET_MIX_SSE_I387)
14208    && flag_unsafe_math_optimizations"
14210   rtx op0 = gen_reg_rtx (XFmode);
14212   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14213   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14214   DONE;
14217 (define_expand "atanxf2"
14218   [(parallel [(set (match_operand:XF 0 "register_operand")
14219                    (unspec:XF [(match_dup 2)
14220                                (match_operand:XF 1 "register_operand")]
14221                               UNSPEC_FPATAN))
14222               (clobber (match_scratch:XF 3))])]
14223   "TARGET_USE_FANCY_MATH_387
14224    && flag_unsafe_math_optimizations"
14226   operands[2] = gen_reg_rtx (XFmode);
14227   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
14230 (define_expand "atan<mode>2"
14231   [(use (match_operand:MODEF 0 "register_operand"))
14232    (use (match_operand:MODEF 1 "register_operand"))]
14233   "TARGET_USE_FANCY_MATH_387
14234    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14235        || TARGET_MIX_SSE_I387)
14236    && flag_unsafe_math_optimizations"
14238   rtx op0 = gen_reg_rtx (XFmode);
14240   rtx op2 = gen_reg_rtx (<MODE>mode);
14241   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
14243   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14244   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14245   DONE;
14248 (define_expand "asinxf2"
14249   [(set (match_dup 2)
14250         (mult:XF (match_operand:XF 1 "register_operand")
14251                  (match_dup 1)))
14252    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14253    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14254    (parallel [(set (match_operand:XF 0 "register_operand")
14255                    (unspec:XF [(match_dup 5) (match_dup 1)]
14256                               UNSPEC_FPATAN))
14257               (clobber (match_scratch:XF 6))])]
14258   "TARGET_USE_FANCY_MATH_387
14259    && flag_unsafe_math_optimizations"
14261   int i;
14263   if (optimize_insn_for_size_p ())
14264     FAIL;
14266   for (i = 2; i < 6; i++)
14267     operands[i] = gen_reg_rtx (XFmode);
14269   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14272 (define_expand "asin<mode>2"
14273   [(use (match_operand:MODEF 0 "register_operand"))
14274    (use (match_operand:MODEF 1 "general_operand"))]
14275  "TARGET_USE_FANCY_MATH_387
14276    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14277        || TARGET_MIX_SSE_I387)
14278    && flag_unsafe_math_optimizations"
14280   rtx op0 = gen_reg_rtx (XFmode);
14281   rtx op1 = gen_reg_rtx (XFmode);
14283   if (optimize_insn_for_size_p ())
14284     FAIL;
14286   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14287   emit_insn (gen_asinxf2 (op0, op1));
14288   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14289   DONE;
14292 (define_expand "acosxf2"
14293   [(set (match_dup 2)
14294         (mult:XF (match_operand:XF 1 "register_operand")
14295                  (match_dup 1)))
14296    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14297    (set (match_dup 5) (sqrt:XF (match_dup 4)))
14298    (parallel [(set (match_operand:XF 0 "register_operand")
14299                    (unspec:XF [(match_dup 1) (match_dup 5)]
14300                               UNSPEC_FPATAN))
14301               (clobber (match_scratch:XF 6))])]
14302   "TARGET_USE_FANCY_MATH_387
14303    && flag_unsafe_math_optimizations"
14305   int i;
14307   if (optimize_insn_for_size_p ())
14308     FAIL;
14310   for (i = 2; i < 6; i++)
14311     operands[i] = gen_reg_rtx (XFmode);
14313   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
14316 (define_expand "acos<mode>2"
14317   [(use (match_operand:MODEF 0 "register_operand"))
14318    (use (match_operand:MODEF 1 "general_operand"))]
14319  "TARGET_USE_FANCY_MATH_387
14320    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14321        || TARGET_MIX_SSE_I387)
14322    && flag_unsafe_math_optimizations"
14324   rtx op0 = gen_reg_rtx (XFmode);
14325   rtx op1 = gen_reg_rtx (XFmode);
14327   if (optimize_insn_for_size_p ())
14328     FAIL;
14330   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14331   emit_insn (gen_acosxf2 (op0, op1));
14332   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14333   DONE;
14336 (define_insn "fyl2xxf3_i387"
14337   [(set (match_operand:XF 0 "register_operand" "=f")
14338         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14339                     (match_operand:XF 2 "register_operand" "u")]
14340                    UNSPEC_FYL2X))
14341    (clobber (match_scratch:XF 3 "=2"))]
14342   "TARGET_USE_FANCY_MATH_387
14343    && flag_unsafe_math_optimizations"
14344   "fyl2x"
14345   [(set_attr "type" "fpspc")
14346    (set_attr "mode" "XF")])
14348 (define_insn "fyl2x_extend<mode>xf3_i387"
14349   [(set (match_operand:XF 0 "register_operand" "=f")
14350         (unspec:XF [(float_extend:XF
14351                       (match_operand:MODEF 1 "register_operand" "0"))
14352                     (match_operand:XF 2 "register_operand" "u")]
14353                    UNSPEC_FYL2X))
14354    (clobber (match_scratch:XF 3 "=2"))]
14355   "TARGET_USE_FANCY_MATH_387
14356    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14357        || TARGET_MIX_SSE_I387)
14358    && flag_unsafe_math_optimizations"
14359   "fyl2x"
14360   [(set_attr "type" "fpspc")
14361    (set_attr "mode" "XF")])
14363 (define_expand "logxf2"
14364   [(parallel [(set (match_operand:XF 0 "register_operand")
14365                    (unspec:XF [(match_operand:XF 1 "register_operand")
14366                                (match_dup 2)] UNSPEC_FYL2X))
14367               (clobber (match_scratch:XF 3))])]
14368   "TARGET_USE_FANCY_MATH_387
14369    && flag_unsafe_math_optimizations"
14371   operands[2] = gen_reg_rtx (XFmode);
14372   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14375 (define_expand "log<mode>2"
14376   [(use (match_operand:MODEF 0 "register_operand"))
14377    (use (match_operand:MODEF 1 "register_operand"))]
14378   "TARGET_USE_FANCY_MATH_387
14379    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14380        || TARGET_MIX_SSE_I387)
14381    && flag_unsafe_math_optimizations"
14383   rtx op0 = gen_reg_rtx (XFmode);
14385   rtx op2 = gen_reg_rtx (XFmode);
14386   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14388   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14389   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14390   DONE;
14393 (define_expand "log10xf2"
14394   [(parallel [(set (match_operand:XF 0 "register_operand")
14395                    (unspec:XF [(match_operand:XF 1 "register_operand")
14396                                (match_dup 2)] UNSPEC_FYL2X))
14397               (clobber (match_scratch:XF 3))])]
14398   "TARGET_USE_FANCY_MATH_387
14399    && flag_unsafe_math_optimizations"
14401   operands[2] = gen_reg_rtx (XFmode);
14402   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14405 (define_expand "log10<mode>2"
14406   [(use (match_operand:MODEF 0 "register_operand"))
14407    (use (match_operand:MODEF 1 "register_operand"))]
14408   "TARGET_USE_FANCY_MATH_387
14409    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14410        || TARGET_MIX_SSE_I387)
14411    && flag_unsafe_math_optimizations"
14413   rtx op0 = gen_reg_rtx (XFmode);
14415   rtx op2 = gen_reg_rtx (XFmode);
14416   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14418   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14419   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14420   DONE;
14423 (define_expand "log2xf2"
14424   [(parallel [(set (match_operand:XF 0 "register_operand")
14425                    (unspec:XF [(match_operand:XF 1 "register_operand")
14426                                (match_dup 2)] UNSPEC_FYL2X))
14427               (clobber (match_scratch:XF 3))])]
14428   "TARGET_USE_FANCY_MATH_387
14429    && flag_unsafe_math_optimizations"
14431   operands[2] = gen_reg_rtx (XFmode);
14432   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14435 (define_expand "log2<mode>2"
14436   [(use (match_operand:MODEF 0 "register_operand"))
14437    (use (match_operand:MODEF 1 "register_operand"))]
14438   "TARGET_USE_FANCY_MATH_387
14439    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14440        || TARGET_MIX_SSE_I387)
14441    && flag_unsafe_math_optimizations"
14443   rtx op0 = gen_reg_rtx (XFmode);
14445   rtx op2 = gen_reg_rtx (XFmode);
14446   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14448   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14449   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14450   DONE;
14453 (define_insn "fyl2xp1xf3_i387"
14454   [(set (match_operand:XF 0 "register_operand" "=f")
14455         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14456                     (match_operand:XF 2 "register_operand" "u")]
14457                    UNSPEC_FYL2XP1))
14458    (clobber (match_scratch:XF 3 "=2"))]
14459   "TARGET_USE_FANCY_MATH_387
14460    && flag_unsafe_math_optimizations"
14461   "fyl2xp1"
14462   [(set_attr "type" "fpspc")
14463    (set_attr "mode" "XF")])
14465 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14466   [(set (match_operand:XF 0 "register_operand" "=f")
14467         (unspec:XF [(float_extend:XF
14468                       (match_operand:MODEF 1 "register_operand" "0"))
14469                     (match_operand:XF 2 "register_operand" "u")]
14470                    UNSPEC_FYL2XP1))
14471    (clobber (match_scratch:XF 3 "=2"))]
14472   "TARGET_USE_FANCY_MATH_387
14473    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14474        || TARGET_MIX_SSE_I387)
14475    && flag_unsafe_math_optimizations"
14476   "fyl2xp1"
14477   [(set_attr "type" "fpspc")
14478    (set_attr "mode" "XF")])
14480 (define_expand "log1pxf2"
14481   [(use (match_operand:XF 0 "register_operand"))
14482    (use (match_operand:XF 1 "register_operand"))]
14483   "TARGET_USE_FANCY_MATH_387
14484    && flag_unsafe_math_optimizations"
14486   if (optimize_insn_for_size_p ())
14487     FAIL;
14489   ix86_emit_i387_log1p (operands[0], operands[1]);
14490   DONE;
14493 (define_expand "log1p<mode>2"
14494   [(use (match_operand:MODEF 0 "register_operand"))
14495    (use (match_operand:MODEF 1 "register_operand"))]
14496   "TARGET_USE_FANCY_MATH_387
14497    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14498        || TARGET_MIX_SSE_I387)
14499    && flag_unsafe_math_optimizations"
14501   rtx op0;
14503   if (optimize_insn_for_size_p ())
14504     FAIL;
14506   op0 = gen_reg_rtx (XFmode);
14508   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14510   ix86_emit_i387_log1p (op0, operands[1]);
14511   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14512   DONE;
14515 (define_insn "fxtractxf3_i387"
14516   [(set (match_operand:XF 0 "register_operand" "=f")
14517         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14518                    UNSPEC_XTRACT_FRACT))
14519    (set (match_operand:XF 1 "register_operand" "=u")
14520         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14521   "TARGET_USE_FANCY_MATH_387
14522    && flag_unsafe_math_optimizations"
14523   "fxtract"
14524   [(set_attr "type" "fpspc")
14525    (set_attr "mode" "XF")])
14527 (define_insn "fxtract_extend<mode>xf3_i387"
14528   [(set (match_operand:XF 0 "register_operand" "=f")
14529         (unspec:XF [(float_extend:XF
14530                       (match_operand:MODEF 2 "register_operand" "0"))]
14531                    UNSPEC_XTRACT_FRACT))
14532    (set (match_operand:XF 1 "register_operand" "=u")
14533         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14534   "TARGET_USE_FANCY_MATH_387
14535    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14536        || TARGET_MIX_SSE_I387)
14537    && flag_unsafe_math_optimizations"
14538   "fxtract"
14539   [(set_attr "type" "fpspc")
14540    (set_attr "mode" "XF")])
14542 (define_expand "logbxf2"
14543   [(parallel [(set (match_dup 2)
14544                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14545                               UNSPEC_XTRACT_FRACT))
14546               (set (match_operand:XF 0 "register_operand")
14547                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14548   "TARGET_USE_FANCY_MATH_387
14549    && flag_unsafe_math_optimizations"
14550   "operands[2] = gen_reg_rtx (XFmode);")
14552 (define_expand "logb<mode>2"
14553   [(use (match_operand:MODEF 0 "register_operand"))
14554    (use (match_operand:MODEF 1 "register_operand"))]
14555   "TARGET_USE_FANCY_MATH_387
14556    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14557        || TARGET_MIX_SSE_I387)
14558    && flag_unsafe_math_optimizations"
14560   rtx op0 = gen_reg_rtx (XFmode);
14561   rtx op1 = gen_reg_rtx (XFmode);
14563   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14564   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14565   DONE;
14568 (define_expand "ilogbxf2"
14569   [(use (match_operand:SI 0 "register_operand"))
14570    (use (match_operand:XF 1 "register_operand"))]
14571   "TARGET_USE_FANCY_MATH_387
14572    && flag_unsafe_math_optimizations"
14574   rtx op0, op1;
14576   if (optimize_insn_for_size_p ())
14577     FAIL;
14579   op0 = gen_reg_rtx (XFmode);
14580   op1 = gen_reg_rtx (XFmode);
14582   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14583   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14584   DONE;
14587 (define_expand "ilogb<mode>2"
14588   [(use (match_operand:SI 0 "register_operand"))
14589    (use (match_operand:MODEF 1 "register_operand"))]
14590   "TARGET_USE_FANCY_MATH_387
14591    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14592        || TARGET_MIX_SSE_I387)
14593    && flag_unsafe_math_optimizations"
14595   rtx op0, op1;
14597   if (optimize_insn_for_size_p ())
14598     FAIL;
14600   op0 = gen_reg_rtx (XFmode);
14601   op1 = gen_reg_rtx (XFmode);
14603   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14604   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14605   DONE;
14608 (define_insn "*f2xm1xf2_i387"
14609   [(set (match_operand:XF 0 "register_operand" "=f")
14610         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14611                    UNSPEC_F2XM1))]
14612   "TARGET_USE_FANCY_MATH_387
14613    && flag_unsafe_math_optimizations"
14614   "f2xm1"
14615   [(set_attr "type" "fpspc")
14616    (set_attr "mode" "XF")])
14618 (define_insn "fscalexf4_i387"
14619   [(set (match_operand:XF 0 "register_operand" "=f")
14620         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14621                     (match_operand:XF 3 "register_operand" "1")]
14622                    UNSPEC_FSCALE_FRACT))
14623    (set (match_operand:XF 1 "register_operand" "=u")
14624         (unspec:XF [(match_dup 2) (match_dup 3)]
14625                    UNSPEC_FSCALE_EXP))]
14626   "TARGET_USE_FANCY_MATH_387
14627    && flag_unsafe_math_optimizations"
14628   "fscale"
14629   [(set_attr "type" "fpspc")
14630    (set_attr "mode" "XF")])
14632 (define_expand "expNcorexf3"
14633   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14634                                (match_operand:XF 2 "register_operand")))
14635    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14636    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14637    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14638    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14639    (parallel [(set (match_operand:XF 0 "register_operand")
14640                    (unspec:XF [(match_dup 8) (match_dup 4)]
14641                               UNSPEC_FSCALE_FRACT))
14642               (set (match_dup 9)
14643                    (unspec:XF [(match_dup 8) (match_dup 4)]
14644                               UNSPEC_FSCALE_EXP))])]
14645   "TARGET_USE_FANCY_MATH_387
14646    && flag_unsafe_math_optimizations"
14648   int i;
14650   if (optimize_insn_for_size_p ())
14651     FAIL;
14653   for (i = 3; i < 10; i++)
14654     operands[i] = gen_reg_rtx (XFmode);
14656   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
14659 (define_expand "expxf2"
14660   [(use (match_operand:XF 0 "register_operand"))
14661    (use (match_operand:XF 1 "register_operand"))]
14662   "TARGET_USE_FANCY_MATH_387
14663    && flag_unsafe_math_optimizations"
14665   rtx op2;
14667   if (optimize_insn_for_size_p ())
14668     FAIL;
14670   op2 = gen_reg_rtx (XFmode);
14671   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14673   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14674   DONE;
14677 (define_expand "exp<mode>2"
14678   [(use (match_operand:MODEF 0 "register_operand"))
14679    (use (match_operand:MODEF 1 "general_operand"))]
14680  "TARGET_USE_FANCY_MATH_387
14681    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14682        || TARGET_MIX_SSE_I387)
14683    && flag_unsafe_math_optimizations"
14685   rtx op0, op1;
14687   if (optimize_insn_for_size_p ())
14688     FAIL;
14690   op0 = gen_reg_rtx (XFmode);
14691   op1 = gen_reg_rtx (XFmode);
14693   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14694   emit_insn (gen_expxf2 (op0, op1));
14695   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14696   DONE;
14699 (define_expand "exp10xf2"
14700   [(use (match_operand:XF 0 "register_operand"))
14701    (use (match_operand:XF 1 "register_operand"))]
14702   "TARGET_USE_FANCY_MATH_387
14703    && flag_unsafe_math_optimizations"
14705   rtx op2;
14707   if (optimize_insn_for_size_p ())
14708     FAIL;
14710   op2 = gen_reg_rtx (XFmode);
14711   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14713   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14714   DONE;
14717 (define_expand "exp10<mode>2"
14718   [(use (match_operand:MODEF 0 "register_operand"))
14719    (use (match_operand:MODEF 1 "general_operand"))]
14720  "TARGET_USE_FANCY_MATH_387
14721    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14722        || TARGET_MIX_SSE_I387)
14723    && flag_unsafe_math_optimizations"
14725   rtx op0, op1;
14727   if (optimize_insn_for_size_p ())
14728     FAIL;
14730   op0 = gen_reg_rtx (XFmode);
14731   op1 = gen_reg_rtx (XFmode);
14733   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14734   emit_insn (gen_exp10xf2 (op0, op1));
14735   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14736   DONE;
14739 (define_expand "exp2xf2"
14740   [(use (match_operand:XF 0 "register_operand"))
14741    (use (match_operand:XF 1 "register_operand"))]
14742   "TARGET_USE_FANCY_MATH_387
14743    && flag_unsafe_math_optimizations"
14745   rtx op2;
14747   if (optimize_insn_for_size_p ())
14748     FAIL;
14750   op2 = gen_reg_rtx (XFmode);
14751   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
14753   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14754   DONE;
14757 (define_expand "exp2<mode>2"
14758   [(use (match_operand:MODEF 0 "register_operand"))
14759    (use (match_operand:MODEF 1 "general_operand"))]
14760  "TARGET_USE_FANCY_MATH_387
14761    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14762        || TARGET_MIX_SSE_I387)
14763    && flag_unsafe_math_optimizations"
14765   rtx op0, op1;
14767   if (optimize_insn_for_size_p ())
14768     FAIL;
14770   op0 = gen_reg_rtx (XFmode);
14771   op1 = gen_reg_rtx (XFmode);
14773   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14774   emit_insn (gen_exp2xf2 (op0, op1));
14775   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14776   DONE;
14779 (define_expand "expm1xf2"
14780   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14781                                (match_dup 2)))
14782    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14783    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14784    (set (match_dup 9) (float_extend:XF (match_dup 13)))
14785    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14786    (parallel [(set (match_dup 7)
14787                    (unspec:XF [(match_dup 6) (match_dup 4)]
14788                               UNSPEC_FSCALE_FRACT))
14789               (set (match_dup 8)
14790                    (unspec:XF [(match_dup 6) (match_dup 4)]
14791                               UNSPEC_FSCALE_EXP))])
14792    (parallel [(set (match_dup 10)
14793                    (unspec:XF [(match_dup 9) (match_dup 8)]
14794                               UNSPEC_FSCALE_FRACT))
14795               (set (match_dup 11)
14796                    (unspec:XF [(match_dup 9) (match_dup 8)]
14797                               UNSPEC_FSCALE_EXP))])
14798    (set (match_dup 12) (minus:XF (match_dup 10)
14799                                  (float_extend:XF (match_dup 13))))
14800    (set (match_operand:XF 0 "register_operand")
14801         (plus:XF (match_dup 12) (match_dup 7)))]
14802   "TARGET_USE_FANCY_MATH_387
14803    && flag_unsafe_math_optimizations"
14805   int i;
14807   if (optimize_insn_for_size_p ())
14808     FAIL;
14810   for (i = 2; i < 13; i++)
14811     operands[i] = gen_reg_rtx (XFmode);
14813   operands[13]
14814     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14816   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14819 (define_expand "expm1<mode>2"
14820   [(use (match_operand:MODEF 0 "register_operand"))
14821    (use (match_operand:MODEF 1 "general_operand"))]
14822  "TARGET_USE_FANCY_MATH_387
14823    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14824        || TARGET_MIX_SSE_I387)
14825    && flag_unsafe_math_optimizations"
14827   rtx op0, op1;
14829   if (optimize_insn_for_size_p ())
14830     FAIL;
14832   op0 = gen_reg_rtx (XFmode);
14833   op1 = gen_reg_rtx (XFmode);
14835   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14836   emit_insn (gen_expm1xf2 (op0, op1));
14837   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14838   DONE;
14841 (define_expand "ldexpxf3"
14842   [(match_operand:XF 0 "register_operand")
14843    (match_operand:XF 1 "register_operand")
14844    (match_operand:SI 2 "register_operand")]
14845   "TARGET_USE_FANCY_MATH_387
14846    && flag_unsafe_math_optimizations"
14848   rtx tmp1, tmp2;
14849   if (optimize_insn_for_size_p ())
14850     FAIL;
14852   tmp1 = gen_reg_rtx (XFmode);
14853   tmp2 = gen_reg_rtx (XFmode);
14855   emit_insn (gen_floatsixf2 (tmp1, operands[2]));
14856   emit_insn (gen_fscalexf4_i387 (operands[0], tmp2,
14857                                  operands[1], tmp1));
14858   DONE;
14861 (define_expand "ldexp<mode>3"
14862   [(use (match_operand:MODEF 0 "register_operand"))
14863    (use (match_operand:MODEF 1 "general_operand"))
14864    (use (match_operand:SI 2 "register_operand"))]
14865  "TARGET_USE_FANCY_MATH_387
14866    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14867        || TARGET_MIX_SSE_I387)
14868    && flag_unsafe_math_optimizations"
14870   rtx op0, op1;
14872   if (optimize_insn_for_size_p ())
14873     FAIL;
14875   op0 = gen_reg_rtx (XFmode);
14876   op1 = gen_reg_rtx (XFmode);
14878   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14879   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14880   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14881   DONE;
14884 (define_expand "scalbxf3"
14885   [(parallel [(set (match_operand:XF 0 " register_operand")
14886                    (unspec:XF [(match_operand:XF 1 "register_operand")
14887                                (match_operand:XF 2 "register_operand")]
14888                               UNSPEC_FSCALE_FRACT))
14889               (set (match_dup 3)
14890                    (unspec:XF [(match_dup 1) (match_dup 2)]
14891                               UNSPEC_FSCALE_EXP))])]
14892   "TARGET_USE_FANCY_MATH_387
14893    && flag_unsafe_math_optimizations"
14895   if (optimize_insn_for_size_p ())
14896     FAIL;
14898   operands[3] = gen_reg_rtx (XFmode);
14901 (define_expand "scalb<mode>3"
14902   [(use (match_operand:MODEF 0 "register_operand"))
14903    (use (match_operand:MODEF 1 "general_operand"))
14904    (use (match_operand:MODEF 2 "general_operand"))]
14905  "TARGET_USE_FANCY_MATH_387
14906    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14907        || TARGET_MIX_SSE_I387)
14908    && flag_unsafe_math_optimizations"
14910   rtx op0, op1, op2;
14912   if (optimize_insn_for_size_p ())
14913     FAIL;
14915   op0 = gen_reg_rtx (XFmode);
14916   op1 = gen_reg_rtx (XFmode);
14917   op2 = gen_reg_rtx (XFmode);
14919   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14920   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14921   emit_insn (gen_scalbxf3 (op0, op1, op2));
14922   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14923   DONE;
14926 (define_expand "significandxf2"
14927   [(parallel [(set (match_operand:XF 0 "register_operand")
14928                    (unspec:XF [(match_operand:XF 1 "register_operand")]
14929                               UNSPEC_XTRACT_FRACT))
14930               (set (match_dup 2)
14931                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14932   "TARGET_USE_FANCY_MATH_387
14933    && flag_unsafe_math_optimizations"
14934   "operands[2] = gen_reg_rtx (XFmode);")
14936 (define_expand "significand<mode>2"
14937   [(use (match_operand:MODEF 0 "register_operand"))
14938    (use (match_operand:MODEF 1 "register_operand"))]
14939   "TARGET_USE_FANCY_MATH_387
14940    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14941        || TARGET_MIX_SSE_I387)
14942    && flag_unsafe_math_optimizations"
14944   rtx op0 = gen_reg_rtx (XFmode);
14945   rtx op1 = gen_reg_rtx (XFmode);
14947   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14948   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14949   DONE;
14953 (define_insn "sse4_1_round<mode>2"
14954   [(set (match_operand:MODEF 0 "register_operand" "=x")
14955         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14956                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
14957                       UNSPEC_ROUND))]
14958   "TARGET_ROUND"
14959   "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14960   [(set_attr "type" "ssecvt")
14961    (set_attr "prefix_extra" "1")
14962    (set_attr "prefix" "maybe_vex")
14963    (set_attr "mode" "<MODE>")])
14965 (define_insn "rintxf2"
14966   [(set (match_operand:XF 0 "register_operand" "=f")
14967         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14968                    UNSPEC_FRNDINT))]
14969   "TARGET_USE_FANCY_MATH_387
14970    && flag_unsafe_math_optimizations"
14971   "frndint"
14972   [(set_attr "type" "fpspc")
14973    (set_attr "mode" "XF")])
14975 (define_expand "rint<mode>2"
14976   [(use (match_operand:MODEF 0 "register_operand"))
14977    (use (match_operand:MODEF 1 "register_operand"))]
14978   "(TARGET_USE_FANCY_MATH_387
14979     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14980         || TARGET_MIX_SSE_I387)
14981     && flag_unsafe_math_optimizations)
14982    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14983        && !flag_trapping_math)"
14985   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14986       && !flag_trapping_math)
14987     {
14988       if (TARGET_ROUND)
14989         emit_insn (gen_sse4_1_round<mode>2
14990                    (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14991       else if (optimize_insn_for_size_p ())
14992         FAIL;
14993       else
14994         ix86_expand_rint (operands[0], operands[1]);
14995     }
14996   else
14997     {
14998       rtx op0 = gen_reg_rtx (XFmode);
14999       rtx op1 = gen_reg_rtx (XFmode);
15001       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15002       emit_insn (gen_rintxf2 (op0, op1));
15004       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15005     }
15006   DONE;
15009 (define_expand "round<mode>2"
15010   [(match_operand:X87MODEF 0 "register_operand")
15011    (match_operand:X87MODEF 1 "nonimmediate_operand")]
15012   "(TARGET_USE_FANCY_MATH_387
15013     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15014         || TARGET_MIX_SSE_I387)
15015     && flag_unsafe_math_optimizations)
15016    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15017        && !flag_trapping_math && !flag_rounding_math)"
15019   if (optimize_insn_for_size_p ())
15020     FAIL;
15022   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15023       && !flag_trapping_math && !flag_rounding_math)
15024     {
15025       if (TARGET_ROUND)
15026         {
15027           operands[1] = force_reg (<MODE>mode, operands[1]);
15028           ix86_expand_round_sse4 (operands[0], operands[1]);
15029         }
15030       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15031         ix86_expand_round (operands[0], operands[1]);
15032       else
15033         ix86_expand_rounddf_32 (operands[0], operands[1]);
15034     }
15035   else
15036     {
15037       operands[1] = force_reg (<MODE>mode, operands[1]);
15038       ix86_emit_i387_round (operands[0], operands[1]);
15039     }
15040   DONE;
15043 (define_insn_and_split "*fistdi2_1"
15044   [(set (match_operand:DI 0 "nonimmediate_operand")
15045         (unspec:DI [(match_operand:XF 1 "register_operand")]
15046                    UNSPEC_FIST))]
15047   "TARGET_USE_FANCY_MATH_387
15048    && can_create_pseudo_p ()"
15049   "#"
15050   "&& 1"
15051   [(const_int 0)]
15053   if (memory_operand (operands[0], VOIDmode))
15054     emit_insn (gen_fistdi2 (operands[0], operands[1]));
15055   else
15056     {
15057       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
15058       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
15059                                          operands[2]));
15060     }
15061   DONE;
15063   [(set_attr "type" "fpspc")
15064    (set_attr "mode" "DI")])
15066 (define_insn "fistdi2"
15067   [(set (match_operand:DI 0 "memory_operand" "=m")
15068         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15069                    UNSPEC_FIST))
15070    (clobber (match_scratch:XF 2 "=&1f"))]
15071   "TARGET_USE_FANCY_MATH_387"
15072   "* return output_fix_trunc (insn, operands, false);"
15073   [(set_attr "type" "fpspc")
15074    (set_attr "mode" "DI")])
15076 (define_insn "fistdi2_with_temp"
15077   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15078         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15079                    UNSPEC_FIST))
15080    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
15081    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
15082   "TARGET_USE_FANCY_MATH_387"
15083   "#"
15084   [(set_attr "type" "fpspc")
15085    (set_attr "mode" "DI")])
15087 (define_split
15088   [(set (match_operand:DI 0 "register_operand")
15089         (unspec:DI [(match_operand:XF 1 "register_operand")]
15090                    UNSPEC_FIST))
15091    (clobber (match_operand:DI 2 "memory_operand"))
15092    (clobber (match_scratch 3))]
15093   "reload_completed"
15094   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15095               (clobber (match_dup 3))])
15096    (set (match_dup 0) (match_dup 2))])
15098 (define_split
15099   [(set (match_operand:DI 0 "memory_operand")
15100         (unspec:DI [(match_operand:XF 1 "register_operand")]
15101                    UNSPEC_FIST))
15102    (clobber (match_operand:DI 2 "memory_operand"))
15103    (clobber (match_scratch 3))]
15104   "reload_completed"
15105   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
15106               (clobber (match_dup 3))])])
15108 (define_insn_and_split "*fist<mode>2_1"
15109   [(set (match_operand:SWI24 0 "register_operand")
15110         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15111                       UNSPEC_FIST))]
15112   "TARGET_USE_FANCY_MATH_387
15113    && can_create_pseudo_p ()"
15114   "#"
15115   "&& 1"
15116   [(const_int 0)]
15118   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15119   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15120                                         operands[2]));
15121   DONE;
15123   [(set_attr "type" "fpspc")
15124    (set_attr "mode" "<MODE>")])
15126 (define_insn "fist<mode>2"
15127   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15128         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15129                       UNSPEC_FIST))]
15130   "TARGET_USE_FANCY_MATH_387"
15131   "* return output_fix_trunc (insn, operands, false);"
15132   [(set_attr "type" "fpspc")
15133    (set_attr "mode" "<MODE>")])
15135 (define_insn "fist<mode>2_with_temp"
15136   [(set (match_operand:SWI24 0 "register_operand" "=r")
15137         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15138                       UNSPEC_FIST))
15139    (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15140   "TARGET_USE_FANCY_MATH_387"
15141   "#"
15142   [(set_attr "type" "fpspc")
15143    (set_attr "mode" "<MODE>")])
15145 (define_split
15146   [(set (match_operand:SWI24 0 "register_operand")
15147         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15148                       UNSPEC_FIST))
15149    (clobber (match_operand:SWI24 2 "memory_operand"))]
15150   "reload_completed"
15151   [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15152    (set (match_dup 0) (match_dup 2))])
15154 (define_split
15155   [(set (match_operand:SWI24 0 "memory_operand")
15156         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15157                       UNSPEC_FIST))
15158    (clobber (match_operand:SWI24 2 "memory_operand"))]
15159   "reload_completed"
15160   [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15162 (define_expand "lrintxf<mode>2"
15163   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15164      (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15165                      UNSPEC_FIST))]
15166   "TARGET_USE_FANCY_MATH_387")
15168 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
15169   [(set (match_operand:SWI48 0 "nonimmediate_operand")
15170      (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15171                    UNSPEC_FIX_NOTRUNC))]
15172   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
15174 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15175   [(match_operand:SWI248x 0 "nonimmediate_operand")
15176    (match_operand:X87MODEF 1 "register_operand")]
15177   "(TARGET_USE_FANCY_MATH_387
15178     && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15179         || TARGET_MIX_SSE_I387)
15180     && flag_unsafe_math_optimizations)
15181    || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15182        && <SWI248x:MODE>mode != HImode 
15183        && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15184        && !flag_trapping_math && !flag_rounding_math)"
15186   if (optimize_insn_for_size_p ())
15187     FAIL;
15189   if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15190       && <SWI248x:MODE>mode != HImode
15191       && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15192       && !flag_trapping_math && !flag_rounding_math)
15193     ix86_expand_lround (operands[0], operands[1]);
15194   else
15195     ix86_emit_i387_round (operands[0], operands[1]);
15196   DONE;
15199 (define_int_iterator FRNDINT_ROUNDING
15200         [UNSPEC_FRNDINT_FLOOR
15201          UNSPEC_FRNDINT_CEIL
15202          UNSPEC_FRNDINT_TRUNC])
15204 (define_int_iterator FIST_ROUNDING
15205         [UNSPEC_FIST_FLOOR
15206          UNSPEC_FIST_CEIL])
15208 ;; Base name for define_insn
15209 (define_int_attr rounding_insn
15210         [(UNSPEC_FRNDINT_FLOOR "floor")
15211          (UNSPEC_FRNDINT_CEIL "ceil")
15212          (UNSPEC_FRNDINT_TRUNC "btrunc")
15213          (UNSPEC_FIST_FLOOR "floor")
15214          (UNSPEC_FIST_CEIL "ceil")])
15216 (define_int_attr rounding
15217         [(UNSPEC_FRNDINT_FLOOR "floor")
15218          (UNSPEC_FRNDINT_CEIL "ceil")
15219          (UNSPEC_FRNDINT_TRUNC "trunc")
15220          (UNSPEC_FIST_FLOOR "floor")
15221          (UNSPEC_FIST_CEIL "ceil")])
15223 (define_int_attr ROUNDING
15224         [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15225          (UNSPEC_FRNDINT_CEIL "CEIL")
15226          (UNSPEC_FRNDINT_TRUNC "TRUNC")
15227          (UNSPEC_FIST_FLOOR "FLOOR")
15228          (UNSPEC_FIST_CEIL "CEIL")])
15230 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15231 (define_insn_and_split "frndintxf2_<rounding>"
15232   [(set (match_operand:XF 0 "register_operand")
15233         (unspec:XF [(match_operand:XF 1 "register_operand")]
15234                    FRNDINT_ROUNDING))
15235    (clobber (reg:CC FLAGS_REG))]
15236   "TARGET_USE_FANCY_MATH_387
15237    && flag_unsafe_math_optimizations
15238    && can_create_pseudo_p ()"
15239   "#"
15240   "&& 1"
15241   [(const_int 0)]
15243   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15245   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15246   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15248   emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15249                                              operands[2], operands[3]));
15250   DONE;
15252   [(set_attr "type" "frndint")
15253    (set_attr "i387_cw" "<rounding>")
15254    (set_attr "mode" "XF")])
15256 (define_insn "frndintxf2_<rounding>_i387"
15257   [(set (match_operand:XF 0 "register_operand" "=f")
15258         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15259                    FRNDINT_ROUNDING))
15260    (use (match_operand:HI 2 "memory_operand" "m"))
15261    (use (match_operand:HI 3 "memory_operand" "m"))]
15262   "TARGET_USE_FANCY_MATH_387
15263    && flag_unsafe_math_optimizations"
15264   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15265   [(set_attr "type" "frndint")
15266    (set_attr "i387_cw" "<rounding>")
15267    (set_attr "mode" "XF")])
15269 (define_expand "<rounding_insn>xf2"
15270   [(parallel [(set (match_operand:XF 0 "register_operand")
15271                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15272                               FRNDINT_ROUNDING))
15273               (clobber (reg:CC FLAGS_REG))])]
15274   "TARGET_USE_FANCY_MATH_387
15275    && flag_unsafe_math_optimizations
15276    && !optimize_insn_for_size_p ()")
15278 (define_expand "<rounding_insn><mode>2"
15279   [(parallel [(set (match_operand:MODEF 0 "register_operand")
15280                    (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15281                                  FRNDINT_ROUNDING))
15282               (clobber (reg:CC FLAGS_REG))])]
15283   "(TARGET_USE_FANCY_MATH_387
15284     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15285         || TARGET_MIX_SSE_I387)
15286     && flag_unsafe_math_optimizations)
15287    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15288        && !flag_trapping_math)"
15290   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15291       && !flag_trapping_math)
15292     {
15293       if (TARGET_ROUND)
15294         emit_insn (gen_sse4_1_round<mode>2
15295                    (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15296       else if (optimize_insn_for_size_p ())
15297         FAIL;
15298       else if (TARGET_64BIT || (<MODE>mode != DFmode))
15299         {
15300           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15301             ix86_expand_floorceil (operands[0], operands[1], true);
15302           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15303             ix86_expand_floorceil (operands[0], operands[1], false);
15304           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15305             ix86_expand_trunc (operands[0], operands[1]);
15306           else
15307             gcc_unreachable ();
15308         }
15309       else
15310         {
15311           if (ROUND_<ROUNDING> == ROUND_FLOOR)
15312             ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15313           else if (ROUND_<ROUNDING> == ROUND_CEIL)
15314             ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15315           else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15316             ix86_expand_truncdf_32 (operands[0], operands[1]);
15317           else
15318             gcc_unreachable ();
15319         }
15320     }
15321   else
15322     {
15323       rtx op0, op1;
15325       if (optimize_insn_for_size_p ())
15326         FAIL;
15328       op0 = gen_reg_rtx (XFmode);
15329       op1 = gen_reg_rtx (XFmode);
15330       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15331       emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15333       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15334     }
15335   DONE;
15338 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15339 (define_insn_and_split "frndintxf2_mask_pm"
15340   [(set (match_operand:XF 0 "register_operand")
15341         (unspec:XF [(match_operand:XF 1 "register_operand")]
15342                    UNSPEC_FRNDINT_MASK_PM))
15343    (clobber (reg:CC FLAGS_REG))]
15344   "TARGET_USE_FANCY_MATH_387
15345    && flag_unsafe_math_optimizations
15346    && can_create_pseudo_p ()"
15347   "#"
15348   "&& 1"
15349   [(const_int 0)]
15351   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15353   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15354   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15356   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15357                                           operands[2], operands[3]));
15358   DONE;
15360   [(set_attr "type" "frndint")
15361    (set_attr "i387_cw" "mask_pm")
15362    (set_attr "mode" "XF")])
15364 (define_insn "frndintxf2_mask_pm_i387"
15365   [(set (match_operand:XF 0 "register_operand" "=f")
15366         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15367                    UNSPEC_FRNDINT_MASK_PM))
15368    (use (match_operand:HI 2 "memory_operand" "m"))
15369    (use (match_operand:HI 3 "memory_operand" "m"))]
15370   "TARGET_USE_FANCY_MATH_387
15371    && flag_unsafe_math_optimizations"
15372   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15373   [(set_attr "type" "frndint")
15374    (set_attr "i387_cw" "mask_pm")
15375    (set_attr "mode" "XF")])
15377 (define_expand "nearbyintxf2"
15378   [(parallel [(set (match_operand:XF 0 "register_operand")
15379                    (unspec:XF [(match_operand:XF 1 "register_operand")]
15380                               UNSPEC_FRNDINT_MASK_PM))
15381               (clobber (reg:CC FLAGS_REG))])]
15382   "TARGET_USE_FANCY_MATH_387
15383    && flag_unsafe_math_optimizations")
15385 (define_expand "nearbyint<mode>2"
15386   [(use (match_operand:MODEF 0 "register_operand"))
15387    (use (match_operand:MODEF 1 "register_operand"))]
15388   "TARGET_USE_FANCY_MATH_387
15389    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15390        || TARGET_MIX_SSE_I387)
15391    && flag_unsafe_math_optimizations"
15393   rtx op0 = gen_reg_rtx (XFmode);
15394   rtx op1 = gen_reg_rtx (XFmode);
15396   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15397   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15399   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15400   DONE;
15403 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15404 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15405   [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15406         (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15407                         FIST_ROUNDING))
15408    (clobber (reg:CC FLAGS_REG))]
15409   "TARGET_USE_FANCY_MATH_387
15410    && flag_unsafe_math_optimizations
15411    && can_create_pseudo_p ()"
15412   "#"
15413   "&& 1"
15414   [(const_int 0)]
15416   ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15418   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15419   operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15420   if (memory_operand (operands[0], VOIDmode))
15421     emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15422                                            operands[2], operands[3]));
15423   else
15424     {
15425       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15426       emit_insn (gen_fist<mode>2_<rounding>_with_temp
15427                   (operands[0], operands[1], operands[2],
15428                    operands[3], operands[4]));
15429     }
15430   DONE;
15432   [(set_attr "type" "fistp")
15433    (set_attr "i387_cw" "<rounding>")
15434    (set_attr "mode" "<MODE>")])
15436 (define_insn "fistdi2_<rounding>"
15437   [(set (match_operand:DI 0 "memory_operand" "=m")
15438         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15439                    FIST_ROUNDING))
15440    (use (match_operand:HI 2 "memory_operand" "m"))
15441    (use (match_operand:HI 3 "memory_operand" "m"))
15442    (clobber (match_scratch:XF 4 "=&1f"))]
15443   "TARGET_USE_FANCY_MATH_387
15444    && flag_unsafe_math_optimizations"
15445   "* return output_fix_trunc (insn, operands, false);"
15446   [(set_attr "type" "fistp")
15447    (set_attr "i387_cw" "<rounding>")
15448    (set_attr "mode" "DI")])
15450 (define_insn "fistdi2_<rounding>_with_temp"
15451   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15452         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15453                    FIST_ROUNDING))
15454    (use (match_operand:HI 2 "memory_operand" "m,m"))
15455    (use (match_operand:HI 3 "memory_operand" "m,m"))
15456    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15457    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15458   "TARGET_USE_FANCY_MATH_387
15459    && flag_unsafe_math_optimizations"
15460   "#"
15461   [(set_attr "type" "fistp")
15462    (set_attr "i387_cw" "<rounding>")
15463    (set_attr "mode" "DI")])
15465 (define_split
15466   [(set (match_operand:DI 0 "register_operand")
15467         (unspec:DI [(match_operand:XF 1 "register_operand")]
15468                    FIST_ROUNDING))
15469    (use (match_operand:HI 2 "memory_operand"))
15470    (use (match_operand:HI 3 "memory_operand"))
15471    (clobber (match_operand:DI 4 "memory_operand"))
15472    (clobber (match_scratch 5))]
15473   "reload_completed"
15474   [(parallel [(set (match_dup 4)
15475                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15476               (use (match_dup 2))
15477               (use (match_dup 3))
15478               (clobber (match_dup 5))])
15479    (set (match_dup 0) (match_dup 4))])
15481 (define_split
15482   [(set (match_operand:DI 0 "memory_operand")
15483         (unspec:DI [(match_operand:XF 1 "register_operand")]
15484                    FIST_ROUNDING))
15485    (use (match_operand:HI 2 "memory_operand"))
15486    (use (match_operand:HI 3 "memory_operand"))
15487    (clobber (match_operand:DI 4 "memory_operand"))
15488    (clobber (match_scratch 5))]
15489   "reload_completed"
15490   [(parallel [(set (match_dup 0)
15491                    (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15492               (use (match_dup 2))
15493               (use (match_dup 3))
15494               (clobber (match_dup 5))])])
15496 (define_insn "fist<mode>2_<rounding>"
15497   [(set (match_operand:SWI24 0 "memory_operand" "=m")
15498         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15499                       FIST_ROUNDING))
15500    (use (match_operand:HI 2 "memory_operand" "m"))
15501    (use (match_operand:HI 3 "memory_operand" "m"))]
15502   "TARGET_USE_FANCY_MATH_387
15503    && flag_unsafe_math_optimizations"
15504   "* return output_fix_trunc (insn, operands, false);"
15505   [(set_attr "type" "fistp")
15506    (set_attr "i387_cw" "<rounding>")
15507    (set_attr "mode" "<MODE>")])
15509 (define_insn "fist<mode>2_<rounding>_with_temp"
15510   [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15511         (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15512                       FIST_ROUNDING))
15513    (use (match_operand:HI 2 "memory_operand" "m,m"))
15514    (use (match_operand:HI 3 "memory_operand" "m,m"))
15515    (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15516   "TARGET_USE_FANCY_MATH_387
15517    && flag_unsafe_math_optimizations"
15518   "#"
15519   [(set_attr "type" "fistp")
15520    (set_attr "i387_cw" "<rounding>")
15521    (set_attr "mode" "<MODE>")])
15523 (define_split
15524   [(set (match_operand:SWI24 0 "register_operand")
15525         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15526                       FIST_ROUNDING))
15527    (use (match_operand:HI 2 "memory_operand"))
15528    (use (match_operand:HI 3 "memory_operand"))
15529    (clobber (match_operand:SWI24 4 "memory_operand"))]
15530   "reload_completed"
15531   [(parallel [(set (match_dup 4)
15532                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15533               (use (match_dup 2))
15534               (use (match_dup 3))])
15535    (set (match_dup 0) (match_dup 4))])
15537 (define_split
15538   [(set (match_operand:SWI24 0 "memory_operand")
15539         (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15540                       FIST_ROUNDING))
15541    (use (match_operand:HI 2 "memory_operand"))
15542    (use (match_operand:HI 3 "memory_operand"))
15543    (clobber (match_operand:SWI24 4 "memory_operand"))]
15544   "reload_completed"
15545   [(parallel [(set (match_dup 0)
15546                    (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15547               (use (match_dup 2))
15548               (use (match_dup 3))])])
15550 (define_expand "l<rounding_insn>xf<mode>2"
15551   [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15552                    (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15553                                    FIST_ROUNDING))
15554               (clobber (reg:CC FLAGS_REG))])]
15555   "TARGET_USE_FANCY_MATH_387
15556    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15557    && flag_unsafe_math_optimizations")
15559 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15560   [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15561                    (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15562                                  FIST_ROUNDING))
15563               (clobber (reg:CC FLAGS_REG))])]
15564   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15565    && !flag_trapping_math"
15567   if (TARGET_64BIT && optimize_insn_for_size_p ())
15568     FAIL;
15570   if (ROUND_<ROUNDING> == ROUND_FLOOR)
15571     ix86_expand_lfloorceil (operands[0], operands[1], true);
15572   else if (ROUND_<ROUNDING> == ROUND_CEIL)
15573     ix86_expand_lfloorceil (operands[0], operands[1], false);
15574   else
15575     gcc_unreachable ();
15577   DONE;
15580 (define_insn "fxam<mode>2_i387"
15581   [(set (match_operand:HI 0 "register_operand" "=a")
15582         (unspec:HI
15583           [(match_operand:X87MODEF 1 "register_operand" "f")]
15584           UNSPEC_FXAM))]
15585   "TARGET_USE_FANCY_MATH_387"
15586   "fxam\n\tfnstsw\t%0"
15587   [(set_attr "type" "multi")
15588    (set_attr "length" "4")
15589    (set_attr "unit" "i387")
15590    (set_attr "mode" "<MODE>")])
15592 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15593   [(set (match_operand:HI 0 "register_operand")
15594         (unspec:HI
15595           [(match_operand:MODEF 1 "memory_operand")]
15596           UNSPEC_FXAM_MEM))]
15597   "TARGET_USE_FANCY_MATH_387
15598    && can_create_pseudo_p ()"
15599   "#"
15600   "&& 1"
15601   [(set (match_dup 2)(match_dup 1))
15602    (set (match_dup 0)
15603         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15605   operands[2] = gen_reg_rtx (<MODE>mode);
15607   MEM_VOLATILE_P (operands[1]) = 1;
15609   [(set_attr "type" "multi")
15610    (set_attr "unit" "i387")
15611    (set_attr "mode" "<MODE>")])
15613 (define_expand "isinfxf2"
15614   [(use (match_operand:SI 0 "register_operand"))
15615    (use (match_operand:XF 1 "register_operand"))]
15616   "TARGET_USE_FANCY_MATH_387
15617    && ix86_libc_has_function (function_c99_misc)"
15619   rtx mask = GEN_INT (0x45);
15620   rtx val = GEN_INT (0x05);
15622   rtx cond;
15624   rtx scratch = gen_reg_rtx (HImode);
15625   rtx res = gen_reg_rtx (QImode);
15627   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15629   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15630   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15631   cond = gen_rtx_fmt_ee (EQ, QImode,
15632                          gen_rtx_REG (CCmode, FLAGS_REG),
15633                          const0_rtx);
15634   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15635   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15636   DONE;
15639 (define_expand "isinf<mode>2"
15640   [(use (match_operand:SI 0 "register_operand"))
15641    (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15642   "TARGET_USE_FANCY_MATH_387
15643    && ix86_libc_has_function (function_c99_misc)
15644    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15646   rtx mask = GEN_INT (0x45);
15647   rtx val = GEN_INT (0x05);
15649   rtx cond;
15651   rtx scratch = gen_reg_rtx (HImode);
15652   rtx res = gen_reg_rtx (QImode);
15654   /* Remove excess precision by forcing value through memory. */
15655   if (memory_operand (operands[1], VOIDmode))
15656     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15657   else
15658     {
15659       rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15661       emit_move_insn (temp, operands[1]);
15662       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15663     }
15665   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15666   emit_insn (gen_cmpqi_ext_3 (scratch, val));
15667   cond = gen_rtx_fmt_ee (EQ, QImode,
15668                          gen_rtx_REG (CCmode, FLAGS_REG),
15669                          const0_rtx);
15670   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15671   emit_insn (gen_zero_extendqisi2 (operands[0], res));
15672   DONE;
15675 (define_expand "signbitxf2"
15676   [(use (match_operand:SI 0 "register_operand"))
15677    (use (match_operand:XF 1 "register_operand"))]
15678   "TARGET_USE_FANCY_MATH_387"
15680   rtx scratch = gen_reg_rtx (HImode);
15682   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15683   emit_insn (gen_andsi3 (operands[0],
15684              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15685   DONE;
15688 (define_insn "movmsk_df"
15689   [(set (match_operand:SI 0 "register_operand" "=r")
15690         (unspec:SI
15691           [(match_operand:DF 1 "register_operand" "x")]
15692           UNSPEC_MOVMSK))]
15693   "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15694   "%vmovmskpd\t{%1, %0|%0, %1}"
15695   [(set_attr "type" "ssemov")
15696    (set_attr "prefix" "maybe_vex")
15697    (set_attr "mode" "DF")])
15699 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15700 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15701 (define_expand "signbitdf2"
15702   [(use (match_operand:SI 0 "register_operand"))
15703    (use (match_operand:DF 1 "register_operand"))]
15704   "TARGET_USE_FANCY_MATH_387
15705    || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15707   if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15708     {
15709       emit_insn (gen_movmsk_df (operands[0], operands[1]));
15710       emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15711     }
15712   else
15713     {
15714       rtx scratch = gen_reg_rtx (HImode);
15716       emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15717       emit_insn (gen_andsi3 (operands[0],
15718                  gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15719     }
15720   DONE;
15723 (define_expand "signbitsf2"
15724   [(use (match_operand:SI 0 "register_operand"))
15725    (use (match_operand:SF 1 "register_operand"))]
15726   "TARGET_USE_FANCY_MATH_387
15727    && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15729   rtx scratch = gen_reg_rtx (HImode);
15731   emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15732   emit_insn (gen_andsi3 (operands[0],
15733              gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15734   DONE;
15737 ;; Block operation instructions
15739 (define_insn "cld"
15740   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15741   ""
15742   "cld"
15743   [(set_attr "length" "1")
15744    (set_attr "length_immediate" "0")
15745    (set_attr "modrm" "0")])
15747 (define_expand "movmem<mode>"
15748   [(use (match_operand:BLK 0 "memory_operand"))
15749    (use (match_operand:BLK 1 "memory_operand"))
15750    (use (match_operand:SWI48 2 "nonmemory_operand"))
15751    (use (match_operand:SWI48 3 "const_int_operand"))
15752    (use (match_operand:SI 4 "const_int_operand"))
15753    (use (match_operand:SI 5 "const_int_operand"))
15754    (use (match_operand:SI 6 ""))
15755    (use (match_operand:SI 7 ""))
15756    (use (match_operand:SI 8 ""))]
15757   ""
15759  if (ix86_expand_set_or_movmem (operands[0], operands[1],
15760                                 operands[2], NULL, operands[3],
15761                                 operands[4], operands[5],
15762                                 operands[6], operands[7],
15763                                 operands[8], false))
15764    DONE;
15765  else
15766    FAIL;
15769 ;; Most CPUs don't like single string operations
15770 ;; Handle this case here to simplify previous expander.
15772 (define_expand "strmov"
15773   [(set (match_dup 4) (match_operand 3 "memory_operand"))
15774    (set (match_operand 1 "memory_operand") (match_dup 4))
15775    (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15776               (clobber (reg:CC FLAGS_REG))])
15777    (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15778               (clobber (reg:CC FLAGS_REG))])]
15779   ""
15781   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15783   /* If .md ever supports :P for Pmode, these can be directly
15784      in the pattern above.  */
15785   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15786   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15788   /* Can't use this if the user has appropriated esi or edi.  */
15789   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15790       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15791     {
15792       emit_insn (gen_strmov_singleop (operands[0], operands[1],
15793                                       operands[2], operands[3],
15794                                       operands[5], operands[6]));
15795       DONE;
15796     }
15798   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15801 (define_expand "strmov_singleop"
15802   [(parallel [(set (match_operand 1 "memory_operand")
15803                    (match_operand 3 "memory_operand"))
15804               (set (match_operand 0 "register_operand")
15805                    (match_operand 4))
15806               (set (match_operand 2 "register_operand")
15807                    (match_operand 5))])]
15808   ""
15809   "ix86_current_function_needs_cld = 1;")
15811 (define_insn "*strmovdi_rex_1"
15812   [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15813         (mem:DI (match_operand:P 3 "register_operand" "1")))
15814    (set (match_operand:P 0 "register_operand" "=D")
15815         (plus:P (match_dup 2)
15816                 (const_int 8)))
15817    (set (match_operand:P 1 "register_operand" "=S")
15818         (plus:P (match_dup 3)
15819                 (const_int 8)))]
15820   "TARGET_64BIT
15821    && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15822   "%^movsq"
15823   [(set_attr "type" "str")
15824    (set_attr "memory" "both")
15825    (set_attr "mode" "DI")])
15827 (define_insn "*strmovsi_1"
15828   [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15829         (mem:SI (match_operand:P 3 "register_operand" "1")))
15830    (set (match_operand:P 0 "register_operand" "=D")
15831         (plus:P (match_dup 2)
15832                 (const_int 4)))
15833    (set (match_operand:P 1 "register_operand" "=S")
15834         (plus:P (match_dup 3)
15835                 (const_int 4)))]
15836   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15837   "%^movs{l|d}"
15838   [(set_attr "type" "str")
15839    (set_attr "memory" "both")
15840    (set_attr "mode" "SI")])
15842 (define_insn "*strmovhi_1"
15843   [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15844         (mem:HI (match_operand:P 3 "register_operand" "1")))
15845    (set (match_operand:P 0 "register_operand" "=D")
15846         (plus:P (match_dup 2)
15847                 (const_int 2)))
15848    (set (match_operand:P 1 "register_operand" "=S")
15849         (plus:P (match_dup 3)
15850                 (const_int 2)))]
15851   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15852   "%^movsw"
15853   [(set_attr "type" "str")
15854    (set_attr "memory" "both")
15855    (set_attr "mode" "HI")])
15857 (define_insn "*strmovqi_1"
15858   [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15859         (mem:QI (match_operand:P 3 "register_operand" "1")))
15860    (set (match_operand:P 0 "register_operand" "=D")
15861         (plus:P (match_dup 2)
15862                 (const_int 1)))
15863    (set (match_operand:P 1 "register_operand" "=S")
15864         (plus:P (match_dup 3)
15865                 (const_int 1)))]
15866   "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15867   "%^movsb"
15868   [(set_attr "type" "str")
15869    (set_attr "memory" "both")
15870    (set (attr "prefix_rex")
15871         (if_then_else
15872           (match_test "<P:MODE>mode == DImode")
15873           (const_string "0")
15874           (const_string "*")))
15875    (set_attr "mode" "QI")])
15877 (define_expand "rep_mov"
15878   [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15879               (set (match_operand 0 "register_operand")
15880                    (match_operand 5))
15881               (set (match_operand 2 "register_operand")
15882                    (match_operand 6))
15883               (set (match_operand 1 "memory_operand")
15884                    (match_operand 3 "memory_operand"))
15885               (use (match_dup 4))])]
15886   ""
15887   "ix86_current_function_needs_cld = 1;")
15889 (define_insn "*rep_movdi_rex64"
15890   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15891    (set (match_operand:P 0 "register_operand" "=D")
15892         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15893                           (const_int 3))
15894                 (match_operand:P 3 "register_operand" "0")))
15895    (set (match_operand:P 1 "register_operand" "=S")
15896         (plus:P (ashift:P (match_dup 5) (const_int 3))
15897                 (match_operand:P 4 "register_operand" "1")))
15898    (set (mem:BLK (match_dup 3))
15899         (mem:BLK (match_dup 4)))
15900    (use (match_dup 5))]
15901   "TARGET_64BIT
15902    && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15903   "%^rep{%;} movsq"
15904   [(set_attr "type" "str")
15905    (set_attr "prefix_rep" "1")
15906    (set_attr "memory" "both")
15907    (set_attr "mode" "DI")])
15909 (define_insn "*rep_movsi"
15910   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15911    (set (match_operand:P 0 "register_operand" "=D")
15912         (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15913                           (const_int 2))
15914                  (match_operand:P 3 "register_operand" "0")))
15915    (set (match_operand:P 1 "register_operand" "=S")
15916         (plus:P (ashift:P (match_dup 5) (const_int 2))
15917                 (match_operand:P 4 "register_operand" "1")))
15918    (set (mem:BLK (match_dup 3))
15919         (mem:BLK (match_dup 4)))
15920    (use (match_dup 5))]
15921   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15922   "%^rep{%;} movs{l|d}"
15923   [(set_attr "type" "str")
15924    (set_attr "prefix_rep" "1")
15925    (set_attr "memory" "both")
15926    (set_attr "mode" "SI")])
15928 (define_insn "*rep_movqi"
15929   [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15930    (set (match_operand:P 0 "register_operand" "=D")
15931         (plus:P (match_operand:P 3 "register_operand" "0")
15932                 (match_operand:P 5 "register_operand" "2")))
15933    (set (match_operand:P 1 "register_operand" "=S")
15934         (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15935    (set (mem:BLK (match_dup 3))
15936         (mem:BLK (match_dup 4)))
15937    (use (match_dup 5))]
15938   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15939   "%^rep{%;} movsb"
15940   [(set_attr "type" "str")
15941    (set_attr "prefix_rep" "1")
15942    (set_attr "memory" "both")
15943    (set_attr "mode" "QI")])
15945 (define_expand "setmem<mode>"
15946    [(use (match_operand:BLK 0 "memory_operand"))
15947     (use (match_operand:SWI48 1 "nonmemory_operand"))
15948     (use (match_operand:QI 2 "nonmemory_operand"))
15949     (use (match_operand 3 "const_int_operand"))
15950     (use (match_operand:SI 4 "const_int_operand"))
15951     (use (match_operand:SI 5 "const_int_operand"))
15952     (use (match_operand:SI 6 ""))
15953     (use (match_operand:SI 7 ""))
15954     (use (match_operand:SI 8 ""))]
15955   ""
15957  if (ix86_expand_set_or_movmem (operands[0], NULL,
15958                                 operands[1], operands[2],
15959                                 operands[3], operands[4],
15960                                 operands[5], operands[6],
15961                                 operands[7], operands[8], true))
15962    DONE;
15963  else
15964    FAIL;
15967 ;; Most CPUs don't like single string operations
15968 ;; Handle this case here to simplify previous expander.
15970 (define_expand "strset"
15971   [(set (match_operand 1 "memory_operand")
15972         (match_operand 2 "register_operand"))
15973    (parallel [(set (match_operand 0 "register_operand")
15974                    (match_dup 3))
15975               (clobber (reg:CC FLAGS_REG))])]
15976   ""
15978   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15979     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15981   /* If .md ever supports :P for Pmode, this can be directly
15982      in the pattern above.  */
15983   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15984                               GEN_INT (GET_MODE_SIZE (GET_MODE
15985                                                       (operands[2]))));
15986   /* Can't use this if the user has appropriated eax or edi.  */
15987   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15988       && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15989     {
15990       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15991                                       operands[3]));
15992       DONE;
15993     }
15996 (define_expand "strset_singleop"
15997   [(parallel [(set (match_operand 1 "memory_operand")
15998                    (match_operand 2 "register_operand"))
15999               (set (match_operand 0 "register_operand")
16000                    (match_operand 3))
16001               (unspec [(const_int 0)] UNSPEC_STOS)])]
16002   ""
16003   "ix86_current_function_needs_cld = 1;")
16005 (define_insn "*strsetdi_rex_1"
16006   [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16007         (match_operand:DI 2 "register_operand" "a"))
16008    (set (match_operand:P 0 "register_operand" "=D")
16009         (plus:P (match_dup 1)
16010                 (const_int 8)))
16011    (unspec [(const_int 0)] UNSPEC_STOS)]
16012   "TARGET_64BIT
16013    && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16014   "%^stosq"
16015   [(set_attr "type" "str")
16016    (set_attr "memory" "store")
16017    (set_attr "mode" "DI")])
16019 (define_insn "*strsetsi_1"
16020   [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16021         (match_operand:SI 2 "register_operand" "a"))
16022    (set (match_operand:P 0 "register_operand" "=D")
16023         (plus:P (match_dup 1)
16024                 (const_int 4)))
16025    (unspec [(const_int 0)] UNSPEC_STOS)]
16026   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16027   "%^stos{l|d}"
16028   [(set_attr "type" "str")
16029    (set_attr "memory" "store")
16030    (set_attr "mode" "SI")])
16032 (define_insn "*strsethi_1"
16033   [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16034         (match_operand:HI 2 "register_operand" "a"))
16035    (set (match_operand:P 0 "register_operand" "=D")
16036         (plus:P (match_dup 1)
16037                 (const_int 2)))
16038    (unspec [(const_int 0)] UNSPEC_STOS)]
16039   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16040   "%^stosw"
16041   [(set_attr "type" "str")
16042    (set_attr "memory" "store")
16043    (set_attr "mode" "HI")])
16045 (define_insn "*strsetqi_1"
16046   [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16047         (match_operand:QI 2 "register_operand" "a"))
16048    (set (match_operand:P 0 "register_operand" "=D")
16049         (plus:P (match_dup 1)
16050                 (const_int 1)))
16051    (unspec [(const_int 0)] UNSPEC_STOS)]
16052   "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16053   "%^stosb"
16054   [(set_attr "type" "str")
16055    (set_attr "memory" "store")
16056    (set (attr "prefix_rex")
16057         (if_then_else
16058           (match_test "<P:MODE>mode == DImode")
16059           (const_string "0")
16060           (const_string "*")))
16061    (set_attr "mode" "QI")])
16063 (define_expand "rep_stos"
16064   [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16065               (set (match_operand 0 "register_operand")
16066                    (match_operand 4))
16067               (set (match_operand 2 "memory_operand") (const_int 0))
16068               (use (match_operand 3 "register_operand"))
16069               (use (match_dup 1))])]
16070   ""
16071   "ix86_current_function_needs_cld = 1;")
16073 (define_insn "*rep_stosdi_rex64"
16074   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16075    (set (match_operand:P 0 "register_operand" "=D")
16076         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16077                           (const_int 3))
16078                  (match_operand:P 3 "register_operand" "0")))
16079    (set (mem:BLK (match_dup 3))
16080         (const_int 0))
16081    (use (match_operand:DI 2 "register_operand" "a"))
16082    (use (match_dup 4))]
16083   "TARGET_64BIT
16084    && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16085   "%^rep{%;} stosq"
16086   [(set_attr "type" "str")
16087    (set_attr "prefix_rep" "1")
16088    (set_attr "memory" "store")
16089    (set_attr "mode" "DI")])
16091 (define_insn "*rep_stossi"
16092   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16093    (set (match_operand:P 0 "register_operand" "=D")
16094         (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16095                           (const_int 2))
16096                  (match_operand:P 3 "register_operand" "0")))
16097    (set (mem:BLK (match_dup 3))
16098         (const_int 0))
16099    (use (match_operand:SI 2 "register_operand" "a"))
16100    (use (match_dup 4))]
16101   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16102   "%^rep{%;} stos{l|d}"
16103   [(set_attr "type" "str")
16104    (set_attr "prefix_rep" "1")
16105    (set_attr "memory" "store")
16106    (set_attr "mode" "SI")])
16108 (define_insn "*rep_stosqi"
16109   [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16110    (set (match_operand:P 0 "register_operand" "=D")
16111         (plus:P (match_operand:P 3 "register_operand" "0")
16112                 (match_operand:P 4 "register_operand" "1")))
16113    (set (mem:BLK (match_dup 3))
16114         (const_int 0))
16115    (use (match_operand:QI 2 "register_operand" "a"))
16116    (use (match_dup 4))]
16117   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16118   "%^rep{%;} stosb"
16119   [(set_attr "type" "str")
16120    (set_attr "prefix_rep" "1")
16121    (set_attr "memory" "store")
16122    (set (attr "prefix_rex")
16123         (if_then_else
16124           (match_test "<P:MODE>mode == DImode")
16125           (const_string "0")
16126           (const_string "*")))
16127    (set_attr "mode" "QI")])
16129 (define_expand "cmpstrnsi"
16130   [(set (match_operand:SI 0 "register_operand")
16131         (compare:SI (match_operand:BLK 1 "general_operand")
16132                     (match_operand:BLK 2 "general_operand")))
16133    (use (match_operand 3 "general_operand"))
16134    (use (match_operand 4 "immediate_operand"))]
16135   ""
16137   rtx addr1, addr2, out, outlow, count, countreg, align;
16139   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16140     FAIL;
16142   /* Can't use this if the user has appropriated ecx, esi or edi.  */
16143   if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16144     FAIL;
16146   out = operands[0];
16147   if (!REG_P (out))
16148     out = gen_reg_rtx (SImode);
16150   addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16151   addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16152   if (addr1 != XEXP (operands[1], 0))
16153     operands[1] = replace_equiv_address_nv (operands[1], addr1);
16154   if (addr2 != XEXP (operands[2], 0))
16155     operands[2] = replace_equiv_address_nv (operands[2], addr2);
16157   count = operands[3];
16158   countreg = ix86_zero_extend_to_Pmode (count);
16160   /* %%% Iff we are testing strict equality, we can use known alignment
16161      to good advantage.  This may be possible with combine, particularly
16162      once cc0 is dead.  */
16163   align = operands[4];
16165   if (CONST_INT_P (count))
16166     {
16167       if (INTVAL (count) == 0)
16168         {
16169           emit_move_insn (operands[0], const0_rtx);
16170           DONE;
16171         }
16172       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16173                                      operands[1], operands[2]));
16174     }
16175   else
16176     {
16177       rtx (*gen_cmp) (rtx, rtx);
16179       gen_cmp = (TARGET_64BIT
16180                  ? gen_cmpdi_1 : gen_cmpsi_1);
16182       emit_insn (gen_cmp (countreg, countreg));
16183       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16184                                   operands[1], operands[2]));
16185     }
16187   outlow = gen_lowpart (QImode, out);
16188   emit_insn (gen_cmpintqi (outlow));
16189   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16191   if (operands[0] != out)
16192     emit_move_insn (operands[0], out);
16194   DONE;
16197 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16199 (define_expand "cmpintqi"
16200   [(set (match_dup 1)
16201         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16202    (set (match_dup 2)
16203         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16204    (parallel [(set (match_operand:QI 0 "register_operand")
16205                    (minus:QI (match_dup 1)
16206                              (match_dup 2)))
16207               (clobber (reg:CC FLAGS_REG))])]
16208   ""
16210   operands[1] = gen_reg_rtx (QImode);
16211   operands[2] = gen_reg_rtx (QImode);
16214 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
16215 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
16217 (define_expand "cmpstrnqi_nz_1"
16218   [(parallel [(set (reg:CC FLAGS_REG)
16219                    (compare:CC (match_operand 4 "memory_operand")
16220                                (match_operand 5 "memory_operand")))
16221               (use (match_operand 2 "register_operand"))
16222               (use (match_operand:SI 3 "immediate_operand"))
16223               (clobber (match_operand 0 "register_operand"))
16224               (clobber (match_operand 1 "register_operand"))
16225               (clobber (match_dup 2))])]
16226   ""
16227   "ix86_current_function_needs_cld = 1;")
16229 (define_insn "*cmpstrnqi_nz_1"
16230   [(set (reg:CC FLAGS_REG)
16231         (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16232                     (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16233    (use (match_operand:P 6 "register_operand" "2"))
16234    (use (match_operand:SI 3 "immediate_operand" "i"))
16235    (clobber (match_operand:P 0 "register_operand" "=S"))
16236    (clobber (match_operand:P 1 "register_operand" "=D"))
16237    (clobber (match_operand:P 2 "register_operand" "=c"))]
16238   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16239   "%^repz{%;} cmpsb"
16240   [(set_attr "type" "str")
16241    (set_attr "mode" "QI")
16242    (set (attr "prefix_rex")
16243         (if_then_else
16244           (match_test "<P:MODE>mode == DImode")
16245           (const_string "0")
16246           (const_string "*")))
16247    (set_attr "prefix_rep" "1")])
16249 ;; The same, but the count is not known to not be zero.
16251 (define_expand "cmpstrnqi_1"
16252   [(parallel [(set (reg:CC FLAGS_REG)
16253                 (if_then_else:CC (ne (match_operand 2 "register_operand")
16254                                      (const_int 0))
16255                   (compare:CC (match_operand 4 "memory_operand")
16256                               (match_operand 5 "memory_operand"))
16257                   (const_int 0)))
16258               (use (match_operand:SI 3 "immediate_operand"))
16259               (use (reg:CC FLAGS_REG))
16260               (clobber (match_operand 0 "register_operand"))
16261               (clobber (match_operand 1 "register_operand"))
16262               (clobber (match_dup 2))])]
16263   ""
16264   "ix86_current_function_needs_cld = 1;")
16266 (define_insn "*cmpstrnqi_1"
16267   [(set (reg:CC FLAGS_REG)
16268         (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16269                              (const_int 0))
16270           (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16271                       (mem:BLK (match_operand:P 5 "register_operand" "1")))
16272           (const_int 0)))
16273    (use (match_operand:SI 3 "immediate_operand" "i"))
16274    (use (reg:CC FLAGS_REG))
16275    (clobber (match_operand:P 0 "register_operand" "=S"))
16276    (clobber (match_operand:P 1 "register_operand" "=D"))
16277    (clobber (match_operand:P 2 "register_operand" "=c"))]
16278   "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16279   "%^repz{%;} cmpsb"
16280   [(set_attr "type" "str")
16281    (set_attr "mode" "QI")
16282    (set (attr "prefix_rex")
16283         (if_then_else
16284           (match_test "<P:MODE>mode == DImode")
16285           (const_string "0")
16286           (const_string "*")))
16287    (set_attr "prefix_rep" "1")])
16289 (define_expand "strlen<mode>"
16290   [(set (match_operand:P 0 "register_operand")
16291         (unspec:P [(match_operand:BLK 1 "general_operand")
16292                    (match_operand:QI 2 "immediate_operand")
16293                    (match_operand 3 "immediate_operand")]
16294                   UNSPEC_SCAS))]
16295   ""
16297  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16298    DONE;
16299  else
16300    FAIL;
16303 (define_expand "strlenqi_1"
16304   [(parallel [(set (match_operand 0 "register_operand")
16305                    (match_operand 2))
16306               (clobber (match_operand 1 "register_operand"))
16307               (clobber (reg:CC FLAGS_REG))])]
16308   ""
16309   "ix86_current_function_needs_cld = 1;")
16311 (define_insn "*strlenqi_1"
16312   [(set (match_operand:P 0 "register_operand" "=&c")
16313         (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16314                    (match_operand:QI 2 "register_operand" "a")
16315                    (match_operand:P 3 "immediate_operand" "i")
16316                    (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16317    (clobber (match_operand:P 1 "register_operand" "=D"))
16318    (clobber (reg:CC FLAGS_REG))]
16319   "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16320   "%^repnz{%;} scasb"
16321   [(set_attr "type" "str")
16322    (set_attr "mode" "QI")
16323    (set (attr "prefix_rex")
16324         (if_then_else
16325           (match_test "<P:MODE>mode == DImode")
16326           (const_string "0")
16327           (const_string "*")))
16328    (set_attr "prefix_rep" "1")])
16330 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
16331 ;; handled in combine, but it is not currently up to the task.
16332 ;; When used for their truth value, the cmpstrn* expanders generate
16333 ;; code like this:
16335 ;;   repz cmpsb
16336 ;;   seta       %al
16337 ;;   setb       %dl
16338 ;;   cmpb       %al, %dl
16339 ;;   jcc        label
16341 ;; The intermediate three instructions are unnecessary.
16343 ;; This one handles cmpstrn*_nz_1...
16344 (define_peephole2
16345   [(parallel[
16346      (set (reg:CC FLAGS_REG)
16347           (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16348                       (mem:BLK (match_operand 5 "register_operand"))))
16349      (use (match_operand 6 "register_operand"))
16350      (use (match_operand:SI 3 "immediate_operand"))
16351      (clobber (match_operand 0 "register_operand"))
16352      (clobber (match_operand 1 "register_operand"))
16353      (clobber (match_operand 2 "register_operand"))])
16354    (set (match_operand:QI 7 "register_operand")
16355         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16356    (set (match_operand:QI 8 "register_operand")
16357         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16358    (set (reg FLAGS_REG)
16359         (compare (match_dup 7) (match_dup 8)))
16360   ]
16361   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16362   [(parallel[
16363      (set (reg:CC FLAGS_REG)
16364           (compare:CC (mem:BLK (match_dup 4))
16365                       (mem:BLK (match_dup 5))))
16366      (use (match_dup 6))
16367      (use (match_dup 3))
16368      (clobber (match_dup 0))
16369      (clobber (match_dup 1))
16370      (clobber (match_dup 2))])])
16372 ;; ...and this one handles cmpstrn*_1.
16373 (define_peephole2
16374   [(parallel[
16375      (set (reg:CC FLAGS_REG)
16376           (if_then_else:CC (ne (match_operand 6 "register_operand")
16377                                (const_int 0))
16378             (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16379                         (mem:BLK (match_operand 5 "register_operand")))
16380             (const_int 0)))
16381      (use (match_operand:SI 3 "immediate_operand"))
16382      (use (reg:CC FLAGS_REG))
16383      (clobber (match_operand 0 "register_operand"))
16384      (clobber (match_operand 1 "register_operand"))
16385      (clobber (match_operand 2 "register_operand"))])
16386    (set (match_operand:QI 7 "register_operand")
16387         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16388    (set (match_operand:QI 8 "register_operand")
16389         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16390    (set (reg FLAGS_REG)
16391         (compare (match_dup 7) (match_dup 8)))
16392   ]
16393   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16394   [(parallel[
16395      (set (reg:CC FLAGS_REG)
16396           (if_then_else:CC (ne (match_dup 6)
16397                                (const_int 0))
16398             (compare:CC (mem:BLK (match_dup 4))
16399                         (mem:BLK (match_dup 5)))
16400             (const_int 0)))
16401      (use (match_dup 3))
16402      (use (reg:CC FLAGS_REG))
16403      (clobber (match_dup 0))
16404      (clobber (match_dup 1))
16405      (clobber (match_dup 2))])])
16407 ;; Conditional move instructions.
16409 (define_expand "mov<mode>cc"
16410   [(set (match_operand:SWIM 0 "register_operand")
16411         (if_then_else:SWIM (match_operand 1 "comparison_operator")
16412                            (match_operand:SWIM 2 "<general_operand>")
16413                            (match_operand:SWIM 3 "<general_operand>")))]
16414   ""
16415   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16417 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16418 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16419 ;; So just document what we're doing explicitly.
16421 (define_expand "x86_mov<mode>cc_0_m1"
16422   [(parallel
16423     [(set (match_operand:SWI48 0 "register_operand")
16424           (if_then_else:SWI48
16425             (match_operator:SWI48 2 "ix86_carry_flag_operator"
16426              [(match_operand 1 "flags_reg_operand")
16427               (const_int 0)])
16428             (const_int -1)
16429             (const_int 0)))
16430      (clobber (reg:CC FLAGS_REG))])])
16432 (define_insn "*x86_mov<mode>cc_0_m1"
16433   [(set (match_operand:SWI48 0 "register_operand" "=r")
16434         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16435                              [(reg FLAGS_REG) (const_int 0)])
16436           (const_int -1)
16437           (const_int 0)))
16438    (clobber (reg:CC FLAGS_REG))]
16439   ""
16440   "sbb{<imodesuffix>}\t%0, %0"
16441   ; Since we don't have the proper number of operands for an alu insn,
16442   ; fill in all the blanks.
16443   [(set_attr "type" "alu")
16444    (set_attr "use_carry" "1")
16445    (set_attr "pent_pair" "pu")
16446    (set_attr "memory" "none")
16447    (set_attr "imm_disp" "false")
16448    (set_attr "mode" "<MODE>")
16449    (set_attr "length_immediate" "0")])
16451 (define_insn "*x86_mov<mode>cc_0_m1_se"
16452   [(set (match_operand:SWI48 0 "register_operand" "=r")
16453         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16454                              [(reg FLAGS_REG) (const_int 0)])
16455                             (const_int 1)
16456                             (const_int 0)))
16457    (clobber (reg:CC FLAGS_REG))]
16458   ""
16459   "sbb{<imodesuffix>}\t%0, %0"
16460   [(set_attr "type" "alu")
16461    (set_attr "use_carry" "1")
16462    (set_attr "pent_pair" "pu")
16463    (set_attr "memory" "none")
16464    (set_attr "imm_disp" "false")
16465    (set_attr "mode" "<MODE>")
16466    (set_attr "length_immediate" "0")])
16468 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16469   [(set (match_operand:SWI48 0 "register_operand" "=r")
16470         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16471                     [(reg FLAGS_REG) (const_int 0)])))
16472    (clobber (reg:CC FLAGS_REG))]
16473   ""
16474   "sbb{<imodesuffix>}\t%0, %0"
16475   [(set_attr "type" "alu")
16476    (set_attr "use_carry" "1")
16477    (set_attr "pent_pair" "pu")
16478    (set_attr "memory" "none")
16479    (set_attr "imm_disp" "false")
16480    (set_attr "mode" "<MODE>")
16481    (set_attr "length_immediate" "0")])
16483 (define_insn "*mov<mode>cc_noc"
16484   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16485         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16486                                [(reg FLAGS_REG) (const_int 0)])
16487           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16488           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16489   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16490   "@
16491    cmov%O2%C1\t{%2, %0|%0, %2}
16492    cmov%O2%c1\t{%3, %0|%0, %3}"
16493   [(set_attr "type" "icmov")
16494    (set_attr "mode" "<MODE>")])
16496 ;; Don't do conditional moves with memory inputs.  This splitter helps
16497 ;; register starved x86_32 by forcing inputs into registers before reload.
16498 (define_split
16499   [(set (match_operand:SWI248 0 "register_operand")
16500         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16501                                [(reg FLAGS_REG) (const_int 0)])
16502           (match_operand:SWI248 2 "nonimmediate_operand")
16503           (match_operand:SWI248 3 "nonimmediate_operand")))]
16504   "!TARGET_64BIT && TARGET_CMOVE
16505    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16506    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16507    && can_create_pseudo_p ()
16508    && optimize_insn_for_speed_p ()"
16509   [(set (match_dup 0)
16510         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16512   if (MEM_P (operands[2]))
16513     operands[2] = force_reg (<MODE>mode, operands[2]);
16514   if (MEM_P (operands[3]))
16515     operands[3] = force_reg (<MODE>mode, operands[3]);
16518 (define_insn "*movqicc_noc"
16519   [(set (match_operand:QI 0 "register_operand" "=r,r")
16520         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16521                            [(reg FLAGS_REG) (const_int 0)])
16522                       (match_operand:QI 2 "register_operand" "r,0")
16523                       (match_operand:QI 3 "register_operand" "0,r")))]
16524   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16525   "#"
16526   [(set_attr "type" "icmov")
16527    (set_attr "mode" "QI")])
16529 (define_split
16530   [(set (match_operand:SWI12 0 "register_operand")
16531         (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16532                               [(reg FLAGS_REG) (const_int 0)])
16533                       (match_operand:SWI12 2 "register_operand")
16534                       (match_operand:SWI12 3 "register_operand")))]
16535   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16536    && reload_completed"
16537   [(set (match_dup 0)
16538         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16540   operands[0] = gen_lowpart (SImode, operands[0]);
16541   operands[2] = gen_lowpart (SImode, operands[2]);
16542   operands[3] = gen_lowpart (SImode, operands[3]);
16545 ;; Don't do conditional moves with memory inputs
16546 (define_peephole2
16547   [(match_scratch:SWI248 2 "r")
16548    (set (match_operand:SWI248 0 "register_operand")
16549         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16550                                [(reg FLAGS_REG) (const_int 0)])
16551           (match_dup 0)
16552           (match_operand:SWI248 3 "memory_operand")))]
16553   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16554    && optimize_insn_for_speed_p ()"
16555   [(set (match_dup 2) (match_dup 3))
16556    (set (match_dup 0)
16557         (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16559 (define_peephole2
16560   [(match_scratch:SWI248 2 "r")
16561    (set (match_operand:SWI248 0 "register_operand")
16562         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16563                                [(reg FLAGS_REG) (const_int 0)])
16564           (match_operand:SWI248 3 "memory_operand")
16565           (match_dup 0)))]
16566   "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16567    && optimize_insn_for_speed_p ()"
16568   [(set (match_dup 2) (match_dup 3))
16569    (set (match_dup 0)
16570         (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16572 (define_expand "mov<mode>cc"
16573   [(set (match_operand:X87MODEF 0 "register_operand")
16574         (if_then_else:X87MODEF
16575           (match_operand 1 "comparison_operator")
16576           (match_operand:X87MODEF 2 "register_operand")
16577           (match_operand:X87MODEF 3 "register_operand")))]
16578   "(TARGET_80387 && TARGET_CMOVE)
16579    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16580   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16582 (define_insn "*movxfcc_1"
16583   [(set (match_operand:XF 0 "register_operand" "=f,f")
16584         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16585                                 [(reg FLAGS_REG) (const_int 0)])
16586                       (match_operand:XF 2 "register_operand" "f,0")
16587                       (match_operand:XF 3 "register_operand" "0,f")))]
16588   "TARGET_80387 && TARGET_CMOVE"
16589   "@
16590    fcmov%F1\t{%2, %0|%0, %2}
16591    fcmov%f1\t{%3, %0|%0, %3}"
16592   [(set_attr "type" "fcmov")
16593    (set_attr "mode" "XF")])
16595 (define_insn "*movdfcc_1"
16596   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
16597         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16598                                 [(reg FLAGS_REG) (const_int 0)])
16599                       (match_operand:DF 2 "nonimmediate_operand"
16600                                                "f ,0,rm,0 ,rm,0")
16601                       (match_operand:DF 3 "nonimmediate_operand"
16602                                                "0 ,f,0 ,rm,0, rm")))]
16603   "TARGET_80387 && TARGET_CMOVE
16604    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16605   "@
16606    fcmov%F1\t{%2, %0|%0, %2}
16607    fcmov%f1\t{%3, %0|%0, %3}
16608    #
16609    #
16610    cmov%O2%C1\t{%2, %0|%0, %2}
16611    cmov%O2%c1\t{%3, %0|%0, %3}"
16612   [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
16613    (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
16614    (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
16616 (define_split
16617   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16618         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16619                                 [(reg FLAGS_REG) (const_int 0)])
16620                       (match_operand:DF 2 "nonimmediate_operand")
16621                       (match_operand:DF 3 "nonimmediate_operand")))]
16622   "!TARGET_64BIT && reload_completed"
16623   [(set (match_dup 2)
16624         (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16625    (set (match_dup 3)
16626         (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16628   split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16629   split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16632 (define_insn "*movsfcc_1_387"
16633   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16634         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16635                                 [(reg FLAGS_REG) (const_int 0)])
16636                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16637                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16638   "TARGET_80387 && TARGET_CMOVE
16639    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16640   "@
16641    fcmov%F1\t{%2, %0|%0, %2}
16642    fcmov%f1\t{%3, %0|%0, %3}
16643    cmov%O2%C1\t{%2, %0|%0, %2}
16644    cmov%O2%c1\t{%3, %0|%0, %3}"
16645   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16646    (set_attr "mode" "SF,SF,SI,SI")])
16648 ;; Don't do conditional moves with memory inputs.  This splitter helps
16649 ;; register starved x86_32 by forcing inputs into registers before reload.
16650 (define_split
16651   [(set (match_operand:MODEF 0 "register_operand")
16652         (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16653                               [(reg FLAGS_REG) (const_int 0)])
16654           (match_operand:MODEF 2 "nonimmediate_operand")
16655           (match_operand:MODEF 3 "nonimmediate_operand")))]
16656   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16657    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16658    && (MEM_P (operands[2]) || MEM_P (operands[3]))
16659    && can_create_pseudo_p ()
16660    && optimize_insn_for_speed_p ()"
16661   [(set (match_dup 0)
16662         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16664   if (MEM_P (operands[2]))
16665     operands[2] = force_reg (<MODE>mode, operands[2]);
16666   if (MEM_P (operands[3]))
16667     operands[3] = force_reg (<MODE>mode, operands[3]);
16670 ;; Don't do conditional moves with memory inputs
16671 (define_peephole2
16672   [(match_scratch:MODEF 2 "r")
16673    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16674         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16675                               [(reg FLAGS_REG) (const_int 0)])
16676           (match_dup 0)
16677           (match_operand:MODEF 3 "memory_operand")))]
16678   "(<MODE>mode != DFmode || TARGET_64BIT)
16679    && TARGET_80387 && TARGET_CMOVE
16680    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16681    && optimize_insn_for_speed_p ()"
16682   [(set (match_dup 2) (match_dup 3))
16683    (set (match_dup 0)
16684         (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16686 (define_peephole2
16687   [(match_scratch:MODEF 2 "r")
16688    (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16689         (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16690                               [(reg FLAGS_REG) (const_int 0)])
16691           (match_operand:MODEF 3 "memory_operand")
16692           (match_dup 0)))]
16693   "(<MODE>mode != DFmode || TARGET_64BIT)
16694    && TARGET_80387 && TARGET_CMOVE
16695    && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16696    && optimize_insn_for_speed_p ()"
16697   [(set (match_dup 2) (match_dup 3))
16698    (set (match_dup 0)
16699         (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16701 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16702 ;; the scalar versions to have only XMM registers as operands.
16704 ;; XOP conditional move
16705 (define_insn "*xop_pcmov_<mode>"
16706   [(set (match_operand:MODEF 0 "register_operand" "=x")
16707         (if_then_else:MODEF
16708           (match_operand:MODEF 1 "register_operand" "x")
16709           (match_operand:MODEF 2 "register_operand" "x")
16710           (match_operand:MODEF 3 "register_operand" "x")))]
16711   "TARGET_XOP"
16712   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16713   [(set_attr "type" "sse4arg")])
16715 ;; These versions of the min/max patterns are intentionally ignorant of
16716 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16717 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16718 ;; are undefined in this condition, we're certain this is correct.
16720 (define_insn "<code><mode>3"
16721   [(set (match_operand:MODEF 0 "register_operand" "=x,v")
16722         (smaxmin:MODEF
16723           (match_operand:MODEF 1 "nonimmediate_operand" "%0,v")
16724           (match_operand:MODEF 2 "nonimmediate_operand" "xm,vm")))]
16725   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16726   "@
16727    <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16728    v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16729   [(set_attr "isa" "noavx,avx")
16730    (set_attr "prefix" "orig,vex")
16731    (set_attr "type" "sseadd")
16732    (set_attr "mode" "<MODE>")])
16734 ;; These versions of the min/max patterns implement exactly the operations
16735 ;;   min = (op1 < op2 ? op1 : op2)
16736 ;;   max = (!(op1 < op2) ? op1 : op2)
16737 ;; Their operands are not commutative, and thus they may be used in the
16738 ;; presence of -0.0 and NaN.
16740 (define_int_iterator IEEE_MAXMIN
16741         [UNSPEC_IEEE_MAX
16742          UNSPEC_IEEE_MIN])
16744 (define_int_attr ieee_maxmin
16745         [(UNSPEC_IEEE_MAX "max")
16746          (UNSPEC_IEEE_MIN "min")])
16748 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16749   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16750         (unspec:MODEF
16751           [(match_operand:MODEF 1 "register_operand" "0,x")
16752            (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16753           IEEE_MAXMIN))]
16754   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16755   "@
16756    <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16757    v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16758   [(set_attr "isa" "noavx,avx")
16759    (set_attr "prefix" "orig,vex")
16760    (set_attr "type" "sseadd")
16761    (set_attr "mode" "<MODE>")])
16763 ;; Make two stack loads independent:
16764 ;;   fld aa              fld aa
16765 ;;   fld %st(0)     ->   fld bb
16766 ;;   fmul bb             fmul %st(1), %st
16768 ;; Actually we only match the last two instructions for simplicity.
16769 (define_peephole2
16770   [(set (match_operand 0 "fp_register_operand")
16771         (match_operand 1 "fp_register_operand"))
16772    (set (match_dup 0)
16773         (match_operator 2 "binary_fp_operator"
16774            [(match_dup 0)
16775             (match_operand 3 "memory_operand")]))]
16776   "REGNO (operands[0]) != REGNO (operands[1])"
16777   [(set (match_dup 0) (match_dup 3))
16778    (set (match_dup 0) (match_dup 4))]
16780   ;; The % modifier is not operational anymore in peephole2's, so we have to
16781   ;; swap the operands manually in the case of addition and multiplication.
16783   rtx op0, op1;
16785   if (COMMUTATIVE_ARITH_P (operands[2]))
16786     op0 = operands[0], op1 = operands[1];
16787   else
16788     op0 = operands[1], op1 = operands[0];
16790   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16791                                 GET_MODE (operands[2]),
16792                                 op0, op1);
16795 ;; Conditional addition patterns
16796 (define_expand "add<mode>cc"
16797   [(match_operand:SWI 0 "register_operand")
16798    (match_operand 1 "ordered_comparison_operator")
16799    (match_operand:SWI 2 "register_operand")
16800    (match_operand:SWI 3 "const_int_operand")]
16801   ""
16802   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16804 ;; Misc patterns (?)
16806 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16807 ;; Otherwise there will be nothing to keep
16809 ;; [(set (reg ebp) (reg esp))]
16810 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16811 ;;  (clobber (eflags)]
16812 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16814 ;; in proper program order.
16816 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16817   [(set (match_operand:P 0 "register_operand" "=r,r")
16818         (plus:P (match_operand:P 1 "register_operand" "0,r")
16819                 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16820    (clobber (reg:CC FLAGS_REG))
16821    (clobber (mem:BLK (scratch)))]
16822   ""
16824   switch (get_attr_type (insn))
16825     {
16826     case TYPE_IMOV:
16827       return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16829     case TYPE_ALU:
16830       gcc_assert (rtx_equal_p (operands[0], operands[1]));
16831       if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16832         return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16834       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16836     default:
16837       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16838       return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16839     }
16841   [(set (attr "type")
16842         (cond [(and (eq_attr "alternative" "0")
16843                     (not (match_test "TARGET_OPT_AGU")))
16844                  (const_string "alu")
16845                (match_operand:<MODE> 2 "const0_operand")
16846                  (const_string "imov")
16847               ]
16848               (const_string "lea")))
16849    (set (attr "length_immediate")
16850         (cond [(eq_attr "type" "imov")
16851                  (const_string "0")
16852                (and (eq_attr "type" "alu")
16853                     (match_operand 2 "const128_operand"))
16854                  (const_string "1")
16855               ]
16856               (const_string "*")))
16857    (set_attr "mode" "<MODE>")])
16859 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16860   [(set (match_operand:P 0 "register_operand" "=r")
16861         (minus:P (match_operand:P 1 "register_operand" "0")
16862                  (match_operand:P 2 "register_operand" "r")))
16863    (clobber (reg:CC FLAGS_REG))
16864    (clobber (mem:BLK (scratch)))]
16865   ""
16866   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16867   [(set_attr "type" "alu")
16868    (set_attr "mode" "<MODE>")])
16870 (define_insn "allocate_stack_worker_probe_<mode>"
16871   [(set (match_operand:P 0 "register_operand" "=a")
16872         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16873                             UNSPECV_STACK_PROBE))
16874    (clobber (reg:CC FLAGS_REG))]
16875   "ix86_target_stack_probe ()"
16876   "call\t___chkstk_ms"
16877   [(set_attr "type" "multi")
16878    (set_attr "length" "5")])
16880 (define_expand "allocate_stack"
16881   [(match_operand 0 "register_operand")
16882    (match_operand 1 "general_operand")]
16883   "ix86_target_stack_probe ()"
16885   rtx x;
16887 #ifndef CHECK_STACK_LIMIT
16888 #define CHECK_STACK_LIMIT 0
16889 #endif
16891   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16892       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16893     x = operands[1];
16894   else
16895     {
16896       rtx (*insn) (rtx, rtx);
16898       x = copy_to_mode_reg (Pmode, operands[1]);
16900       insn = (TARGET_64BIT
16901               ? gen_allocate_stack_worker_probe_di
16902               : gen_allocate_stack_worker_probe_si);
16904       emit_insn (insn (x, x));
16905     }
16907   x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16908                            stack_pointer_rtx, 0, OPTAB_DIRECT);
16910   if (x != stack_pointer_rtx)
16911     emit_move_insn (stack_pointer_rtx, x);
16913   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16914   DONE;
16917 ;; Use IOR for stack probes, this is shorter.
16918 (define_expand "probe_stack"
16919   [(match_operand 0 "memory_operand")]
16920   ""
16922   rtx (*gen_ior3) (rtx, rtx, rtx);
16924   gen_ior3 = (GET_MODE (operands[0]) == DImode
16925               ? gen_iordi3 : gen_iorsi3);
16927   emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16928   DONE;
16931 (define_insn "adjust_stack_and_probe<mode>"
16932   [(set (match_operand:P 0 "register_operand" "=r")
16933         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16934                             UNSPECV_PROBE_STACK_RANGE))
16935    (set (reg:P SP_REG)
16936         (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16937    (clobber (reg:CC FLAGS_REG))
16938    (clobber (mem:BLK (scratch)))]
16939   ""
16940   "* return output_adjust_stack_and_probe (operands[0]);"
16941   [(set_attr "type" "multi")])
16943 (define_insn "probe_stack_range<mode>"
16944   [(set (match_operand:P 0 "register_operand" "=r")
16945         (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16946                             (match_operand:P 2 "const_int_operand" "n")]
16947                             UNSPECV_PROBE_STACK_RANGE))
16948    (clobber (reg:CC FLAGS_REG))]
16949   ""
16950   "* return output_probe_stack_range (operands[0], operands[2]);"
16951   [(set_attr "type" "multi")])
16953 (define_expand "builtin_setjmp_receiver"
16954   [(label_ref (match_operand 0))]
16955   "!TARGET_64BIT && flag_pic"
16957 #if TARGET_MACHO
16958   if (TARGET_MACHO)
16959     {
16960       rtx xops[3];
16961       rtx_code_label *label_rtx = gen_label_rtx ();
16962       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16963       xops[0] = xops[1] = pic_offset_table_rtx;
16964       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16965       ix86_expand_binary_operator (MINUS, SImode, xops);
16966     }
16967   else
16968 #endif
16969     emit_insn (gen_set_got (pic_offset_table_rtx));
16970   DONE;
16973 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16974 ;; Do not split instructions with mask registers.
16975 (define_split
16976   [(set (match_operand 0 "general_reg_operand")
16977         (match_operator 3 "promotable_binary_operator"
16978            [(match_operand 1 "general_reg_operand")
16979             (match_operand 2 "aligned_operand")]))
16980    (clobber (reg:CC FLAGS_REG))]
16981   "! TARGET_PARTIAL_REG_STALL && reload_completed
16982    && ((GET_MODE (operands[0]) == HImode
16983         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16984             /* ??? next two lines just !satisfies_constraint_K (...) */
16985             || !CONST_INT_P (operands[2])
16986             || satisfies_constraint_K (operands[2])))
16987        || (GET_MODE (operands[0]) == QImode
16988            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16989   [(parallel [(set (match_dup 0)
16990                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16991               (clobber (reg:CC FLAGS_REG))])]
16993   operands[0] = gen_lowpart (SImode, operands[0]);
16994   operands[1] = gen_lowpart (SImode, operands[1]);
16995   if (GET_CODE (operands[3]) != ASHIFT)
16996     operands[2] = gen_lowpart (SImode, operands[2]);
16997   PUT_MODE (operands[3], SImode);
17000 ; Promote the QImode tests, as i386 has encoding of the AND
17001 ; instruction with 32-bit sign-extended immediate and thus the
17002 ; instruction size is unchanged, except in the %eax case for
17003 ; which it is increased by one byte, hence the ! optimize_size.
17004 (define_split
17005   [(set (match_operand 0 "flags_reg_operand")
17006         (match_operator 2 "compare_operator"
17007           [(and (match_operand 3 "aligned_operand")
17008                 (match_operand 4 "const_int_operand"))
17009            (const_int 0)]))
17010    (set (match_operand 1 "register_operand")
17011         (and (match_dup 3) (match_dup 4)))]
17012   "! TARGET_PARTIAL_REG_STALL && reload_completed
17013    && optimize_insn_for_speed_p ()
17014    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
17015        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
17016    /* Ensure that the operand will remain sign-extended immediate.  */
17017    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
17018   [(parallel [(set (match_dup 0)
17019                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
17020                                     (const_int 0)]))
17021               (set (match_dup 1)
17022                    (and:SI (match_dup 3) (match_dup 4)))])]
17024   operands[4]
17025     = gen_int_mode (INTVAL (operands[4])
17026                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
17027   operands[1] = gen_lowpart (SImode, operands[1]);
17028   operands[3] = gen_lowpart (SImode, operands[3]);
17031 ; Don't promote the QImode tests, as i386 doesn't have encoding of
17032 ; the TEST instruction with 32-bit sign-extended immediate and thus
17033 ; the instruction size would at least double, which is not what we
17034 ; want even with ! optimize_size.
17035 (define_split
17036   [(set (match_operand 0 "flags_reg_operand")
17037         (match_operator 1 "compare_operator"
17038           [(and (match_operand:HI 2 "aligned_operand")
17039                 (match_operand:HI 3 "const_int_operand"))
17040            (const_int 0)]))]
17041   "! TARGET_PARTIAL_REG_STALL && reload_completed
17042    && ! TARGET_FAST_PREFIX
17043    && optimize_insn_for_speed_p ()
17044    /* Ensure that the operand will remain sign-extended immediate.  */
17045    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
17046   [(set (match_dup 0)
17047         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17048                          (const_int 0)]))]
17050   operands[3]
17051     = gen_int_mode (INTVAL (operands[3])
17052                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
17053   operands[2] = gen_lowpart (SImode, operands[2]);
17056 (define_split
17057   [(set (match_operand 0 "register_operand")
17058         (neg (match_operand 1 "register_operand")))
17059    (clobber (reg:CC FLAGS_REG))]
17060   "! TARGET_PARTIAL_REG_STALL && reload_completed
17061    && (GET_MODE (operands[0]) == HImode
17062        || (GET_MODE (operands[0]) == QImode
17063            && (TARGET_PROMOTE_QImode
17064                || optimize_insn_for_size_p ())))"
17065   [(parallel [(set (match_dup 0)
17066                    (neg:SI (match_dup 1)))
17067               (clobber (reg:CC FLAGS_REG))])]
17069   operands[0] = gen_lowpart (SImode, operands[0]);
17070   operands[1] = gen_lowpart (SImode, operands[1]);
17073 ;; Do not split instructions with mask regs.
17074 (define_split
17075   [(set (match_operand 0 "general_reg_operand")
17076         (not (match_operand 1 "general_reg_operand")))]
17077   "! TARGET_PARTIAL_REG_STALL && reload_completed
17078    && (GET_MODE (operands[0]) == HImode
17079        || (GET_MODE (operands[0]) == QImode
17080            && (TARGET_PROMOTE_QImode
17081                || optimize_insn_for_size_p ())))"
17082   [(set (match_dup 0)
17083         (not:SI (match_dup 1)))]
17085   operands[0] = gen_lowpart (SImode, operands[0]);
17086   operands[1] = gen_lowpart (SImode, operands[1]);
17089 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
17090 ;; transform a complex memory operation into two memory to register operations.
17092 ;; Don't push memory operands
17093 (define_peephole2
17094   [(set (match_operand:SWI 0 "push_operand")
17095         (match_operand:SWI 1 "memory_operand"))
17096    (match_scratch:SWI 2 "<r>")]
17097   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17098    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17099   [(set (match_dup 2) (match_dup 1))
17100    (set (match_dup 0) (match_dup 2))])
17102 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17103 ;; SImode pushes.
17104 (define_peephole2
17105   [(set (match_operand:SF 0 "push_operand")
17106         (match_operand:SF 1 "memory_operand"))
17107    (match_scratch:SF 2 "r")]
17108   "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17109    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17110   [(set (match_dup 2) (match_dup 1))
17111    (set (match_dup 0) (match_dup 2))])
17113 ;; Don't move an immediate directly to memory when the instruction
17114 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17115 (define_peephole2
17116   [(match_scratch:SWI124 1 "<r>")
17117    (set (match_operand:SWI124 0 "memory_operand")
17118         (const_int 0))]
17119   "optimize_insn_for_speed_p ()
17120    && ((<MODE>mode == HImode
17121        && TARGET_LCP_STALL)
17122        || (!TARGET_USE_MOV0
17123           && TARGET_SPLIT_LONG_MOVES
17124           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17125    && peep2_regno_dead_p (0, FLAGS_REG)"
17126   [(parallel [(set (match_dup 2) (const_int 0))
17127               (clobber (reg:CC FLAGS_REG))])
17128    (set (match_dup 0) (match_dup 1))]
17129   "operands[2] = gen_lowpart (SImode, operands[1]);")
17131 (define_peephole2
17132   [(match_scratch:SWI124 2 "<r>")
17133    (set (match_operand:SWI124 0 "memory_operand")
17134         (match_operand:SWI124 1 "immediate_operand"))]
17135   "optimize_insn_for_speed_p ()
17136    && ((<MODE>mode == HImode
17137        && TARGET_LCP_STALL)
17138        || (TARGET_SPLIT_LONG_MOVES
17139           && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17140   [(set (match_dup 2) (match_dup 1))
17141    (set (match_dup 0) (match_dup 2))])
17143 ;; Don't compare memory with zero, load and use a test instead.
17144 (define_peephole2
17145   [(set (match_operand 0 "flags_reg_operand")
17146         (match_operator 1 "compare_operator"
17147           [(match_operand:SI 2 "memory_operand")
17148            (const_int 0)]))
17149    (match_scratch:SI 3 "r")]
17150   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17151   [(set (match_dup 3) (match_dup 2))
17152    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17154 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17155 ;; Don't split NOTs with a displacement operand, because resulting XOR
17156 ;; will not be pairable anyway.
17158 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17159 ;; represented using a modRM byte.  The XOR replacement is long decoded,
17160 ;; so this split helps here as well.
17162 ;; Note: Can't do this as a regular split because we can't get proper
17163 ;; lifetime information then.
17165 (define_peephole2
17166   [(set (match_operand:SWI124 0 "nonimmediate_operand")
17167         (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17168   "optimize_insn_for_speed_p ()
17169    && ((TARGET_NOT_UNPAIRABLE
17170         && (!MEM_P (operands[0])
17171             || !memory_displacement_operand (operands[0], <MODE>mode)))
17172        || (TARGET_NOT_VECTORMODE
17173            && long_memory_operand (operands[0], <MODE>mode)))
17174    && peep2_regno_dead_p (0, FLAGS_REG)"
17175   [(parallel [(set (match_dup 0)
17176                    (xor:SWI124 (match_dup 1) (const_int -1)))
17177               (clobber (reg:CC FLAGS_REG))])])
17179 ;; Non pairable "test imm, reg" instructions can be translated to
17180 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
17181 ;; byte opcode instead of two, have a short form for byte operands),
17182 ;; so do it for other CPUs as well.  Given that the value was dead,
17183 ;; this should not create any new dependencies.  Pass on the sub-word
17184 ;; versions if we're concerned about partial register stalls.
17186 (define_peephole2
17187   [(set (match_operand 0 "flags_reg_operand")
17188         (match_operator 1 "compare_operator"
17189           [(and:SI (match_operand:SI 2 "register_operand")
17190                    (match_operand:SI 3 "immediate_operand"))
17191            (const_int 0)]))]
17192   "ix86_match_ccmode (insn, CCNOmode)
17193    && (true_regnum (operands[2]) != AX_REG
17194        || satisfies_constraint_K (operands[3]))
17195    && peep2_reg_dead_p (1, operands[2])"
17196   [(parallel
17197      [(set (match_dup 0)
17198            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17199                             (const_int 0)]))
17200       (set (match_dup 2)
17201            (and:SI (match_dup 2) (match_dup 3)))])])
17203 ;; We don't need to handle HImode case, because it will be promoted to SImode
17204 ;; on ! TARGET_PARTIAL_REG_STALL
17206 (define_peephole2
17207   [(set (match_operand 0 "flags_reg_operand")
17208         (match_operator 1 "compare_operator"
17209           [(and:QI (match_operand:QI 2 "register_operand")
17210                    (match_operand:QI 3 "immediate_operand"))
17211            (const_int 0)]))]
17212   "! TARGET_PARTIAL_REG_STALL
17213    && ix86_match_ccmode (insn, CCNOmode)
17214    && true_regnum (operands[2]) != AX_REG
17215    && peep2_reg_dead_p (1, operands[2])"
17216   [(parallel
17217      [(set (match_dup 0)
17218            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17219                             (const_int 0)]))
17220       (set (match_dup 2)
17221            (and:QI (match_dup 2) (match_dup 3)))])])
17223 (define_peephole2
17224   [(set (match_operand 0 "flags_reg_operand")
17225         (match_operator 1 "compare_operator"
17226           [(and:SI
17227              (zero_extract:SI
17228                (match_operand 2 "ext_register_operand")
17229                (const_int 8)
17230                (const_int 8))
17231              (match_operand 3 "const_int_operand"))
17232            (const_int 0)]))]
17233   "! TARGET_PARTIAL_REG_STALL
17234    && ix86_match_ccmode (insn, CCNOmode)
17235    && true_regnum (operands[2]) != AX_REG
17236    && peep2_reg_dead_p (1, operands[2])"
17237   [(parallel [(set (match_dup 0)
17238                    (match_op_dup 1
17239                      [(and:SI
17240                         (zero_extract:SI
17241                           (match_dup 2)
17242                           (const_int 8)
17243                           (const_int 8))
17244                         (match_dup 3))
17245                       (const_int 0)]))
17246               (set (zero_extract:SI (match_dup 2)
17247                                     (const_int 8)
17248                                     (const_int 8))
17249                    (and:SI
17250                      (zero_extract:SI
17251                        (match_dup 2)
17252                        (const_int 8)
17253                        (const_int 8))
17254                      (match_dup 3)))])])
17256 ;; Don't do logical operations with memory inputs.
17257 (define_peephole2
17258   [(match_scratch:SI 2 "r")
17259    (parallel [(set (match_operand:SI 0 "register_operand")
17260                    (match_operator:SI 3 "arith_or_logical_operator"
17261                      [(match_dup 0)
17262                       (match_operand:SI 1 "memory_operand")]))
17263               (clobber (reg:CC FLAGS_REG))])]
17264   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17265   [(set (match_dup 2) (match_dup 1))
17266    (parallel [(set (match_dup 0)
17267                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17268               (clobber (reg:CC FLAGS_REG))])])
17270 (define_peephole2
17271   [(match_scratch:SI 2 "r")
17272    (parallel [(set (match_operand:SI 0 "register_operand")
17273                    (match_operator:SI 3 "arith_or_logical_operator"
17274                      [(match_operand:SI 1 "memory_operand")
17275                       (match_dup 0)]))
17276               (clobber (reg:CC FLAGS_REG))])]
17277   "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17278   [(set (match_dup 2) (match_dup 1))
17279    (parallel [(set (match_dup 0)
17280                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17281               (clobber (reg:CC FLAGS_REG))])])
17283 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
17284 ;; refers to the destination of the load!
17286 (define_peephole2
17287   [(set (match_operand:SI 0 "register_operand")
17288         (match_operand:SI 1 "register_operand"))
17289    (parallel [(set (match_dup 0)
17290                    (match_operator:SI 3 "commutative_operator"
17291                      [(match_dup 0)
17292                       (match_operand:SI 2 "memory_operand")]))
17293               (clobber (reg:CC FLAGS_REG))])]
17294   "REGNO (operands[0]) != REGNO (operands[1])
17295    && GENERAL_REGNO_P (REGNO (operands[0]))
17296    && GENERAL_REGNO_P (REGNO (operands[1]))"
17297   [(set (match_dup 0) (match_dup 4))
17298    (parallel [(set (match_dup 0)
17299                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17300               (clobber (reg:CC FLAGS_REG))])]
17301   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17303 (define_peephole2
17304   [(set (match_operand 0 "register_operand")
17305         (match_operand 1 "register_operand"))
17306    (set (match_dup 0)
17307                    (match_operator 3 "commutative_operator"
17308                      [(match_dup 0)
17309                       (match_operand 2 "memory_operand")]))]
17310   "REGNO (operands[0]) != REGNO (operands[1])
17311    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
17312        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17313   [(set (match_dup 0) (match_dup 2))
17314    (set (match_dup 0)
17315         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17317 ; Don't do logical operations with memory outputs
17319 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17320 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
17321 ; the same decoder scheduling characteristics as the original.
17323 (define_peephole2
17324   [(match_scratch:SI 2 "r")
17325    (parallel [(set (match_operand:SI 0 "memory_operand")
17326                    (match_operator:SI 3 "arith_or_logical_operator"
17327                      [(match_dup 0)
17328                       (match_operand:SI 1 "nonmemory_operand")]))
17329               (clobber (reg:CC FLAGS_REG))])]
17330   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17331    /* Do not split stack checking probes.  */
17332    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17333   [(set (match_dup 2) (match_dup 0))
17334    (parallel [(set (match_dup 2)
17335                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17336               (clobber (reg:CC FLAGS_REG))])
17337    (set (match_dup 0) (match_dup 2))])
17339 (define_peephole2
17340   [(match_scratch:SI 2 "r")
17341    (parallel [(set (match_operand:SI 0 "memory_operand")
17342                    (match_operator:SI 3 "arith_or_logical_operator"
17343                      [(match_operand:SI 1 "nonmemory_operand")
17344                       (match_dup 0)]))
17345               (clobber (reg:CC FLAGS_REG))])]
17346   "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17347    /* Do not split stack checking probes.  */
17348    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17349   [(set (match_dup 2) (match_dup 0))
17350    (parallel [(set (match_dup 2)
17351                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17352               (clobber (reg:CC FLAGS_REG))])
17353    (set (match_dup 0) (match_dup 2))])
17355 ;; Attempt to use arith or logical operations with memory outputs with
17356 ;; setting of flags.
17357 (define_peephole2
17358   [(set (match_operand:SWI 0 "register_operand")
17359         (match_operand:SWI 1 "memory_operand"))
17360    (parallel [(set (match_dup 0)
17361                    (match_operator:SWI 3 "plusminuslogic_operator"
17362                      [(match_dup 0)
17363                       (match_operand:SWI 2 "<nonmemory_operand>")]))
17364               (clobber (reg:CC FLAGS_REG))])
17365    (set (match_dup 1) (match_dup 0))
17366    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17367   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17368    && peep2_reg_dead_p (4, operands[0])
17369    && !reg_overlap_mentioned_p (operands[0], operands[1])
17370    && !reg_overlap_mentioned_p (operands[0], operands[2])
17371    && (<MODE>mode != QImode
17372        || immediate_operand (operands[2], QImode)
17373        || q_regs_operand (operands[2], QImode))
17374    && ix86_match_ccmode (peep2_next_insn (3),
17375                          (GET_CODE (operands[3]) == PLUS
17376                           || GET_CODE (operands[3]) == MINUS)
17377                          ? CCGOCmode : CCNOmode)"
17378   [(parallel [(set (match_dup 4) (match_dup 5))
17379               (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17380                                                   (match_dup 2)]))])]
17382   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17383   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17384                                 copy_rtx (operands[1]),
17385                                 copy_rtx (operands[2]));
17386   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17387                                  operands[5], const0_rtx);
17390 (define_peephole2
17391   [(parallel [(set (match_operand:SWI 0 "register_operand")
17392                    (match_operator:SWI 2 "plusminuslogic_operator"
17393                      [(match_dup 0)
17394                       (match_operand:SWI 1 "memory_operand")]))
17395               (clobber (reg:CC FLAGS_REG))])
17396    (set (match_dup 1) (match_dup 0))
17397    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17398   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17399    && GET_CODE (operands[2]) != MINUS
17400    && peep2_reg_dead_p (3, operands[0])
17401    && !reg_overlap_mentioned_p (operands[0], operands[1])
17402    && ix86_match_ccmode (peep2_next_insn (2),
17403                          GET_CODE (operands[2]) == PLUS
17404                          ? CCGOCmode : CCNOmode)"
17405   [(parallel [(set (match_dup 3) (match_dup 4))
17406               (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17407                                                   (match_dup 0)]))])]
17409   operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17410   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17411                                 copy_rtx (operands[1]),
17412                                 copy_rtx (operands[0]));
17413   operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17414                                  operands[4], const0_rtx);
17417 (define_peephole2
17418   [(set (match_operand:SWI12 0 "register_operand")
17419         (match_operand:SWI12 1 "memory_operand"))
17420    (parallel [(set (match_operand:SI 4 "register_operand")
17421                    (match_operator:SI 3 "plusminuslogic_operator"
17422                      [(match_dup 4)
17423                       (match_operand:SI 2 "nonmemory_operand")]))
17424               (clobber (reg:CC FLAGS_REG))])
17425    (set (match_dup 1) (match_dup 0))
17426    (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17427   "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17428    && REG_P (operands[0]) && REG_P (operands[4])
17429    && REGNO (operands[0]) == REGNO (operands[4])
17430    && peep2_reg_dead_p (4, operands[0])
17431    && (<MODE>mode != QImode
17432        || immediate_operand (operands[2], SImode)
17433        || q_regs_operand (operands[2], SImode))
17434    && !reg_overlap_mentioned_p (operands[0], operands[1])
17435    && !reg_overlap_mentioned_p (operands[0], operands[2])
17436    && ix86_match_ccmode (peep2_next_insn (3),
17437                          (GET_CODE (operands[3]) == PLUS
17438                           || GET_CODE (operands[3]) == MINUS)
17439                          ? CCGOCmode : CCNOmode)"
17440   [(parallel [(set (match_dup 4) (match_dup 5))
17441               (set (match_dup 1) (match_dup 6))])]
17443   operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17444   operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17445   operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17446                                 copy_rtx (operands[1]), operands[2]);
17447   operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17448                                  operands[5], const0_rtx);
17449   operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17450                                 copy_rtx (operands[1]),
17451                                 copy_rtx (operands[2]));
17454 ;; Attempt to always use XOR for zeroing registers.
17455 (define_peephole2
17456   [(set (match_operand 0 "register_operand")
17457         (match_operand 1 "const0_operand"))]
17458   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17459    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17460    && GENERAL_REG_P (operands[0])
17461    && peep2_regno_dead_p (0, FLAGS_REG)"
17462   [(parallel [(set (match_dup 0) (const_int 0))
17463               (clobber (reg:CC FLAGS_REG))])]
17464   "operands[0] = gen_lowpart (word_mode, operands[0]);")
17466 (define_peephole2
17467   [(set (strict_low_part (match_operand 0 "register_operand"))
17468         (const_int 0))]
17469   "(GET_MODE (operands[0]) == QImode
17470     || GET_MODE (operands[0]) == HImode)
17471    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17472    && peep2_regno_dead_p (0, FLAGS_REG)"
17473   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17474               (clobber (reg:CC FLAGS_REG))])])
17476 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17477 (define_peephole2
17478   [(set (match_operand:SWI248 0 "register_operand")
17479         (const_int -1))]
17480   "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17481    && peep2_regno_dead_p (0, FLAGS_REG)"
17482   [(parallel [(set (match_dup 0) (const_int -1))
17483               (clobber (reg:CC FLAGS_REG))])]
17485   if (<MODE_SIZE> < GET_MODE_SIZE (SImode))
17486     operands[0] = gen_lowpart (SImode, operands[0]);
17489 ;; Attempt to convert simple lea to add/shift.
17490 ;; These can be created by move expanders.
17491 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17492 ;; relevant lea instructions were already split.
17494 (define_peephole2
17495   [(set (match_operand:SWI48 0 "register_operand")
17496         (plus:SWI48 (match_dup 0)
17497                     (match_operand:SWI48 1 "<nonmemory_operand>")))]
17498   "!TARGET_OPT_AGU
17499    && peep2_regno_dead_p (0, FLAGS_REG)"
17500   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17501               (clobber (reg:CC FLAGS_REG))])])
17503 (define_peephole2
17504   [(set (match_operand:SWI48 0 "register_operand")
17505         (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17506                     (match_dup 0)))]
17507   "!TARGET_OPT_AGU
17508    && peep2_regno_dead_p (0, FLAGS_REG)"
17509   [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17510               (clobber (reg:CC FLAGS_REG))])])
17512 (define_peephole2
17513   [(set (match_operand:DI 0 "register_operand")
17514         (zero_extend:DI
17515           (plus:SI (match_operand:SI 1 "register_operand")
17516                    (match_operand:SI 2 "nonmemory_operand"))))]
17517   "TARGET_64BIT && !TARGET_OPT_AGU
17518    && REGNO (operands[0]) == REGNO (operands[1])
17519    && peep2_regno_dead_p (0, FLAGS_REG)"
17520   [(parallel [(set (match_dup 0)
17521                    (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17522               (clobber (reg:CC FLAGS_REG))])])
17524 (define_peephole2
17525   [(set (match_operand:DI 0 "register_operand")
17526         (zero_extend:DI
17527           (plus:SI (match_operand:SI 1 "nonmemory_operand")
17528                    (match_operand:SI 2 "register_operand"))))]
17529   "TARGET_64BIT && !TARGET_OPT_AGU
17530    && REGNO (operands[0]) == REGNO (operands[2])
17531    && peep2_regno_dead_p (0, FLAGS_REG)"
17532   [(parallel [(set (match_dup 0)
17533                    (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17534               (clobber (reg:CC FLAGS_REG))])])
17536 (define_peephole2
17537   [(set (match_operand:SWI48 0 "register_operand")
17538         (mult:SWI48 (match_dup 0)
17539                     (match_operand:SWI48 1 "const_int_operand")))]
17540   "exact_log2 (INTVAL (operands[1])) >= 0
17541    && peep2_regno_dead_p (0, FLAGS_REG)"
17542   [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17543               (clobber (reg:CC FLAGS_REG))])]
17544   "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17546 (define_peephole2
17547   [(set (match_operand:DI 0 "register_operand")
17548         (zero_extend:DI
17549           (mult:SI (match_operand:SI 1 "register_operand")
17550                    (match_operand:SI 2 "const_int_operand"))))]
17551   "TARGET_64BIT
17552    && exact_log2 (INTVAL (operands[2])) >= 0
17553    && REGNO (operands[0]) == REGNO (operands[1])
17554    && peep2_regno_dead_p (0, FLAGS_REG)"
17555   [(parallel [(set (match_dup 0)
17556                    (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))
17557               (clobber (reg:CC FLAGS_REG))])]
17558   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17560 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
17561 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17562 ;; On many CPUs it is also faster, since special hardware to avoid esp
17563 ;; dependencies is present.
17565 ;; While some of these conversions may be done using splitters, we use
17566 ;; peepholes in order to allow combine_stack_adjustments pass to see
17567 ;; nonobfuscated RTL.
17569 ;; Convert prologue esp subtractions to push.
17570 ;; We need register to push.  In order to keep verify_flow_info happy we have
17571 ;; two choices
17572 ;; - use scratch and clobber it in order to avoid dependencies
17573 ;; - use already live register
17574 ;; We can't use the second way right now, since there is no reliable way how to
17575 ;; verify that given register is live.  First choice will also most likely in
17576 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
17577 ;; call clobbered registers are dead.  We may want to use base pointer as an
17578 ;; alternative when no register is available later.
17580 (define_peephole2
17581   [(match_scratch:W 1 "r")
17582    (parallel [(set (reg:P SP_REG)
17583                    (plus:P (reg:P SP_REG)
17584                            (match_operand:P 0 "const_int_operand")))
17585               (clobber (reg:CC FLAGS_REG))
17586               (clobber (mem:BLK (scratch)))])]
17587   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17588    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17589   [(clobber (match_dup 1))
17590    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17591               (clobber (mem:BLK (scratch)))])])
17593 (define_peephole2
17594   [(match_scratch:W 1 "r")
17595    (parallel [(set (reg:P SP_REG)
17596                    (plus:P (reg:P SP_REG)
17597                            (match_operand:P 0 "const_int_operand")))
17598               (clobber (reg:CC FLAGS_REG))
17599               (clobber (mem:BLK (scratch)))])]
17600   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17601    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17602   [(clobber (match_dup 1))
17603    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17604    (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17605               (clobber (mem:BLK (scratch)))])])
17607 ;; Convert esp subtractions to push.
17608 (define_peephole2
17609   [(match_scratch:W 1 "r")
17610    (parallel [(set (reg:P SP_REG)
17611                    (plus:P (reg:P SP_REG)
17612                            (match_operand:P 0 "const_int_operand")))
17613               (clobber (reg:CC FLAGS_REG))])]
17614   "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17615    && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17616   [(clobber (match_dup 1))
17617    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17619 (define_peephole2
17620   [(match_scratch:W 1 "r")
17621    (parallel [(set (reg:P SP_REG)
17622                    (plus:P (reg:P SP_REG)
17623                            (match_operand:P 0 "const_int_operand")))
17624               (clobber (reg:CC FLAGS_REG))])]
17625   "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17626    && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17627   [(clobber (match_dup 1))
17628    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17629    (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17631 ;; Convert epilogue deallocator to pop.
17632 (define_peephole2
17633   [(match_scratch:W 1 "r")
17634    (parallel [(set (reg:P SP_REG)
17635                    (plus:P (reg:P SP_REG)
17636                            (match_operand:P 0 "const_int_operand")))
17637               (clobber (reg:CC FLAGS_REG))
17638               (clobber (mem:BLK (scratch)))])]
17639   "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17640    && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17641   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17642               (clobber (mem:BLK (scratch)))])])
17644 ;; Two pops case is tricky, since pop causes dependency
17645 ;; on destination register.  We use two registers if available.
17646 (define_peephole2
17647   [(match_scratch:W 1 "r")
17648    (match_scratch:W 2 "r")
17649    (parallel [(set (reg:P SP_REG)
17650                    (plus:P (reg:P SP_REG)
17651                            (match_operand:P 0 "const_int_operand")))
17652               (clobber (reg:CC FLAGS_REG))
17653               (clobber (mem:BLK (scratch)))])]
17654   "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17655    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17656   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17657               (clobber (mem:BLK (scratch)))])
17658    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17660 (define_peephole2
17661   [(match_scratch:W 1 "r")
17662    (parallel [(set (reg:P SP_REG)
17663                    (plus:P (reg:P SP_REG)
17664                            (match_operand:P 0 "const_int_operand")))
17665               (clobber (reg:CC FLAGS_REG))
17666               (clobber (mem:BLK (scratch)))])]
17667   "optimize_insn_for_size_p ()
17668    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17669   [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17670               (clobber (mem:BLK (scratch)))])
17671    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17673 ;; Convert esp additions to pop.
17674 (define_peephole2
17675   [(match_scratch:W 1 "r")
17676    (parallel [(set (reg:P SP_REG)
17677                    (plus:P (reg:P SP_REG)
17678                            (match_operand:P 0 "const_int_operand")))
17679               (clobber (reg:CC FLAGS_REG))])]
17680   "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17681   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17683 ;; Two pops case is tricky, since pop causes dependency
17684 ;; on destination register.  We use two registers if available.
17685 (define_peephole2
17686   [(match_scratch:W 1 "r")
17687    (match_scratch:W 2 "r")
17688    (parallel [(set (reg:P SP_REG)
17689                    (plus:P (reg:P SP_REG)
17690                            (match_operand:P 0 "const_int_operand")))
17691               (clobber (reg:CC FLAGS_REG))])]
17692   "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17693   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17694    (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17696 (define_peephole2
17697   [(match_scratch:W 1 "r")
17698    (parallel [(set (reg:P SP_REG)
17699                    (plus:P (reg:P SP_REG)
17700                            (match_operand:P 0 "const_int_operand")))
17701               (clobber (reg:CC FLAGS_REG))])]
17702   "optimize_insn_for_size_p ()
17703    && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17704   [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17705    (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17707 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17708 ;; required and register dies.  Similarly for 128 to -128.
17709 (define_peephole2
17710   [(set (match_operand 0 "flags_reg_operand")
17711         (match_operator 1 "compare_operator"
17712           [(match_operand 2 "register_operand")
17713            (match_operand 3 "const_int_operand")]))]
17714   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17715      && incdec_operand (operands[3], GET_MODE (operands[3])))
17716     || (!TARGET_FUSE_CMP_AND_BRANCH
17717         && INTVAL (operands[3]) == 128))
17718    && ix86_match_ccmode (insn, CCGCmode)
17719    && peep2_reg_dead_p (1, operands[2])"
17720   [(parallel [(set (match_dup 0)
17721                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17722               (clobber (match_dup 2))])])
17724 ;; Convert imul by three, five and nine into lea
17725 (define_peephole2
17726   [(parallel
17727     [(set (match_operand:SWI48 0 "register_operand")
17728           (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17729                       (match_operand:SWI48 2 "const359_operand")))
17730      (clobber (reg:CC FLAGS_REG))])]
17731   "!TARGET_PARTIAL_REG_STALL
17732    || <MODE>mode == SImode
17733    || optimize_function_for_size_p (cfun)"
17734   [(set (match_dup 0)
17735         (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17736                     (match_dup 1)))]
17737   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17739 (define_peephole2
17740   [(parallel
17741     [(set (match_operand:SWI48 0 "register_operand")
17742           (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17743                       (match_operand:SWI48 2 "const359_operand")))
17744      (clobber (reg:CC FLAGS_REG))])]
17745   "optimize_insn_for_speed_p ()
17746    && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17747   [(set (match_dup 0) (match_dup 1))
17748    (set (match_dup 0)
17749         (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17750                     (match_dup 0)))]
17751   "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17753 ;; imul $32bit_imm, mem, reg is vector decoded, while
17754 ;; imul $32bit_imm, reg, reg is direct decoded.
17755 (define_peephole2
17756   [(match_scratch:SWI48 3 "r")
17757    (parallel [(set (match_operand:SWI48 0 "register_operand")
17758                    (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17759                                (match_operand:SWI48 2 "immediate_operand")))
17760               (clobber (reg:CC FLAGS_REG))])]
17761   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17762    && !satisfies_constraint_K (operands[2])"
17763   [(set (match_dup 3) (match_dup 1))
17764    (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17765               (clobber (reg:CC FLAGS_REG))])])
17767 (define_peephole2
17768   [(match_scratch:SI 3 "r")
17769    (parallel [(set (match_operand:DI 0 "register_operand")
17770                    (zero_extend:DI
17771                      (mult:SI (match_operand:SI 1 "memory_operand")
17772                               (match_operand:SI 2 "immediate_operand"))))
17773               (clobber (reg:CC FLAGS_REG))])]
17774   "TARGET_64BIT
17775    && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17776    && !satisfies_constraint_K (operands[2])"
17777   [(set (match_dup 3) (match_dup 1))
17778    (parallel [(set (match_dup 0)
17779                    (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17780               (clobber (reg:CC FLAGS_REG))])])
17782 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17783 ;; Convert it into imul reg, reg
17784 ;; It would be better to force assembler to encode instruction using long
17785 ;; immediate, but there is apparently no way to do so.
17786 (define_peephole2
17787   [(parallel [(set (match_operand:SWI248 0 "register_operand")
17788                    (mult:SWI248
17789                     (match_operand:SWI248 1 "nonimmediate_operand")
17790                     (match_operand:SWI248 2 "const_int_operand")))
17791               (clobber (reg:CC FLAGS_REG))])
17792    (match_scratch:SWI248 3 "r")]
17793   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17794    && satisfies_constraint_K (operands[2])"
17795   [(set (match_dup 3) (match_dup 2))
17796    (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17797               (clobber (reg:CC FLAGS_REG))])]
17799   if (!rtx_equal_p (operands[0], operands[1]))
17800     emit_move_insn (operands[0], operands[1]);
17803 ;; After splitting up read-modify operations, array accesses with memory
17804 ;; operands might end up in form:
17805 ;;  sall    $2, %eax
17806 ;;  movl    4(%esp), %edx
17807 ;;  addl    %edx, %eax
17808 ;; instead of pre-splitting:
17809 ;;  sall    $2, %eax
17810 ;;  addl    4(%esp), %eax
17811 ;; Turn it into:
17812 ;;  movl    4(%esp), %edx
17813 ;;  leal    (%edx,%eax,4), %eax
17815 (define_peephole2
17816   [(match_scratch:W 5 "r")
17817    (parallel [(set (match_operand 0 "register_operand")
17818                    (ashift (match_operand 1 "register_operand")
17819                            (match_operand 2 "const_int_operand")))
17820                (clobber (reg:CC FLAGS_REG))])
17821    (parallel [(set (match_operand 3 "register_operand")
17822                    (plus (match_dup 0)
17823                          (match_operand 4 "x86_64_general_operand")))
17824                    (clobber (reg:CC FLAGS_REG))])]
17825   "IN_RANGE (INTVAL (operands[2]), 1, 3)
17826    /* Validate MODE for lea.  */
17827    && ((!TARGET_PARTIAL_REG_STALL
17828         && (GET_MODE (operands[0]) == QImode
17829             || GET_MODE (operands[0]) == HImode))
17830        || GET_MODE (operands[0]) == SImode
17831        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17832    && (rtx_equal_p (operands[0], operands[3])
17833        || peep2_reg_dead_p (2, operands[0]))
17834    /* We reorder load and the shift.  */
17835    && !reg_overlap_mentioned_p (operands[0], operands[4])"
17836   [(set (match_dup 5) (match_dup 4))
17837    (set (match_dup 0) (match_dup 1))]
17839   machine_mode op1mode = GET_MODE (operands[1]);
17840   machine_mode mode = op1mode == DImode ? DImode : SImode;
17841   int scale = 1 << INTVAL (operands[2]);
17842   rtx index = gen_lowpart (word_mode, operands[1]);
17843   rtx base = gen_lowpart (word_mode, operands[5]);
17844   rtx dest = gen_lowpart (mode, operands[3]);
17846   operands[1] = gen_rtx_PLUS (word_mode, base,
17847                               gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17848   operands[5] = base;
17849   if (mode != word_mode)
17850     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17851   if (op1mode != word_mode)
17852     operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17853   operands[0] = dest;
17856 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17857 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17858 ;; caught for use by garbage collectors and the like.  Using an insn that
17859 ;; maps to SIGILL makes it more likely the program will rightfully die.
17860 ;; Keeping with tradition, "6" is in honor of #UD.
17861 (define_insn "trap"
17862   [(trap_if (const_int 1) (const_int 6))]
17863   ""
17865 #ifdef HAVE_AS_IX86_UD2
17866   return "ud2";
17867 #else
17868   return ASM_SHORT "0x0b0f";
17869 #endif
17871   [(set_attr "length" "2")])
17873 (define_expand "prefetch"
17874   [(prefetch (match_operand 0 "address_operand")
17875              (match_operand:SI 1 "const_int_operand")
17876              (match_operand:SI 2 "const_int_operand"))]
17877   "TARGET_PREFETCH_SSE || TARGET_PRFCHW || TARGET_PREFETCHWT1"
17879   bool write = INTVAL (operands[1]) != 0;
17880   int locality = INTVAL (operands[2]);
17882   gcc_assert (IN_RANGE (locality, 0, 3));
17884   /* Use 3dNOW prefetch in case we are asking for write prefetch not
17885      supported by SSE counterpart or the SSE prefetch is not available
17886      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
17887      of locality.  */
17888   if (TARGET_PREFETCHWT1 && write && locality <= 2)
17889     operands[2] = const2_rtx;
17890   else if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17891     operands[2] = GEN_INT (3);
17892   else
17893     operands[1] = const0_rtx;
17896 (define_insn "*prefetch_sse"
17897   [(prefetch (match_operand 0 "address_operand" "p")
17898              (const_int 0)
17899              (match_operand:SI 1 "const_int_operand"))]
17900   "TARGET_PREFETCH_SSE"
17902   static const char * const patterns[4] = {
17903    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17904   };
17906   int locality = INTVAL (operands[1]);
17907   gcc_assert (IN_RANGE (locality, 0, 3));
17909   return patterns[locality];
17911   [(set_attr "type" "sse")
17912    (set_attr "atom_sse_attr" "prefetch")
17913    (set (attr "length_address")
17914         (symbol_ref "memory_address_length (operands[0], false)"))
17915    (set_attr "memory" "none")])
17917 (define_insn "*prefetch_3dnow"
17918   [(prefetch (match_operand 0 "address_operand" "p")
17919              (match_operand:SI 1 "const_int_operand" "n")
17920              (const_int 3))]
17921   "TARGET_PRFCHW"
17923   if (INTVAL (operands[1]) == 0)
17924     return "prefetch\t%a0";
17925   else
17926     return "prefetchw\t%a0";
17928   [(set_attr "type" "mmx")
17929    (set (attr "length_address")
17930         (symbol_ref "memory_address_length (operands[0], false)"))
17931    (set_attr "memory" "none")])
17933 (define_insn "*prefetch_prefetchwt1_<mode>"
17934   [(prefetch (match_operand:P 0 "address_operand" "p")
17935              (const_int 1)
17936              (const_int 2))]
17937   "TARGET_PREFETCHWT1"
17938   "prefetchwt1\t%a0";
17939   [(set_attr "type" "sse")
17940    (set (attr "length_address")
17941         (symbol_ref "memory_address_length (operands[0], false)"))
17942    (set_attr "memory" "none")])
17944 (define_expand "stack_protect_set"
17945   [(match_operand 0 "memory_operand")
17946    (match_operand 1 "memory_operand")]
17947   "TARGET_SSP_TLS_GUARD"
17949   rtx (*insn)(rtx, rtx);
17951 #ifdef TARGET_THREAD_SSP_OFFSET
17952   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17953   insn = (TARGET_LP64
17954           ? gen_stack_tls_protect_set_di
17955           : gen_stack_tls_protect_set_si);
17956 #else
17957   insn = (TARGET_LP64
17958           ? gen_stack_protect_set_di
17959           : gen_stack_protect_set_si);
17960 #endif
17962   emit_insn (insn (operands[0], operands[1]));
17963   DONE;
17966 (define_insn "stack_protect_set_<mode>"
17967   [(set (match_operand:PTR 0 "memory_operand" "=m")
17968         (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17969                     UNSPEC_SP_SET))
17970    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17971    (clobber (reg:CC FLAGS_REG))]
17972   "TARGET_SSP_TLS_GUARD"
17973   "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17974   [(set_attr "type" "multi")])
17976 (define_insn "stack_tls_protect_set_<mode>"
17977   [(set (match_operand:PTR 0 "memory_operand" "=m")
17978         (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17979                     UNSPEC_SP_TLS_SET))
17980    (set (match_scratch:PTR 2 "=&r") (const_int 0))
17981    (clobber (reg:CC FLAGS_REG))]
17982   ""
17983   "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17984   [(set_attr "type" "multi")])
17986 (define_expand "stack_protect_test"
17987   [(match_operand 0 "memory_operand")
17988    (match_operand 1 "memory_operand")
17989    (match_operand 2)]
17990   "TARGET_SSP_TLS_GUARD"
17992   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17994   rtx (*insn)(rtx, rtx, rtx);
17996 #ifdef TARGET_THREAD_SSP_OFFSET
17997   operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17998   insn = (TARGET_LP64
17999           ? gen_stack_tls_protect_test_di
18000           : gen_stack_tls_protect_test_si);
18001 #else
18002   insn = (TARGET_LP64
18003           ? gen_stack_protect_test_di
18004           : gen_stack_protect_test_si);
18005 #endif
18007   emit_insn (insn (flags, operands[0], operands[1]));
18009   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
18010                                   flags, const0_rtx, operands[2]));
18011   DONE;
18014 (define_insn "stack_protect_test_<mode>"
18015   [(set (match_operand:CCZ 0 "flags_reg_operand")
18016         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18017                      (match_operand:PTR 2 "memory_operand" "m")]
18018                     UNSPEC_SP_TEST))
18019    (clobber (match_scratch:PTR 3 "=&r"))]
18020   "TARGET_SSP_TLS_GUARD"
18021   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
18022   [(set_attr "type" "multi")])
18024 (define_insn "stack_tls_protect_test_<mode>"
18025   [(set (match_operand:CCZ 0 "flags_reg_operand")
18026         (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
18027                      (match_operand:PTR 2 "const_int_operand" "i")]
18028                     UNSPEC_SP_TLS_TEST))
18029    (clobber (match_scratch:PTR 3 "=r"))]
18030   ""
18031   "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
18032   [(set_attr "type" "multi")])
18034 (define_insn "sse4_2_crc32<mode>"
18035   [(set (match_operand:SI 0 "register_operand" "=r")
18036         (unspec:SI
18037           [(match_operand:SI 1 "register_operand" "0")
18038            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
18039           UNSPEC_CRC32))]
18040   "TARGET_SSE4_2 || TARGET_CRC32"
18041   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
18042   [(set_attr "type" "sselog1")
18043    (set_attr "prefix_rep" "1")
18044    (set_attr "prefix_extra" "1")
18045    (set (attr "prefix_data16")
18046      (if_then_else (match_operand:HI 2)
18047        (const_string "1")
18048        (const_string "*")))
18049    (set (attr "prefix_rex")
18050      (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
18051        (const_string "1")
18052        (const_string "*")))
18053    (set_attr "mode" "SI")])
18055 (define_insn "sse4_2_crc32di"
18056   [(set (match_operand:DI 0 "register_operand" "=r")
18057         (unspec:DI
18058           [(match_operand:DI 1 "register_operand" "0")
18059            (match_operand:DI 2 "nonimmediate_operand" "rm")]
18060           UNSPEC_CRC32))]
18061   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
18062   "crc32{q}\t{%2, %0|%0, %2}"
18063   [(set_attr "type" "sselog1")
18064    (set_attr "prefix_rep" "1")
18065    (set_attr "prefix_extra" "1")
18066    (set_attr "mode" "DI")])
18068 (define_insn "rdpmc"
18069   [(set (match_operand:DI 0 "register_operand" "=A")
18070         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18071                             UNSPECV_RDPMC))]
18072   "!TARGET_64BIT"
18073   "rdpmc"
18074   [(set_attr "type" "other")
18075    (set_attr "length" "2")])
18077 (define_insn "rdpmc_rex64"
18078   [(set (match_operand:DI 0 "register_operand" "=a")
18079         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18080                             UNSPECV_RDPMC))
18081    (set (match_operand:DI 1 "register_operand" "=d")
18082         (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
18083   "TARGET_64BIT"
18084   "rdpmc"
18085   [(set_attr "type" "other")
18086    (set_attr "length" "2")])
18088 (define_insn "rdtsc"
18089   [(set (match_operand:DI 0 "register_operand" "=A")
18090         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18091   "!TARGET_64BIT"
18092   "rdtsc"
18093   [(set_attr "type" "other")
18094    (set_attr "length" "2")])
18096 (define_insn "rdtsc_rex64"
18097   [(set (match_operand:DI 0 "register_operand" "=a")
18098         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18099    (set (match_operand:DI 1 "register_operand" "=d")
18100         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18101   "TARGET_64BIT"
18102   "rdtsc"
18103   [(set_attr "type" "other")
18104    (set_attr "length" "2")])
18106 (define_insn "rdtscp"
18107   [(set (match_operand:DI 0 "register_operand" "=A")
18108         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18109    (set (match_operand:SI 1 "register_operand" "=c")
18110         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18111   "!TARGET_64BIT"
18112   "rdtscp"
18113   [(set_attr "type" "other")
18114    (set_attr "length" "3")])
18116 (define_insn "rdtscp_rex64"
18117   [(set (match_operand:DI 0 "register_operand" "=a")
18118         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18119    (set (match_operand:DI 1 "register_operand" "=d")
18120         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18121    (set (match_operand:SI 2 "register_operand" "=c")
18122         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18123   "TARGET_64BIT"
18124   "rdtscp"
18125   [(set_attr "type" "other")
18126    (set_attr "length" "3")])
18128 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18130 ;; FXSR, XSAVE and XSAVEOPT instructions
18132 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18134 (define_insn "fxsave"
18135   [(set (match_operand:BLK 0 "memory_operand" "=m")
18136         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
18137   "TARGET_FXSR"
18138   "fxsave\t%0"
18139   [(set_attr "type" "other")
18140    (set_attr "memory" "store")
18141    (set (attr "length")
18142         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18144 (define_insn "fxsave64"
18145   [(set (match_operand:BLK 0 "memory_operand" "=m")
18146         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
18147   "TARGET_64BIT && TARGET_FXSR"
18148   "fxsave64\t%0"
18149   [(set_attr "type" "other")
18150    (set_attr "memory" "store")
18151    (set (attr "length")
18152         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18154 (define_insn "fxrstor"
18155   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18156                     UNSPECV_FXRSTOR)]
18157   "TARGET_FXSR"
18158   "fxrstor\t%0"
18159   [(set_attr "type" "other")
18160    (set_attr "memory" "load")
18161    (set (attr "length")
18162         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18164 (define_insn "fxrstor64"
18165   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18166                     UNSPECV_FXRSTOR64)]
18167   "TARGET_64BIT && TARGET_FXSR"
18168   "fxrstor64\t%0"
18169   [(set_attr "type" "other")
18170    (set_attr "memory" "load")
18171    (set (attr "length")
18172         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18174 (define_int_iterator ANY_XSAVE
18175         [UNSPECV_XSAVE
18176          (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")
18177          (UNSPECV_XSAVEC "TARGET_XSAVEC")
18178          (UNSPECV_XSAVES "TARGET_XSAVES")])
18180 (define_int_iterator ANY_XSAVE64
18181         [UNSPECV_XSAVE64
18182          (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")
18183          (UNSPECV_XSAVEC64 "TARGET_XSAVEC")
18184          (UNSPECV_XSAVES64 "TARGET_XSAVES")])
18186 (define_int_attr xsave
18187         [(UNSPECV_XSAVE "xsave")
18188          (UNSPECV_XSAVE64 "xsave64")
18189          (UNSPECV_XSAVEOPT "xsaveopt")
18190          (UNSPECV_XSAVEOPT64 "xsaveopt64")
18191          (UNSPECV_XSAVEC "xsavec")
18192          (UNSPECV_XSAVEC64 "xsavec64")
18193          (UNSPECV_XSAVES "xsaves")
18194          (UNSPECV_XSAVES64 "xsaves64")])
18196 (define_int_iterator ANY_XRSTOR
18197         [UNSPECV_XRSTOR
18198          (UNSPECV_XRSTORS "TARGET_XSAVES")])
18200 (define_int_iterator ANY_XRSTOR64
18201         [UNSPECV_XRSTOR64
18202          (UNSPECV_XRSTORS64 "TARGET_XSAVES")])
18204 (define_int_attr xrstor
18205         [(UNSPECV_XRSTOR "xrstor")
18206          (UNSPECV_XRSTOR64 "xrstor")
18207          (UNSPECV_XRSTORS "xrstors")
18208          (UNSPECV_XRSTORS64 "xrstors")])
18210 (define_insn "<xsave>"
18211   [(set (match_operand:BLK 0 "memory_operand" "=m")
18212         (unspec_volatile:BLK
18213          [(match_operand:DI 1 "register_operand" "A")]
18214          ANY_XSAVE))]
18215   "!TARGET_64BIT && TARGET_XSAVE"
18216   "<xsave>\t%0"
18217   [(set_attr "type" "other")
18218    (set_attr "memory" "store")
18219    (set (attr "length")
18220         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18222 (define_insn "<xsave>_rex64"
18223   [(set (match_operand:BLK 0 "memory_operand" "=m")
18224         (unspec_volatile:BLK
18225          [(match_operand:SI 1 "register_operand" "a")
18226           (match_operand:SI 2 "register_operand" "d")]
18227          ANY_XSAVE))]
18228   "TARGET_64BIT && TARGET_XSAVE"
18229   "<xsave>\t%0"
18230   [(set_attr "type" "other")
18231    (set_attr "memory" "store")
18232    (set (attr "length")
18233         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18235 (define_insn "<xsave>"
18236   [(set (match_operand:BLK 0 "memory_operand" "=m")
18237         (unspec_volatile:BLK
18238          [(match_operand:SI 1 "register_operand" "a")
18239           (match_operand:SI 2 "register_operand" "d")]
18240          ANY_XSAVE64))]
18241   "TARGET_64BIT && TARGET_XSAVE"
18242   "<xsave>\t%0"
18243   [(set_attr "type" "other")
18244    (set_attr "memory" "store")
18245    (set (attr "length")
18246         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18248 (define_insn "<xrstor>"
18249    [(unspec_volatile:BLK
18250      [(match_operand:BLK 0 "memory_operand" "m")
18251       (match_operand:DI 1 "register_operand" "A")]
18252      ANY_XRSTOR)]
18253   "!TARGET_64BIT && TARGET_XSAVE"
18254   "<xrstor>\t%0"
18255   [(set_attr "type" "other")
18256    (set_attr "memory" "load")
18257    (set (attr "length")
18258         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18260 (define_insn "<xrstor>_rex64"
18261    [(unspec_volatile:BLK
18262      [(match_operand:BLK 0 "memory_operand" "m")
18263       (match_operand:SI 1 "register_operand" "a")
18264       (match_operand:SI 2 "register_operand" "d")]
18265      ANY_XRSTOR)]
18266   "TARGET_64BIT && TARGET_XSAVE"
18267   "<xrstor>\t%0"
18268   [(set_attr "type" "other")
18269    (set_attr "memory" "load")
18270    (set (attr "length")
18271         (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
18273 (define_insn "<xrstor>64"
18274    [(unspec_volatile:BLK
18275      [(match_operand:BLK 0 "memory_operand" "m")
18276       (match_operand:SI 1 "register_operand" "a")
18277       (match_operand:SI 2 "register_operand" "d")]
18278      ANY_XRSTOR64)]
18279   "TARGET_64BIT && TARGET_XSAVE"
18280   "<xrstor>64\t%0"
18281   [(set_attr "type" "other")
18282    (set_attr "memory" "load")
18283    (set (attr "length")
18284         (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
18286 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18288 ;; Floating-point instructions for atomic compound assignments
18290 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18292 ; Clobber all floating-point registers on environment save and restore
18293 ; to ensure that the TOS value saved at fnstenv is valid after fldenv.
18294 (define_insn "fnstenv"
18295   [(set (match_operand:BLK 0 "memory_operand" "=m")
18296         (unspec_volatile:BLK [(const_int 0)] UNSPECV_FNSTENV))
18297    (clobber (reg:HI FPCR_REG))
18298    (clobber (reg:XF ST0_REG))
18299    (clobber (reg:XF ST1_REG))
18300    (clobber (reg:XF ST2_REG))
18301    (clobber (reg:XF ST3_REG))
18302    (clobber (reg:XF ST4_REG))
18303    (clobber (reg:XF ST5_REG))
18304    (clobber (reg:XF ST6_REG))
18305    (clobber (reg:XF ST7_REG))]
18306   "TARGET_80387"
18307   "fnstenv\t%0"
18308   [(set_attr "type" "other")
18309    (set_attr "memory" "store")
18310    (set (attr "length")
18311         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18313 (define_insn "fldenv"
18314   [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
18315                     UNSPECV_FLDENV)
18316    (clobber (reg:CCFP FPSR_REG))
18317    (clobber (reg:HI FPCR_REG))
18318    (clobber (reg:XF ST0_REG))
18319    (clobber (reg:XF ST1_REG))
18320    (clobber (reg:XF ST2_REG))
18321    (clobber (reg:XF ST3_REG))
18322    (clobber (reg:XF ST4_REG))
18323    (clobber (reg:XF ST5_REG))
18324    (clobber (reg:XF ST6_REG))
18325    (clobber (reg:XF ST7_REG))]
18326   "TARGET_80387"
18327   "fldenv\t%0"
18328   [(set_attr "type" "other")
18329    (set_attr "memory" "load")
18330    (set (attr "length")
18331         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18333 (define_insn "fnstsw"
18334   [(set (match_operand:HI 0 "nonimmediate_operand" "=a,m")
18335         (unspec_volatile:HI [(const_int 0)] UNSPECV_FNSTSW))]
18336   "TARGET_80387"
18337   "fnstsw\t%0"
18338   [(set_attr "type" "other,other")
18339    (set_attr "memory" "none,store")
18340    (set (attr "length")
18341         (symbol_ref "ix86_attr_length_address_default (insn) + 2"))])
18343 (define_insn "fnclex"
18344   [(unspec_volatile [(const_int 0)] UNSPECV_FNCLEX)]
18345   "TARGET_80387"
18346   "fnclex"
18347   [(set_attr "type" "other")
18348    (set_attr "memory" "none")
18349    (set_attr "length" "2")])
18351 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18353 ;; LWP instructions
18355 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18357 (define_expand "lwp_llwpcb"
18358   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18359                     UNSPECV_LLWP_INTRINSIC)]
18360   "TARGET_LWP")
18362 (define_insn "*lwp_llwpcb<mode>1"
18363   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18364                     UNSPECV_LLWP_INTRINSIC)]
18365   "TARGET_LWP"
18366   "llwpcb\t%0"
18367   [(set_attr "type" "lwp")
18368    (set_attr "mode" "<MODE>")
18369    (set_attr "length" "5")])
18371 (define_expand "lwp_slwpcb"
18372   [(set (match_operand 0 "register_operand" "=r")
18373         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18374   "TARGET_LWP"
18376   rtx (*insn)(rtx);
18378   insn = (Pmode == DImode
18379           ? gen_lwp_slwpcbdi
18380           : gen_lwp_slwpcbsi);
18382   emit_insn (insn (operands[0]));
18383   DONE;
18386 (define_insn "lwp_slwpcb<mode>"
18387   [(set (match_operand:P 0 "register_operand" "=r")
18388         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18389   "TARGET_LWP"
18390   "slwpcb\t%0"
18391   [(set_attr "type" "lwp")
18392    (set_attr "mode" "<MODE>")
18393    (set_attr "length" "5")])
18395 (define_expand "lwp_lwpval<mode>3"
18396   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18397                      (match_operand:SI 2 "nonimmediate_operand" "rm")
18398                      (match_operand:SI 3 "const_int_operand" "i")]
18399                     UNSPECV_LWPVAL_INTRINSIC)]
18400   "TARGET_LWP"
18401   ;; Avoid unused variable warning.
18402   "(void) operands[0];")
18404 (define_insn "*lwp_lwpval<mode>3_1"
18405   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18406                      (match_operand:SI 1 "nonimmediate_operand" "rm")
18407                      (match_operand:SI 2 "const_int_operand" "i")]
18408                     UNSPECV_LWPVAL_INTRINSIC)]
18409   "TARGET_LWP"
18410   "lwpval\t{%2, %1, %0|%0, %1, %2}"
18411   [(set_attr "type" "lwp")
18412    (set_attr "mode" "<MODE>")
18413    (set (attr "length")
18414         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18416 (define_expand "lwp_lwpins<mode>3"
18417   [(set (reg:CCC FLAGS_REG)
18418         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18419                               (match_operand:SI 2 "nonimmediate_operand" "rm")
18420                               (match_operand:SI 3 "const_int_operand" "i")]
18421                              UNSPECV_LWPINS_INTRINSIC))
18422    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18423         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18424   "TARGET_LWP")
18426 (define_insn "*lwp_lwpins<mode>3_1"
18427   [(set (reg:CCC FLAGS_REG)
18428         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18429                               (match_operand:SI 1 "nonimmediate_operand" "rm")
18430                               (match_operand:SI 2 "const_int_operand" "i")]
18431                              UNSPECV_LWPINS_INTRINSIC))]
18432   "TARGET_LWP"
18433   "lwpins\t{%2, %1, %0|%0, %1, %2}"
18434   [(set_attr "type" "lwp")
18435    (set_attr "mode" "<MODE>")
18436    (set (attr "length")
18437         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18439 (define_int_iterator RDFSGSBASE
18440         [UNSPECV_RDFSBASE
18441          UNSPECV_RDGSBASE])
18443 (define_int_iterator WRFSGSBASE
18444         [UNSPECV_WRFSBASE
18445          UNSPECV_WRGSBASE])
18447 (define_int_attr fsgs
18448         [(UNSPECV_RDFSBASE "fs")
18449          (UNSPECV_RDGSBASE "gs")
18450          (UNSPECV_WRFSBASE "fs")
18451          (UNSPECV_WRGSBASE "gs")])
18453 (define_insn "rd<fsgs>base<mode>"
18454   [(set (match_operand:SWI48 0 "register_operand" "=r")
18455         (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18456   "TARGET_64BIT && TARGET_FSGSBASE"
18457   "rd<fsgs>base\t%0"
18458   [(set_attr "type" "other")
18459    (set_attr "prefix_extra" "2")])
18461 (define_insn "wr<fsgs>base<mode>"
18462   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18463                     WRFSGSBASE)]
18464   "TARGET_64BIT && TARGET_FSGSBASE"
18465   "wr<fsgs>base\t%0"
18466   [(set_attr "type" "other")
18467    (set_attr "prefix_extra" "2")])
18469 (define_insn "rdrand<mode>_1"
18470   [(set (match_operand:SWI248 0 "register_operand" "=r")
18471         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18472    (set (reg:CCC FLAGS_REG)
18473         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18474   "TARGET_RDRND"
18475   "rdrand\t%0"
18476   [(set_attr "type" "other")
18477    (set_attr "prefix_extra" "1")])
18479 (define_insn "rdseed<mode>_1"
18480   [(set (match_operand:SWI248 0 "register_operand" "=r")
18481         (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18482    (set (reg:CCC FLAGS_REG)
18483         (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18484   "TARGET_RDSEED"
18485   "rdseed\t%0"
18486   [(set_attr "type" "other")
18487    (set_attr "prefix_extra" "1")])
18489 (define_expand "pause"
18490   [(set (match_dup 0)
18491         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18492   ""
18494   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18495   MEM_VOLATILE_P (operands[0]) = 1;
18498 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18499 ;; They have the same encoding.
18500 (define_insn "*pause"
18501   [(set (match_operand:BLK 0)
18502         (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18503   ""
18504   "rep%; nop"
18505   [(set_attr "length" "2")
18506    (set_attr "memory" "unknown")])
18508 (define_expand "xbegin"
18509   [(set (match_operand:SI 0 "register_operand")
18510         (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18511   "TARGET_RTM"
18513   rtx_code_label *label = gen_label_rtx ();
18515   /* xbegin is emitted as jump_insn, so reload won't be able
18516      to reload its operand.  Force the value into AX hard register.  */
18517   rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18518   emit_move_insn (ax_reg, constm1_rtx);
18520   emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18522   emit_label (label);
18523   LABEL_NUSES (label) = 1;
18525   emit_move_insn (operands[0], ax_reg);
18527   DONE;
18530 (define_insn "xbegin_1"
18531   [(set (pc)
18532         (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18533                           (const_int 0))
18534                       (label_ref (match_operand 1))
18535                       (pc)))
18536    (set (match_operand:SI 0 "register_operand" "+a")
18537         (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18538   "TARGET_RTM"
18539   "xbegin\t%l1"
18540   [(set_attr "type" "other")
18541    (set_attr "length" "6")])
18543 (define_insn "xend"
18544   [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18545   "TARGET_RTM"
18546   "xend"
18547   [(set_attr "type" "other")
18548    (set_attr "length" "3")])
18550 (define_insn "xabort"
18551   [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18552                     UNSPECV_XABORT)]
18553   "TARGET_RTM"
18554   "xabort\t%0"
18555   [(set_attr "type" "other")
18556    (set_attr "length" "3")])
18558 (define_expand "xtest"
18559   [(set (match_operand:QI 0 "register_operand")
18560         (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18561   "TARGET_RTM"
18563   emit_insn (gen_xtest_1 ());
18565   ix86_expand_setcc (operands[0], NE,
18566                      gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18567   DONE;
18570 (define_insn "xtest_1"
18571   [(set (reg:CCZ FLAGS_REG)
18572         (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18573   "TARGET_RTM"
18574   "xtest"
18575   [(set_attr "type" "other")
18576    (set_attr "length" "3")])
18578 (define_insn "clflushopt"
18579   [(unspec_volatile [(match_operand 0 "address_operand" "p")]
18580                    UNSPECV_CLFLUSHOPT)]
18581   "TARGET_CLFLUSHOPT"
18582   "clflushopt\t%a0"
18583   [(set_attr "type" "sse")
18584    (set_attr "atom_sse_attr" "fence")
18585    (set_attr "memory" "unknown")])
18587 ;; MPX instructions
18589 (define_expand "<mode>_mk"
18590   [(set (match_operand:BND 0 "register_operand")
18591     (unspec:BND
18592       [(mem:<bnd_ptr>
18593        (match_par_dup 3
18594         [(match_operand:<bnd_ptr> 1 "register_operand")
18595          (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand")]))]
18596       UNSPEC_BNDMK))]
18597   "TARGET_MPX"
18599   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18600                                                   operands[2]),
18601                                 UNSPEC_BNDMK_ADDR);
18604 (define_insn "*<mode>_mk"
18605   [(set (match_operand:BND 0 "register_operand" "=w")
18606     (unspec:BND
18607       [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18608         [(unspec:<bnd_ptr>
18609            [(match_operand:<bnd_ptr> 1 "register_operand" "r")
18610             (match_operand:<bnd_ptr> 2 "address_mpx_no_base_operand" "Tb")]
18611            UNSPEC_BNDMK_ADDR)])]
18612       UNSPEC_BNDMK))]
18613   "TARGET_MPX"
18614   "bndmk\t{%3, %0|%0, %3}"
18615   [(set_attr "type" "mpxmk")])
18617 (define_expand "mov<mode>"
18618   [(set (match_operand:BND 0 "general_operand")
18619         (match_operand:BND 1 "general_operand"))]
18620   "TARGET_MPX"
18622   ix86_expand_move (<MODE>mode, operands);DONE;
18625 (define_insn "*mov<mode>_internal_mpx"
18626   [(set (match_operand:BND 0 "nonimmediate_operand" "=w,m")
18627         (match_operand:BND 1 "general_operand" "wm,w"))]
18628   "TARGET_MPX"
18629   "bndmov\t{%1, %0|%0, %1}"
18630   [(set_attr "type" "mpxmov")])
18632 (define_expand "<mode>_<bndcheck>"
18633   [(parallel [(unspec [(match_operand:BND 0 "register_operand")
18634                        (match_operand:<bnd_ptr> 1 "address_no_seg_operand")] BNDCHECK)
18635               (set (match_dup 2)
18636                    (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18637   "TARGET_MPX"
18639   operands[2] = gen_rtx_MEM (BLKmode, operands[1]);
18640   MEM_VOLATILE_P (operands[2]) = 1;
18643 (define_insn "*<mode>_<bndcheck>"
18644   [(parallel [(unspec [(match_operand:BND 0 "register_operand" "w")
18645                        (match_operand:<bnd_ptr> 1 "address_no_seg_operand" "Ts")] BNDCHECK)
18646               (set (match_operand:BLK 2 "bnd_mem_operator")
18647                    (unspec:BLK [(match_dup 2)] UNSPEC_MPX_FENCE))])]
18648   "TARGET_MPX"
18649   "bnd<bndcheck>\t{%a1, %0|%0, %a1}"
18650   [(set_attr "type" "mpxchk")])
18652 (define_expand "<mode>_ldx"
18653   [(parallel [(set:BND (match_operand:BND 0 "register_operand")
18654                        (unspec:BND
18655                          [(mem:<bnd_ptr>
18656                            (match_par_dup 3
18657                              [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand")
18658                               (match_operand:<bnd_ptr> 2 "register_operand")]))]
18659                          UNSPEC_BNDLDX))
18660               (use (mem:BLK (match_dup 1)))])]
18661   "TARGET_MPX"
18663   /* Avoid registers which connot be used as index.  */
18664   if (!index_register_operand (operands[2], Pmode))
18665     {
18666       rtx temp = gen_reg_rtx (Pmode);
18667       emit_move_insn (temp, operands[2]);
18668       operands[2] = temp;
18669     }
18671   /* If it was a register originally then it may have
18672      mode other than Pmode.  We need to extend in such
18673      case because bndldx may work only with Pmode regs.  */
18674   if (GET_MODE (operands[2]) != Pmode)
18675     operands[2] = ix86_zero_extend_to_Pmode (operands[2]);
18677   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[1],
18678                                                   operands[2]),
18679                                 UNSPEC_BNDLDX_ADDR);
18682 (define_insn "*<mode>_ldx"
18683   [(parallel [(set:BND (match_operand:BND 0 "register_operand" "=w")
18684                        (unspec:BND
18685                          [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18686                            [(unspec:<bnd_ptr>
18687                              [(match_operand:<bnd_ptr> 1 "address_mpx_no_index_operand" "Ti")
18688                               (match_operand:<bnd_ptr> 2 "register_operand" "l")]
18689                             UNSPEC_BNDLDX_ADDR)])]
18690                          UNSPEC_BNDLDX))
18691               (use (mem:BLK (match_dup 1)))])]
18692   "TARGET_MPX"
18693   "bndldx\t{%3, %0|%0, %3}"
18694   [(set_attr "type" "mpxld")])
18696 (define_expand "<mode>_stx"
18697   [(parallel [(unspec [(mem:<bnd_ptr>
18698                          (match_par_dup 3
18699                            [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand")
18700                             (match_operand:<bnd_ptr> 1 "register_operand")]))
18701                        (match_operand:BND 2 "register_operand")] UNSPEC_BNDSTX)
18702               (set (match_dup 4)
18703                    (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18704   "TARGET_MPX"
18706   /* Avoid registers which connot be used as index.  */
18707   if (!index_register_operand (operands[1], Pmode))
18708     {
18709       rtx temp = gen_reg_rtx (Pmode);
18710       emit_move_insn (temp, operands[1]);
18711       operands[1] = temp;
18712     }
18714   /* If it was a register originally then it may have
18715      mode other than Pmode.  We need to extend in such
18716      case because bndstx may work only with Pmode regs.  */
18717   if (GET_MODE (operands[1]) != Pmode)
18718     operands[1] = ix86_zero_extend_to_Pmode (operands[1]);
18720   operands[3] = gen_rtx_UNSPEC (Pmode, gen_rtvec (2, operands[0],
18721                                                   operands[1]),
18722                                 UNSPEC_BNDLDX_ADDR);
18723   operands[4] = gen_rtx_MEM (BLKmode, operands[0]);
18724   MEM_VOLATILE_P (operands[4]) = 1;
18727 (define_insn "*<mode>_stx"
18728   [(parallel [(unspec [(match_operator:<bnd_ptr> 3 "bnd_mem_operator"
18729                          [(unspec:<bnd_ptr>
18730                           [(match_operand:<bnd_ptr> 0 "address_mpx_no_index_operand" "Ti")
18731                            (match_operand:<bnd_ptr> 1 "register_operand" "l")]
18732                          UNSPEC_BNDLDX_ADDR)])
18733                        (match_operand:BND 2 "register_operand" "w")] UNSPEC_BNDSTX)
18734               (set (match_operand:BLK 4 "bnd_mem_operator")
18735                    (unspec:BLK [(match_dup 4)] UNSPEC_MPX_FENCE))])]
18736   "TARGET_MPX"
18737   "bndstx\t{%2, %3|%3, %2}"
18738   [(set_attr "type" "mpxst")])
18740 (define_insn "move_size_reloc_<mode>"
18741   [(set (match_operand:SWI48 0 "register_operand" "=r")
18742        (unspec:SWI48
18743         [(match_operand:SWI48 1 "symbol_operand")]
18744         UNSPEC_SIZEOF))]
18745   "TARGET_MPX"
18747   if (x86_64_immediate_size_operand (operands[1], VOIDmode))
18748     return "mov{l}\t{%1@SIZE, %k0|%k0, %1@SIZE}";
18749   else
18750     return "movabs{q}\t{%1@SIZE, %0|%0, %1@SIZE}";
18752   [(set_attr "type" "imov")
18753    (set_attr "mode" "<MODE>")])
18755 (include "mmx.md")
18756 (include "sse.md")
18757 (include "sync.md")