Merged r157653 through r157895 into branch.
[official-gcc.git] / gcc / config / i386 / i386.md
blob9adf0a67cb941b26589ed11378d890234f42b75c
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; E,e -- likewise, but for compare-and-branch fused insn.
34 ;; F,f -- likewise, but for floating-point.
35 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;;      otherwise nothing
37 ;; R -- print the prefix for register names.
38 ;; z -- print the opcode suffix for the size of the current operand.
39 ;; Z -- likewise, with special suffixes for x87 instructions.
40 ;; * -- print a star (in certain assembler syntax)
41 ;; A -- print an absolute memory reference.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
44 ;;      delimiter.
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;;      %b0 would print %al if operands[0] is reg 0.
47 ;; w --  likewise, print the HImode name of the register.
48 ;; k --  likewise, print the SImode name of the register.
49 ;; q --  likewise, print the DImode name of the register.
50 ;; x --  likewise, print the V4SFmode name of the register.
51 ;; t --  likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for 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).
64 ;; UNSPEC usage:
66 (define_constants
67   [; Relocation specifiers
68    (UNSPEC_GOT                  0)
69    (UNSPEC_GOTOFF               1)
70    (UNSPEC_GOTPCREL             2)
71    (UNSPEC_GOTTPOFF             3)
72    (UNSPEC_TPOFF                4)
73    (UNSPEC_NTPOFF               5)
74    (UNSPEC_DTPOFF               6)
75    (UNSPEC_GOTNTPOFF            7)
76    (UNSPEC_INDNTPOFF            8)
77    (UNSPEC_PLTOFF               9)
78    (UNSPEC_MACHOPIC_OFFSET      10)
80    ; Prologue support
81    (UNSPEC_STACK_ALLOC          11)
82    (UNSPEC_SET_GOT              12)
83    (UNSPEC_SSE_PROLOGUE_SAVE    13)
84    (UNSPEC_REG_SAVE             14)
85    (UNSPEC_DEF_CFA              15)
86    (UNSPEC_SET_RIP              16)
87    (UNSPEC_SET_GOT_OFFSET       17)
88    (UNSPEC_MEMORY_BLOCKAGE      18)
90    ; TLS support
91    (UNSPEC_TP                   20)
92    (UNSPEC_TLS_GD               21)
93    (UNSPEC_TLS_LD_BASE          22)
94    (UNSPEC_TLSDESC              23)
96    ; Other random patterns
97    (UNSPEC_SCAS                 30)
98    (UNSPEC_FNSTSW               31)
99    (UNSPEC_SAHF                 32)
100    (UNSPEC_FSTCW                33)
101    (UNSPEC_ADD_CARRY            34)
102    (UNSPEC_FLDCW                35)
103    (UNSPEC_REP                  36)
104    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
105    (UNSPEC_TRUNC_NOOP           39)
107    ; For SSE/MMX support:
108    (UNSPEC_FIX_NOTRUNC          40)
109    (UNSPEC_MASKMOV              41)
110    (UNSPEC_MOVMSK               42)
111    (UNSPEC_MOVNT                43)
112    (UNSPEC_MOVU                 44)
113    (UNSPEC_RCP                  45)
114    (UNSPEC_RSQRT                46)
115    (UNSPEC_SFENCE               47)
116    (UNSPEC_PFRCP                49)
117    (UNSPEC_PFRCPIT1             40)
118    (UNSPEC_PFRCPIT2             41)
119    (UNSPEC_PFRSQRT              42)
120    (UNSPEC_PFRSQIT1             43)
121    (UNSPEC_MFENCE               44)
122    (UNSPEC_LFENCE               45)
123    (UNSPEC_PSADBW               46)
124    (UNSPEC_LDDQU                47)
125    (UNSPEC_MS_TO_SYSV_CALL      48)
127    ; Generic math support
128    (UNSPEC_COPYSIGN             50)
129    (UNSPEC_IEEE_MIN             51)     ; not commutative
130    (UNSPEC_IEEE_MAX             52)     ; not commutative
132    ; x87 Floating point
133    (UNSPEC_SIN                  60)
134    (UNSPEC_COS                  61)
135    (UNSPEC_FPATAN               62)
136    (UNSPEC_FYL2X                63)
137    (UNSPEC_FYL2XP1              64)
138    (UNSPEC_FRNDINT              65)
139    (UNSPEC_FIST                 66)
140    (UNSPEC_F2XM1                67)
141    (UNSPEC_TAN                  68)
142    (UNSPEC_FXAM                 69)
144    ; x87 Rounding
145    (UNSPEC_FRNDINT_FLOOR        70)
146    (UNSPEC_FRNDINT_CEIL         71)
147    (UNSPEC_FRNDINT_TRUNC        72)
148    (UNSPEC_FRNDINT_MASK_PM      73)
149    (UNSPEC_FIST_FLOOR           74)
150    (UNSPEC_FIST_CEIL            75)
152    ; x87 Double output FP
153    (UNSPEC_SINCOS_COS           80)
154    (UNSPEC_SINCOS_SIN           81)
155    (UNSPEC_XTRACT_FRACT         84)
156    (UNSPEC_XTRACT_EXP           85)
157    (UNSPEC_FSCALE_FRACT         86)
158    (UNSPEC_FSCALE_EXP           87)
159    (UNSPEC_FPREM_F              88)
160    (UNSPEC_FPREM_U              89)
161    (UNSPEC_FPREM1_F             90)
162    (UNSPEC_FPREM1_U             91)
164    (UNSPEC_C2_FLAG              95)
165    (UNSPEC_FXAM_MEM             96)
167    ; SSP patterns
168    (UNSPEC_SP_SET               100)
169    (UNSPEC_SP_TEST              101)
170    (UNSPEC_SP_TLS_SET           102)
171    (UNSPEC_SP_TLS_TEST          103)
173    ; SSSE3
174    (UNSPEC_PSHUFB               120)
175    (UNSPEC_PSIGN                121)
176    (UNSPEC_PALIGNR              122)
178    ; For SSE4A support
179    (UNSPEC_EXTRQI               130)
180    (UNSPEC_EXTRQ                131)
181    (UNSPEC_INSERTQI             132)
182    (UNSPEC_INSERTQ              133)
184    ; For SSE4.1 support
185    (UNSPEC_BLENDV               134)
186    (UNSPEC_INSERTPS             135)
187    (UNSPEC_DP                   136)
188    (UNSPEC_MOVNTDQA             137)
189    (UNSPEC_MPSADBW              138)
190    (UNSPEC_PHMINPOSUW           139)
191    (UNSPEC_PTEST                140)
192    (UNSPEC_ROUND                141)
194    ; For SSE4.2 support
195    (UNSPEC_CRC32                143)
196    (UNSPEC_PCMPESTR             144)
197    (UNSPEC_PCMPISTR             145)
199    ; For FMA4 support
200    (UNSPEC_FMA4_INTRINSIC       150)
201    (UNSPEC_FMA4_FMADDSUB        151)
202    (UNSPEC_FMA4_FMSUBADD        152)
203    (UNSPEC_XOP_UNSIGNED_CMP     151)
204    (UNSPEC_XOP_TRUEFALSE        152)
205    (UNSPEC_XOP_PERMUTE          153)
206    (UNSPEC_FRCZ                 154)
208    ; For AES support
209    (UNSPEC_AESENC               159)
210    (UNSPEC_AESENCLAST           160)
211    (UNSPEC_AESDEC               161)
212    (UNSPEC_AESDECLAST           162)
213    (UNSPEC_AESIMC               163)
214    (UNSPEC_AESKEYGENASSIST      164)
216    ; For PCLMUL support
217    (UNSPEC_PCLMUL               165)
219    ; For AVX support
220    (UNSPEC_PCMP                 166)
221    (UNSPEC_VPERMIL              167)
222    (UNSPEC_VPERMIL2             168)
223    (UNSPEC_VPERMIL2F128         169)
224    (UNSPEC_MASKLOAD             170)
225    (UNSPEC_MASKSTORE            171)
226    (UNSPEC_CAST                 172)
227    (UNSPEC_VTESTP               173)
228   ])
230 (define_constants
231   [(UNSPECV_BLOCKAGE            0)
232    (UNSPECV_STACK_PROBE         1)
233    (UNSPECV_EMMS                2)
234    (UNSPECV_LDMXCSR             3)
235    (UNSPECV_STMXCSR             4)
236    (UNSPECV_FEMMS               5)
237    (UNSPECV_CLFLUSH             6)
238    (UNSPECV_ALIGN               7)
239    (UNSPECV_MONITOR             8)
240    (UNSPECV_MWAIT               9)
241    (UNSPECV_CMPXCHG             10)
242    (UNSPECV_XCHG                12)
243    (UNSPECV_LOCK                13)
244    (UNSPECV_PROLOGUE_USE        14)
245    (UNSPECV_CLD                 15)
246    (UNSPECV_VZEROALL            16)
247    (UNSPECV_VZEROUPPER          17)
248    (UNSPECV_RDTSC               18)
249    (UNSPECV_RDTSCP              19)
250    (UNSPECV_RDPMC               20)
251    (UNSPECV_VSWAPMOV            21)
252    (UNSPECV_LLWP_INTRINSIC      22)
253    (UNSPECV_SLWP_INTRINSIC      23)
254    (UNSPECV_LWPVAL_INTRINSIC    24)
255    (UNSPECV_LWPINS_INTRINSIC    25)
256   ])
258 ;; Constants to represent pcomtrue/pcomfalse variants
259 (define_constants
260   [(PCOM_FALSE                  0)
261    (PCOM_TRUE                   1)
262    (COM_FALSE_S                 2)
263    (COM_FALSE_P                 3)
264    (COM_TRUE_S                  4)
265    (COM_TRUE_P                  5)
266   ])
268 ;; Constants used in the XOP pperm instruction
269 (define_constants
270   [(PPERM_SRC                   0x00)   /* copy source */
271    (PPERM_INVERT                0x20)   /* invert source */
272    (PPERM_REVERSE               0x40)   /* bit reverse source */
273    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
274    (PPERM_ZERO                  0x80)   /* all 0's */
275    (PPERM_ONES                  0xa0)   /* all 1's */
276    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
277    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
278    (PPERM_SRC1                  0x00)   /* use first source byte */
279    (PPERM_SRC2                  0x10)   /* use second source byte */
280    ])
282 ;; Registers by name.
283 (define_constants
284   [(AX_REG                       0)
285    (DX_REG                       1)
286    (CX_REG                       2)
287    (BX_REG                       3)
288    (SI_REG                       4)
289    (DI_REG                       5)
290    (BP_REG                       6)
291    (SP_REG                       7)
292    (ST0_REG                      8)
293    (ST1_REG                      9)
294    (ST2_REG                     10)
295    (ST3_REG                     11)
296    (ST4_REG                     12)
297    (ST5_REG                     13)
298    (ST6_REG                     14)
299    (ST7_REG                     15)
300    (FLAGS_REG                   17)
301    (FPSR_REG                    18)
302    (FPCR_REG                    19)
303    (XMM0_REG                    21)
304    (XMM1_REG                    22)
305    (XMM2_REG                    23)
306    (XMM3_REG                    24)
307    (XMM4_REG                    25)
308    (XMM5_REG                    26)
309    (XMM6_REG                    27)
310    (XMM7_REG                    28)
311    (MM0_REG                     29)
312    (MM1_REG                     30)
313    (MM2_REG                     31)
314    (MM3_REG                     32)
315    (MM4_REG                     33)
316    (MM5_REG                     34)
317    (MM6_REG                     35)
318    (MM7_REG                     36)
319    (R8_REG                      37)
320    (R9_REG                      38)
321    (R10_REG                     39)
322    (R11_REG                     40)
323    (R12_REG                     41)
324    (R13_REG                     42)
325    (XMM8_REG                    45)
326    (XMM9_REG                    46)
327    (XMM10_REG                   47)
328    (XMM11_REG                   48)
329    (XMM12_REG                   49)
330    (XMM13_REG                   50)
331    (XMM14_REG                   51)
332    (XMM15_REG                   52)
333   ])
335 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
336 ;; from i386.c.
338 ;; In C guard expressions, put expressions which may be compile-time
339 ;; constants first.  This allows for better optimization.  For
340 ;; example, write "TARGET_64BIT && reload_completed", not
341 ;; "reload_completed && TARGET_64BIT".
344 ;; Processor type.
345 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
346                     generic64,amdfam10"
347   (const (symbol_ref "ix86_schedule")))
349 ;; A basic instruction type.  Refinements due to arguments to be
350 ;; provided in other attributes.
351 (define_attr "type"
352   "other,multi,
353    alu,alu1,negnot,imov,imovx,lea,
354    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
355    icmp,test,ibr,setcc,icmov,
356    push,pop,call,callv,leave,
357    str,bitmanip,
358    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
359    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
360    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
361    ssemuladd,sse4arg,lwp,
362    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
363   (const_string "other"))
365 ;; Main data type used by the insn
366 (define_attr "mode"
367   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
368   (const_string "unknown"))
370 ;; The CPU unit operations uses.
371 (define_attr "unit" "integer,i387,sse,mmx,unknown"
372   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
373            (const_string "i387")
374          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
375                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
376                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
377            (const_string "sse")
378          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
379            (const_string "mmx")
380          (eq_attr "type" "other")
381            (const_string "unknown")]
382          (const_string "integer")))
384 ;; The (bounding maximum) length of an instruction immediate.
385 (define_attr "length_immediate" ""
386   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
387                           bitmanip")
388            (const_int 0)
389          (eq_attr "unit" "i387,sse,mmx")
390            (const_int 0)
391          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
392                           imul,icmp,push,pop")
393            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
394          (eq_attr "type" "imov,test")
395            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
396          (eq_attr "type" "call")
397            (if_then_else (match_operand 0 "constant_call_address_operand" "")
398              (const_int 4)
399              (const_int 0))
400          (eq_attr "type" "callv")
401            (if_then_else (match_operand 1 "constant_call_address_operand" "")
402              (const_int 4)
403              (const_int 0))
404          ;; We don't know the size before shorten_branches.  Expect
405          ;; the instruction to fit for better scheduling.
406          (eq_attr "type" "ibr")
407            (const_int 1)
408          ]
409          (symbol_ref "/* Update immediate_length and other attributes! */
410                       gcc_unreachable (),1")))
412 ;; The (bounding maximum) length of an instruction address.
413 (define_attr "length_address" ""
414   (cond [(eq_attr "type" "str,other,multi,fxch")
415            (const_int 0)
416          (and (eq_attr "type" "call")
417               (match_operand 0 "constant_call_address_operand" ""))
418              (const_int 0)
419          (and (eq_attr "type" "callv")
420               (match_operand 1 "constant_call_address_operand" ""))
421              (const_int 0)
422          ]
423          (symbol_ref "ix86_attr_length_address_default (insn)")))
425 ;; Set when length prefix is used.
426 (define_attr "prefix_data16" ""
427   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
428            (const_int 0)
429          (eq_attr "mode" "HI")
430            (const_int 1)
431          (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
432            (const_int 1)
433         ]
434         (const_int 0)))
436 ;; Set when string REP prefix is used.
437 (define_attr "prefix_rep" ""
438   (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
439            (const_int 0)
440          (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
441            (const_int 1)
442         ]
443         (const_int 0)))
445 ;; Set when 0f opcode prefix is used.
446 (define_attr "prefix_0f" ""
447   (if_then_else
448     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
449          (eq_attr "unit" "sse,mmx"))
450     (const_int 1)
451     (const_int 0)))
453 ;; Set when REX opcode prefix is used.
454 (define_attr "prefix_rex" ""
455   (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
456            (const_int 0)
457          (and (eq_attr "mode" "DI")
458               (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
459                    (eq_attr "unit" "!mmx")))
460            (const_int 1)
461          (and (eq_attr "mode" "QI")
462               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
463                   (const_int 0)))
464            (const_int 1)
465          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
466              (const_int 0))
467            (const_int 1)
468          (and (eq_attr "type" "imovx")
469               (match_operand:QI 1 "ext_QIreg_operand" ""))
470            (const_int 1)
471         ]
472         (const_int 0)))
474 ;; There are also additional prefixes in 3DNOW, SSSE3.
475 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
476 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
477 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
478 (define_attr "prefix_extra" ""
479   (cond [(eq_attr "type" "ssemuladd,sse4arg")
480            (const_int 2)
481          (eq_attr "type" "sseiadd1,ssecvt1")
482            (const_int 1)
483         ]
484         (const_int 0)))
486 ;; Prefix used: original, VEX or maybe VEX.
487 (define_attr "prefix" "orig,vex,maybe_vex"
488   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
489     (const_string "vex")
490     (const_string "orig")))
492 ;; VEX W bit is used.
493 (define_attr "prefix_vex_w" "" (const_int 0))
495 ;; The length of VEX prefix
496 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
497 ;; 0f38/0f3a prefixes can't.  In i386.md 0f3[8a] is
498 ;; still prefix_0f 1, with prefix_extra 1.
499 (define_attr "length_vex" ""
500   (if_then_else (and (eq_attr "prefix_0f" "1")
501                      (eq_attr "prefix_extra" "0"))
502     (if_then_else (eq_attr "prefix_vex_w" "1")
503       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
504       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
505     (if_then_else (eq_attr "prefix_vex_w" "1")
506       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
507       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
509 ;; Set when modrm byte is used.
510 (define_attr "modrm" ""
511   (cond [(eq_attr "type" "str,leave")
512            (const_int 0)
513          (eq_attr "unit" "i387")
514            (const_int 0)
515          (and (eq_attr "type" "incdec")
516               (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
517                    (ior (match_operand:SI 1 "register_operand" "")
518                         (match_operand:HI 1 "register_operand" ""))))
519            (const_int 0)
520          (and (eq_attr "type" "push")
521               (not (match_operand 1 "memory_operand" "")))
522            (const_int 0)
523          (and (eq_attr "type" "pop")
524               (not (match_operand 0 "memory_operand" "")))
525            (const_int 0)
526          (and (eq_attr "type" "imov")
527               (and (not (eq_attr "mode" "DI"))
528                    (ior (and (match_operand 0 "register_operand" "")
529                              (match_operand 1 "immediate_operand" ""))
530                         (ior (and (match_operand 0 "ax_reg_operand" "")
531                                   (match_operand 1 "memory_displacement_only_operand" ""))
532                              (and (match_operand 0 "memory_displacement_only_operand" "")
533                                   (match_operand 1 "ax_reg_operand" ""))))))
534            (const_int 0)
535          (and (eq_attr "type" "call")
536               (match_operand 0 "constant_call_address_operand" ""))
537              (const_int 0)
538          (and (eq_attr "type" "callv")
539               (match_operand 1 "constant_call_address_operand" ""))
540              (const_int 0)
541          (and (eq_attr "type" "alu,alu1,icmp,test")
542               (match_operand 0 "ax_reg_operand" ""))
543              (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
544          ]
545          (const_int 1)))
547 ;; The (bounding maximum) length of an instruction in bytes.
548 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
549 ;; Later we may want to split them and compute proper length as for
550 ;; other insns.
551 (define_attr "length" ""
552   (cond [(eq_attr "type" "other,multi,fistp,frndint")
553            (const_int 16)
554          (eq_attr "type" "fcmp")
555            (const_int 4)
556          (eq_attr "unit" "i387")
557            (plus (const_int 2)
558                  (plus (attr "prefix_data16")
559                        (attr "length_address")))
560          (ior (eq_attr "prefix" "vex")
561               (and (eq_attr "prefix" "maybe_vex")
562                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
563            (plus (attr "length_vex")
564                  (plus (attr "length_immediate")
565                        (plus (attr "modrm")
566                              (attr "length_address"))))]
567          (plus (plus (attr "modrm")
568                      (plus (attr "prefix_0f")
569                            (plus (attr "prefix_rex")
570                                  (plus (attr "prefix_extra")
571                                        (const_int 1)))))
572                (plus (attr "prefix_rep")
573                      (plus (attr "prefix_data16")
574                            (plus (attr "length_immediate")
575                                  (attr "length_address")))))))
577 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
578 ;; `store' if there is a simple memory reference therein, or `unknown'
579 ;; if the instruction is complex.
581 (define_attr "memory" "none,load,store,both,unknown"
582   (cond [(eq_attr "type" "other,multi,str,lwp")
583            (const_string "unknown")
584          (eq_attr "type" "lea,fcmov,fpspc")
585            (const_string "none")
586          (eq_attr "type" "fistp,leave")
587            (const_string "both")
588          (eq_attr "type" "frndint")
589            (const_string "load")
590          (eq_attr "type" "push")
591            (if_then_else (match_operand 1 "memory_operand" "")
592              (const_string "both")
593              (const_string "store"))
594          (eq_attr "type" "pop")
595            (if_then_else (match_operand 0 "memory_operand" "")
596              (const_string "both")
597              (const_string "load"))
598          (eq_attr "type" "setcc")
599            (if_then_else (match_operand 0 "memory_operand" "")
600              (const_string "store")
601              (const_string "none"))
602          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
603            (if_then_else (ior (match_operand 0 "memory_operand" "")
604                               (match_operand 1 "memory_operand" ""))
605              (const_string "load")
606              (const_string "none"))
607          (eq_attr "type" "ibr")
608            (if_then_else (match_operand 0 "memory_operand" "")
609              (const_string "load")
610              (const_string "none"))
611          (eq_attr "type" "call")
612            (if_then_else (match_operand 0 "constant_call_address_operand" "")
613              (const_string "none")
614              (const_string "load"))
615          (eq_attr "type" "callv")
616            (if_then_else (match_operand 1 "constant_call_address_operand" "")
617              (const_string "none")
618              (const_string "load"))
619          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
620               (match_operand 1 "memory_operand" ""))
621            (const_string "both")
622          (and (match_operand 0 "memory_operand" "")
623               (match_operand 1 "memory_operand" ""))
624            (const_string "both")
625          (match_operand 0 "memory_operand" "")
626            (const_string "store")
627          (match_operand 1 "memory_operand" "")
628            (const_string "load")
629          (and (eq_attr "type"
630                  "!alu1,negnot,ishift1,
631                    imov,imovx,icmp,test,bitmanip,
632                    fmov,fcmp,fsgn,
633                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
634                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
635               (match_operand 2 "memory_operand" ""))
636            (const_string "load")
637          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
638               (match_operand 3 "memory_operand" ""))
639            (const_string "load")
640         ]
641         (const_string "none")))
643 ;; Indicates if an instruction has both an immediate and a displacement.
645 (define_attr "imm_disp" "false,true,unknown"
646   (cond [(eq_attr "type" "other,multi")
647            (const_string "unknown")
648          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
649               (and (match_operand 0 "memory_displacement_operand" "")
650                    (match_operand 1 "immediate_operand" "")))
651            (const_string "true")
652          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
653               (and (match_operand 0 "memory_displacement_operand" "")
654                    (match_operand 2 "immediate_operand" "")))
655            (const_string "true")
656         ]
657         (const_string "false")))
659 ;; Indicates if an FP operation has an integer source.
661 (define_attr "fp_int_src" "false,true"
662   (const_string "false"))
664 ;; Defines rounding mode of an FP operation.
666 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
667   (const_string "any"))
669 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
670 (define_attr "use_carry" "0,1" (const_string "0"))
672 ;; Define attribute to indicate unaligned ssemov insns
673 (define_attr "movu" "0,1" (const_string "0"))
675 ;; Describe a user's asm statement.
676 (define_asm_attributes
677   [(set_attr "length" "128")
678    (set_attr "type" "multi")])
680 ;; All integer comparison codes.
681 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu])
683 ;; All floating-point comparison codes.
684 (define_code_iterator fp_cond [unordered ordered
685                                uneq unge ungt unle unlt ltgt])
687 (define_code_iterator plusminus [plus minus])
689 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
691 ;; Base name for define_insn
692 (define_code_attr plusminus_insn
693   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
694    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
696 ;; Base name for insn mnemonic.
697 (define_code_attr plusminus_mnemonic
698   [(plus "add") (ss_plus "adds") (us_plus "addus")
699    (minus "sub") (ss_minus "subs") (us_minus "subus")])
700 (define_code_attr plusminus_carry_mnemonic
701   [(plus "adc") (minus "sbb")])
703 ;; Mark commutative operators as such in constraints.
704 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
705                         (minus "") (ss_minus "") (us_minus "")])
707 ;; Mapping of signed max and min
708 (define_code_iterator smaxmin [smax smin])
710 ;; Mapping of unsigned max and min
711 (define_code_iterator umaxmin [umax umin])
713 ;; Mapping of signed/unsigned max and min
714 (define_code_iterator maxmin [smax smin umax umin])
716 ;; Base name for integer and FP insn mnemonic
717 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
718                                  (umax "maxu") (umin "minu")])
719 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
721 ;; Mapping of logic operators
722 (define_code_iterator any_logic [and ior xor])
723 (define_code_iterator any_or [ior xor])
725 ;; Base name for insn mnemonic.
726 (define_code_attr logicprefix [(and "and") (ior "or") (xor "xor")])
728 ;; Mapping of abs neg operators
729 (define_code_iterator absneg [abs neg])
731 ;; Base name for x87 insn mnemonic.
732 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
734 ;; Used in signed and unsigned widening multiplications.
735 (define_code_iterator any_extend [sign_extend zero_extend])
737 ;; Various insn prefixes for signed and unsigned operations.
738 (define_code_attr u [(sign_extend "") (zero_extend "u")
739                      (div "") (udiv "u")])
740 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
742 ;; Used in signed and unsigned divisions.
743 (define_code_iterator any_div [div udiv])
745 ;; Instruction prefix for signed and unsigned operations.
746 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
747                              (div "i") (udiv "")])
749 ;; All single word integer modes.
750 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
752 ;; Single word integer modes without DImode.
753 (define_mode_iterator SWI124 [QI HI SI])
755 ;; Single word integer modes without QImode.
756 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
758 ;; Single word integer modes without QImode and HImode.
759 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
761 ;; All math-dependant single and double word integer modes.
762 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
763                              (HI "TARGET_HIMODE_MATH")
764                              SI DI (TI "TARGET_64BIT")])
766 ;; Math-dependant single word integer modes.
767 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
768                             (HI "TARGET_HIMODE_MATH")
769                             SI (DI "TARGET_64BIT")])
771 ;; Math-dependant single word integer modes without QImode.
772 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
773                                SI (DI "TARGET_64BIT")])
775 ;; Half mode for double word integer modes.
776 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
777                             (DI "TARGET_64BIT")])
779 ;; Double word integer modes.
780 (define_mode_attr DWI [(SI "DI") (DI "TI")])
781 (define_mode_attr dwi [(SI "di") (DI "ti")])
783 ;; Instruction suffix for integer modes.
784 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
786 ;; Register class for integer modes.
787 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
789 ;; Immediate operand constraint for integer modes.
790 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
792 ;; General operand constraint for word modes.
793 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
795 ;; Immediate operand constraint for double integer modes.
796 (define_mode_attr di [(SI "iF") (DI "e")])
798 ;; General operand predicate for integer modes.
799 (define_mode_attr general_operand
800         [(QI "general_operand")
801          (HI "general_operand")
802          (SI "general_operand")
803          (DI "x86_64_general_operand")
804          (TI "x86_64_general_operand")])
806 ;; General sign/zero extend operand predicate for integer modes.
807 (define_mode_attr general_szext_operand
808         [(QI "general_operand")
809          (HI "general_operand")
810          (SI "general_operand")
811          (DI "x86_64_szext_general_operand")])
813 ;; SSE and x87 SFmode and DFmode floating point modes
814 (define_mode_iterator MODEF [SF DF])
816 ;; All x87 floating point modes
817 (define_mode_iterator X87MODEF [SF DF XF])
819 ;; All integer modes handled by x87 fisttp operator.
820 (define_mode_iterator X87MODEI [HI SI DI])
822 ;; All integer modes handled by integer x87 operators.
823 (define_mode_iterator X87MODEI12 [HI SI])
825 ;; All integer modes handled by SSE cvtts?2si* operators.
826 (define_mode_iterator SSEMODEI24 [SI DI])
828 ;; SSE asm suffix for floating point modes
829 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
831 ;; SSE vector mode corresponding to a scalar mode
832 (define_mode_attr ssevecmode
833   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
835 ;; Instruction suffix for REX 64bit operators.
836 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
838 ;; This mode iterator allows :P to be used for patterns that operate on
839 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
840 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
842 ;; Scheduling descriptions
844 (include "pentium.md")
845 (include "ppro.md")
846 (include "k6.md")
847 (include "athlon.md")
848 (include "geode.md")
849 (include "atom.md")
852 ;; Operand and operator predicates and constraints
854 (include "predicates.md")
855 (include "constraints.md")
858 ;; Compare and branch/compare and store instructions.
860 (define_expand "cbranch<mode>4"
861   [(set (reg:CC FLAGS_REG)
862         (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
863                     (match_operand:SDWIM 2 "<general_operand>" "")))
864    (set (pc) (if_then_else
865                (match_operator 0 "comparison_operator"
866                 [(reg:CC FLAGS_REG) (const_int 0)])
867                (label_ref (match_operand 3 "" ""))
868                (pc)))]
869   ""
871   if (MEM_P (operands[1]) && MEM_P (operands[2]))
872     operands[1] = force_reg (<MODE>mode, operands[1]);
873   ix86_compare_op0 = operands[1];
874   ix86_compare_op1 = operands[2];
875   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
876   DONE;
879 (define_expand "cstore<mode>4"
880   [(set (reg:CC FLAGS_REG)
881         (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
882                     (match_operand:SWIM 3 "<general_operand>" "")))
883    (set (match_operand:QI 0 "register_operand" "")
884         (match_operator 1 "comparison_operator"
885           [(reg:CC FLAGS_REG) (const_int 0)]))]
886   ""
888   if (MEM_P (operands[2]) && MEM_P (operands[3]))
889     operands[2] = force_reg (<MODE>mode, operands[2]);
890   ix86_compare_op0 = operands[2];
891   ix86_compare_op1 = operands[3];
892   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
893   DONE;
896 (define_expand "cmp<mode>_1"
897   [(set (reg:CC FLAGS_REG)
898         (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
899                     (match_operand:SWI48 1 "<general_operand>" "")))]
900   ""
901   "")
903 (define_insn "*cmp<mode>_ccno_1"
904   [(set (reg FLAGS_REG)
905         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
906                  (match_operand:SWI 1 "const0_operand" "")))]
907   "ix86_match_ccmode (insn, CCNOmode)"
908   "@
909    test{<imodesuffix>}\t%0, %0
910    cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
911   [(set_attr "type" "test,icmp")
912    (set_attr "length_immediate" "0,1")
913    (set_attr "mode" "<MODE>")])
915 (define_insn "*cmp<mode>_1"
916   [(set (reg FLAGS_REG)
917         (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
918                  (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
919   "ix86_match_ccmode (insn, CCmode)"
920   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
921   [(set_attr "type" "icmp")
922    (set_attr "mode" "<MODE>")])
924 (define_insn "*cmp<mode>_minus_1"
925   [(set (reg FLAGS_REG)
926         (compare
927           (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
928                      (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
929           (const_int 0)))]
930   "ix86_match_ccmode (insn, CCGOCmode)"
931   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
932   [(set_attr "type" "icmp")
933    (set_attr "mode" "<MODE>")])
935 (define_insn "*cmpqi_ext_1"
936   [(set (reg FLAGS_REG)
937         (compare
938           (match_operand:QI 0 "general_operand" "Qm")
939           (subreg:QI
940             (zero_extract:SI
941               (match_operand 1 "ext_register_operand" "Q")
942               (const_int 8)
943               (const_int 8)) 0)))]
944   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
945   "cmp{b}\t{%h1, %0|%0, %h1}"
946   [(set_attr "type" "icmp")
947    (set_attr "mode" "QI")])
949 (define_insn "*cmpqi_ext_1_rex64"
950   [(set (reg FLAGS_REG)
951         (compare
952           (match_operand:QI 0 "register_operand" "Q")
953           (subreg:QI
954             (zero_extract:SI
955               (match_operand 1 "ext_register_operand" "Q")
956               (const_int 8)
957               (const_int 8)) 0)))]
958   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
959   "cmp{b}\t{%h1, %0|%0, %h1}"
960   [(set_attr "type" "icmp")
961    (set_attr "mode" "QI")])
963 (define_insn "*cmpqi_ext_2"
964   [(set (reg FLAGS_REG)
965         (compare
966           (subreg:QI
967             (zero_extract:SI
968               (match_operand 0 "ext_register_operand" "Q")
969               (const_int 8)
970               (const_int 8)) 0)
971           (match_operand:QI 1 "const0_operand" "")))]
972   "ix86_match_ccmode (insn, CCNOmode)"
973   "test{b}\t%h0, %h0"
974   [(set_attr "type" "test")
975    (set_attr "length_immediate" "0")
976    (set_attr "mode" "QI")])
978 (define_expand "cmpqi_ext_3"
979   [(set (reg:CC FLAGS_REG)
980         (compare:CC
981           (subreg:QI
982             (zero_extract:SI
983               (match_operand 0 "ext_register_operand" "")
984               (const_int 8)
985               (const_int 8)) 0)
986           (match_operand:QI 1 "immediate_operand" "")))]
987   ""
988   "")
990 (define_insn "*cmpqi_ext_3_insn"
991   [(set (reg FLAGS_REG)
992         (compare
993           (subreg:QI
994             (zero_extract:SI
995               (match_operand 0 "ext_register_operand" "Q")
996               (const_int 8)
997               (const_int 8)) 0)
998           (match_operand:QI 1 "general_operand" "Qmn")))]
999   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1000   "cmp{b}\t{%1, %h0|%h0, %1}"
1001   [(set_attr "type" "icmp")
1002    (set_attr "modrm" "1")
1003    (set_attr "mode" "QI")])
1005 (define_insn "*cmpqi_ext_3_insn_rex64"
1006   [(set (reg FLAGS_REG)
1007         (compare
1008           (subreg:QI
1009             (zero_extract:SI
1010               (match_operand 0 "ext_register_operand" "Q")
1011               (const_int 8)
1012               (const_int 8)) 0)
1013           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1014   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1015   "cmp{b}\t{%1, %h0|%h0, %1}"
1016   [(set_attr "type" "icmp")
1017    (set_attr "modrm" "1")
1018    (set_attr "mode" "QI")])
1020 (define_insn "*cmpqi_ext_4"
1021   [(set (reg FLAGS_REG)
1022         (compare
1023           (subreg:QI
1024             (zero_extract:SI
1025               (match_operand 0 "ext_register_operand" "Q")
1026               (const_int 8)
1027               (const_int 8)) 0)
1028           (subreg:QI
1029             (zero_extract:SI
1030               (match_operand 1 "ext_register_operand" "Q")
1031               (const_int 8)
1032               (const_int 8)) 0)))]
1033   "ix86_match_ccmode (insn, CCmode)"
1034   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1035   [(set_attr "type" "icmp")
1036    (set_attr "mode" "QI")])
1038 ;; These implement float point compares.
1039 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1040 ;; which would allow mix and match FP modes on the compares.  Which is what
1041 ;; the old patterns did, but with many more of them.
1043 (define_expand "cbranchxf4"
1044   [(set (reg:CC FLAGS_REG)
1045         (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1046                     (match_operand:XF 2 "nonmemory_operand" "")))
1047    (set (pc) (if_then_else
1048               (match_operator 0 "ix86_fp_comparison_operator"
1049                [(reg:CC FLAGS_REG)
1050                 (const_int 0)])
1051               (label_ref (match_operand 3 "" ""))
1052               (pc)))]
1053   "TARGET_80387"
1055   ix86_compare_op0 = operands[1];
1056   ix86_compare_op1 = operands[2];
1057   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1058   DONE;
1061 (define_expand "cstorexf4"
1062   [(set (reg:CC FLAGS_REG)
1063         (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1064                     (match_operand:XF 3 "nonmemory_operand" "")))
1065    (set (match_operand:QI 0 "register_operand" "")
1066               (match_operator 1 "ix86_fp_comparison_operator"
1067                [(reg:CC FLAGS_REG)
1068                 (const_int 0)]))]
1069   "TARGET_80387"
1071   ix86_compare_op0 = operands[2];
1072   ix86_compare_op1 = operands[3];
1073   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1074   DONE;
1077 (define_expand "cbranch<mode>4"
1078   [(set (reg:CC FLAGS_REG)
1079         (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1080                     (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1081    (set (pc) (if_then_else
1082               (match_operator 0 "ix86_fp_comparison_operator"
1083                [(reg:CC FLAGS_REG)
1084                 (const_int 0)])
1085               (label_ref (match_operand 3 "" ""))
1086               (pc)))]
1087   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1089   ix86_compare_op0 = operands[1];
1090   ix86_compare_op1 = operands[2];
1091   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1092   DONE;
1095 (define_expand "cstore<mode>4"
1096   [(set (reg:CC FLAGS_REG)
1097         (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1098                     (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1099    (set (match_operand:QI 0 "register_operand" "")
1100               (match_operator 1 "ix86_fp_comparison_operator"
1101                [(reg:CC FLAGS_REG)
1102                 (const_int 0)]))]
1103   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1105   ix86_compare_op0 = operands[2];
1106   ix86_compare_op1 = operands[3];
1107   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1108   DONE;
1111 (define_expand "cbranchcc4"
1112   [(set (pc) (if_then_else
1113               (match_operator 0 "comparison_operator"
1114                [(match_operand 1 "flags_reg_operand" "")
1115                 (match_operand 2 "const0_operand" "")])
1116               (label_ref (match_operand 3 "" ""))
1117               (pc)))]
1118   ""
1120   ix86_compare_op0 = operands[1];
1121   ix86_compare_op1 = operands[2];
1122   ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1123   DONE;
1126 (define_expand "cstorecc4"
1127   [(set (match_operand:QI 0 "register_operand" "")
1128               (match_operator 1 "comparison_operator"
1129                [(match_operand 2 "flags_reg_operand" "")
1130                 (match_operand 3 "const0_operand" "")]))]
1131   ""
1133   ix86_compare_op0 = operands[2];
1134   ix86_compare_op1 = operands[3];
1135   ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1136   DONE;
1140 ;; FP compares, step 1:
1141 ;; Set the FP condition codes.
1143 ;; CCFPmode     compare with exceptions
1144 ;; CCFPUmode    compare with no exceptions
1146 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1147 ;; used to manage the reg stack popping would not be preserved.
1149 (define_insn "*cmpfp_0"
1150   [(set (match_operand:HI 0 "register_operand" "=a")
1151         (unspec:HI
1152           [(compare:CCFP
1153              (match_operand 1 "register_operand" "f")
1154              (match_operand 2 "const0_operand" ""))]
1155         UNSPEC_FNSTSW))]
1156   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1157    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1158   "* return output_fp_compare (insn, operands, 0, 0);"
1159   [(set_attr "type" "multi")
1160    (set_attr "unit" "i387")
1161    (set (attr "mode")
1162      (cond [(match_operand:SF 1 "" "")
1163               (const_string "SF")
1164             (match_operand:DF 1 "" "")
1165               (const_string "DF")
1166            ]
1167            (const_string "XF")))])
1169 (define_insn_and_split "*cmpfp_0_cc"
1170   [(set (reg:CCFP FLAGS_REG)
1171         (compare:CCFP
1172           (match_operand 1 "register_operand" "f")
1173           (match_operand 2 "const0_operand" "")))
1174    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1175   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1176    && TARGET_SAHF && !TARGET_CMOVE
1177    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1178   "#"
1179   "&& reload_completed"
1180   [(set (match_dup 0)
1181         (unspec:HI
1182           [(compare:CCFP (match_dup 1)(match_dup 2))]
1183         UNSPEC_FNSTSW))
1184    (set (reg:CC FLAGS_REG)
1185         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1186   ""
1187   [(set_attr "type" "multi")
1188    (set_attr "unit" "i387")
1189    (set (attr "mode")
1190      (cond [(match_operand:SF 1 "" "")
1191               (const_string "SF")
1192             (match_operand:DF 1 "" "")
1193               (const_string "DF")
1194            ]
1195            (const_string "XF")))])
1197 (define_insn "*cmpfp_xf"
1198   [(set (match_operand:HI 0 "register_operand" "=a")
1199         (unspec:HI
1200           [(compare:CCFP
1201              (match_operand:XF 1 "register_operand" "f")
1202              (match_operand:XF 2 "register_operand" "f"))]
1203           UNSPEC_FNSTSW))]
1204   "TARGET_80387"
1205   "* return output_fp_compare (insn, operands, 0, 0);"
1206   [(set_attr "type" "multi")
1207    (set_attr "unit" "i387")
1208    (set_attr "mode" "XF")])
1210 (define_insn_and_split "*cmpfp_xf_cc"
1211   [(set (reg:CCFP FLAGS_REG)
1212         (compare:CCFP
1213           (match_operand:XF 1 "register_operand" "f")
1214           (match_operand:XF 2 "register_operand" "f")))
1215    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1216   "TARGET_80387
1217    && TARGET_SAHF && !TARGET_CMOVE"
1218   "#"
1219   "&& reload_completed"
1220   [(set (match_dup 0)
1221         (unspec:HI
1222           [(compare:CCFP (match_dup 1)(match_dup 2))]
1223         UNSPEC_FNSTSW))
1224    (set (reg:CC FLAGS_REG)
1225         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1226   ""
1227   [(set_attr "type" "multi")
1228    (set_attr "unit" "i387")
1229    (set_attr "mode" "XF")])
1231 (define_insn "*cmpfp_<mode>"
1232   [(set (match_operand:HI 0 "register_operand" "=a")
1233         (unspec:HI
1234           [(compare:CCFP
1235              (match_operand:MODEF 1 "register_operand" "f")
1236              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1237           UNSPEC_FNSTSW))]
1238   "TARGET_80387"
1239   "* return output_fp_compare (insn, operands, 0, 0);"
1240   [(set_attr "type" "multi")
1241    (set_attr "unit" "i387")
1242    (set_attr "mode" "<MODE>")])
1244 (define_insn_and_split "*cmpfp_<mode>_cc"
1245   [(set (reg:CCFP FLAGS_REG)
1246         (compare:CCFP
1247           (match_operand:MODEF 1 "register_operand" "f")
1248           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1249    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1250   "TARGET_80387
1251    && TARGET_SAHF && !TARGET_CMOVE"
1252   "#"
1253   "&& reload_completed"
1254   [(set (match_dup 0)
1255         (unspec:HI
1256           [(compare:CCFP (match_dup 1)(match_dup 2))]
1257         UNSPEC_FNSTSW))
1258    (set (reg:CC FLAGS_REG)
1259         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1260   ""
1261   [(set_attr "type" "multi")
1262    (set_attr "unit" "i387")
1263    (set_attr "mode" "<MODE>")])
1265 (define_insn "*cmpfp_u"
1266   [(set (match_operand:HI 0 "register_operand" "=a")
1267         (unspec:HI
1268           [(compare:CCFPU
1269              (match_operand 1 "register_operand" "f")
1270              (match_operand 2 "register_operand" "f"))]
1271           UNSPEC_FNSTSW))]
1272   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1273    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1274   "* return output_fp_compare (insn, operands, 0, 1);"
1275   [(set_attr "type" "multi")
1276    (set_attr "unit" "i387")
1277    (set (attr "mode")
1278      (cond [(match_operand:SF 1 "" "")
1279               (const_string "SF")
1280             (match_operand:DF 1 "" "")
1281               (const_string "DF")
1282            ]
1283            (const_string "XF")))])
1285 (define_insn_and_split "*cmpfp_u_cc"
1286   [(set (reg:CCFPU FLAGS_REG)
1287         (compare:CCFPU
1288           (match_operand 1 "register_operand" "f")
1289           (match_operand 2 "register_operand" "f")))
1290    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1291   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1292    && TARGET_SAHF && !TARGET_CMOVE
1293    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1294   "#"
1295   "&& reload_completed"
1296   [(set (match_dup 0)
1297         (unspec:HI
1298           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1299         UNSPEC_FNSTSW))
1300    (set (reg:CC FLAGS_REG)
1301         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1302   ""
1303   [(set_attr "type" "multi")
1304    (set_attr "unit" "i387")
1305    (set (attr "mode")
1306      (cond [(match_operand:SF 1 "" "")
1307               (const_string "SF")
1308             (match_operand:DF 1 "" "")
1309               (const_string "DF")
1310            ]
1311            (const_string "XF")))])
1313 (define_insn "*cmpfp_<mode>"
1314   [(set (match_operand:HI 0 "register_operand" "=a")
1315         (unspec:HI
1316           [(compare:CCFP
1317              (match_operand 1 "register_operand" "f")
1318              (match_operator 3 "float_operator"
1319                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1320           UNSPEC_FNSTSW))]
1321   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1322    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1323    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1324   "* return output_fp_compare (insn, operands, 0, 0);"
1325   [(set_attr "type" "multi")
1326    (set_attr "unit" "i387")
1327    (set_attr "fp_int_src" "true")
1328    (set_attr "mode" "<MODE>")])
1330 (define_insn_and_split "*cmpfp_<mode>_cc"
1331   [(set (reg:CCFP FLAGS_REG)
1332         (compare:CCFP
1333           (match_operand 1 "register_operand" "f")
1334           (match_operator 3 "float_operator"
1335             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1336    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1337   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1338    && TARGET_SAHF && !TARGET_CMOVE
1339    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1340    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1341   "#"
1342   "&& reload_completed"
1343   [(set (match_dup 0)
1344         (unspec:HI
1345           [(compare:CCFP
1346              (match_dup 1)
1347              (match_op_dup 3 [(match_dup 2)]))]
1348         UNSPEC_FNSTSW))
1349    (set (reg:CC FLAGS_REG)
1350         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1351   ""
1352   [(set_attr "type" "multi")
1353    (set_attr "unit" "i387")
1354    (set_attr "fp_int_src" "true")
1355    (set_attr "mode" "<MODE>")])
1357 ;; FP compares, step 2
1358 ;; Move the fpsw to ax.
1360 (define_insn "x86_fnstsw_1"
1361   [(set (match_operand:HI 0 "register_operand" "=a")
1362         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1363   "TARGET_80387"
1364   "fnstsw\t%0"
1365   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1366    (set_attr "mode" "SI")
1367    (set_attr "unit" "i387")])
1369 ;; FP compares, step 3
1370 ;; Get ax into flags, general case.
1372 (define_insn "x86_sahf_1"
1373   [(set (reg:CC FLAGS_REG)
1374         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1375                    UNSPEC_SAHF))]
1376   "TARGET_SAHF"
1378 #ifdef HAVE_AS_IX86_SAHF
1379   return "sahf";
1380 #else
1381   return ASM_BYTE "0x9e";
1382 #endif
1384   [(set_attr "length" "1")
1385    (set_attr "athlon_decode" "vector")
1386    (set_attr "amdfam10_decode" "direct")
1387    (set_attr "mode" "SI")])
1389 ;; Pentium Pro can do steps 1 through 3 in one go.
1390 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1391 (define_insn "*cmpfp_i_mixed"
1392   [(set (reg:CCFP FLAGS_REG)
1393         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1394                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1395   "TARGET_MIX_SSE_I387
1396    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1397    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1398   "* return output_fp_compare (insn, operands, 1, 0);"
1399   [(set_attr "type" "fcmp,ssecomi")
1400    (set_attr "prefix" "orig,maybe_vex")
1401    (set (attr "mode")
1402      (if_then_else (match_operand:SF 1 "" "")
1403         (const_string "SF")
1404         (const_string "DF")))
1405    (set (attr "prefix_rep")
1406         (if_then_else (eq_attr "type" "ssecomi")
1407                       (const_string "0")
1408                       (const_string "*")))
1409    (set (attr "prefix_data16")
1410         (cond [(eq_attr "type" "fcmp")
1411                  (const_string "*")
1412                (eq_attr "mode" "DF")
1413                  (const_string "1")
1414               ]
1415               (const_string "0")))
1416    (set_attr "athlon_decode" "vector")
1417    (set_attr "amdfam10_decode" "direct")])
1419 (define_insn "*cmpfp_i_sse"
1420   [(set (reg:CCFP FLAGS_REG)
1421         (compare:CCFP (match_operand 0 "register_operand" "x")
1422                       (match_operand 1 "nonimmediate_operand" "xm")))]
1423   "TARGET_SSE_MATH
1424    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1425    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1426   "* return output_fp_compare (insn, operands, 1, 0);"
1427   [(set_attr "type" "ssecomi")
1428    (set_attr "prefix" "maybe_vex")
1429    (set (attr "mode")
1430      (if_then_else (match_operand:SF 1 "" "")
1431         (const_string "SF")
1432         (const_string "DF")))
1433    (set_attr "prefix_rep" "0")
1434    (set (attr "prefix_data16")
1435         (if_then_else (eq_attr "mode" "DF")
1436                       (const_string "1")
1437                       (const_string "0")))
1438    (set_attr "athlon_decode" "vector")
1439    (set_attr "amdfam10_decode" "direct")])
1441 (define_insn "*cmpfp_i_i387"
1442   [(set (reg:CCFP FLAGS_REG)
1443         (compare:CCFP (match_operand 0 "register_operand" "f")
1444                       (match_operand 1 "register_operand" "f")))]
1445   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1446    && TARGET_CMOVE
1447    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1448    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1449   "* return output_fp_compare (insn, operands, 1, 0);"
1450   [(set_attr "type" "fcmp")
1451    (set (attr "mode")
1452      (cond [(match_operand:SF 1 "" "")
1453               (const_string "SF")
1454             (match_operand:DF 1 "" "")
1455               (const_string "DF")
1456            ]
1457            (const_string "XF")))
1458    (set_attr "athlon_decode" "vector")
1459    (set_attr "amdfam10_decode" "direct")])
1461 (define_insn "*cmpfp_iu_mixed"
1462   [(set (reg:CCFPU FLAGS_REG)
1463         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1464                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1465   "TARGET_MIX_SSE_I387
1466    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1467    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1468   "* return output_fp_compare (insn, operands, 1, 1);"
1469   [(set_attr "type" "fcmp,ssecomi")
1470    (set_attr "prefix" "orig,maybe_vex")
1471    (set (attr "mode")
1472      (if_then_else (match_operand:SF 1 "" "")
1473         (const_string "SF")
1474         (const_string "DF")))
1475    (set (attr "prefix_rep")
1476         (if_then_else (eq_attr "type" "ssecomi")
1477                       (const_string "0")
1478                       (const_string "*")))
1479    (set (attr "prefix_data16")
1480         (cond [(eq_attr "type" "fcmp")
1481                  (const_string "*")
1482                (eq_attr "mode" "DF")
1483                  (const_string "1")
1484               ]
1485               (const_string "0")))
1486    (set_attr "athlon_decode" "vector")
1487    (set_attr "amdfam10_decode" "direct")])
1489 (define_insn "*cmpfp_iu_sse"
1490   [(set (reg:CCFPU FLAGS_REG)
1491         (compare:CCFPU (match_operand 0 "register_operand" "x")
1492                        (match_operand 1 "nonimmediate_operand" "xm")))]
1493   "TARGET_SSE_MATH
1494    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1495    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1496   "* return output_fp_compare (insn, operands, 1, 1);"
1497   [(set_attr "type" "ssecomi")
1498    (set_attr "prefix" "maybe_vex")
1499    (set (attr "mode")
1500      (if_then_else (match_operand:SF 1 "" "")
1501         (const_string "SF")
1502         (const_string "DF")))
1503    (set_attr "prefix_rep" "0")
1504    (set (attr "prefix_data16")
1505         (if_then_else (eq_attr "mode" "DF")
1506                       (const_string "1")
1507                       (const_string "0")))
1508    (set_attr "athlon_decode" "vector")
1509    (set_attr "amdfam10_decode" "direct")])
1511 (define_insn "*cmpfp_iu_387"
1512   [(set (reg:CCFPU FLAGS_REG)
1513         (compare:CCFPU (match_operand 0 "register_operand" "f")
1514                        (match_operand 1 "register_operand" "f")))]
1515   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1516    && TARGET_CMOVE
1517    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1518    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1519   "* return output_fp_compare (insn, operands, 1, 1);"
1520   [(set_attr "type" "fcmp")
1521    (set (attr "mode")
1522      (cond [(match_operand:SF 1 "" "")
1523               (const_string "SF")
1524             (match_operand:DF 1 "" "")
1525               (const_string "DF")
1526            ]
1527            (const_string "XF")))
1528    (set_attr "athlon_decode" "vector")
1529    (set_attr "amdfam10_decode" "direct")])
1531 ;; Move instructions.
1533 ;; General case of fullword move.
1535 (define_expand "movsi"
1536   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1537         (match_operand:SI 1 "general_operand" ""))]
1538   ""
1539   "ix86_expand_move (SImode, operands); DONE;")
1541 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1542 ;; general_operand.
1544 ;; %%% We don't use a post-inc memory reference because x86 is not a
1545 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1546 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1547 ;; targets without our curiosities, and it is just as easy to represent
1548 ;; this differently.
1550 (define_insn "*pushsi2"
1551   [(set (match_operand:SI 0 "push_operand" "=<")
1552         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1553   "!TARGET_64BIT"
1554   "push{l}\t%1"
1555   [(set_attr "type" "push")
1556    (set_attr "mode" "SI")])
1558 ;; For 64BIT abi we always round up to 8 bytes.
1559 (define_insn "*pushsi2_rex64"
1560   [(set (match_operand:SI 0 "push_operand" "=X")
1561         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1562   "TARGET_64BIT"
1563   "push{q}\t%q1"
1564   [(set_attr "type" "push")
1565    (set_attr "mode" "SI")])
1567 (define_insn "*pushsi2_prologue"
1568   [(set (match_operand:SI 0 "push_operand" "=<")
1569         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1570    (clobber (mem:BLK (scratch)))]
1571   "!TARGET_64BIT"
1572   "push{l}\t%1"
1573   [(set_attr "type" "push")
1574    (set_attr "mode" "SI")])
1576 (define_insn "*popsi1_epilogue"
1577   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1578         (mem:SI (reg:SI SP_REG)))
1579    (set (reg:SI SP_REG)
1580         (plus:SI (reg:SI SP_REG) (const_int 4)))
1581    (clobber (mem:BLK (scratch)))]
1582   "!TARGET_64BIT"
1583   "pop{l}\t%0"
1584   [(set_attr "type" "pop")
1585    (set_attr "mode" "SI")])
1587 (define_insn "popsi1"
1588   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1589         (mem:SI (reg:SI SP_REG)))
1590    (set (reg:SI SP_REG)
1591         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1592   "!TARGET_64BIT"
1593   "pop{l}\t%0"
1594   [(set_attr "type" "pop")
1595    (set_attr "mode" "SI")])
1597 (define_insn "*movsi_xor"
1598   [(set (match_operand:SI 0 "register_operand" "=r")
1599         (match_operand:SI 1 "const0_operand" ""))
1600    (clobber (reg:CC FLAGS_REG))]
1601   "reload_completed"
1602   "xor{l}\t%0, %0"
1603   [(set_attr "type" "alu1")
1604    (set_attr "mode" "SI")
1605    (set_attr "length_immediate" "0")])
1607 (define_insn "*movsi_or"
1608   [(set (match_operand:SI 0 "register_operand" "=r")
1609         (match_operand:SI 1 "immediate_operand" "i"))
1610    (clobber (reg:CC FLAGS_REG))]
1611   "reload_completed
1612    && operands[1] == constm1_rtx"
1614   operands[1] = constm1_rtx;
1615   return "or{l}\t{%1, %0|%0, %1}";
1617   [(set_attr "type" "alu1")
1618    (set_attr "mode" "SI")
1619    (set_attr "length_immediate" "1")])
1621 (define_insn "*movsi_1"
1622   [(set (match_operand:SI 0 "nonimmediate_operand"
1623                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1624         (match_operand:SI 1 "general_operand"
1625                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1626   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1628   switch (get_attr_type (insn))
1629     {
1630     case TYPE_SSELOG1:
1631       if (get_attr_mode (insn) == MODE_TI)
1632         return "%vpxor\t%0, %d0";
1633       return "%vxorps\t%0, %d0";
1635     case TYPE_SSEMOV:
1636       switch (get_attr_mode (insn))
1637         {
1638         case MODE_TI:
1639           return "%vmovdqa\t{%1, %0|%0, %1}";
1640         case MODE_V4SF:
1641           return "%vmovaps\t{%1, %0|%0, %1}";
1642         case MODE_SI:
1643           return "%vmovd\t{%1, %0|%0, %1}";
1644         case MODE_SF:
1645           return "%vmovss\t{%1, %0|%0, %1}";
1646         default:
1647           gcc_unreachable ();
1648         }
1650     case TYPE_MMX:
1651       return "pxor\t%0, %0";
1653     case TYPE_MMXMOV:
1654       if (get_attr_mode (insn) == MODE_DI)
1655         return "movq\t{%1, %0|%0, %1}";
1656       return "movd\t{%1, %0|%0, %1}";
1658     case TYPE_LEA:
1659       return "lea{l}\t{%1, %0|%0, %1}";
1661     default:
1662       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1663       return "mov{l}\t{%1, %0|%0, %1}";
1664     }
1666   [(set (attr "type")
1667      (cond [(eq_attr "alternative" "2")
1668               (const_string "mmx")
1669             (eq_attr "alternative" "3,4,5")
1670               (const_string "mmxmov")
1671             (eq_attr "alternative" "6")
1672               (const_string "sselog1")
1673             (eq_attr "alternative" "7,8,9,10,11")
1674               (const_string "ssemov")
1675             (match_operand:DI 1 "pic_32bit_operand" "")
1676               (const_string "lea")
1677            ]
1678            (const_string "imov")))
1679    (set (attr "prefix")
1680      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1681        (const_string "orig")
1682        (const_string "maybe_vex")))
1683    (set (attr "prefix_data16")
1684      (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1685        (const_string "1")
1686        (const_string "*")))
1687    (set (attr "mode")
1688      (cond [(eq_attr "alternative" "2,3")
1689               (const_string "DI")
1690             (eq_attr "alternative" "6,7")
1691               (if_then_else
1692                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1693                 (const_string "V4SF")
1694                 (const_string "TI"))
1695             (and (eq_attr "alternative" "8,9,10,11")
1696                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1697               (const_string "SF")
1698            ]
1699            (const_string "SI")))])
1701 ;; Stores and loads of ax to arbitrary constant address.
1702 ;; We fake an second form of instruction to force reload to load address
1703 ;; into register when rax is not available
1704 (define_insn "*movabssi_1_rex64"
1705   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1706         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1707   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1708   "@
1709    movabs{l}\t{%1, %P0|%P0, %1}
1710    mov{l}\t{%1, %a0|%a0, %1}"
1711   [(set_attr "type" "imov")
1712    (set_attr "modrm" "0,*")
1713    (set_attr "length_address" "8,0")
1714    (set_attr "length_immediate" "0,*")
1715    (set_attr "memory" "store")
1716    (set_attr "mode" "SI")])
1718 (define_insn "*movabssi_2_rex64"
1719   [(set (match_operand:SI 0 "register_operand" "=a,r")
1720         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1721   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1722   "@
1723    movabs{l}\t{%P1, %0|%0, %P1}
1724    mov{l}\t{%a1, %0|%0, %a1}"
1725   [(set_attr "type" "imov")
1726    (set_attr "modrm" "0,*")
1727    (set_attr "length_address" "8,0")
1728    (set_attr "length_immediate" "0")
1729    (set_attr "memory" "load")
1730    (set_attr "mode" "SI")])
1732 (define_insn "*swapsi"
1733   [(set (match_operand:SI 0 "register_operand" "+r")
1734         (match_operand:SI 1 "register_operand" "+r"))
1735    (set (match_dup 1)
1736         (match_dup 0))]
1737   ""
1738   "xchg{l}\t%1, %0"
1739   [(set_attr "type" "imov")
1740    (set_attr "mode" "SI")
1741    (set_attr "pent_pair" "np")
1742    (set_attr "athlon_decode" "vector")
1743    (set_attr "amdfam10_decode" "double")])
1745 (define_expand "movhi"
1746   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1747         (match_operand:HI 1 "general_operand" ""))]
1748   ""
1749   "ix86_expand_move (HImode, operands); DONE;")
1751 (define_insn "*pushhi2"
1752   [(set (match_operand:HI 0 "push_operand" "=X")
1753         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1754   "!TARGET_64BIT"
1755   "push{l}\t%k1"
1756   [(set_attr "type" "push")
1757    (set_attr "mode" "SI")])
1759 ;; For 64BIT abi we always round up to 8 bytes.
1760 (define_insn "*pushhi2_rex64"
1761   [(set (match_operand:HI 0 "push_operand" "=X")
1762         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1763   "TARGET_64BIT"
1764   "push{q}\t%q1"
1765   [(set_attr "type" "push")
1766    (set_attr "mode" "DI")])
1768 (define_insn "*movhi_1"
1769   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1770         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1771   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1773   switch (get_attr_type (insn))
1774     {
1775     case TYPE_IMOVX:
1776       /* movzwl is faster than movw on p2 due to partial word stalls,
1777          though not as fast as an aligned movl.  */
1778       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1779     default:
1780       if (get_attr_mode (insn) == MODE_SI)
1781         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1782       else
1783         return "mov{w}\t{%1, %0|%0, %1}";
1784     }
1786   [(set (attr "type")
1787      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1788               (const_string "imov")
1789             (and (eq_attr "alternative" "0")
1790                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1791                           (const_int 0))
1792                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1793                           (const_int 0))))
1794               (const_string "imov")
1795             (and (eq_attr "alternative" "1,2")
1796                  (match_operand:HI 1 "aligned_operand" ""))
1797               (const_string "imov")
1798             (and (ne (symbol_ref "TARGET_MOVX")
1799                      (const_int 0))
1800                  (eq_attr "alternative" "0,2"))
1801               (const_string "imovx")
1802            ]
1803            (const_string "imov")))
1804     (set (attr "mode")
1805       (cond [(eq_attr "type" "imovx")
1806                (const_string "SI")
1807              (and (eq_attr "alternative" "1,2")
1808                   (match_operand:HI 1 "aligned_operand" ""))
1809                (const_string "SI")
1810              (and (eq_attr "alternative" "0")
1811                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1812                            (const_int 0))
1813                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1814                            (const_int 0))))
1815                (const_string "SI")
1816             ]
1817             (const_string "HI")))])
1819 ;; Stores and loads of ax to arbitrary constant address.
1820 ;; We fake an second form of instruction to force reload to load address
1821 ;; into register when rax is not available
1822 (define_insn "*movabshi_1_rex64"
1823   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1824         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1825   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1826   "@
1827    movabs{w}\t{%1, %P0|%P0, %1}
1828    mov{w}\t{%1, %a0|%a0, %1}"
1829   [(set_attr "type" "imov")
1830    (set_attr "modrm" "0,*")
1831    (set_attr "length_address" "8,0")
1832    (set_attr "length_immediate" "0,*")
1833    (set_attr "memory" "store")
1834    (set_attr "mode" "HI")])
1836 (define_insn "*movabshi_2_rex64"
1837   [(set (match_operand:HI 0 "register_operand" "=a,r")
1838         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1839   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1840   "@
1841    movabs{w}\t{%P1, %0|%0, %P1}
1842    mov{w}\t{%a1, %0|%0, %a1}"
1843   [(set_attr "type" "imov")
1844    (set_attr "modrm" "0,*")
1845    (set_attr "length_address" "8,0")
1846    (set_attr "length_immediate" "0")
1847    (set_attr "memory" "load")
1848    (set_attr "mode" "HI")])
1850 (define_insn "*swaphi_1"
1851   [(set (match_operand:HI 0 "register_operand" "+r")
1852         (match_operand:HI 1 "register_operand" "+r"))
1853    (set (match_dup 1)
1854         (match_dup 0))]
1855   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1856   "xchg{l}\t%k1, %k0"
1857   [(set_attr "type" "imov")
1858    (set_attr "mode" "SI")
1859    (set_attr "pent_pair" "np")
1860    (set_attr "athlon_decode" "vector")
1861    (set_attr "amdfam10_decode" "double")])
1863 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1864 (define_insn "*swaphi_2"
1865   [(set (match_operand:HI 0 "register_operand" "+r")
1866         (match_operand:HI 1 "register_operand" "+r"))
1867    (set (match_dup 1)
1868         (match_dup 0))]
1869   "TARGET_PARTIAL_REG_STALL"
1870   "xchg{w}\t%1, %0"
1871   [(set_attr "type" "imov")
1872    (set_attr "mode" "HI")
1873    (set_attr "pent_pair" "np")
1874    (set_attr "athlon_decode" "vector")])
1876 (define_expand "movstricthi"
1877   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1878         (match_operand:HI 1 "general_operand" ""))]
1879   ""
1881   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1882     FAIL;
1883   /* Don't generate memory->memory moves, go through a register */
1884   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1885     operands[1] = force_reg (HImode, operands[1]);
1888 (define_insn "*movstricthi_1"
1889   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1890         (match_operand:HI 1 "general_operand" "rn,m"))]
1891   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1892    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1893   "mov{w}\t{%1, %0|%0, %1}"
1894   [(set_attr "type" "imov")
1895    (set_attr "mode" "HI")])
1897 (define_insn "*movstricthi_xor"
1898   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1899         (match_operand:HI 1 "const0_operand" ""))
1900    (clobber (reg:CC FLAGS_REG))]
1901   "reload_completed"
1902   "xor{w}\t%0, %0"
1903   [(set_attr "type" "alu1")
1904    (set_attr "mode" "HI")
1905    (set_attr "length_immediate" "0")])
1907 (define_expand "movqi"
1908   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1909         (match_operand:QI 1 "general_operand" ""))]
1910   ""
1911   "ix86_expand_move (QImode, operands); DONE;")
1913 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1914 ;; "push a byte".  But actually we use pushl, which has the effect
1915 ;; of rounding the amount pushed up to a word.
1917 (define_insn "*pushqi2"
1918   [(set (match_operand:QI 0 "push_operand" "=X")
1919         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1920   "!TARGET_64BIT"
1921   "push{l}\t%k1"
1922   [(set_attr "type" "push")
1923    (set_attr "mode" "SI")])
1925 ;; For 64BIT abi we always round up to 8 bytes.
1926 (define_insn "*pushqi2_rex64"
1927   [(set (match_operand:QI 0 "push_operand" "=X")
1928         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1929   "TARGET_64BIT"
1930   "push{q}\t%q1"
1931   [(set_attr "type" "push")
1932    (set_attr "mode" "DI")])
1934 ;; Situation is quite tricky about when to choose full sized (SImode) move
1935 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1936 ;; partial register dependency machines (such as AMD Athlon), where QImode
1937 ;; moves issue extra dependency and for partial register stalls machines
1938 ;; that don't use QImode patterns (and QImode move cause stall on the next
1939 ;; instruction).
1941 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1942 ;; register stall machines with, where we use QImode instructions, since
1943 ;; partial register stall can be caused there.  Then we use movzx.
1944 (define_insn "*movqi_1"
1945   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1946         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1947   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1949   switch (get_attr_type (insn))
1950     {
1951     case TYPE_IMOVX:
1952       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1953       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1954     default:
1955       if (get_attr_mode (insn) == MODE_SI)
1956         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1957       else
1958         return "mov{b}\t{%1, %0|%0, %1}";
1959     }
1961   [(set (attr "type")
1962      (cond [(and (eq_attr "alternative" "5")
1963                  (not (match_operand:QI 1 "aligned_operand" "")))
1964               (const_string "imovx")
1965             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1966               (const_string "imov")
1967             (and (eq_attr "alternative" "3")
1968                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1969                           (const_int 0))
1970                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1971                           (const_int 0))))
1972               (const_string "imov")
1973             (eq_attr "alternative" "3,5")
1974               (const_string "imovx")
1975             (and (ne (symbol_ref "TARGET_MOVX")
1976                      (const_int 0))
1977                  (eq_attr "alternative" "2"))
1978               (const_string "imovx")
1979            ]
1980            (const_string "imov")))
1981    (set (attr "mode")
1982       (cond [(eq_attr "alternative" "3,4,5")
1983                (const_string "SI")
1984              (eq_attr "alternative" "6")
1985                (const_string "QI")
1986              (eq_attr "type" "imovx")
1987                (const_string "SI")
1988              (and (eq_attr "type" "imov")
1989                   (and (eq_attr "alternative" "0,1")
1990                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1991                                 (const_int 0))
1992                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1993                                      (const_int 0))
1994                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1995                                      (const_int 0))))))
1996                (const_string "SI")
1997              ;; Avoid partial register stalls when not using QImode arithmetic
1998              (and (eq_attr "type" "imov")
1999                   (and (eq_attr "alternative" "0,1")
2000                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2001                                 (const_int 0))
2002                             (eq (symbol_ref "TARGET_QIMODE_MATH")
2003                                 (const_int 0)))))
2004                (const_string "SI")
2005            ]
2006            (const_string "QI")))])
2008 (define_insn "*swapqi_1"
2009   [(set (match_operand:QI 0 "register_operand" "+r")
2010         (match_operand:QI 1 "register_operand" "+r"))
2011    (set (match_dup 1)
2012         (match_dup 0))]
2013   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2014   "xchg{l}\t%k1, %k0"
2015   [(set_attr "type" "imov")
2016    (set_attr "mode" "SI")
2017    (set_attr "pent_pair" "np")
2018    (set_attr "athlon_decode" "vector")
2019    (set_attr "amdfam10_decode" "vector")])
2021 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2022 (define_insn "*swapqi_2"
2023   [(set (match_operand:QI 0 "register_operand" "+q")
2024         (match_operand:QI 1 "register_operand" "+q"))
2025    (set (match_dup 1)
2026         (match_dup 0))]
2027   "TARGET_PARTIAL_REG_STALL"
2028   "xchg{b}\t%1, %0"
2029   [(set_attr "type" "imov")
2030    (set_attr "mode" "QI")
2031    (set_attr "pent_pair" "np")
2032    (set_attr "athlon_decode" "vector")])
2034 (define_expand "movstrictqi"
2035   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2036         (match_operand:QI 1 "general_operand" ""))]
2037   ""
2039   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2040     FAIL;
2041   /* Don't generate memory->memory moves, go through a register.  */
2042   if (MEM_P (operands[0]) && MEM_P (operands[1]))
2043     operands[1] = force_reg (QImode, operands[1]);
2046 (define_insn "*movstrictqi_1"
2047   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2048         (match_operand:QI 1 "general_operand" "*qn,m"))]
2049   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2050    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2051   "mov{b}\t{%1, %0|%0, %1}"
2052   [(set_attr "type" "imov")
2053    (set_attr "mode" "QI")])
2055 (define_insn "*movstrictqi_xor"
2056   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2057         (match_operand:QI 1 "const0_operand" ""))
2058    (clobber (reg:CC FLAGS_REG))]
2059   "reload_completed"
2060   "xor{b}\t%0, %0"
2061   [(set_attr "type" "alu1")
2062    (set_attr "mode" "QI")
2063    (set_attr "length_immediate" "0")])
2065 (define_insn "*movsi_extv_1"
2066   [(set (match_operand:SI 0 "register_operand" "=R")
2067         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2068                          (const_int 8)
2069                          (const_int 8)))]
2070   ""
2071   "movs{bl|x}\t{%h1, %0|%0, %h1}"
2072   [(set_attr "type" "imovx")
2073    (set_attr "mode" "SI")])
2075 (define_insn "*movhi_extv_1"
2076   [(set (match_operand:HI 0 "register_operand" "=R")
2077         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2078                          (const_int 8)
2079                          (const_int 8)))]
2080   ""
2081   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2082   [(set_attr "type" "imovx")
2083    (set_attr "mode" "SI")])
2085 (define_insn "*movqi_extv_1"
2086   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2087         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2088                          (const_int 8)
2089                          (const_int 8)))]
2090   "!TARGET_64BIT"
2092   switch (get_attr_type (insn))
2093     {
2094     case TYPE_IMOVX:
2095       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2096     default:
2097       return "mov{b}\t{%h1, %0|%0, %h1}";
2098     }
2100   [(set (attr "type")
2101      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2102                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2103                              (ne (symbol_ref "TARGET_MOVX")
2104                                  (const_int 0))))
2105         (const_string "imovx")
2106         (const_string "imov")))
2107    (set (attr "mode")
2108      (if_then_else (eq_attr "type" "imovx")
2109         (const_string "SI")
2110         (const_string "QI")))])
2112 (define_insn "*movqi_extv_1_rex64"
2113   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2114         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2115                          (const_int 8)
2116                          (const_int 8)))]
2117   "TARGET_64BIT"
2119   switch (get_attr_type (insn))
2120     {
2121     case TYPE_IMOVX:
2122       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2123     default:
2124       return "mov{b}\t{%h1, %0|%0, %h1}";
2125     }
2127   [(set (attr "type")
2128      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2129                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2130                              (ne (symbol_ref "TARGET_MOVX")
2131                                  (const_int 0))))
2132         (const_string "imovx")
2133         (const_string "imov")))
2134    (set (attr "mode")
2135      (if_then_else (eq_attr "type" "imovx")
2136         (const_string "SI")
2137         (const_string "QI")))])
2139 ;; Stores and loads of ax to arbitrary constant address.
2140 ;; We fake an second form of instruction to force reload to load address
2141 ;; into register when rax is not available
2142 (define_insn "*movabsqi_1_rex64"
2143   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2144         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2145   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2146   "@
2147    movabs{b}\t{%1, %P0|%P0, %1}
2148    mov{b}\t{%1, %a0|%a0, %1}"
2149   [(set_attr "type" "imov")
2150    (set_attr "modrm" "0,*")
2151    (set_attr "length_address" "8,0")
2152    (set_attr "length_immediate" "0,*")
2153    (set_attr "memory" "store")
2154    (set_attr "mode" "QI")])
2156 (define_insn "*movabsqi_2_rex64"
2157   [(set (match_operand:QI 0 "register_operand" "=a,r")
2158         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2159   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2160   "@
2161    movabs{b}\t{%P1, %0|%0, %P1}
2162    mov{b}\t{%a1, %0|%0, %a1}"
2163   [(set_attr "type" "imov")
2164    (set_attr "modrm" "0,*")
2165    (set_attr "length_address" "8,0")
2166    (set_attr "length_immediate" "0")
2167    (set_attr "memory" "load")
2168    (set_attr "mode" "QI")])
2170 (define_insn "*movdi_extzv_1"
2171   [(set (match_operand:DI 0 "register_operand" "=R")
2172         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2173                          (const_int 8)
2174                          (const_int 8)))]
2175   "TARGET_64BIT"
2176   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2177   [(set_attr "type" "imovx")
2178    (set_attr "mode" "SI")])
2180 (define_insn "*movsi_extzv_1"
2181   [(set (match_operand:SI 0 "register_operand" "=R")
2182         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2183                          (const_int 8)
2184                          (const_int 8)))]
2185   ""
2186   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2187   [(set_attr "type" "imovx")
2188    (set_attr "mode" "SI")])
2190 (define_insn "*movqi_extzv_2"
2191   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2192         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2193                                     (const_int 8)
2194                                     (const_int 8)) 0))]
2195   "!TARGET_64BIT"
2197   switch (get_attr_type (insn))
2198     {
2199     case TYPE_IMOVX:
2200       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2201     default:
2202       return "mov{b}\t{%h1, %0|%0, %h1}";
2203     }
2205   [(set (attr "type")
2206      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2207                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2208                              (ne (symbol_ref "TARGET_MOVX")
2209                                  (const_int 0))))
2210         (const_string "imovx")
2211         (const_string "imov")))
2212    (set (attr "mode")
2213      (if_then_else (eq_attr "type" "imovx")
2214         (const_string "SI")
2215         (const_string "QI")))])
2217 (define_insn "*movqi_extzv_2_rex64"
2218   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2219         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2220                                     (const_int 8)
2221                                     (const_int 8)) 0))]
2222   "TARGET_64BIT"
2224   switch (get_attr_type (insn))
2225     {
2226     case TYPE_IMOVX:
2227       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2228     default:
2229       return "mov{b}\t{%h1, %0|%0, %h1}";
2230     }
2232   [(set (attr "type")
2233      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2234                         (ne (symbol_ref "TARGET_MOVX")
2235                             (const_int 0)))
2236         (const_string "imovx")
2237         (const_string "imov")))
2238    (set (attr "mode")
2239      (if_then_else (eq_attr "type" "imovx")
2240         (const_string "SI")
2241         (const_string "QI")))])
2243 (define_insn "movsi_insv_1"
2244   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2245                          (const_int 8)
2246                          (const_int 8))
2247         (match_operand:SI 1 "general_operand" "Qmn"))]
2248   "!TARGET_64BIT"
2249   "mov{b}\t{%b1, %h0|%h0, %b1}"
2250   [(set_attr "type" "imov")
2251    (set_attr "mode" "QI")])
2253 (define_insn "*movsi_insv_1_rex64"
2254   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2255                          (const_int 8)
2256                          (const_int 8))
2257         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2258   "TARGET_64BIT"
2259   "mov{b}\t{%b1, %h0|%h0, %b1}"
2260   [(set_attr "type" "imov")
2261    (set_attr "mode" "QI")])
2263 (define_insn "movdi_insv_1_rex64"
2264   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2265                          (const_int 8)
2266                          (const_int 8))
2267         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2268   "TARGET_64BIT"
2269   "mov{b}\t{%b1, %h0|%h0, %b1}"
2270   [(set_attr "type" "imov")
2271    (set_attr "mode" "QI")])
2273 (define_insn "*movqi_insv_2"
2274   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2275                          (const_int 8)
2276                          (const_int 8))
2277         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2278                      (const_int 8)))]
2279   ""
2280   "mov{b}\t{%h1, %h0|%h0, %h1}"
2281   [(set_attr "type" "imov")
2282    (set_attr "mode" "QI")])
2284 (define_expand "movdi"
2285   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2286         (match_operand:DI 1 "general_operand" ""))]
2287   ""
2288   "ix86_expand_move (DImode, operands); DONE;")
2290 (define_insn "*pushdi"
2291   [(set (match_operand:DI 0 "push_operand" "=<")
2292         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2293   "!TARGET_64BIT"
2294   "#")
2296 (define_insn "*pushdi2_rex64"
2297   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2298         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2299   "TARGET_64BIT"
2300   "@
2301    push{q}\t%1
2302    #"
2303   [(set_attr "type" "push,multi")
2304    (set_attr "mode" "DI")])
2306 ;; Convert impossible pushes of immediate to existing instructions.
2307 ;; First try to get scratch register and go through it.  In case this
2308 ;; fails, push sign extended lower part first and then overwrite
2309 ;; upper part by 32bit move.
2310 (define_peephole2
2311   [(match_scratch:DI 2 "r")
2312    (set (match_operand:DI 0 "push_operand" "")
2313         (match_operand:DI 1 "immediate_operand" ""))]
2314   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2315    && !x86_64_immediate_operand (operands[1], DImode)"
2316   [(set (match_dup 2) (match_dup 1))
2317    (set (match_dup 0) (match_dup 2))]
2318   "")
2320 ;; We need to define this as both peepholer and splitter for case
2321 ;; peephole2 pass is not run.
2322 ;; "&& 1" is needed to keep it from matching the previous pattern.
2323 (define_peephole2
2324   [(set (match_operand:DI 0 "push_operand" "")
2325         (match_operand:DI 1 "immediate_operand" ""))]
2326   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2327    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2328   [(set (match_dup 0) (match_dup 1))
2329    (set (match_dup 2) (match_dup 3))]
2330   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2331    operands[1] = gen_lowpart (DImode, operands[2]);
2332    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2333                                                     GEN_INT (4)));
2334   ")
2336 (define_split
2337   [(set (match_operand:DI 0 "push_operand" "")
2338         (match_operand:DI 1 "immediate_operand" ""))]
2339   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2340                     ? epilogue_completed : reload_completed)
2341    && !symbolic_operand (operands[1], DImode)
2342    && !x86_64_immediate_operand (operands[1], DImode)"
2343   [(set (match_dup 0) (match_dup 1))
2344    (set (match_dup 2) (match_dup 3))]
2345   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2346    operands[1] = gen_lowpart (DImode, operands[2]);
2347    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2348                                                     GEN_INT (4)));
2349   ")
2351 (define_insn "*pushdi2_prologue_rex64"
2352   [(set (match_operand:DI 0 "push_operand" "=<")
2353         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2354    (clobber (mem:BLK (scratch)))]
2355   "TARGET_64BIT"
2356   "push{q}\t%1"
2357   [(set_attr "type" "push")
2358    (set_attr "mode" "DI")])
2360 (define_insn "*popdi1_epilogue_rex64"
2361   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2362         (mem:DI (reg:DI SP_REG)))
2363    (set (reg:DI SP_REG)
2364         (plus:DI (reg:DI SP_REG) (const_int 8)))
2365    (clobber (mem:BLK (scratch)))]
2366   "TARGET_64BIT"
2367   "pop{q}\t%0"
2368   [(set_attr "type" "pop")
2369    (set_attr "mode" "DI")])
2371 (define_insn "popdi1"
2372   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2373         (mem:DI (reg:DI SP_REG)))
2374    (set (reg:DI SP_REG)
2375         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2376   "TARGET_64BIT"
2377   "pop{q}\t%0"
2378   [(set_attr "type" "pop")
2379    (set_attr "mode" "DI")])
2381 (define_insn "*movdi_xor_rex64"
2382   [(set (match_operand:DI 0 "register_operand" "=r")
2383         (match_operand:DI 1 "const0_operand" ""))
2384    (clobber (reg:CC FLAGS_REG))]
2385   "TARGET_64BIT
2386    && reload_completed"
2387   "xor{l}\t%k0, %k0";
2388   [(set_attr "type" "alu1")
2389    (set_attr "mode" "SI")
2390    (set_attr "length_immediate" "0")])
2392 (define_insn "*movdi_or_rex64"
2393   [(set (match_operand:DI 0 "register_operand" "=r")
2394         (match_operand:DI 1 "const_int_operand" "i"))
2395    (clobber (reg:CC FLAGS_REG))]
2396   "TARGET_64BIT
2397    && reload_completed
2398    && operands[1] == constm1_rtx"
2400   operands[1] = constm1_rtx;
2401   return "or{q}\t{%1, %0|%0, %1}";
2403   [(set_attr "type" "alu1")
2404    (set_attr "mode" "DI")
2405    (set_attr "length_immediate" "1")])
2407 (define_insn "*movdi_2"
2408   [(set (match_operand:DI 0 "nonimmediate_operand"
2409                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2410         (match_operand:DI 1 "general_operand"
2411                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2412   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2413   "@
2414    #
2415    #
2416    pxor\t%0, %0
2417    movq\t{%1, %0|%0, %1}
2418    movq\t{%1, %0|%0, %1}
2419    %vpxor\t%0, %d0
2420    %vmovq\t{%1, %0|%0, %1}
2421    %vmovdqa\t{%1, %0|%0, %1}
2422    %vmovq\t{%1, %0|%0, %1}
2423    xorps\t%0, %0
2424    movlps\t{%1, %0|%0, %1}
2425    movaps\t{%1, %0|%0, %1}
2426    movlps\t{%1, %0|%0, %1}"
2427   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2428    (set (attr "prefix")
2429      (if_then_else (eq_attr "alternative" "5,6,7,8")
2430        (const_string "vex")
2431        (const_string "orig")))
2432    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2434 (define_split
2435   [(set (match_operand:DI 0 "push_operand" "")
2436         (match_operand:DI 1 "general_operand" ""))]
2437   "!TARGET_64BIT && reload_completed
2438    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2439   [(const_int 0)]
2440   "ix86_split_long_move (operands); DONE;")
2442 ;; %%% This multiword shite has got to go.
2443 (define_split
2444   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2445         (match_operand:DI 1 "general_operand" ""))]
2446   "!TARGET_64BIT && reload_completed
2447    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2448    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2449   [(const_int 0)]
2450   "ix86_split_long_move (operands); DONE;")
2452 (define_insn "*movdi_1_rex64"
2453   [(set (match_operand:DI 0 "nonimmediate_operand"
2454           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2455         (match_operand:DI 1 "general_operand"
2456           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2457   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2459   switch (get_attr_type (insn))
2460     {
2461     case TYPE_SSECVT:
2462       if (SSE_REG_P (operands[0]))
2463         return "movq2dq\t{%1, %0|%0, %1}";
2464       else
2465         return "movdq2q\t{%1, %0|%0, %1}";
2467     case TYPE_SSEMOV:
2468       if (TARGET_AVX)
2469         {
2470           if (get_attr_mode (insn) == MODE_TI)
2471             return "vmovdqa\t{%1, %0|%0, %1}";
2472           else
2473             return "vmovq\t{%1, %0|%0, %1}";
2474         }
2476       if (get_attr_mode (insn) == MODE_TI)
2477         return "movdqa\t{%1, %0|%0, %1}";
2478       /* FALLTHRU */
2480     case TYPE_MMXMOV:
2481       /* Moves from and into integer register is done using movd
2482          opcode with REX prefix.  */
2483       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2484         return "movd\t{%1, %0|%0, %1}";
2485       return "movq\t{%1, %0|%0, %1}";
2487     case TYPE_SSELOG1:
2488       return "%vpxor\t%0, %d0";
2490     case TYPE_MMX:
2491       return "pxor\t%0, %0";
2493     case TYPE_MULTI:
2494       return "#";
2496     case TYPE_LEA:
2497       return "lea{q}\t{%a1, %0|%0, %a1}";
2499     default:
2500       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2501       if (get_attr_mode (insn) == MODE_SI)
2502         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2503       else if (which_alternative == 2)
2504         return "movabs{q}\t{%1, %0|%0, %1}";
2505       else
2506         return "mov{q}\t{%1, %0|%0, %1}";
2507     }
2509   [(set (attr "type")
2510      (cond [(eq_attr "alternative" "5")
2511               (const_string "mmx")
2512             (eq_attr "alternative" "6,7,8,9,10")
2513               (const_string "mmxmov")
2514             (eq_attr "alternative" "11")
2515               (const_string "sselog1")
2516             (eq_attr "alternative" "12,13,14,15,16")
2517               (const_string "ssemov")
2518             (eq_attr "alternative" "17,18")
2519               (const_string "ssecvt")
2520             (eq_attr "alternative" "4")
2521               (const_string "multi")
2522             (match_operand:DI 1 "pic_32bit_operand" "")
2523               (const_string "lea")
2524            ]
2525            (const_string "imov")))
2526    (set (attr "modrm")
2527      (if_then_else
2528        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2529          (const_string "0")
2530          (const_string "*")))
2531    (set (attr "length_immediate")
2532      (if_then_else
2533        (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2534          (const_string "8")
2535          (const_string "*")))
2536    (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2537    (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2538    (set (attr "prefix")
2539      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2540        (const_string "maybe_vex")
2541        (const_string "orig")))
2542    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2544 ;; Stores and loads of ax to arbitrary constant address.
2545 ;; We fake an second form of instruction to force reload to load address
2546 ;; into register when rax is not available
2547 (define_insn "*movabsdi_1_rex64"
2548   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2549         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2550   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2551   "@
2552    movabs{q}\t{%1, %P0|%P0, %1}
2553    mov{q}\t{%1, %a0|%a0, %1}"
2554   [(set_attr "type" "imov")
2555    (set_attr "modrm" "0,*")
2556    (set_attr "length_address" "8,0")
2557    (set_attr "length_immediate" "0,*")
2558    (set_attr "memory" "store")
2559    (set_attr "mode" "DI")])
2561 (define_insn "*movabsdi_2_rex64"
2562   [(set (match_operand:DI 0 "register_operand" "=a,r")
2563         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2564   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2565   "@
2566    movabs{q}\t{%P1, %0|%0, %P1}
2567    mov{q}\t{%a1, %0|%0, %a1}"
2568   [(set_attr "type" "imov")
2569    (set_attr "modrm" "0,*")
2570    (set_attr "length_address" "8,0")
2571    (set_attr "length_immediate" "0")
2572    (set_attr "memory" "load")
2573    (set_attr "mode" "DI")])
2575 ;; Convert impossible stores of immediate to existing instructions.
2576 ;; First try to get scratch register and go through it.  In case this
2577 ;; fails, move by 32bit parts.
2578 (define_peephole2
2579   [(match_scratch:DI 2 "r")
2580    (set (match_operand:DI 0 "memory_operand" "")
2581         (match_operand:DI 1 "immediate_operand" ""))]
2582   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2583    && !x86_64_immediate_operand (operands[1], DImode)"
2584   [(set (match_dup 2) (match_dup 1))
2585    (set (match_dup 0) (match_dup 2))]
2586   "")
2588 ;; We need to define this as both peepholer and splitter for case
2589 ;; peephole2 pass is not run.
2590 ;; "&& 1" is needed to keep it from matching the previous pattern.
2591 (define_peephole2
2592   [(set (match_operand:DI 0 "memory_operand" "")
2593         (match_operand:DI 1 "immediate_operand" ""))]
2594   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2595    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2596   [(set (match_dup 2) (match_dup 3))
2597    (set (match_dup 4) (match_dup 5))]
2598   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2600 (define_split
2601   [(set (match_operand:DI 0 "memory_operand" "")
2602         (match_operand:DI 1 "immediate_operand" ""))]
2603   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2604                     ? epilogue_completed : reload_completed)
2605    && !symbolic_operand (operands[1], DImode)
2606    && !x86_64_immediate_operand (operands[1], DImode)"
2607   [(set (match_dup 2) (match_dup 3))
2608    (set (match_dup 4) (match_dup 5))]
2609   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2611 (define_insn "*swapdi_rex64"
2612   [(set (match_operand:DI 0 "register_operand" "+r")
2613         (match_operand:DI 1 "register_operand" "+r"))
2614    (set (match_dup 1)
2615         (match_dup 0))]
2616   "TARGET_64BIT"
2617   "xchg{q}\t%1, %0"
2618   [(set_attr "type" "imov")
2619    (set_attr "mode" "DI")
2620    (set_attr "pent_pair" "np")
2621    (set_attr "athlon_decode" "vector")
2622    (set_attr "amdfam10_decode" "double")])
2624 (define_expand "movoi"
2625   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2626         (match_operand:OI 1 "general_operand" ""))]
2627   "TARGET_AVX"
2628   "ix86_expand_move (OImode, operands); DONE;")
2630 (define_insn "*movoi_internal"
2631   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2632         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2633   "TARGET_AVX
2634    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2636   switch (which_alternative)
2637     {
2638     case 0:
2639       return "vxorps\t%0, %0, %0";
2640     case 1:
2641     case 2:
2642       if (misaligned_operand (operands[0], OImode)
2643           || misaligned_operand (operands[1], OImode))
2644         return "vmovdqu\t{%1, %0|%0, %1}";
2645       else
2646         return "vmovdqa\t{%1, %0|%0, %1}";
2647     default:
2648       gcc_unreachable ();
2649     }
2651   [(set_attr "type" "sselog1,ssemov,ssemov")
2652    (set_attr "prefix" "vex")
2653    (set_attr "mode" "OI")])
2655 (define_expand "movti"
2656   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2657         (match_operand:TI 1 "nonimmediate_operand" ""))]
2658   "TARGET_SSE || TARGET_64BIT"
2660   if (TARGET_64BIT)
2661     ix86_expand_move (TImode, operands);
2662   else if (push_operand (operands[0], TImode))
2663     ix86_expand_push (TImode, operands[1]);
2664   else
2665     ix86_expand_vector_move (TImode, operands);
2666   DONE;
2669 (define_insn "*movti_internal"
2670   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2671         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2672   "TARGET_SSE && !TARGET_64BIT
2673    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2675   switch (which_alternative)
2676     {
2677     case 0:
2678       if (get_attr_mode (insn) == MODE_V4SF)
2679         return "%vxorps\t%0, %d0";
2680       else
2681         return "%vpxor\t%0, %d0";
2682     case 1:
2683     case 2:
2684       /* TDmode values are passed as TImode on the stack.  Moving them
2685          to stack may result in unaligned memory access.  */
2686       if (misaligned_operand (operands[0], TImode)
2687           || misaligned_operand (operands[1], TImode))
2688         {
2689           if (get_attr_mode (insn) == MODE_V4SF)
2690             return "%vmovups\t{%1, %0|%0, %1}";
2691          else
2692            return "%vmovdqu\t{%1, %0|%0, %1}";
2693         }
2694       else
2695         {
2696           if (get_attr_mode (insn) == MODE_V4SF)
2697             return "%vmovaps\t{%1, %0|%0, %1}";
2698          else
2699            return "%vmovdqa\t{%1, %0|%0, %1}";
2700         }
2701     default:
2702       gcc_unreachable ();
2703     }
2705   [(set_attr "type" "sselog1,ssemov,ssemov")
2706    (set_attr "prefix" "maybe_vex")
2707    (set (attr "mode")
2708         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2709                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2710                  (const_string "V4SF")
2711                (and (eq_attr "alternative" "2")
2712                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2713                         (const_int 0)))
2714                  (const_string "V4SF")]
2715               (const_string "TI")))])
2717 (define_insn "*movti_rex64"
2718   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2719         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2720   "TARGET_64BIT
2721    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2723   switch (which_alternative)
2724     {
2725     case 0:
2726     case 1:
2727       return "#";
2728     case 2:
2729       if (get_attr_mode (insn) == MODE_V4SF)
2730         return "%vxorps\t%0, %d0";
2731       else
2732         return "%vpxor\t%0, %d0";
2733     case 3:
2734     case 4:
2735       /* TDmode values are passed as TImode on the stack.  Moving them
2736          to stack may result in unaligned memory access.  */
2737       if (misaligned_operand (operands[0], TImode)
2738           || misaligned_operand (operands[1], TImode))
2739         {
2740           if (get_attr_mode (insn) == MODE_V4SF)
2741             return "%vmovups\t{%1, %0|%0, %1}";
2742          else
2743            return "%vmovdqu\t{%1, %0|%0, %1}";
2744         }
2745       else
2746         {
2747           if (get_attr_mode (insn) == MODE_V4SF)
2748             return "%vmovaps\t{%1, %0|%0, %1}";
2749          else
2750            return "%vmovdqa\t{%1, %0|%0, %1}";
2751         }
2752     default:
2753       gcc_unreachable ();
2754     }
2756   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2757    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2758    (set (attr "mode")
2759         (cond [(eq_attr "alternative" "2,3")
2760                  (if_then_else
2761                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2762                        (const_int 0))
2763                    (const_string "V4SF")
2764                    (const_string "TI"))
2765                (eq_attr "alternative" "4")
2766                  (if_then_else
2767                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2768                             (const_int 0))
2769                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2770                             (const_int 0)))
2771                    (const_string "V4SF")
2772                    (const_string "TI"))]
2773                (const_string "DI")))])
2775 (define_split
2776   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2777         (match_operand:TI 1 "general_operand" ""))]
2778   "reload_completed && !SSE_REG_P (operands[0])
2779    && !SSE_REG_P (operands[1])"
2780   [(const_int 0)]
2781   "ix86_split_long_move (operands); DONE;")
2783 ;; This expands to what emit_move_complex would generate if we didn't
2784 ;; have a movti pattern.  Having this avoids problems with reload on
2785 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2786 ;; to have around all the time.
2787 (define_expand "movcdi"
2788   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2789         (match_operand:CDI 1 "general_operand" ""))]
2790   ""
2792   if (push_operand (operands[0], CDImode))
2793     emit_move_complex_push (CDImode, operands[0], operands[1]);
2794   else
2795     emit_move_complex_parts (operands[0], operands[1]);
2796   DONE;
2799 (define_expand "movsf"
2800   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2801         (match_operand:SF 1 "general_operand" ""))]
2802   ""
2803   "ix86_expand_move (SFmode, operands); DONE;")
2805 (define_insn "*pushsf"
2806   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2807         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2808   "!TARGET_64BIT"
2810   /* Anything else should be already split before reg-stack.  */
2811   gcc_assert (which_alternative == 1);
2812   return "push{l}\t%1";
2814   [(set_attr "type" "multi,push,multi")
2815    (set_attr "unit" "i387,*,*")
2816    (set_attr "mode" "SF,SI,SF")])
2818 (define_insn "*pushsf_rex64"
2819   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2820         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2821   "TARGET_64BIT"
2823   /* Anything else should be already split before reg-stack.  */
2824   gcc_assert (which_alternative == 1);
2825   return "push{q}\t%q1";
2827   [(set_attr "type" "multi,push,multi")
2828    (set_attr "unit" "i387,*,*")
2829    (set_attr "mode" "SF,DI,SF")])
2831 (define_split
2832   [(set (match_operand:SF 0 "push_operand" "")
2833         (match_operand:SF 1 "memory_operand" ""))]
2834   "reload_completed
2835    && MEM_P (operands[1])
2836    && (operands[2] = find_constant_src (insn))"
2837   [(set (match_dup 0)
2838         (match_dup 2))])
2840 ;; %%% Kill this when call knows how to work this out.
2841 (define_split
2842   [(set (match_operand:SF 0 "push_operand" "")
2843         (match_operand:SF 1 "any_fp_register_operand" ""))]
2844   "!TARGET_64BIT"
2845   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2846    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2848 (define_split
2849   [(set (match_operand:SF 0 "push_operand" "")
2850         (match_operand:SF 1 "any_fp_register_operand" ""))]
2851   "TARGET_64BIT"
2852   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2853    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2855 (define_insn "*movsf_1"
2856   [(set (match_operand:SF 0 "nonimmediate_operand"
2857           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2858         (match_operand:SF 1 "general_operand"
2859           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2860   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2861    && (reload_in_progress || reload_completed
2862        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2863        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2864            && standard_80387_constant_p (operands[1]))
2865        || GET_CODE (operands[1]) != CONST_DOUBLE
2866        || memory_operand (operands[0], SFmode))"
2868   switch (which_alternative)
2869     {
2870     case 0:
2871     case 1:
2872       return output_387_reg_move (insn, operands);
2874     case 2:
2875       return standard_80387_constant_opcode (operands[1]);
2877     case 3:
2878     case 4:
2879       return "mov{l}\t{%1, %0|%0, %1}";
2880     case 5:
2881       if (get_attr_mode (insn) == MODE_TI)
2882         return "%vpxor\t%0, %d0";
2883       else
2884         return "%vxorps\t%0, %d0";
2885     case 6:
2886       if (get_attr_mode (insn) == MODE_V4SF)
2887         return "%vmovaps\t{%1, %0|%0, %1}";
2888       else
2889         return "%vmovss\t{%1, %d0|%d0, %1}";
2890     case 7:
2891       if (TARGET_AVX)
2892         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2893                                    : "vmovss\t{%1, %0|%0, %1}";
2894       else
2895         return "movss\t{%1, %0|%0, %1}";
2896     case 8:
2897       return "%vmovss\t{%1, %0|%0, %1}";
2899     case 9: case 10: case 14: case 15:
2900       return "movd\t{%1, %0|%0, %1}";
2901     case 12: case 13:
2902       return "%vmovd\t{%1, %0|%0, %1}";
2904     case 11:
2905       return "movq\t{%1, %0|%0, %1}";
2907     default:
2908       gcc_unreachable ();
2909     }
2911   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2912    (set (attr "prefix")
2913      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2914        (const_string "maybe_vex")
2915        (const_string "orig")))
2916    (set (attr "mode")
2917         (cond [(eq_attr "alternative" "3,4,9,10")
2918                  (const_string "SI")
2919                (eq_attr "alternative" "5")
2920                  (if_then_else
2921                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2922                                  (const_int 0))
2923                              (ne (symbol_ref "TARGET_SSE2")
2924                                  (const_int 0)))
2925                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2926                             (const_int 0)))
2927                    (const_string "TI")
2928                    (const_string "V4SF"))
2929                /* For architectures resolving dependencies on
2930                   whole SSE registers use APS move to break dependency
2931                   chains, otherwise use short move to avoid extra work.
2933                   Do the same for architectures resolving dependencies on
2934                   the parts.  While in DF mode it is better to always handle
2935                   just register parts, the SF mode is different due to lack
2936                   of instructions to load just part of the register.  It is
2937                   better to maintain the whole registers in single format
2938                   to avoid problems on using packed logical operations.  */
2939                (eq_attr "alternative" "6")
2940                  (if_then_else
2941                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2942                             (const_int 0))
2943                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2944                             (const_int 0)))
2945                    (const_string "V4SF")
2946                    (const_string "SF"))
2947                (eq_attr "alternative" "11")
2948                  (const_string "DI")]
2949                (const_string "SF")))])
2951 (define_insn "*swapsf"
2952   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2953         (match_operand:SF 1 "fp_register_operand" "+f"))
2954    (set (match_dup 1)
2955         (match_dup 0))]
2956   "reload_completed || TARGET_80387"
2958   if (STACK_TOP_P (operands[0]))
2959     return "fxch\t%1";
2960   else
2961     return "fxch\t%0";
2963   [(set_attr "type" "fxch")
2964    (set_attr "mode" "SF")])
2966 (define_expand "movdf"
2967   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2968         (match_operand:DF 1 "general_operand" ""))]
2969   ""
2970   "ix86_expand_move (DFmode, operands); DONE;")
2972 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2973 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2974 ;; On the average, pushdf using integers can be still shorter.  Allow this
2975 ;; pattern for optimize_size too.
2977 (define_insn "*pushdf_nointeger"
2978   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2979         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2980   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2982   /* This insn should be already split before reg-stack.  */
2983   gcc_unreachable ();
2985   [(set_attr "type" "multi")
2986    (set_attr "unit" "i387,*,*,*")
2987    (set_attr "mode" "DF,SI,SI,DF")])
2989 (define_insn "*pushdf_integer"
2990   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2991         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2992   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2994   /* This insn should be already split before reg-stack.  */
2995   gcc_unreachable ();
2997   [(set_attr "type" "multi")
2998    (set_attr "unit" "i387,*,*")
2999    (set_attr "mode" "DF,SI,DF")])
3001 ;; %%% Kill this when call knows how to work this out.
3002 (define_split
3003   [(set (match_operand:DF 0 "push_operand" "")
3004         (match_operand:DF 1 "any_fp_register_operand" ""))]
3005   "reload_completed"
3006   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3007    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3008   "")
3010 (define_split
3011   [(set (match_operand:DF 0 "push_operand" "")
3012         (match_operand:DF 1 "general_operand" ""))]
3013   "reload_completed"
3014   [(const_int 0)]
3015   "ix86_split_long_move (operands); DONE;")
3017 ;; Moving is usually shorter when only FP registers are used. This separate
3018 ;; movdf pattern avoids the use of integer registers for FP operations
3019 ;; when optimizing for size.
3021 (define_insn "*movdf_nointeger"
3022   [(set (match_operand:DF 0 "nonimmediate_operand"
3023                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
3024         (match_operand:DF 1 "general_operand"
3025                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
3026   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3027    && ((optimize_function_for_size_p (cfun)
3028        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3029    && (reload_in_progress || reload_completed
3030        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3031        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3032            && optimize_function_for_size_p (cfun)
3033            && !memory_operand (operands[0], DFmode)
3034            && standard_80387_constant_p (operands[1]))
3035        || GET_CODE (operands[1]) != CONST_DOUBLE
3036        || ((optimize_function_for_size_p (cfun)
3037             || !TARGET_MEMORY_MISMATCH_STALL
3038             || reload_in_progress || reload_completed)
3039            && memory_operand (operands[0], DFmode)))"
3041   switch (which_alternative)
3042     {
3043     case 0:
3044     case 1:
3045       return output_387_reg_move (insn, operands);
3047     case 2:
3048       return standard_80387_constant_opcode (operands[1]);
3050     case 3:
3051     case 4:
3052       return "#";
3053     case 5:
3054       switch (get_attr_mode (insn))
3055         {
3056         case MODE_V4SF:
3057           return "%vxorps\t%0, %d0";
3058         case MODE_V2DF:
3059           return "%vxorpd\t%0, %d0";
3060         case MODE_TI:
3061           return "%vpxor\t%0, %d0";
3062         default:
3063           gcc_unreachable ();
3064         }
3065     case 6:
3066     case 7:
3067     case 8:
3068       switch (get_attr_mode (insn))
3069         {
3070         case MODE_V4SF:
3071           return "%vmovaps\t{%1, %0|%0, %1}";
3072         case MODE_V2DF:
3073           return "%vmovapd\t{%1, %0|%0, %1}";
3074         case MODE_TI:
3075           return "%vmovdqa\t{%1, %0|%0, %1}";
3076         case MODE_DI:
3077           return "%vmovq\t{%1, %0|%0, %1}";
3078         case MODE_DF:
3079           if (TARGET_AVX)
3080             {
3081               if (REG_P (operands[0]) && REG_P (operands[1]))
3082                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3083               else
3084                 return "vmovsd\t{%1, %0|%0, %1}";
3085             }
3086           else
3087             return "movsd\t{%1, %0|%0, %1}";
3088         case MODE_V1DF:
3089           if (TARGET_AVX)
3090             {
3091               if (REG_P (operands[0]))
3092                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3093               else
3094                 return "vmovlpd\t{%1, %0|%0, %1}";
3095             }
3096           else
3097             return "movlpd\t{%1, %0|%0, %1}";
3098         case MODE_V2SF:
3099           if (TARGET_AVX)
3100             {
3101               if (REG_P (operands[0]))
3102                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3103               else
3104                 return "vmovlps\t{%1, %0|%0, %1}";
3105             }
3106           else
3107             return "movlps\t{%1, %0|%0, %1}";
3108         default:
3109           gcc_unreachable ();
3110         }
3112     default:
3113       gcc_unreachable ();
3114     }
3116   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3117    (set (attr "prefix")
3118      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3119        (const_string "orig")
3120        (const_string "maybe_vex")))
3121    (set (attr "prefix_data16")
3122      (if_then_else (eq_attr "mode" "V1DF")
3123        (const_string "1")
3124        (const_string "*")))
3125    (set (attr "mode")
3126         (cond [(eq_attr "alternative" "0,1,2")
3127                  (const_string "DF")
3128                (eq_attr "alternative" "3,4")
3129                  (const_string "SI")
3131                /* For SSE1, we have many fewer alternatives.  */
3132                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3133                  (cond [(eq_attr "alternative" "5,6")
3134                           (const_string "V4SF")
3135                        ]
3136                    (const_string "V2SF"))
3138                /* xorps is one byte shorter.  */
3139                (eq_attr "alternative" "5")
3140                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3141                             (const_int 0))
3142                           (const_string "V4SF")
3143                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3144                             (const_int 0))
3145                           (const_string "TI")
3146                        ]
3147                        (const_string "V2DF"))
3149                /* For architectures resolving dependencies on
3150                   whole SSE registers use APD move to break dependency
3151                   chains, otherwise use short move to avoid extra work.
3153                   movaps encodes one byte shorter.  */
3154                (eq_attr "alternative" "6")
3155                  (cond
3156                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3157                         (const_int 0))
3158                       (const_string "V4SF")
3159                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3160                         (const_int 0))
3161                       (const_string "V2DF")
3162                    ]
3163                    (const_string "DF"))
3164                /* For architectures resolving dependencies on register
3165                   parts we may avoid extra work to zero out upper part
3166                   of register.  */
3167                (eq_attr "alternative" "7")
3168                  (if_then_else
3169                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3170                        (const_int 0))
3171                    (const_string "V1DF")
3172                    (const_string "DF"))
3173               ]
3174               (const_string "DF")))])
3176 (define_insn "*movdf_integer_rex64"
3177   [(set (match_operand:DF 0 "nonimmediate_operand"
3178                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3179         (match_operand:DF 1 "general_operand"
3180                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3181   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3182    && (reload_in_progress || reload_completed
3183        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3184        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3185            && optimize_function_for_size_p (cfun)
3186            && standard_80387_constant_p (operands[1]))
3187        || GET_CODE (operands[1]) != CONST_DOUBLE
3188        || memory_operand (operands[0], DFmode))"
3190   switch (which_alternative)
3191     {
3192     case 0:
3193     case 1:
3194       return output_387_reg_move (insn, operands);
3196     case 2:
3197       return standard_80387_constant_opcode (operands[1]);
3199     case 3:
3200     case 4:
3201       return "#";
3203     case 5:
3204       switch (get_attr_mode (insn))
3205         {
3206         case MODE_V4SF:
3207           return "%vxorps\t%0, %d0";
3208         case MODE_V2DF:
3209           return "%vxorpd\t%0, %d0";
3210         case MODE_TI:
3211           return "%vpxor\t%0, %d0";
3212         default:
3213           gcc_unreachable ();
3214         }
3215     case 6:
3216     case 7:
3217     case 8:
3218       switch (get_attr_mode (insn))
3219         {
3220         case MODE_V4SF:
3221           return "%vmovaps\t{%1, %0|%0, %1}";
3222         case MODE_V2DF:
3223           return "%vmovapd\t{%1, %0|%0, %1}";
3224         case MODE_TI:
3225           return "%vmovdqa\t{%1, %0|%0, %1}";
3226         case MODE_DI:
3227           return "%vmovq\t{%1, %0|%0, %1}";
3228         case MODE_DF:
3229           if (TARGET_AVX)
3230             {
3231               if (REG_P (operands[0]) && REG_P (operands[1]))
3232                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3233               else
3234                 return "vmovsd\t{%1, %0|%0, %1}";
3235             }
3236           else
3237             return "movsd\t{%1, %0|%0, %1}";
3238         case MODE_V1DF:
3239           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3240         case MODE_V2SF:
3241           return "%vmovlps\t{%1, %d0|%d0, %1}";
3242         default:
3243           gcc_unreachable ();
3244         }
3246     case 9:
3247     case 10:
3248     return "%vmovd\t{%1, %0|%0, %1}";
3250     default:
3251       gcc_unreachable();
3252     }
3254   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3255    (set (attr "prefix")
3256      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3257        (const_string "orig")
3258        (const_string "maybe_vex")))
3259    (set (attr "prefix_data16")
3260      (if_then_else (eq_attr "mode" "V1DF")
3261        (const_string "1")
3262        (const_string "*")))
3263    (set (attr "mode")
3264         (cond [(eq_attr "alternative" "0,1,2")
3265                  (const_string "DF")
3266                (eq_attr "alternative" "3,4,9,10")
3267                  (const_string "DI")
3269                /* For SSE1, we have many fewer alternatives.  */
3270                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3271                  (cond [(eq_attr "alternative" "5,6")
3272                           (const_string "V4SF")
3273                        ]
3274                    (const_string "V2SF"))
3276                /* xorps is one byte shorter.  */
3277                (eq_attr "alternative" "5")
3278                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3279                             (const_int 0))
3280                           (const_string "V4SF")
3281                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3282                             (const_int 0))
3283                           (const_string "TI")
3284                        ]
3285                        (const_string "V2DF"))
3287                /* For architectures resolving dependencies on
3288                   whole SSE registers use APD move to break dependency
3289                   chains, otherwise use short move to avoid extra work.
3291                   movaps encodes one byte shorter.  */
3292                (eq_attr "alternative" "6")
3293                  (cond
3294                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3295                         (const_int 0))
3296                       (const_string "V4SF")
3297                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3298                         (const_int 0))
3299                       (const_string "V2DF")
3300                    ]
3301                    (const_string "DF"))
3302                /* For architectures resolving dependencies on register
3303                   parts we may avoid extra work to zero out upper part
3304                   of register.  */
3305                (eq_attr "alternative" "7")
3306                  (if_then_else
3307                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3308                        (const_int 0))
3309                    (const_string "V1DF")
3310                    (const_string "DF"))
3311               ]
3312               (const_string "DF")))])
3314 (define_insn "*movdf_integer"
3315   [(set (match_operand:DF 0 "nonimmediate_operand"
3316                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3317         (match_operand:DF 1 "general_operand"
3318                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3319   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3320    && optimize_function_for_speed_p (cfun)
3321    && TARGET_INTEGER_DFMODE_MOVES
3322    && (reload_in_progress || reload_completed
3323        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3324        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3325            && optimize_function_for_size_p (cfun)
3326            && standard_80387_constant_p (operands[1]))
3327        || GET_CODE (operands[1]) != CONST_DOUBLE
3328        || memory_operand (operands[0], DFmode))"
3330   switch (which_alternative)
3331     {
3332     case 0:
3333     case 1:
3334       return output_387_reg_move (insn, operands);
3336     case 2:
3337       return standard_80387_constant_opcode (operands[1]);
3339     case 3:
3340     case 4:
3341       return "#";
3343     case 5:
3344       switch (get_attr_mode (insn))
3345         {
3346         case MODE_V4SF:
3347           return "xorps\t%0, %0";
3348         case MODE_V2DF:
3349           return "xorpd\t%0, %0";
3350         case MODE_TI:
3351           return "pxor\t%0, %0";
3352         default:
3353           gcc_unreachable ();
3354         }
3355     case 6:
3356     case 7:
3357     case 8:
3358       switch (get_attr_mode (insn))
3359         {
3360         case MODE_V4SF:
3361           return "movaps\t{%1, %0|%0, %1}";
3362         case MODE_V2DF:
3363           return "movapd\t{%1, %0|%0, %1}";
3364         case MODE_TI:
3365           return "movdqa\t{%1, %0|%0, %1}";
3366         case MODE_DI:
3367           return "movq\t{%1, %0|%0, %1}";
3368         case MODE_DF:
3369           return "movsd\t{%1, %0|%0, %1}";
3370         case MODE_V1DF:
3371           return "movlpd\t{%1, %0|%0, %1}";
3372         case MODE_V2SF:
3373           return "movlps\t{%1, %0|%0, %1}";
3374         default:
3375           gcc_unreachable ();
3376         }
3378     default:
3379       gcc_unreachable();
3380     }
3382   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3383    (set (attr "prefix_data16")
3384      (if_then_else (eq_attr "mode" "V1DF")
3385        (const_string "1")
3386        (const_string "*")))
3387    (set (attr "mode")
3388         (cond [(eq_attr "alternative" "0,1,2")
3389                  (const_string "DF")
3390                (eq_attr "alternative" "3,4")
3391                  (const_string "SI")
3393                /* For SSE1, we have many fewer alternatives.  */
3394                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3395                  (cond [(eq_attr "alternative" "5,6")
3396                           (const_string "V4SF")
3397                        ]
3398                    (const_string "V2SF"))
3400                /* xorps is one byte shorter.  */
3401                (eq_attr "alternative" "5")
3402                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3403                             (const_int 0))
3404                           (const_string "V4SF")
3405                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3406                             (const_int 0))
3407                           (const_string "TI")
3408                        ]
3409                        (const_string "V2DF"))
3411                /* For architectures resolving dependencies on
3412                   whole SSE registers use APD move to break dependency
3413                   chains, otherwise use short move to avoid extra work.
3415                   movaps encodes one byte shorter.  */
3416                (eq_attr "alternative" "6")
3417                  (cond
3418                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3419                         (const_int 0))
3420                       (const_string "V4SF")
3421                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3422                         (const_int 0))
3423                       (const_string "V2DF")
3424                    ]
3425                    (const_string "DF"))
3426                /* For architectures resolving dependencies on register
3427                   parts we may avoid extra work to zero out upper part
3428                   of register.  */
3429                (eq_attr "alternative" "7")
3430                  (if_then_else
3431                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3432                        (const_int 0))
3433                    (const_string "V1DF")
3434                    (const_string "DF"))
3435               ]
3436               (const_string "DF")))])
3438 (define_split
3439   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3440         (match_operand:DF 1 "general_operand" ""))]
3441   "reload_completed
3442    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3443    && ! (ANY_FP_REG_P (operands[0]) ||
3444          (GET_CODE (operands[0]) == SUBREG
3445           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3446    && ! (ANY_FP_REG_P (operands[1]) ||
3447          (GET_CODE (operands[1]) == SUBREG
3448           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3449   [(const_int 0)]
3450   "ix86_split_long_move (operands); DONE;")
3452 (define_insn "*swapdf"
3453   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3454         (match_operand:DF 1 "fp_register_operand" "+f"))
3455    (set (match_dup 1)
3456         (match_dup 0))]
3457   "reload_completed || TARGET_80387"
3459   if (STACK_TOP_P (operands[0]))
3460     return "fxch\t%1";
3461   else
3462     return "fxch\t%0";
3464   [(set_attr "type" "fxch")
3465    (set_attr "mode" "DF")])
3467 (define_expand "movxf"
3468   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3469         (match_operand:XF 1 "general_operand" ""))]
3470   ""
3471   "ix86_expand_move (XFmode, operands); DONE;")
3473 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3474 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3475 ;; Pushing using integer instructions is longer except for constants
3476 ;; and direct memory references.
3477 ;; (assuming that any given constant is pushed only once, but this ought to be
3478 ;;  handled elsewhere).
3480 (define_insn "*pushxf_nointeger"
3481   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3482         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3483   "optimize_function_for_size_p (cfun)"
3485   /* This insn should be already split before reg-stack.  */
3486   gcc_unreachable ();
3488   [(set_attr "type" "multi")
3489    (set_attr "unit" "i387,*,*")
3490    (set_attr "mode" "XF,SI,SI")])
3492 (define_insn "*pushxf_integer"
3493   [(set (match_operand:XF 0 "push_operand" "=<,<")
3494         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3495   "optimize_function_for_speed_p (cfun)"
3497   /* This insn should be already split before reg-stack.  */
3498   gcc_unreachable ();
3500   [(set_attr "type" "multi")
3501    (set_attr "unit" "i387,*")
3502    (set_attr "mode" "XF,SI")])
3504 (define_split
3505   [(set (match_operand 0 "push_operand" "")
3506         (match_operand 1 "general_operand" ""))]
3507   "reload_completed
3508    && (GET_MODE (operands[0]) == XFmode
3509        || GET_MODE (operands[0]) == DFmode)
3510    && !ANY_FP_REG_P (operands[1])"
3511   [(const_int 0)]
3512   "ix86_split_long_move (operands); DONE;")
3514 (define_split
3515   [(set (match_operand:XF 0 "push_operand" "")
3516         (match_operand:XF 1 "any_fp_register_operand" ""))]
3517   ""
3518   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3519    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3520   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3522 ;; Do not use integer registers when optimizing for size
3523 (define_insn "*movxf_nointeger"
3524   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3525         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3526   "optimize_function_for_size_p (cfun)
3527    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3528    && (reload_in_progress || reload_completed
3529        || standard_80387_constant_p (operands[1])
3530        || GET_CODE (operands[1]) != CONST_DOUBLE
3531        || memory_operand (operands[0], XFmode))"
3533   switch (which_alternative)
3534     {
3535     case 0:
3536     case 1:
3537       return output_387_reg_move (insn, operands);
3539     case 2:
3540       return standard_80387_constant_opcode (operands[1]);
3542     case 3: case 4:
3543       return "#";
3544     default:
3545       gcc_unreachable ();
3546     }
3548   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3549    (set_attr "mode" "XF,XF,XF,SI,SI")])
3551 (define_insn "*movxf_integer"
3552   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3553         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3554   "optimize_function_for_speed_p (cfun)
3555    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3556    && (reload_in_progress || reload_completed
3557        || GET_CODE (operands[1]) != CONST_DOUBLE
3558        || memory_operand (operands[0], XFmode))"
3560   switch (which_alternative)
3561     {
3562     case 0:
3563     case 1:
3564       return output_387_reg_move (insn, operands);
3566     case 2:
3567       return standard_80387_constant_opcode (operands[1]);
3569     case 3: case 4:
3570       return "#";
3572     default:
3573       gcc_unreachable ();
3574     }
3576   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3577    (set_attr "mode" "XF,XF,XF,SI,SI")])
3579 (define_expand "movtf"
3580   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3581         (match_operand:TF 1 "nonimmediate_operand" ""))]
3582   "TARGET_SSE2"
3584   ix86_expand_move (TFmode, operands);
3585   DONE;
3588 (define_insn "*movtf_internal"
3589   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3590         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3591   "TARGET_SSE2
3592    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3594   switch (which_alternative)
3595     {
3596     case 0:
3597     case 1:
3598       if (get_attr_mode (insn) == MODE_V4SF)
3599         return "%vmovaps\t{%1, %0|%0, %1}";
3600       else
3601         return "%vmovdqa\t{%1, %0|%0, %1}";
3602     case 2:
3603       if (get_attr_mode (insn) == MODE_V4SF)
3604         return "%vxorps\t%0, %d0";
3605       else
3606         return "%vpxor\t%0, %d0";
3607     case 3:
3608     case 4:
3609         return "#";
3610     default:
3611       gcc_unreachable ();
3612     }
3614   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3615    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3616    (set (attr "mode")
3617         (cond [(eq_attr "alternative" "0,2")
3618                  (if_then_else
3619                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3620                        (const_int 0))
3621                    (const_string "V4SF")
3622                    (const_string "TI"))
3623                (eq_attr "alternative" "1")
3624                  (if_then_else
3625                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3626                             (const_int 0))
3627                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3628                             (const_int 0)))
3629                    (const_string "V4SF")
3630                    (const_string "TI"))]
3631                (const_string "DI")))])
3633 (define_insn "*pushtf_sse"
3634   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3635         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3636   "TARGET_SSE2"
3638   /* This insn should be already split before reg-stack.  */
3639   gcc_unreachable ();
3641   [(set_attr "type" "multi")
3642    (set_attr "unit" "sse,*,*")
3643    (set_attr "mode" "TF,SI,SI")])
3645 (define_split
3646   [(set (match_operand:TF 0 "push_operand" "")
3647         (match_operand:TF 1 "general_operand" ""))]
3648   "TARGET_SSE2 && reload_completed
3649    && !SSE_REG_P (operands[1])"
3650   [(const_int 0)]
3651   "ix86_split_long_move (operands); DONE;")
3653 (define_split
3654   [(set (match_operand:TF 0 "push_operand" "")
3655         (match_operand:TF 1 "any_fp_register_operand" ""))]
3656   "TARGET_SSE2"
3657   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3658    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3659   "")
3661 (define_split
3662   [(set (match_operand 0 "nonimmediate_operand" "")
3663         (match_operand 1 "general_operand" ""))]
3664   "reload_completed
3665    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3666    && GET_MODE (operands[0]) == XFmode
3667    && ! (ANY_FP_REG_P (operands[0]) ||
3668          (GET_CODE (operands[0]) == SUBREG
3669           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3670    && ! (ANY_FP_REG_P (operands[1]) ||
3671          (GET_CODE (operands[1]) == SUBREG
3672           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3673   [(const_int 0)]
3674   "ix86_split_long_move (operands); DONE;")
3676 (define_split
3677   [(set (match_operand 0 "register_operand" "")
3678         (match_operand 1 "memory_operand" ""))]
3679   "reload_completed
3680    && MEM_P (operands[1])
3681    && (GET_MODE (operands[0]) == TFmode
3682        || GET_MODE (operands[0]) == XFmode
3683        || GET_MODE (operands[0]) == SFmode
3684        || GET_MODE (operands[0]) == DFmode)
3685    && (operands[2] = find_constant_src (insn))"
3686   [(set (match_dup 0) (match_dup 2))]
3688   rtx c = operands[2];
3689   rtx r = operands[0];
3691   if (GET_CODE (r) == SUBREG)
3692     r = SUBREG_REG (r);
3694   if (SSE_REG_P (r))
3695     {
3696       if (!standard_sse_constant_p (c))
3697         FAIL;
3698     }
3699   else if (FP_REG_P (r))
3700     {
3701       if (!standard_80387_constant_p (c))
3702         FAIL;
3703     }
3704   else if (MMX_REG_P (r))
3705     FAIL;
3708 (define_split
3709   [(set (match_operand 0 "register_operand" "")
3710         (float_extend (match_operand 1 "memory_operand" "")))]
3711   "reload_completed
3712    && MEM_P (operands[1])
3713    && (GET_MODE (operands[0]) == TFmode
3714        || GET_MODE (operands[0]) == XFmode
3715        || GET_MODE (operands[0]) == SFmode
3716        || GET_MODE (operands[0]) == DFmode)
3717    && (operands[2] = find_constant_src (insn))"
3718   [(set (match_dup 0) (match_dup 2))]
3720   rtx c = operands[2];
3721   rtx r = operands[0];
3723   if (GET_CODE (r) == SUBREG)
3724     r = SUBREG_REG (r);
3726   if (SSE_REG_P (r))
3727     {
3728       if (!standard_sse_constant_p (c))
3729         FAIL;
3730     }
3731   else if (FP_REG_P (r))
3732     {
3733       if (!standard_80387_constant_p (c))
3734         FAIL;
3735     }
3736   else if (MMX_REG_P (r))
3737     FAIL;
3740 (define_insn "swapxf"
3741   [(set (match_operand:XF 0 "register_operand" "+f")
3742         (match_operand:XF 1 "register_operand" "+f"))
3743    (set (match_dup 1)
3744         (match_dup 0))]
3745   "TARGET_80387"
3747   if (STACK_TOP_P (operands[0]))
3748     return "fxch\t%1";
3749   else
3750     return "fxch\t%0";
3752   [(set_attr "type" "fxch")
3753    (set_attr "mode" "XF")])
3755 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3756 (define_split
3757   [(set (match_operand:X87MODEF 0 "register_operand" "")
3758         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3759   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3760    && (standard_80387_constant_p (operands[1]) == 8
3761        || standard_80387_constant_p (operands[1]) == 9)"
3762   [(set (match_dup 0)(match_dup 1))
3763    (set (match_dup 0)
3764         (neg:X87MODEF (match_dup 0)))]
3766   REAL_VALUE_TYPE r;
3768   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3769   if (real_isnegzero (&r))
3770     operands[1] = CONST0_RTX (<MODE>mode);
3771   else
3772     operands[1] = CONST1_RTX (<MODE>mode);
3775 (define_split
3776   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3777         (match_operand:TF 1 "general_operand" ""))]
3778   "reload_completed
3779    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3780   [(const_int 0)]
3781   "ix86_split_long_move (operands); DONE;")
3783 ;; Zero extension instructions
3785 (define_expand "zero_extendhisi2"
3786   [(set (match_operand:SI 0 "register_operand" "")
3787      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3788   ""
3790   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3791     {
3792       operands[1] = force_reg (HImode, operands[1]);
3793       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3794       DONE;
3795     }
3798 (define_insn "zero_extendhisi2_and"
3799   [(set (match_operand:SI 0 "register_operand" "=r")
3800      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3801    (clobber (reg:CC FLAGS_REG))]
3802   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3803   "#"
3804   [(set_attr "type" "alu1")
3805    (set_attr "mode" "SI")])
3807 (define_split
3808   [(set (match_operand:SI 0 "register_operand" "")
3809         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3810    (clobber (reg:CC FLAGS_REG))]
3811   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3812    && optimize_function_for_speed_p (cfun)"
3813   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3814               (clobber (reg:CC FLAGS_REG))])]
3815   "")
3817 (define_insn "*zero_extendhisi2_movzwl"
3818   [(set (match_operand:SI 0 "register_operand" "=r")
3819      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3820   "!TARGET_ZERO_EXTEND_WITH_AND
3821    || optimize_function_for_size_p (cfun)"
3822   "movz{wl|x}\t{%1, %0|%0, %1}"
3823   [(set_attr "type" "imovx")
3824    (set_attr "mode" "SI")])
3826 (define_expand "zero_extendqihi2"
3827   [(parallel
3828     [(set (match_operand:HI 0 "register_operand" "")
3829        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3830      (clobber (reg:CC FLAGS_REG))])]
3831   ""
3832   "")
3834 (define_insn "*zero_extendqihi2_and"
3835   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3836      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3837    (clobber (reg:CC FLAGS_REG))]
3838   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3839   "#"
3840   [(set_attr "type" "alu1")
3841    (set_attr "mode" "HI")])
3843 (define_insn "*zero_extendqihi2_movzbw_and"
3844   [(set (match_operand:HI 0 "register_operand" "=r,r")
3845      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3846    (clobber (reg:CC FLAGS_REG))]
3847   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3848   "#"
3849   [(set_attr "type" "imovx,alu1")
3850    (set_attr "mode" "HI")])
3852 ; zero extend to SImode here to avoid partial register stalls
3853 (define_insn "*zero_extendqihi2_movzbl"
3854   [(set (match_operand:HI 0 "register_operand" "=r")
3855      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3856   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3857    && reload_completed"
3858   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3859   [(set_attr "type" "imovx")
3860    (set_attr "mode" "SI")])
3862 ;; For the movzbw case strip only the clobber
3863 (define_split
3864   [(set (match_operand:HI 0 "register_operand" "")
3865         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3866    (clobber (reg:CC FLAGS_REG))]
3867   "reload_completed
3868    && (!TARGET_ZERO_EXTEND_WITH_AND
3869        || optimize_function_for_size_p (cfun))
3870    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3871   [(set (match_operand:HI 0 "register_operand" "")
3872         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3874 ;; When source and destination does not overlap, clear destination
3875 ;; first and then do the movb
3876 (define_split
3877   [(set (match_operand:HI 0 "register_operand" "")
3878         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3879    (clobber (reg:CC FLAGS_REG))]
3880   "reload_completed
3881    && ANY_QI_REG_P (operands[0])
3882    && (TARGET_ZERO_EXTEND_WITH_AND
3883        && optimize_function_for_speed_p (cfun))
3884    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3885   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3887   operands[2] = gen_lowpart (QImode, operands[0]);
3888   ix86_expand_clear (operands[0]);
3891 ;; Rest is handled by single and.
3892 (define_split
3893   [(set (match_operand:HI 0 "register_operand" "")
3894         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3895    (clobber (reg:CC FLAGS_REG))]
3896   "reload_completed
3897    && true_regnum (operands[0]) == true_regnum (operands[1])"
3898   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3899               (clobber (reg:CC FLAGS_REG))])]
3900   "")
3902 (define_expand "zero_extendqisi2"
3903   [(parallel
3904     [(set (match_operand:SI 0 "register_operand" "")
3905        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3906      (clobber (reg:CC FLAGS_REG))])]
3907   ""
3908   "")
3910 (define_insn "*zero_extendqisi2_and"
3911   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3912      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3913    (clobber (reg:CC FLAGS_REG))]
3914   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3915   "#"
3916   [(set_attr "type" "alu1")
3917    (set_attr "mode" "SI")])
3919 (define_insn "*zero_extendqisi2_movzbl_and"
3920   [(set (match_operand:SI 0 "register_operand" "=r,r")
3921      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3922    (clobber (reg:CC FLAGS_REG))]
3923   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3924   "#"
3925   [(set_attr "type" "imovx,alu1")
3926    (set_attr "mode" "SI")])
3928 (define_insn "*zero_extendqisi2_movzbl"
3929   [(set (match_operand:SI 0 "register_operand" "=r")
3930      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3931   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3932    && reload_completed"
3933   "movz{bl|x}\t{%1, %0|%0, %1}"
3934   [(set_attr "type" "imovx")
3935    (set_attr "mode" "SI")])
3937 ;; For the movzbl case strip only the clobber
3938 (define_split
3939   [(set (match_operand:SI 0 "register_operand" "")
3940         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3941    (clobber (reg:CC FLAGS_REG))]
3942   "reload_completed
3943    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3944    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3945   [(set (match_dup 0)
3946         (zero_extend:SI (match_dup 1)))])
3948 ;; When source and destination does not overlap, clear destination
3949 ;; first and then do the movb
3950 (define_split
3951   [(set (match_operand:SI 0 "register_operand" "")
3952         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3953    (clobber (reg:CC FLAGS_REG))]
3954   "reload_completed
3955    && ANY_QI_REG_P (operands[0])
3956    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3957    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3958    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3959   [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3961   operands[2] = gen_lowpart (QImode, operands[0]);
3962   ix86_expand_clear (operands[0]);
3965 ;; Rest is handled by single and.
3966 (define_split
3967   [(set (match_operand:SI 0 "register_operand" "")
3968         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3969    (clobber (reg:CC FLAGS_REG))]
3970   "reload_completed
3971    && true_regnum (operands[0]) == true_regnum (operands[1])"
3972   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3973               (clobber (reg:CC FLAGS_REG))])]
3974   "")
3976 ;; %%% Kill me once multi-word ops are sane.
3977 (define_expand "zero_extendsidi2"
3978   [(set (match_operand:DI 0 "register_operand" "")
3979      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3980   ""
3982   if (!TARGET_64BIT)
3983     {
3984       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3985       DONE;
3986     }
3989 (define_insn "zero_extendsidi2_32"
3990   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3991         (zero_extend:DI
3992          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3993    (clobber (reg:CC FLAGS_REG))]
3994   "!TARGET_64BIT"
3995   "@
3996    #
3997    #
3998    #
3999    movd\t{%1, %0|%0, %1}
4000    movd\t{%1, %0|%0, %1}
4001    %vmovd\t{%1, %0|%0, %1}
4002    %vmovd\t{%1, %0|%0, %1}"
4003   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4004    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4005    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4007 (define_insn "zero_extendsidi2_rex64"
4008   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4009      (zero_extend:DI
4010        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
4011   "TARGET_64BIT"
4012   "@
4013    mov\t{%k1, %k0|%k0, %k1}
4014    #
4015    movd\t{%1, %0|%0, %1}
4016    movd\t{%1, %0|%0, %1}
4017    %vmovd\t{%1, %0|%0, %1}
4018    %vmovd\t{%1, %0|%0, %1}"
4019   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4020    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4021    (set_attr "prefix_0f" "0,*,*,*,*,*")
4022    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4024 (define_split
4025   [(set (match_operand:DI 0 "memory_operand" "")
4026      (zero_extend:DI (match_dup 0)))]
4027   "TARGET_64BIT"
4028   [(set (match_dup 4) (const_int 0))]
4029   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4031 (define_split
4032   [(set (match_operand:DI 0 "register_operand" "")
4033         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4034    (clobber (reg:CC FLAGS_REG))]
4035   "!TARGET_64BIT && reload_completed
4036    && true_regnum (operands[0]) == true_regnum (operands[1])"
4037   [(set (match_dup 4) (const_int 0))]
4038   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4040 (define_split
4041   [(set (match_operand:DI 0 "nonimmediate_operand" "")
4042         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4043    (clobber (reg:CC FLAGS_REG))]
4044   "!TARGET_64BIT && reload_completed
4045    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4046   [(set (match_dup 3) (match_dup 1))
4047    (set (match_dup 4) (const_int 0))]
4048   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4050 (define_insn "zero_extendhidi2"
4051   [(set (match_operand:DI 0 "register_operand" "=r")
4052      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4053   "TARGET_64BIT"
4054   "movz{wl|x}\t{%1, %k0|%k0, %1}"
4055   [(set_attr "type" "imovx")
4056    (set_attr "mode" "SI")])
4058 (define_insn "zero_extendqidi2"
4059   [(set (match_operand:DI 0 "register_operand" "=r")
4060      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4061   "TARGET_64BIT"
4062   "movz{bl|x}\t{%1, %k0|%k0, %1}"
4063   [(set_attr "type" "imovx")
4064    (set_attr "mode" "SI")])
4066 ;; Sign extension instructions
4068 (define_expand "extendsidi2"
4069   [(parallel [(set (match_operand:DI 0 "register_operand" "")
4070                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4071               (clobber (reg:CC FLAGS_REG))
4072               (clobber (match_scratch:SI 2 ""))])]
4073   ""
4075   if (TARGET_64BIT)
4076     {
4077       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4078       DONE;
4079     }
4082 (define_insn "*extendsidi2_1"
4083   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4084         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4085    (clobber (reg:CC FLAGS_REG))
4086    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4087   "!TARGET_64BIT"
4088   "#")
4090 (define_insn "extendsidi2_rex64"
4091   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4092         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4093   "TARGET_64BIT"
4094   "@
4095    {cltq|cdqe}
4096    movs{lq|x}\t{%1, %0|%0, %1}"
4097   [(set_attr "type" "imovx")
4098    (set_attr "mode" "DI")
4099    (set_attr "prefix_0f" "0")
4100    (set_attr "modrm" "0,1")])
4102 (define_insn "extendhidi2"
4103   [(set (match_operand:DI 0 "register_operand" "=r")
4104         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4105   "TARGET_64BIT"
4106   "movs{wq|x}\t{%1, %0|%0, %1}"
4107   [(set_attr "type" "imovx")
4108    (set_attr "mode" "DI")])
4110 (define_insn "extendqidi2"
4111   [(set (match_operand:DI 0 "register_operand" "=r")
4112         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4113   "TARGET_64BIT"
4114   "movs{bq|x}\t{%1, %0|%0, %1}"
4115    [(set_attr "type" "imovx")
4116     (set_attr "mode" "DI")])
4118 ;; Extend to memory case when source register does die.
4119 (define_split
4120   [(set (match_operand:DI 0 "memory_operand" "")
4121         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4122    (clobber (reg:CC FLAGS_REG))
4123    (clobber (match_operand:SI 2 "register_operand" ""))]
4124   "(reload_completed
4125     && dead_or_set_p (insn, operands[1])
4126     && !reg_mentioned_p (operands[1], operands[0]))"
4127   [(set (match_dup 3) (match_dup 1))
4128    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4129               (clobber (reg:CC FLAGS_REG))])
4130    (set (match_dup 4) (match_dup 1))]
4131   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4133 ;; Extend to memory case when source register does not die.
4134 (define_split
4135   [(set (match_operand:DI 0 "memory_operand" "")
4136         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4137    (clobber (reg:CC FLAGS_REG))
4138    (clobber (match_operand:SI 2 "register_operand" ""))]
4139   "reload_completed"
4140   [(const_int 0)]
4142   split_di (&operands[0], 1, &operands[3], &operands[4]);
4144   emit_move_insn (operands[3], operands[1]);
4146   /* Generate a cltd if possible and doing so it profitable.  */
4147   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4148       && true_regnum (operands[1]) == AX_REG
4149       && true_regnum (operands[2]) == DX_REG)
4150     {
4151       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4152     }
4153   else
4154     {
4155       emit_move_insn (operands[2], operands[1]);
4156       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4157     }
4158   emit_move_insn (operands[4], operands[2]);
4159   DONE;
4162 ;; Extend to register case.  Optimize case where source and destination
4163 ;; registers match and cases where we can use cltd.
4164 (define_split
4165   [(set (match_operand:DI 0 "register_operand" "")
4166         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4167    (clobber (reg:CC FLAGS_REG))
4168    (clobber (match_scratch:SI 2 ""))]
4169   "reload_completed"
4170   [(const_int 0)]
4172   split_di (&operands[0], 1, &operands[3], &operands[4]);
4174   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4175     emit_move_insn (operands[3], operands[1]);
4177   /* Generate a cltd if possible and doing so it profitable.  */
4178   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4179       && true_regnum (operands[3]) == AX_REG)
4180     {
4181       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4182       DONE;
4183     }
4185   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4186     emit_move_insn (operands[4], operands[1]);
4188   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4189   DONE;
4192 (define_insn "extendhisi2"
4193   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4194         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4195   ""
4197   switch (get_attr_prefix_0f (insn))
4198     {
4199     case 0:
4200       return "{cwtl|cwde}";
4201     default:
4202       return "movs{wl|x}\t{%1, %0|%0, %1}";
4203     }
4205   [(set_attr "type" "imovx")
4206    (set_attr "mode" "SI")
4207    (set (attr "prefix_0f")
4208      ;; movsx is short decodable while cwtl is vector decoded.
4209      (if_then_else (and (eq_attr "cpu" "!k6")
4210                         (eq_attr "alternative" "0"))
4211         (const_string "0")
4212         (const_string "1")))
4213    (set (attr "modrm")
4214      (if_then_else (eq_attr "prefix_0f" "0")
4215         (const_string "0")
4216         (const_string "1")))])
4218 (define_insn "*extendhisi2_zext"
4219   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4220         (zero_extend:DI
4221           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4222   "TARGET_64BIT"
4224   switch (get_attr_prefix_0f (insn))
4225     {
4226     case 0:
4227       return "{cwtl|cwde}";
4228     default:
4229       return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4230     }
4232   [(set_attr "type" "imovx")
4233    (set_attr "mode" "SI")
4234    (set (attr "prefix_0f")
4235      ;; movsx is short decodable while cwtl is vector decoded.
4236      (if_then_else (and (eq_attr "cpu" "!k6")
4237                         (eq_attr "alternative" "0"))
4238         (const_string "0")
4239         (const_string "1")))
4240    (set (attr "modrm")
4241      (if_then_else (eq_attr "prefix_0f" "0")
4242         (const_string "0")
4243         (const_string "1")))])
4245 (define_insn "extendqihi2"
4246   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4247         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4248   ""
4250   switch (get_attr_prefix_0f (insn))
4251     {
4252     case 0:
4253       return "{cbtw|cbw}";
4254     default:
4255       return "movs{bw|x}\t{%1, %0|%0, %1}";
4256     }
4258   [(set_attr "type" "imovx")
4259    (set_attr "mode" "HI")
4260    (set (attr "prefix_0f")
4261      ;; movsx is short decodable while cwtl is vector decoded.
4262      (if_then_else (and (eq_attr "cpu" "!k6")
4263                         (eq_attr "alternative" "0"))
4264         (const_string "0")
4265         (const_string "1")))
4266    (set (attr "modrm")
4267      (if_then_else (eq_attr "prefix_0f" "0")
4268         (const_string "0")
4269         (const_string "1")))])
4271 (define_insn "extendqisi2"
4272   [(set (match_operand:SI 0 "register_operand" "=r")
4273         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4274   ""
4275   "movs{bl|x}\t{%1, %0|%0, %1}"
4276    [(set_attr "type" "imovx")
4277     (set_attr "mode" "SI")])
4279 (define_insn "*extendqisi2_zext"
4280   [(set (match_operand:DI 0 "register_operand" "=r")
4281         (zero_extend:DI
4282           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4283   "TARGET_64BIT"
4284   "movs{bl|x}\t{%1, %k0|%k0, %1}"
4285    [(set_attr "type" "imovx")
4286     (set_attr "mode" "SI")])
4288 ;; Conversions between float and double.
4290 ;; These are all no-ops in the model used for the 80387.  So just
4291 ;; emit moves.
4293 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4294 (define_insn "*dummy_extendsfdf2"
4295   [(set (match_operand:DF 0 "push_operand" "=<")
4296         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4297   "0"
4298   "#")
4300 (define_split
4301   [(set (match_operand:DF 0 "push_operand" "")
4302         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4303   ""
4304   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4305    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4307 (define_insn "*dummy_extendsfxf2"
4308   [(set (match_operand:XF 0 "push_operand" "=<")
4309         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4310   "0"
4311   "#")
4313 (define_split
4314   [(set (match_operand:XF 0 "push_operand" "")
4315         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4316   ""
4317   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4318    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4319   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4321 (define_split
4322   [(set (match_operand:XF 0 "push_operand" "")
4323         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4324   ""
4325   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4326    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4327   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4329 (define_expand "extendsfdf2"
4330   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4331         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4332   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4334   /* ??? Needed for compress_float_constant since all fp constants
4335      are LEGITIMATE_CONSTANT_P.  */
4336   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4337     {
4338       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4339           && standard_80387_constant_p (operands[1]) > 0)
4340         {
4341           operands[1] = simplify_const_unary_operation
4342             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4343           emit_move_insn_1 (operands[0], operands[1]);
4344           DONE;
4345         }
4346       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4347     }
4350 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4351    cvtss2sd:
4352       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4353       cvtps2pd xmm2,xmm1
4354    We do the conversion post reload to avoid producing of 128bit spills
4355    that might lead to ICE on 32bit target.  The sequence unlikely combine
4356    anyway.  */
4357 (define_split
4358   [(set (match_operand:DF 0 "register_operand" "")
4359         (float_extend:DF
4360           (match_operand:SF 1 "nonimmediate_operand" "")))]
4361   "TARGET_USE_VECTOR_FP_CONVERTS
4362    && optimize_insn_for_speed_p ()
4363    && reload_completed && SSE_REG_P (operands[0])"
4364    [(set (match_dup 2)
4365          (float_extend:V2DF
4366            (vec_select:V2SF
4367              (match_dup 3)
4368              (parallel [(const_int 0) (const_int 1)]))))]
4370   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4371   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4372   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4373      Try to avoid move when unpacking can be done in source.  */
4374   if (REG_P (operands[1]))
4375     {
4376       /* If it is unsafe to overwrite upper half of source, we need
4377          to move to destination and unpack there.  */
4378       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4379            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4380           && true_regnum (operands[0]) != true_regnum (operands[1]))
4381         {
4382           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4383           emit_move_insn (tmp, operands[1]);
4384         }
4385       else
4386         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4387       emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4388                                              operands[3]));
4389     }
4390   else
4391     emit_insn (gen_vec_setv4sf_0 (operands[3],
4392                                   CONST0_RTX (V4SFmode), operands[1]));
4395 (define_insn "*extendsfdf2_mixed"
4396   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4397         (float_extend:DF
4398           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4399   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4401   switch (which_alternative)
4402     {
4403     case 0:
4404     case 1:
4405       return output_387_reg_move (insn, operands);
4407     case 2:
4408       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4410     default:
4411       gcc_unreachable ();
4412     }
4414   [(set_attr "type" "fmov,fmov,ssecvt")
4415    (set_attr "prefix" "orig,orig,maybe_vex")
4416    (set_attr "mode" "SF,XF,DF")])
4418 (define_insn "*extendsfdf2_sse"
4419   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4420         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4421   "TARGET_SSE2 && TARGET_SSE_MATH"
4422   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4423   [(set_attr "type" "ssecvt")
4424    (set_attr "prefix" "maybe_vex")
4425    (set_attr "mode" "DF")])
4427 (define_insn "*extendsfdf2_i387"
4428   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4429         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4430   "TARGET_80387"
4431   "* return output_387_reg_move (insn, operands);"
4432   [(set_attr "type" "fmov")
4433    (set_attr "mode" "SF,XF")])
4435 (define_expand "extend<mode>xf2"
4436   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4437         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4438   "TARGET_80387"
4440   /* ??? Needed for compress_float_constant since all fp constants
4441      are LEGITIMATE_CONSTANT_P.  */
4442   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4443     {
4444       if (standard_80387_constant_p (operands[1]) > 0)
4445         {
4446           operands[1] = simplify_const_unary_operation
4447             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4448           emit_move_insn_1 (operands[0], operands[1]);
4449           DONE;
4450         }
4451       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4452     }
4455 (define_insn "*extend<mode>xf2_i387"
4456   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4457         (float_extend:XF
4458           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4459   "TARGET_80387"
4460   "* return output_387_reg_move (insn, operands);"
4461   [(set_attr "type" "fmov")
4462    (set_attr "mode" "<MODE>,XF")])
4464 ;; %%% This seems bad bad news.
4465 ;; This cannot output into an f-reg because there is no way to be sure
4466 ;; of truncating in that case.  Otherwise this is just like a simple move
4467 ;; insn.  So we pretend we can output to a reg in order to get better
4468 ;; register preferencing, but we really use a stack slot.
4470 ;; Conversion from DFmode to SFmode.
4472 (define_expand "truncdfsf2"
4473   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4474         (float_truncate:SF
4475           (match_operand:DF 1 "nonimmediate_operand" "")))]
4476   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4478   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4479     ;
4480   else if (flag_unsafe_math_optimizations)
4481     ;
4482   else
4483     {
4484       enum ix86_stack_slot slot = (virtuals_instantiated
4485                                    ? SLOT_TEMP
4486                                    : SLOT_VIRTUAL);
4487       rtx temp = assign_386_stack_local (SFmode, slot);
4488       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4489       DONE;
4490     }
4493 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4494    cvtsd2ss:
4495       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4496       cvtpd2ps xmm2,xmm1
4497    We do the conversion post reload to avoid producing of 128bit spills
4498    that might lead to ICE on 32bit target.  The sequence unlikely combine
4499    anyway.  */
4500 (define_split
4501   [(set (match_operand:SF 0 "register_operand" "")
4502         (float_truncate:SF
4503           (match_operand:DF 1 "nonimmediate_operand" "")))]
4504   "TARGET_USE_VECTOR_FP_CONVERTS
4505    && optimize_insn_for_speed_p ()
4506    && reload_completed && SSE_REG_P (operands[0])"
4507    [(set (match_dup 2)
4508          (vec_concat:V4SF
4509            (float_truncate:V2SF
4510              (match_dup 4))
4511            (match_dup 3)))]
4513   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4514   operands[3] = CONST0_RTX (V2SFmode);
4515   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4516   /* Use movsd for loading from memory, unpcklpd for registers.
4517      Try to avoid move when unpacking can be done in source, or SSE3
4518      movddup is available.  */
4519   if (REG_P (operands[1]))
4520     {
4521       if (!TARGET_SSE3
4522           && true_regnum (operands[0]) != true_regnum (operands[1])
4523           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4524               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4525         {
4526           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4527           emit_move_insn (tmp, operands[1]);
4528           operands[1] = tmp;
4529         }
4530       else if (!TARGET_SSE3)
4531         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4532       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4533     }
4534   else
4535     emit_insn (gen_sse2_loadlpd (operands[4],
4536                                  CONST0_RTX (V2DFmode), operands[1]));
4539 (define_expand "truncdfsf2_with_temp"
4540   [(parallel [(set (match_operand:SF 0 "" "")
4541                    (float_truncate:SF (match_operand:DF 1 "" "")))
4542               (clobber (match_operand:SF 2 "" ""))])]
4543   "")
4545 (define_insn "*truncdfsf_fast_mixed"
4546   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4547         (float_truncate:SF
4548           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4549   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4551   switch (which_alternative)
4552     {
4553     case 0:
4554       return output_387_reg_move (insn, operands);
4555     case 1:
4556       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4557     default:
4558       gcc_unreachable ();
4559     }
4561   [(set_attr "type" "fmov,ssecvt")
4562    (set_attr "prefix" "orig,maybe_vex")
4563    (set_attr "mode" "SF")])
4565 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4566 ;; because nothing we do here is unsafe.
4567 (define_insn "*truncdfsf_fast_sse"
4568   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4569         (float_truncate:SF
4570           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4571   "TARGET_SSE2 && TARGET_SSE_MATH"
4572   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4573   [(set_attr "type" "ssecvt")
4574    (set_attr "prefix" "maybe_vex")
4575    (set_attr "mode" "SF")])
4577 (define_insn "*truncdfsf_fast_i387"
4578   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4579         (float_truncate:SF
4580           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4581   "TARGET_80387 && flag_unsafe_math_optimizations"
4582   "* return output_387_reg_move (insn, operands);"
4583   [(set_attr "type" "fmov")
4584    (set_attr "mode" "SF")])
4586 (define_insn "*truncdfsf_mixed"
4587   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,Y2 ,?f,?x,?*r")
4588         (float_truncate:SF
4589           (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4590    (clobber (match_operand:SF 2 "memory_operand"     "=X,X  ,m ,m ,m"))]
4591   "TARGET_MIX_SSE_I387"
4593   switch (which_alternative)
4594     {
4595     case 0:
4596       return output_387_reg_move (insn, operands);
4597     case 1:
4598       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4600     default:
4601       return "#";
4602     }
4604   [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4605    (set_attr "unit" "*,*,i387,i387,i387")
4606    (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4607    (set_attr "mode" "SF")])
4609 (define_insn "*truncdfsf_i387"
4610   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?f,?x,?*r")
4611         (float_truncate:SF
4612           (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4613    (clobber (match_operand:SF 2 "memory_operand"     "=X,m ,m ,m"))]
4614   "TARGET_80387"
4616   switch (which_alternative)
4617     {
4618     case 0:
4619       return output_387_reg_move (insn, operands);
4621     default:
4622       return "#";
4623     }
4625   [(set_attr "type" "fmov,multi,multi,multi")
4626    (set_attr "unit" "*,i387,i387,i387")
4627    (set_attr "mode" "SF")])
4629 (define_insn "*truncdfsf2_i387_1"
4630   [(set (match_operand:SF 0 "memory_operand" "=m")
4631         (float_truncate:SF
4632           (match_operand:DF 1 "register_operand" "f")))]
4633   "TARGET_80387
4634    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4635    && !TARGET_MIX_SSE_I387"
4636   "* return output_387_reg_move (insn, operands);"
4637   [(set_attr "type" "fmov")
4638    (set_attr "mode" "SF")])
4640 (define_split
4641   [(set (match_operand:SF 0 "register_operand" "")
4642         (float_truncate:SF
4643          (match_operand:DF 1 "fp_register_operand" "")))
4644    (clobber (match_operand 2 "" ""))]
4645   "reload_completed"
4646   [(set (match_dup 2) (match_dup 1))
4647    (set (match_dup 0) (match_dup 2))]
4649   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4652 ;; Conversion from XFmode to {SF,DF}mode
4654 (define_expand "truncxf<mode>2"
4655   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4656                    (float_truncate:MODEF
4657                      (match_operand:XF 1 "register_operand" "")))
4658               (clobber (match_dup 2))])]
4659   "TARGET_80387"
4661   if (flag_unsafe_math_optimizations)
4662     {
4663       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4664       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4665       if (reg != operands[0])
4666         emit_move_insn (operands[0], reg);
4667       DONE;
4668     }
4669   else
4670     {
4671      enum ix86_stack_slot slot = (virtuals_instantiated
4672                                   ? SLOT_TEMP
4673                                   : SLOT_VIRTUAL);
4674       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4675     }
4678 (define_insn "*truncxfsf2_mixed"
4679   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4680         (float_truncate:SF
4681           (match_operand:XF 1 "register_operand"   "f ,f ,f ,f")))
4682    (clobber (match_operand:SF 2 "memory_operand"   "=X,m ,m ,m"))]
4683   "TARGET_80387"
4685   gcc_assert (!which_alternative);
4686   return output_387_reg_move (insn, operands);
4688   [(set_attr "type" "fmov,multi,multi,multi")
4689    (set_attr "unit" "*,i387,i387,i387")
4690    (set_attr "mode" "SF")])
4692 (define_insn "*truncxfdf2_mixed"
4693   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4694         (float_truncate:DF
4695           (match_operand:XF 1 "register_operand"   "f ,f ,f  ,f")))
4696    (clobber (match_operand:DF 2 "memory_operand"   "=X,m ,m  ,m"))]
4697   "TARGET_80387"
4699   gcc_assert (!which_alternative);
4700   return output_387_reg_move (insn, operands);
4702   [(set_attr "type" "fmov,multi,multi,multi")
4703    (set_attr "unit" "*,i387,i387,i387")
4704    (set_attr "mode" "DF")])
4706 (define_insn "truncxf<mode>2_i387_noop"
4707   [(set (match_operand:MODEF 0 "register_operand" "=f")
4708         (float_truncate:MODEF
4709           (match_operand:XF 1 "register_operand" "f")))]
4710   "TARGET_80387 && flag_unsafe_math_optimizations"
4711   "* return output_387_reg_move (insn, operands);"
4712   [(set_attr "type" "fmov")
4713    (set_attr "mode" "<MODE>")])
4715 (define_insn "*truncxf<mode>2_i387"
4716   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4717         (float_truncate:MODEF
4718           (match_operand:XF 1 "register_operand" "f")))]
4719   "TARGET_80387"
4720   "* return output_387_reg_move (insn, operands);"
4721   [(set_attr "type" "fmov")
4722    (set_attr "mode" "<MODE>")])
4724 (define_split
4725   [(set (match_operand:MODEF 0 "register_operand" "")
4726         (float_truncate:MODEF
4727           (match_operand:XF 1 "register_operand" "")))
4728    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4729   "TARGET_80387 && reload_completed"
4730   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4731    (set (match_dup 0) (match_dup 2))]
4732   "")
4734 (define_split
4735   [(set (match_operand:MODEF 0 "memory_operand" "")
4736         (float_truncate:MODEF
4737           (match_operand:XF 1 "register_operand" "")))
4738    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4739   "TARGET_80387"
4740   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4741   "")
4743 ;; Signed conversion to DImode.
4745 (define_expand "fix_truncxfdi2"
4746   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4747                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4748               (clobber (reg:CC FLAGS_REG))])]
4749   "TARGET_80387"
4751   if (TARGET_FISTTP)
4752    {
4753      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4754      DONE;
4755    }
4758 (define_expand "fix_trunc<mode>di2"
4759   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4760                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4761               (clobber (reg:CC FLAGS_REG))])]
4762   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4764   if (TARGET_FISTTP
4765       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4766    {
4767      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4768      DONE;
4769    }
4770   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4771    {
4772      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4773      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4774      if (out != operands[0])
4775         emit_move_insn (operands[0], out);
4776      DONE;
4777    }
4780 ;; Signed conversion to SImode.
4782 (define_expand "fix_truncxfsi2"
4783   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4784                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4785               (clobber (reg:CC FLAGS_REG))])]
4786   "TARGET_80387"
4788   if (TARGET_FISTTP)
4789    {
4790      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4791      DONE;
4792    }
4795 (define_expand "fix_trunc<mode>si2"
4796   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4797                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4798               (clobber (reg:CC FLAGS_REG))])]
4799   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4801   if (TARGET_FISTTP
4802       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4803    {
4804      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4805      DONE;
4806    }
4807   if (SSE_FLOAT_MODE_P (<MODE>mode))
4808    {
4809      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4810      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4811      if (out != operands[0])
4812         emit_move_insn (operands[0], out);
4813      DONE;
4814    }
4817 ;; Signed conversion to HImode.
4819 (define_expand "fix_trunc<mode>hi2"
4820   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4821                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4822               (clobber (reg:CC FLAGS_REG))])]
4823   "TARGET_80387
4824    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4826   if (TARGET_FISTTP)
4827    {
4828      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4829      DONE;
4830    }
4833 ;; Unsigned conversion to SImode.
4835 (define_expand "fixuns_trunc<mode>si2"
4836   [(parallel
4837     [(set (match_operand:SI 0 "register_operand" "")
4838           (unsigned_fix:SI
4839             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4840      (use (match_dup 2))
4841      (clobber (match_scratch:<ssevecmode> 3 ""))
4842      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4843   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4845   enum machine_mode mode = <MODE>mode;
4846   enum machine_mode vecmode = <ssevecmode>mode;
4847   REAL_VALUE_TYPE TWO31r;
4848   rtx two31;
4850   if (optimize_insn_for_size_p ())
4851     FAIL;
4853   real_ldexp (&TWO31r, &dconst1, 31);
4854   two31 = const_double_from_real_value (TWO31r, mode);
4855   two31 = ix86_build_const_vector (mode, true, two31);
4856   operands[2] = force_reg (vecmode, two31);
4859 (define_insn_and_split "*fixuns_trunc<mode>_1"
4860   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4861         (unsigned_fix:SI
4862           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4863    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4864    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4865    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4866   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4867    && optimize_function_for_speed_p (cfun)"
4868   "#"
4869   "&& reload_completed"
4870   [(const_int 0)]
4872   ix86_split_convert_uns_si_sse (operands);
4873   DONE;
4876 ;; Unsigned conversion to HImode.
4877 ;; Without these patterns, we'll try the unsigned SI conversion which
4878 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4880 (define_expand "fixuns_trunc<mode>hi2"
4881   [(set (match_dup 2)
4882         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4883    (set (match_operand:HI 0 "nonimmediate_operand" "")
4884         (subreg:HI (match_dup 2) 0))]
4885   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4886   "operands[2] = gen_reg_rtx (SImode);")
4888 ;; When SSE is available, it is always faster to use it!
4889 (define_insn "fix_trunc<mode>di_sse"
4890   [(set (match_operand:DI 0 "register_operand" "=r,r")
4891         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4892   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4893    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4894   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4895   [(set_attr "type" "sseicvt")
4896    (set_attr "prefix" "maybe_vex")
4897    (set_attr "prefix_rex" "1")
4898    (set_attr "mode" "<MODE>")
4899    (set_attr "athlon_decode" "double,vector")
4900    (set_attr "amdfam10_decode" "double,double")])
4902 (define_insn "fix_trunc<mode>si_sse"
4903   [(set (match_operand:SI 0 "register_operand" "=r,r")
4904         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4905   "SSE_FLOAT_MODE_P (<MODE>mode)
4906    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4907   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4908   [(set_attr "type" "sseicvt")
4909    (set_attr "prefix" "maybe_vex")
4910    (set_attr "mode" "<MODE>")
4911    (set_attr "athlon_decode" "double,vector")
4912    (set_attr "amdfam10_decode" "double,double")])
4914 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4915 (define_peephole2
4916   [(set (match_operand:MODEF 0 "register_operand" "")
4917         (match_operand:MODEF 1 "memory_operand" ""))
4918    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4919         (fix:SSEMODEI24 (match_dup 0)))]
4920   "TARGET_SHORTEN_X87_SSE
4921    && peep2_reg_dead_p (2, operands[0])"
4922   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4923   "")
4925 ;; Avoid vector decoded forms of the instruction.
4926 (define_peephole2
4927   [(match_scratch:DF 2 "Y2")
4928    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4929         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4930   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4931   [(set (match_dup 2) (match_dup 1))
4932    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4933   "")
4935 (define_peephole2
4936   [(match_scratch:SF 2 "x")
4937    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4938         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4939   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4940   [(set (match_dup 2) (match_dup 1))
4941    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4942   "")
4944 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4945   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4946         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4947   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4948    && TARGET_FISTTP
4949    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4950          && (TARGET_64BIT || <MODE>mode != DImode))
4951         && TARGET_SSE_MATH)
4952    && can_create_pseudo_p ()"
4953   "#"
4954   "&& 1"
4955   [(const_int 0)]
4957   if (memory_operand (operands[0], VOIDmode))
4958     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4959   else
4960     {
4961       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4962       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4963                                                             operands[1],
4964                                                             operands[2]));
4965     }
4966   DONE;
4968   [(set_attr "type" "fisttp")
4969    (set_attr "mode" "<MODE>")])
4971 (define_insn "fix_trunc<mode>_i387_fisttp"
4972   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4973         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4974    (clobber (match_scratch:XF 2 "=&1f"))]
4975   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4976    && TARGET_FISTTP
4977    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4978          && (TARGET_64BIT || <MODE>mode != DImode))
4979         && TARGET_SSE_MATH)"
4980   "* return output_fix_trunc (insn, operands, 1);"
4981   [(set_attr "type" "fisttp")
4982    (set_attr "mode" "<MODE>")])
4984 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4985   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4986         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4987    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4988    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4989   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4990    && TARGET_FISTTP
4991    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4992         && (TARGET_64BIT || <MODE>mode != DImode))
4993         && TARGET_SSE_MATH)"
4994   "#"
4995   [(set_attr "type" "fisttp")
4996    (set_attr "mode" "<MODE>")])
4998 (define_split
4999   [(set (match_operand:X87MODEI 0 "register_operand" "")
5000         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5001    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5002    (clobber (match_scratch 3 ""))]
5003   "reload_completed"
5004   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5005               (clobber (match_dup 3))])
5006    (set (match_dup 0) (match_dup 2))]
5007   "")
5009 (define_split
5010   [(set (match_operand:X87MODEI 0 "memory_operand" "")
5011         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5012    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5013    (clobber (match_scratch 3 ""))]
5014   "reload_completed"
5015   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5016               (clobber (match_dup 3))])]
5017   "")
5019 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5020 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5021 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5022 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5023 ;; function in i386.c.
5024 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5025   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5026         (fix:X87MODEI (match_operand 1 "register_operand" "")))
5027    (clobber (reg:CC FLAGS_REG))]
5028   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5029    && !TARGET_FISTTP
5030    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5031          && (TARGET_64BIT || <MODE>mode != DImode))
5032    && can_create_pseudo_p ()"
5033   "#"
5034   "&& 1"
5035   [(const_int 0)]
5037   ix86_optimize_mode_switching[I387_TRUNC] = 1;
5039   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5040   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5041   if (memory_operand (operands[0], VOIDmode))
5042     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5043                                          operands[2], operands[3]));
5044   else
5045     {
5046       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5047       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5048                                                      operands[2], operands[3],
5049                                                      operands[4]));
5050     }
5051   DONE;
5053   [(set_attr "type" "fistp")
5054    (set_attr "i387_cw" "trunc")
5055    (set_attr "mode" "<MODE>")])
5057 (define_insn "fix_truncdi_i387"
5058   [(set (match_operand:DI 0 "memory_operand" "=m")
5059         (fix:DI (match_operand 1 "register_operand" "f")))
5060    (use (match_operand:HI 2 "memory_operand" "m"))
5061    (use (match_operand:HI 3 "memory_operand" "m"))
5062    (clobber (match_scratch:XF 4 "=&1f"))]
5063   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5064    && !TARGET_FISTTP
5065    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5066   "* return output_fix_trunc (insn, operands, 0);"
5067   [(set_attr "type" "fistp")
5068    (set_attr "i387_cw" "trunc")
5069    (set_attr "mode" "DI")])
5071 (define_insn "fix_truncdi_i387_with_temp"
5072   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5073         (fix:DI (match_operand 1 "register_operand" "f,f")))
5074    (use (match_operand:HI 2 "memory_operand" "m,m"))
5075    (use (match_operand:HI 3 "memory_operand" "m,m"))
5076    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5077    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5078   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5079    && !TARGET_FISTTP
5080    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5081   "#"
5082   [(set_attr "type" "fistp")
5083    (set_attr "i387_cw" "trunc")
5084    (set_attr "mode" "DI")])
5086 (define_split
5087   [(set (match_operand:DI 0 "register_operand" "")
5088         (fix:DI (match_operand 1 "register_operand" "")))
5089    (use (match_operand:HI 2 "memory_operand" ""))
5090    (use (match_operand:HI 3 "memory_operand" ""))
5091    (clobber (match_operand:DI 4 "memory_operand" ""))
5092    (clobber (match_scratch 5 ""))]
5093   "reload_completed"
5094   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5095               (use (match_dup 2))
5096               (use (match_dup 3))
5097               (clobber (match_dup 5))])
5098    (set (match_dup 0) (match_dup 4))]
5099   "")
5101 (define_split
5102   [(set (match_operand:DI 0 "memory_operand" "")
5103         (fix:DI (match_operand 1 "register_operand" "")))
5104    (use (match_operand:HI 2 "memory_operand" ""))
5105    (use (match_operand:HI 3 "memory_operand" ""))
5106    (clobber (match_operand:DI 4 "memory_operand" ""))
5107    (clobber (match_scratch 5 ""))]
5108   "reload_completed"
5109   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5110               (use (match_dup 2))
5111               (use (match_dup 3))
5112               (clobber (match_dup 5))])]
5113   "")
5115 (define_insn "fix_trunc<mode>_i387"
5116   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5117         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5118    (use (match_operand:HI 2 "memory_operand" "m"))
5119    (use (match_operand:HI 3 "memory_operand" "m"))]
5120   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5121    && !TARGET_FISTTP
5122    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5123   "* return output_fix_trunc (insn, operands, 0);"
5124   [(set_attr "type" "fistp")
5125    (set_attr "i387_cw" "trunc")
5126    (set_attr "mode" "<MODE>")])
5128 (define_insn "fix_trunc<mode>_i387_with_temp"
5129   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5130         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5131    (use (match_operand:HI 2 "memory_operand" "m,m"))
5132    (use (match_operand:HI 3 "memory_operand" "m,m"))
5133    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5134   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5135    && !TARGET_FISTTP
5136    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5137   "#"
5138   [(set_attr "type" "fistp")
5139    (set_attr "i387_cw" "trunc")
5140    (set_attr "mode" "<MODE>")])
5142 (define_split
5143   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5144         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5145    (use (match_operand:HI 2 "memory_operand" ""))
5146    (use (match_operand:HI 3 "memory_operand" ""))
5147    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5148   "reload_completed"
5149   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5150               (use (match_dup 2))
5151               (use (match_dup 3))])
5152    (set (match_dup 0) (match_dup 4))]
5153   "")
5155 (define_split
5156   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5157         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5158    (use (match_operand:HI 2 "memory_operand" ""))
5159    (use (match_operand:HI 3 "memory_operand" ""))
5160    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5161   "reload_completed"
5162   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5163               (use (match_dup 2))
5164               (use (match_dup 3))])]
5165   "")
5167 (define_insn "x86_fnstcw_1"
5168   [(set (match_operand:HI 0 "memory_operand" "=m")
5169         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5170   "TARGET_80387"
5171   "fnstcw\t%0"
5172   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5173    (set_attr "mode" "HI")
5174    (set_attr "unit" "i387")])
5176 (define_insn "x86_fldcw_1"
5177   [(set (reg:HI FPCR_REG)
5178         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5179   "TARGET_80387"
5180   "fldcw\t%0"
5181   [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5182    (set_attr "mode" "HI")
5183    (set_attr "unit" "i387")
5184    (set_attr "athlon_decode" "vector")
5185    (set_attr "amdfam10_decode" "vector")])
5187 ;; Conversion between fixed point and floating point.
5189 ;; Even though we only accept memory inputs, the backend _really_
5190 ;; wants to be able to do this between registers.
5192 (define_expand "floathi<mode>2"
5193   [(set (match_operand:X87MODEF 0 "register_operand" "")
5194         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5195   "TARGET_80387
5196    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5197        || TARGET_MIX_SSE_I387)"
5198   "")
5200 ;; Pre-reload splitter to add memory clobber to the pattern.
5201 (define_insn_and_split "*floathi<mode>2_1"
5202   [(set (match_operand:X87MODEF 0 "register_operand" "")
5203         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5204   "TARGET_80387
5205    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5206        || TARGET_MIX_SSE_I387)
5207    && can_create_pseudo_p ()"
5208   "#"
5209   "&& 1"
5210   [(parallel [(set (match_dup 0)
5211               (float:X87MODEF (match_dup 1)))
5212    (clobber (match_dup 2))])]
5213   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5215 (define_insn "*floathi<mode>2_i387_with_temp"
5216   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5217         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5218   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5219   "TARGET_80387
5220    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5221        || TARGET_MIX_SSE_I387)"
5222   "#"
5223   [(set_attr "type" "fmov,multi")
5224    (set_attr "mode" "<MODE>")
5225    (set_attr "unit" "*,i387")
5226    (set_attr "fp_int_src" "true")])
5228 (define_insn "*floathi<mode>2_i387"
5229   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5230         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5231   "TARGET_80387
5232    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5233        || TARGET_MIX_SSE_I387)"
5234   "fild%Z1\t%1"
5235   [(set_attr "type" "fmov")
5236    (set_attr "mode" "<MODE>")
5237    (set_attr "fp_int_src" "true")])
5239 (define_split
5240   [(set (match_operand:X87MODEF 0 "register_operand" "")
5241         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5242    (clobber (match_operand:HI 2 "memory_operand" ""))]
5243   "TARGET_80387
5244    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5245        || TARGET_MIX_SSE_I387)
5246    && reload_completed"
5247   [(set (match_dup 2) (match_dup 1))
5248    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5249   "")
5251 (define_split
5252   [(set (match_operand:X87MODEF 0 "register_operand" "")
5253         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5254    (clobber (match_operand:HI 2 "memory_operand" ""))]
5255    "TARGET_80387
5256     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5257         || TARGET_MIX_SSE_I387)
5258     && reload_completed"
5259   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5260   "")
5262 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5263   [(set (match_operand:X87MODEF 0 "register_operand" "")
5264         (float:X87MODEF
5265           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5266   "TARGET_80387
5267    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5268        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5270   if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5271         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5272       && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5273     {
5274       rtx reg = gen_reg_rtx (XFmode);
5275       rtx insn;
5277       emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5279       if (<X87MODEF:MODE>mode == SFmode)
5280         insn = gen_truncxfsf2 (operands[0], reg);
5281       else if (<X87MODEF:MODE>mode == DFmode)
5282         insn = gen_truncxfdf2 (operands[0], reg);
5283       else
5284         gcc_unreachable ();
5286       emit_insn (insn);
5287       DONE;
5288     }
5291 ;; Pre-reload splitter to add memory clobber to the pattern.
5292 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5293   [(set (match_operand:X87MODEF 0 "register_operand" "")
5294         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5295   "((TARGET_80387
5296      && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5297      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5298            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5299          || TARGET_MIX_SSE_I387))
5300     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5301         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5302         && ((<SSEMODEI24:MODE>mode == SImode
5303              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5304              && optimize_function_for_speed_p (cfun)
5305              && flag_trapping_math)
5306             || !(TARGET_INTER_UNIT_CONVERSIONS
5307                  || optimize_function_for_size_p (cfun)))))
5308    && can_create_pseudo_p ()"
5309   "#"
5310   "&& 1"
5311   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5312               (clobber (match_dup 2))])]
5314   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5316   /* Avoid store forwarding (partial memory) stall penalty
5317      by passing DImode value through XMM registers.  */
5318   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5319       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5320       && optimize_function_for_speed_p (cfun))
5321     {
5322       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5323                                                             operands[1],
5324                                                             operands[2]));
5325       DONE;
5326     }
5329 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5330   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5331         (float:MODEF
5332           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5333    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5334   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5335    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5336   "#"
5337   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5338    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5339    (set_attr "unit" "*,i387,*,*,*")
5340    (set_attr "athlon_decode" "*,*,double,direct,double")
5341    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5342    (set_attr "fp_int_src" "true")])
5344 (define_insn "*floatsi<mode>2_vector_mixed"
5345   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5346         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5347   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5348    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5349   "@
5350    fild%Z1\t%1
5351    #"
5352   [(set_attr "type" "fmov,sseicvt")
5353    (set_attr "mode" "<MODE>,<ssevecmode>")
5354    (set_attr "unit" "i387,*")
5355    (set_attr "athlon_decode" "*,direct")
5356    (set_attr "amdfam10_decode" "*,double")
5357    (set_attr "fp_int_src" "true")])
5359 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5360   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5361         (float:MODEF
5362           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5363   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5364   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5365    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5366   "#"
5367   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5368    (set_attr "mode" "<MODEF:MODE>")
5369    (set_attr "unit" "*,i387,*,*")
5370    (set_attr "athlon_decode" "*,*,double,direct")
5371    (set_attr "amdfam10_decode" "*,*,vector,double")
5372    (set_attr "fp_int_src" "true")])
5374 (define_split
5375   [(set (match_operand:MODEF 0 "register_operand" "")
5376         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5377    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5378   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5379    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5380    && TARGET_INTER_UNIT_CONVERSIONS
5381    && reload_completed
5382    && (SSE_REG_P (operands[0])
5383        || (GET_CODE (operands[0]) == SUBREG
5384            && SSE_REG_P (operands[0])))"
5385   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5386   "")
5388 (define_split
5389   [(set (match_operand:MODEF 0 "register_operand" "")
5390         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5391    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5392   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5393    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5394    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5395    && reload_completed
5396    && (SSE_REG_P (operands[0])
5397        || (GET_CODE (operands[0]) == SUBREG
5398            && SSE_REG_P (operands[0])))"
5399   [(set (match_dup 2) (match_dup 1))
5400    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5401   "")
5403 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5404   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5405         (float:MODEF
5406           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5407   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5408    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5409    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5410   "@
5411    fild%Z1\t%1
5412    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5413    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5414   [(set_attr "type" "fmov,sseicvt,sseicvt")
5415    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5416    (set_attr "mode" "<MODEF:MODE>")
5417    (set (attr "prefix_rex")
5418      (if_then_else
5419        (and (eq_attr "prefix" "maybe_vex")
5420             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5421        (const_string "1")
5422        (const_string "*")))
5423    (set_attr "unit" "i387,*,*")
5424    (set_attr "athlon_decode" "*,double,direct")
5425    (set_attr "amdfam10_decode" "*,vector,double")
5426    (set_attr "fp_int_src" "true")])
5428 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5429   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5430         (float:MODEF
5431           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5432   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5433    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5434    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5435   "@
5436    fild%Z1\t%1
5437    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5438   [(set_attr "type" "fmov,sseicvt")
5439    (set_attr "prefix" "orig,maybe_vex")
5440    (set_attr "mode" "<MODEF:MODE>")
5441    (set (attr "prefix_rex")
5442      (if_then_else
5443        (and (eq_attr "prefix" "maybe_vex")
5444             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5445        (const_string "1")
5446        (const_string "*")))
5447    (set_attr "athlon_decode" "*,direct")
5448    (set_attr "amdfam10_decode" "*,double")
5449    (set_attr "fp_int_src" "true")])
5451 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5452   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5453         (float:MODEF
5454           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5455    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5456   "TARGET_SSE2 && TARGET_SSE_MATH
5457    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5458   "#"
5459   [(set_attr "type" "sseicvt")
5460    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5461    (set_attr "athlon_decode" "double,direct,double")
5462    (set_attr "amdfam10_decode" "vector,double,double")
5463    (set_attr "fp_int_src" "true")])
5465 (define_insn "*floatsi<mode>2_vector_sse"
5466   [(set (match_operand:MODEF 0 "register_operand" "=x")
5467         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5468   "TARGET_SSE2 && TARGET_SSE_MATH
5469    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5470   "#"
5471   [(set_attr "type" "sseicvt")
5472    (set_attr "mode" "<MODE>")
5473    (set_attr "athlon_decode" "direct")
5474    (set_attr "amdfam10_decode" "double")
5475    (set_attr "fp_int_src" "true")])
5477 (define_split
5478   [(set (match_operand:MODEF 0 "register_operand" "")
5479         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5480    (clobber (match_operand:SI 2 "memory_operand" ""))]
5481   "TARGET_SSE2 && TARGET_SSE_MATH
5482    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5483    && reload_completed
5484    && (SSE_REG_P (operands[0])
5485        || (GET_CODE (operands[0]) == SUBREG
5486            && SSE_REG_P (operands[0])))"
5487   [(const_int 0)]
5489   rtx op1 = operands[1];
5491   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5492                                      <MODE>mode, 0);
5493   if (GET_CODE (op1) == SUBREG)
5494     op1 = SUBREG_REG (op1);
5496   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5497     {
5498       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5499       emit_insn (gen_sse2_loadld (operands[4],
5500                                   CONST0_RTX (V4SImode), operands[1]));
5501     }
5502   /* We can ignore possible trapping value in the
5503      high part of SSE register for non-trapping math. */
5504   else if (SSE_REG_P (op1) && !flag_trapping_math)
5505     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5506   else
5507     {
5508       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5509       emit_move_insn (operands[2], operands[1]);
5510       emit_insn (gen_sse2_loadld (operands[4],
5511                                   CONST0_RTX (V4SImode), operands[2]));
5512     }
5513   emit_insn
5514     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5515   DONE;
5518 (define_split
5519   [(set (match_operand:MODEF 0 "register_operand" "")
5520         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5521    (clobber (match_operand:SI 2 "memory_operand" ""))]
5522   "TARGET_SSE2 && TARGET_SSE_MATH
5523    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5524    && reload_completed
5525    && (SSE_REG_P (operands[0])
5526        || (GET_CODE (operands[0]) == SUBREG
5527            && SSE_REG_P (operands[0])))"
5528   [(const_int 0)]
5530   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5531                                      <MODE>mode, 0);
5532   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5534   emit_insn (gen_sse2_loadld (operands[4],
5535                               CONST0_RTX (V4SImode), operands[1]));
5536   emit_insn
5537     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5538   DONE;
5541 (define_split
5542   [(set (match_operand:MODEF 0 "register_operand" "")
5543         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5544   "TARGET_SSE2 && TARGET_SSE_MATH
5545    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5546    && reload_completed
5547    && (SSE_REG_P (operands[0])
5548        || (GET_CODE (operands[0]) == SUBREG
5549            && SSE_REG_P (operands[0])))"
5550   [(const_int 0)]
5552   rtx op1 = operands[1];
5554   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5555                                      <MODE>mode, 0);
5556   if (GET_CODE (op1) == SUBREG)
5557     op1 = SUBREG_REG (op1);
5559   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5560     {
5561       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5562       emit_insn (gen_sse2_loadld (operands[4],
5563                                   CONST0_RTX (V4SImode), operands[1]));
5564     }
5565   /* We can ignore possible trapping value in the
5566      high part of SSE register for non-trapping math. */
5567   else if (SSE_REG_P (op1) && !flag_trapping_math)
5568     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5569   else
5570     gcc_unreachable ();
5571   emit_insn
5572     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5573   DONE;
5576 (define_split
5577   [(set (match_operand:MODEF 0 "register_operand" "")
5578         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5579   "TARGET_SSE2 && TARGET_SSE_MATH
5580    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5581    && reload_completed
5582    && (SSE_REG_P (operands[0])
5583        || (GET_CODE (operands[0]) == SUBREG
5584            && SSE_REG_P (operands[0])))"
5585   [(const_int 0)]
5587   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5588                                      <MODE>mode, 0);
5589   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5591   emit_insn (gen_sse2_loadld (operands[4],
5592                               CONST0_RTX (V4SImode), operands[1]));
5593   emit_insn
5594     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5595   DONE;
5598 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5599   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5600         (float:MODEF
5601           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5602   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5603   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5604    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5605   "#"
5606   [(set_attr "type" "sseicvt")
5607    (set_attr "mode" "<MODEF:MODE>")
5608    (set_attr "athlon_decode" "double,direct")
5609    (set_attr "amdfam10_decode" "vector,double")
5610    (set_attr "fp_int_src" "true")])
5612 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5613   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5614         (float:MODEF
5615           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5616   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5617    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5618    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5619   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5620   [(set_attr "type" "sseicvt")
5621    (set_attr "prefix" "maybe_vex")
5622    (set_attr "mode" "<MODEF:MODE>")
5623    (set (attr "prefix_rex")
5624      (if_then_else
5625        (and (eq_attr "prefix" "maybe_vex")
5626             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5627        (const_string "1")
5628        (const_string "*")))
5629    (set_attr "athlon_decode" "double,direct")
5630    (set_attr "amdfam10_decode" "vector,double")
5631    (set_attr "fp_int_src" "true")])
5633 (define_split
5634   [(set (match_operand:MODEF 0 "register_operand" "")
5635         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5636    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5637   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5638    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5639    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5640    && reload_completed
5641    && (SSE_REG_P (operands[0])
5642        || (GET_CODE (operands[0]) == SUBREG
5643            && SSE_REG_P (operands[0])))"
5644   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5645   "")
5647 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5648   [(set (match_operand:MODEF 0 "register_operand" "=x")
5649         (float:MODEF
5650           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5651   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5652    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5653    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5654   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5655   [(set_attr "type" "sseicvt")
5656    (set_attr "prefix" "maybe_vex")
5657    (set_attr "mode" "<MODEF:MODE>")
5658    (set (attr "prefix_rex")
5659      (if_then_else
5660        (and (eq_attr "prefix" "maybe_vex")
5661             (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5662        (const_string "1")
5663        (const_string "*")))
5664    (set_attr "athlon_decode" "direct")
5665    (set_attr "amdfam10_decode" "double")
5666    (set_attr "fp_int_src" "true")])
5668 (define_split
5669   [(set (match_operand:MODEF 0 "register_operand" "")
5670         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5671    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5672   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5673    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5674    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5675    && reload_completed
5676    && (SSE_REG_P (operands[0])
5677        || (GET_CODE (operands[0]) == SUBREG
5678            && SSE_REG_P (operands[0])))"
5679   [(set (match_dup 2) (match_dup 1))
5680    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5681   "")
5683 (define_split
5684   [(set (match_operand:MODEF 0 "register_operand" "")
5685         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5686    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5687   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5688    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5689    && reload_completed
5690    && (SSE_REG_P (operands[0])
5691        || (GET_CODE (operands[0]) == SUBREG
5692            && SSE_REG_P (operands[0])))"
5693   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5694   "")
5696 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5697   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5698         (float:X87MODEF
5699           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5700   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5701   "TARGET_80387
5702    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5703   "@
5704    fild%Z1\t%1
5705    #"
5706   [(set_attr "type" "fmov,multi")
5707    (set_attr "mode" "<X87MODEF:MODE>")
5708    (set_attr "unit" "*,i387")
5709    (set_attr "fp_int_src" "true")])
5711 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5712   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5713         (float:X87MODEF
5714           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5715   "TARGET_80387
5716    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5717   "fild%Z1\t%1"
5718   [(set_attr "type" "fmov")
5719    (set_attr "mode" "<X87MODEF:MODE>")
5720    (set_attr "fp_int_src" "true")])
5722 (define_split
5723   [(set (match_operand:X87MODEF 0 "register_operand" "")
5724         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5725    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5726   "TARGET_80387
5727    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5728    && reload_completed
5729    && FP_REG_P (operands[0])"
5730   [(set (match_dup 2) (match_dup 1))
5731    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5732   "")
5734 (define_split
5735   [(set (match_operand:X87MODEF 0 "register_operand" "")
5736         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5737    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5738   "TARGET_80387
5739    && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5740    && reload_completed
5741    && FP_REG_P (operands[0])"
5742   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5743   "")
5745 ;; Avoid store forwarding (partial memory) stall penalty
5746 ;; by passing DImode value through XMM registers.  */
5748 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5749   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5750         (float:X87MODEF
5751           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5752    (clobber (match_scratch:V4SI 3 "=X,x"))
5753    (clobber (match_scratch:V4SI 4 "=X,x"))
5754    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5755   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5756    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5757    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5758   "#"
5759   [(set_attr "type" "multi")
5760    (set_attr "mode" "<X87MODEF:MODE>")
5761    (set_attr "unit" "i387")
5762    (set_attr "fp_int_src" "true")])
5764 (define_split
5765   [(set (match_operand:X87MODEF 0 "register_operand" "")
5766         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5767    (clobber (match_scratch:V4SI 3 ""))
5768    (clobber (match_scratch:V4SI 4 ""))
5769    (clobber (match_operand:DI 2 "memory_operand" ""))]
5770   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5771    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5772    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5773    && reload_completed
5774    && FP_REG_P (operands[0])"
5775   [(set (match_dup 2) (match_dup 3))
5776    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5778   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5779      Assemble the 64-bit DImode value in an xmm register.  */
5780   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5781                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5782   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5783                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5784   emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5785                                          operands[4]));
5787   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5790 (define_split
5791   [(set (match_operand:X87MODEF 0 "register_operand" "")
5792         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5793    (clobber (match_scratch:V4SI 3 ""))
5794    (clobber (match_scratch:V4SI 4 ""))
5795    (clobber (match_operand:DI 2 "memory_operand" ""))]
5796   "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5797    && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5798    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5799    && reload_completed
5800    && FP_REG_P (operands[0])"
5801   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5802   "")
5804 ;; Avoid store forwarding (partial memory) stall penalty by extending
5805 ;; SImode value to DImode through XMM register instead of pushing two
5806 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5807 ;; targets benefit from this optimization. Also note that fild
5808 ;; loads from memory only.
5810 (define_insn "*floatunssi<mode>2_1"
5811   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5812         (unsigned_float:X87MODEF
5813           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5814    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5815    (clobber (match_scratch:SI 3 "=X,x"))]
5816   "!TARGET_64BIT
5817    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5818    && TARGET_SSE"
5819   "#"
5820   [(set_attr "type" "multi")
5821    (set_attr "mode" "<MODE>")])
5823 (define_split
5824   [(set (match_operand:X87MODEF 0 "register_operand" "")
5825         (unsigned_float:X87MODEF
5826           (match_operand:SI 1 "register_operand" "")))
5827    (clobber (match_operand:DI 2 "memory_operand" ""))
5828    (clobber (match_scratch:SI 3 ""))]
5829   "!TARGET_64BIT
5830    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5831    && TARGET_SSE
5832    && reload_completed"
5833   [(set (match_dup 2) (match_dup 1))
5834    (set (match_dup 0)
5835         (float:X87MODEF (match_dup 2)))]
5836   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5838 (define_split
5839   [(set (match_operand:X87MODEF 0 "register_operand" "")
5840         (unsigned_float:X87MODEF
5841           (match_operand:SI 1 "memory_operand" "")))
5842    (clobber (match_operand:DI 2 "memory_operand" ""))
5843    (clobber (match_scratch:SI 3 ""))]
5844   "!TARGET_64BIT
5845    && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5846    && TARGET_SSE
5847    && reload_completed"
5848   [(set (match_dup 2) (match_dup 3))
5849    (set (match_dup 0)
5850         (float:X87MODEF (match_dup 2)))]
5852   emit_move_insn (operands[3], operands[1]);
5853   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5856 (define_expand "floatunssi<mode>2"
5857   [(parallel
5858      [(set (match_operand:X87MODEF 0 "register_operand" "")
5859            (unsigned_float:X87MODEF
5860              (match_operand:SI 1 "nonimmediate_operand" "")))
5861       (clobber (match_dup 2))
5862       (clobber (match_scratch:SI 3 ""))])]
5863   "!TARGET_64BIT
5864    && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5865         && TARGET_SSE)
5866        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5868   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5869     {
5870       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5871       DONE;
5872     }
5873   else
5874     {
5875       enum ix86_stack_slot slot = (virtuals_instantiated
5876                                    ? SLOT_TEMP
5877                                    : SLOT_VIRTUAL);
5878       operands[2] = assign_386_stack_local (DImode, slot);
5879     }
5882 (define_expand "floatunsdisf2"
5883   [(use (match_operand:SF 0 "register_operand" ""))
5884    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5885   "TARGET_64BIT && TARGET_SSE_MATH"
5886   "x86_emit_floatuns (operands); DONE;")
5888 (define_expand "floatunsdidf2"
5889   [(use (match_operand:DF 0 "register_operand" ""))
5890    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5891   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5892    && TARGET_SSE2 && TARGET_SSE_MATH"
5894   if (TARGET_64BIT)
5895     x86_emit_floatuns (operands);
5896   else
5897     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5898   DONE;
5901 ;; Add instructions
5903 (define_expand "add<mode>3"
5904   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5905         (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5906                     (match_operand:SDWIM 2 "<general_operand>" "")))]
5907   ""
5908   "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5910 (define_insn_and_split "*add<dwi>3_doubleword"
5911   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5912         (plus:<DWI>
5913           (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5914           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5915    (clobber (reg:CC FLAGS_REG))]
5916   "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5917   "#"
5918   "reload_completed"
5919   [(parallel [(set (reg:CC FLAGS_REG)
5920                    (unspec:CC [(match_dup 1) (match_dup 2)]
5921                               UNSPEC_ADD_CARRY))
5922               (set (match_dup 0)
5923                    (plus:DWIH (match_dup 1) (match_dup 2)))])
5924    (parallel [(set (match_dup 3)
5925                    (plus:DWIH
5926                      (match_dup 4)
5927                      (plus:DWIH
5928                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5929                        (match_dup 5))))
5930               (clobber (reg:CC FLAGS_REG))])]
5931   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5933 (define_insn "*add<mode>3_cc"
5934   [(set (reg:CC FLAGS_REG)
5935         (unspec:CC
5936           [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5937            (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5938           UNSPEC_ADD_CARRY))
5939    (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5940         (plus:SWI48 (match_dup 1) (match_dup 2)))]
5941   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5942   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5943   [(set_attr "type" "alu")
5944    (set_attr "mode" "<MODE>")])
5946 (define_insn "addqi3_cc"
5947   [(set (reg:CC FLAGS_REG)
5948         (unspec:CC
5949           [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5950            (match_operand:QI 2 "general_operand" "qn,qm")]
5951           UNSPEC_ADD_CARRY))
5952    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5953         (plus:QI (match_dup 1) (match_dup 2)))]
5954   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5955   "add{b}\t{%2, %0|%0, %2}"
5956   [(set_attr "type" "alu")
5957    (set_attr "mode" "QI")])
5959 (define_insn "*lea_1"
5960   [(set (match_operand:DWIH 0 "register_operand" "=r")
5961         (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5962   ""
5963   "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5964   [(set_attr "type" "lea")
5965    (set_attr "mode" "<MODE>")])
5967 (define_insn "*lea_2"
5968   [(set (match_operand:SI 0 "register_operand" "=r")
5969         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5970   "TARGET_64BIT"
5971   "lea{l}\t{%a1, %0|%0, %a1}"
5972   [(set_attr "type" "lea")
5973    (set_attr "mode" "SI")])
5975 (define_insn "*lea_2_zext"
5976   [(set (match_operand:DI 0 "register_operand" "=r")
5977         (zero_extend:DI
5978           (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5979   "TARGET_64BIT"
5980   "lea{l}\t{%a1, %k0|%k0, %a1}"
5981   [(set_attr "type" "lea")
5982    (set_attr "mode" "SI")])
5984 (define_insn "*add<mode>_1"
5985   [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5986         (plus:SWI48
5987           (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5988           (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5989    (clobber (reg:CC FLAGS_REG))]
5990   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5992   switch (get_attr_type (insn))
5993     {
5994     case TYPE_LEA:
5995       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5996       return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
5998     case TYPE_INCDEC:
5999       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6000       if (operands[2] == const1_rtx)
6001         return "inc{<imodesuffix>}\t%0";
6002       else
6003         {
6004           gcc_assert (operands[2] == constm1_rtx);
6005           return "dec{<imodesuffix>}\t%0";
6006         }
6008     default:
6009       /* Use add as much as possible to replace lea for AGU optimization. */
6010       if (which_alternative == 2 && TARGET_OPT_AGU)
6011         return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6012         
6013       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6015       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6016          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6017       if (CONST_INT_P (operands[2])
6018           /* Avoid overflows.  */
6019           && (<MODE>mode != DImode
6020               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6021           && (INTVAL (operands[2]) == 128
6022               || (INTVAL (operands[2]) < 0
6023                   && INTVAL (operands[2]) != -128)))
6024         {
6025           operands[2] = GEN_INT (-INTVAL (operands[2]));
6026           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6027         }
6028       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6029     }
6031   [(set (attr "type")
6032      (cond [(and (eq_attr "alternative" "2") 
6033                  (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6034               (const_string "lea")
6035             (eq_attr "alternative" "3")
6036               (const_string "lea")
6037             ; Current assemblers are broken and do not allow @GOTOFF in
6038             ; ought but a memory context.
6039             (match_operand:SWI48 2 "pic_symbolic_operand" "")
6040               (const_string "lea")
6041             (match_operand:SWI48 2 "incdec_operand" "")
6042               (const_string "incdec")
6043            ]
6044            (const_string "alu")))
6045    (set (attr "length_immediate")
6046       (if_then_else
6047         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6048         (const_string "1")
6049         (const_string "*")))
6050    (set_attr "mode" "<MODE>")])
6052 ;; It may seem that nonimmediate operand is proper one for operand 1.
6053 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6054 ;; we take care in ix86_binary_operator_ok to not allow two memory
6055 ;; operands so proper swapping will be done in reload.  This allow
6056 ;; patterns constructed from addsi_1 to match.
6058 (define_insn "*addsi_1_zext"
6059   [(set (match_operand:DI 0 "register_operand" "=r,r")
6060         (zero_extend:DI
6061           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6062                    (match_operand:SI 2 "general_operand" "g,li"))))
6063    (clobber (reg:CC FLAGS_REG))]
6064   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6066   switch (get_attr_type (insn))
6067     {
6068     case TYPE_LEA:
6069       operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6070       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6072     case TYPE_INCDEC:
6073       if (operands[2] == const1_rtx)
6074         return "inc{l}\t%k0";
6075       else
6076         {
6077           gcc_assert (operands[2] == constm1_rtx);
6078           return "dec{l}\t%k0";
6079         }
6081     default:
6082       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6083          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6084       if (CONST_INT_P (operands[2])
6085           && (INTVAL (operands[2]) == 128
6086               || (INTVAL (operands[2]) < 0
6087                   && INTVAL (operands[2]) != -128)))
6088         {
6089           operands[2] = GEN_INT (-INTVAL (operands[2]));
6090           return "sub{l}\t{%2, %k0|%k0, %2}";
6091         }
6092       return "add{l}\t{%2, %k0|%k0, %2}";
6093     }
6095   [(set (attr "type")
6096      (cond [(eq_attr "alternative" "1")
6097               (const_string "lea")
6098             ; Current assemblers are broken and do not allow @GOTOFF in
6099             ; ought but a memory context.
6100             (match_operand:SI 2 "pic_symbolic_operand" "")
6101               (const_string "lea")
6102             (match_operand:SI 2 "incdec_operand" "")
6103               (const_string "incdec")
6104            ]
6105            (const_string "alu")))
6106    (set (attr "length_immediate")
6107       (if_then_else
6108         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6109         (const_string "1")
6110         (const_string "*")))
6111    (set_attr "mode" "SI")])
6113 (define_insn "*addhi_1"
6114   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6115         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6116                  (match_operand:HI 2 "general_operand" "rn,rm")))
6117    (clobber (reg:CC FLAGS_REG))]
6118   "TARGET_PARTIAL_REG_STALL
6119    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6121   switch (get_attr_type (insn))
6122     {
6123     case TYPE_INCDEC:
6124       if (operands[2] == const1_rtx)
6125         return "inc{w}\t%0";
6126       else
6127         {
6128           gcc_assert (operands[2] == constm1_rtx);
6129           return "dec{w}\t%0";
6130         }
6132     default:
6133       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6134          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6135       if (CONST_INT_P (operands[2])
6136           && (INTVAL (operands[2]) == 128
6137               || (INTVAL (operands[2]) < 0
6138                   && INTVAL (operands[2]) != -128)))
6139         {
6140           operands[2] = GEN_INT (-INTVAL (operands[2]));
6141           return "sub{w}\t{%2, %0|%0, %2}";
6142         }
6143       return "add{w}\t{%2, %0|%0, %2}";
6144     }
6146   [(set (attr "type")
6147      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6148         (const_string "incdec")
6149         (const_string "alu")))
6150    (set (attr "length_immediate")
6151       (if_then_else
6152         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6153         (const_string "1")
6154         (const_string "*")))
6155    (set_attr "mode" "HI")])
6157 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6158 ;; type optimizations enabled by define-splits.  This is not important
6159 ;; for PII, and in fact harmful because of partial register stalls.
6161 (define_insn "*addhi_1_lea"
6162   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6163         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6164                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6165    (clobber (reg:CC FLAGS_REG))]
6166   "!TARGET_PARTIAL_REG_STALL
6167    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6169   switch (get_attr_type (insn))
6170     {
6171     case TYPE_LEA:
6172       return "#";
6173     case TYPE_INCDEC:
6174       if (operands[2] == const1_rtx)
6175         return "inc{w}\t%0";
6176       else
6177         {
6178           gcc_assert (operands[2] == constm1_rtx);
6179           return "dec{w}\t%0";
6180         }
6182     default:
6183       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6184          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6185       if (CONST_INT_P (operands[2])
6186           && (INTVAL (operands[2]) == 128
6187               || (INTVAL (operands[2]) < 0
6188                   && INTVAL (operands[2]) != -128)))
6189         {
6190           operands[2] = GEN_INT (-INTVAL (operands[2]));
6191           return "sub{w}\t{%2, %0|%0, %2}";
6192         }
6193       return "add{w}\t{%2, %0|%0, %2}";
6194     }
6196   [(set (attr "type")
6197      (if_then_else (eq_attr "alternative" "2")
6198         (const_string "lea")
6199         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6200            (const_string "incdec")
6201            (const_string "alu"))))
6202    (set (attr "length_immediate")
6203       (if_then_else
6204         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6205         (const_string "1")
6206         (const_string "*")))
6207    (set_attr "mode" "HI,HI,SI")])
6209 (define_insn "*addqi_1"
6210   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6211         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6212                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6213    (clobber (reg:CC FLAGS_REG))]
6214   "TARGET_PARTIAL_REG_STALL
6215    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6217   int widen = (which_alternative == 2);
6218   switch (get_attr_type (insn))
6219     {
6220     case TYPE_INCDEC:
6221       if (operands[2] == const1_rtx)
6222         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6223       else
6224         {
6225           gcc_assert (operands[2] == constm1_rtx);
6226           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6227         }
6229     default:
6230       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6231          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6232       if (CONST_INT_P (operands[2])
6233           && (INTVAL (operands[2]) == 128
6234               || (INTVAL (operands[2]) < 0
6235                   && INTVAL (operands[2]) != -128)))
6236         {
6237           operands[2] = GEN_INT (-INTVAL (operands[2]));
6238           if (widen)
6239             return "sub{l}\t{%2, %k0|%k0, %2}";
6240           else
6241             return "sub{b}\t{%2, %0|%0, %2}";
6242         }
6243       if (widen)
6244         return "add{l}\t{%k2, %k0|%k0, %k2}";
6245       else
6246         return "add{b}\t{%2, %0|%0, %2}";
6247     }
6249   [(set (attr "type")
6250      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6251         (const_string "incdec")
6252         (const_string "alu")))
6253    (set (attr "length_immediate")
6254       (if_then_else
6255         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6256         (const_string "1")
6257         (const_string "*")))
6258    (set_attr "mode" "QI,QI,SI")])
6260 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6261 (define_insn "*addqi_1_lea"
6262   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6263         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6264                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6265    (clobber (reg:CC FLAGS_REG))]
6266   "!TARGET_PARTIAL_REG_STALL
6267    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6269   int widen = (which_alternative == 2);
6270   switch (get_attr_type (insn))
6271     {
6272     case TYPE_LEA:
6273       return "#";
6274     case TYPE_INCDEC:
6275       if (operands[2] == const1_rtx)
6276         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6277       else
6278         {
6279           gcc_assert (operands[2] == constm1_rtx);
6280           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6281         }
6283     default:
6284       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6285          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6286       if (CONST_INT_P (operands[2])
6287           && (INTVAL (operands[2]) == 128
6288               || (INTVAL (operands[2]) < 0
6289                   && INTVAL (operands[2]) != -128)))
6290         {
6291           operands[2] = GEN_INT (-INTVAL (operands[2]));
6292           if (widen)
6293             return "sub{l}\t{%2, %k0|%k0, %2}";
6294           else
6295             return "sub{b}\t{%2, %0|%0, %2}";
6296         }
6297       if (widen)
6298         return "add{l}\t{%k2, %k0|%k0, %k2}";
6299       else
6300         return "add{b}\t{%2, %0|%0, %2}";
6301     }
6303   [(set (attr "type")
6304      (if_then_else (eq_attr "alternative" "3")
6305         (const_string "lea")
6306         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6307            (const_string "incdec")
6308            (const_string "alu"))))
6309    (set (attr "length_immediate")
6310       (if_then_else
6311         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6312         (const_string "1")
6313         (const_string "*")))
6314    (set_attr "mode" "QI,QI,SI,SI")])
6316 (define_insn "*addqi_1_slp"
6317   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6318         (plus:QI (match_dup 0)
6319                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6320    (clobber (reg:CC FLAGS_REG))]
6321   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6322    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6324   switch (get_attr_type (insn))
6325     {
6326     case TYPE_INCDEC:
6327       if (operands[1] == const1_rtx)
6328         return "inc{b}\t%0";
6329       else
6330         {
6331           gcc_assert (operands[1] == constm1_rtx);
6332           return "dec{b}\t%0";
6333         }
6335     default:
6336       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6337       if (CONST_INT_P (operands[1])
6338           && INTVAL (operands[1]) < 0)
6339         {
6340           operands[1] = GEN_INT (-INTVAL (operands[1]));
6341           return "sub{b}\t{%1, %0|%0, %1}";
6342         }
6343       return "add{b}\t{%1, %0|%0, %1}";
6344     }
6346   [(set (attr "type")
6347      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6348         (const_string "incdec")
6349         (const_string "alu1")))
6350    (set (attr "memory")
6351      (if_then_else (match_operand 1 "memory_operand" "")
6352         (const_string "load")
6353         (const_string "none")))
6354    (set_attr "mode" "QI")])
6356 (define_insn "*add<mode>_2"
6357   [(set (reg FLAGS_REG)
6358         (compare
6359           (plus:SWI48
6360             (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6361             (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6362           (const_int 0)))
6363    (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6364         (plus:SWI48 (match_dup 1) (match_dup 2)))]
6365   "ix86_match_ccmode (insn, CCGOCmode)
6366    && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6367    /* Current assemblers are broken and do not allow @GOTOFF in
6368       ought but a memory context.  */
6369    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6371   switch (get_attr_type (insn))
6372     {
6373     case TYPE_INCDEC:
6374       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6375       if (operands[2] == const1_rtx)
6376         return "inc{<imodesuffix>}\t%0";
6377       else
6378         {
6379           gcc_assert (operands[2] == constm1_rtx);
6380           return "dec{<imodesuffix>}\t%0";
6381         }
6383     default:
6384       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6385       /* ???? In DImode, we ought to handle there the 32bit case too
6386          - do we need new constraint?  */
6387       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6388          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6389       if (CONST_INT_P (operands[2])
6390           /* Avoid overflows.  */
6391           && (<MODE>mode != DImode
6392               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6393           && (INTVAL (operands[2]) == 128
6394               || (INTVAL (operands[2]) < 0
6395                   && INTVAL (operands[2]) != -128)))
6396         {
6397           operands[2] = GEN_INT (-INTVAL (operands[2]));
6398           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6399         }
6400       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6401     }
6403   [(set (attr "type")
6404      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6405         (const_string "incdec")
6406         (const_string "alu")))
6407    (set (attr "length_immediate")
6408       (if_then_else
6409         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6410         (const_string "1")
6411         (const_string "*")))
6412    (set_attr "mode" "<MODE>")])
6414 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6415 (define_insn "*addsi_2_zext"
6416   [(set (reg FLAGS_REG)
6417         (compare
6418           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6419                    (match_operand:SI 2 "general_operand" "g"))
6420           (const_int 0)))
6421    (set (match_operand:DI 0 "register_operand" "=r")
6422         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6423   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6424    && ix86_binary_operator_ok (PLUS, SImode, operands)
6425    /* Current assemblers are broken and do not allow @GOTOFF in
6426       ought but a memory context.  */
6427    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6429   switch (get_attr_type (insn))
6430     {
6431     case TYPE_INCDEC:
6432       if (operands[2] == const1_rtx)
6433         return "inc{l}\t%k0";
6434       else
6435         {
6436           gcc_assert (operands[2] == constm1_rtx);
6437           return "dec{l}\t%k0";
6438         }
6440     default:
6441       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6442          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6443       if (CONST_INT_P (operands[2])
6444           && (INTVAL (operands[2]) == 128
6445               || (INTVAL (operands[2]) < 0
6446                   && INTVAL (operands[2]) != -128)))
6447         {
6448           operands[2] = GEN_INT (-INTVAL (operands[2]));
6449           return "sub{l}\t{%2, %k0|%k0, %2}";
6450         }
6451       return "add{l}\t{%2, %k0|%k0, %2}";
6452     }
6454   [(set (attr "type")
6455      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6456         (const_string "incdec")
6457         (const_string "alu")))
6458    (set (attr "length_immediate")
6459       (if_then_else
6460         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6461         (const_string "1")
6462         (const_string "*")))
6463    (set_attr "mode" "SI")])
6465 (define_insn "*addhi_2"
6466   [(set (reg FLAGS_REG)
6467         (compare
6468           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6469                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6470           (const_int 0)))
6471    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6472         (plus:HI (match_dup 1) (match_dup 2)))]
6473   "ix86_match_ccmode (insn, CCGOCmode)
6474    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6476   switch (get_attr_type (insn))
6477     {
6478     case TYPE_INCDEC:
6479       if (operands[2] == const1_rtx)
6480         return "inc{w}\t%0";
6481       else
6482         {
6483           gcc_assert (operands[2] == constm1_rtx);
6484           return "dec{w}\t%0";
6485         }
6487     default:
6488       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6489          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6490       if (CONST_INT_P (operands[2])
6491           && (INTVAL (operands[2]) == 128
6492               || (INTVAL (operands[2]) < 0
6493                   && INTVAL (operands[2]) != -128)))
6494         {
6495           operands[2] = GEN_INT (-INTVAL (operands[2]));
6496           return "sub{w}\t{%2, %0|%0, %2}";
6497         }
6498       return "add{w}\t{%2, %0|%0, %2}";
6499     }
6501   [(set (attr "type")
6502      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6503         (const_string "incdec")
6504         (const_string "alu")))
6505    (set (attr "length_immediate")
6506       (if_then_else
6507         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6508         (const_string "1")
6509         (const_string "*")))
6510    (set_attr "mode" "HI")])
6512 (define_insn "*addqi_2"
6513   [(set (reg FLAGS_REG)
6514         (compare
6515           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6516                    (match_operand:QI 2 "general_operand" "qmn,qn"))
6517           (const_int 0)))
6518    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6519         (plus:QI (match_dup 1) (match_dup 2)))]
6520   "ix86_match_ccmode (insn, CCGOCmode)
6521    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6523   switch (get_attr_type (insn))
6524     {
6525     case TYPE_INCDEC:
6526       if (operands[2] == const1_rtx)
6527         return "inc{b}\t%0";
6528       else
6529         {
6530           gcc_assert (operands[2] == constm1_rtx
6531                       || (CONST_INT_P (operands[2])
6532                           && INTVAL (operands[2]) == 255));
6533           return "dec{b}\t%0";
6534         }
6536     default:
6537       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6538       if (CONST_INT_P (operands[2])
6539           && INTVAL (operands[2]) < 0)
6540         {
6541           operands[2] = GEN_INT (-INTVAL (operands[2]));
6542           return "sub{b}\t{%2, %0|%0, %2}";
6543         }
6544       return "add{b}\t{%2, %0|%0, %2}";
6545     }
6547   [(set (attr "type")
6548      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6549         (const_string "incdec")
6550         (const_string "alu")))
6551    (set_attr "mode" "QI")])
6553 (define_insn "*add<mode>_3"
6554   [(set (reg FLAGS_REG)
6555         (compare
6556           (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6557           (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6558    (clobber (match_scratch:SWI48 0 "=r"))]
6559   "ix86_match_ccmode (insn, CCZmode)
6560    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6561    /* Current assemblers are broken and do not allow @GOTOFF in
6562       ought but a memory context.  */
6563    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6565   switch (get_attr_type (insn))
6566     {
6567     case TYPE_INCDEC:
6568       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6569       if (operands[2] == const1_rtx)
6570         return "inc{<imodesuffix>}\t%0";
6571       else
6572         {
6573           gcc_assert (operands[2] == constm1_rtx);
6574           return "dec{<imodesuffix>}\t%0";
6575         }
6577     default:
6578       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6579       /* ???? In DImode, we ought to handle there the 32bit case too
6580          - do we need new constraint?  */
6581       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6582          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6583       if (CONST_INT_P (operands[2])
6584           /* Avoid overflows.  */
6585           && (<MODE>mode != DImode
6586               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6587           && (INTVAL (operands[2]) == 128
6588               || (INTVAL (operands[2]) < 0
6589                   && INTVAL (operands[2]) != -128)))
6590         {
6591           operands[2] = GEN_INT (-INTVAL (operands[2]));
6592           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6593         }
6594       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6595     }
6597   [(set (attr "type")
6598      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6599         (const_string "incdec")
6600         (const_string "alu")))
6601    (set (attr "length_immediate")
6602       (if_then_else
6603         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6604         (const_string "1")
6605         (const_string "*")))
6606    (set_attr "mode" "<MODE>")])
6608 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6609 (define_insn "*addsi_3_zext"
6610   [(set (reg FLAGS_REG)
6611         (compare
6612           (neg:SI (match_operand:SI 2 "general_operand" "g"))
6613           (match_operand:SI 1 "nonimmediate_operand" "%0")))
6614    (set (match_operand:DI 0 "register_operand" "=r")
6615         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6616   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6617    && ix86_binary_operator_ok (PLUS, SImode, operands)
6618    /* Current assemblers are broken and do not allow @GOTOFF in
6619       ought but a memory context.  */
6620    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6622   switch (get_attr_type (insn))
6623     {
6624     case TYPE_INCDEC:
6625       if (operands[2] == const1_rtx)
6626         return "inc{l}\t%k0";
6627       else
6628         {
6629           gcc_assert (operands[2] == constm1_rtx);
6630           return "dec{l}\t%k0";
6631         }
6633     default:
6634       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6635          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6636       if (CONST_INT_P (operands[2])
6637           && (INTVAL (operands[2]) == 128
6638               || (INTVAL (operands[2]) < 0
6639                   && INTVAL (operands[2]) != -128)))
6640         {
6641           operands[2] = GEN_INT (-INTVAL (operands[2]));
6642           return "sub{l}\t{%2, %k0|%k0, %2}";
6643         }
6644       return "add{l}\t{%2, %k0|%k0, %2}";
6645     }
6647   [(set (attr "type")
6648      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6649         (const_string "incdec")
6650         (const_string "alu")))
6651    (set (attr "length_immediate")
6652       (if_then_else
6653         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6654         (const_string "1")
6655         (const_string "*")))
6656    (set_attr "mode" "SI")])
6658 (define_insn "*addhi_3"
6659   [(set (reg FLAGS_REG)
6660         (compare
6661           (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6662           (match_operand:HI 1 "nonimmediate_operand" "%0")))
6663    (clobber (match_scratch:HI 0 "=r"))]
6664   "ix86_match_ccmode (insn, CCZmode)
6665    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6667   switch (get_attr_type (insn))
6668     {
6669     case TYPE_INCDEC:
6670       if (operands[2] == const1_rtx)
6671         return "inc{w}\t%0";
6672       else
6673         {
6674           gcc_assert (operands[2] == constm1_rtx);
6675           return "dec{w}\t%0";
6676         }
6678     default:
6679       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6680          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6681       if (CONST_INT_P (operands[2])
6682           && (INTVAL (operands[2]) == 128
6683               || (INTVAL (operands[2]) < 0
6684                   && INTVAL (operands[2]) != -128)))
6685         {
6686           operands[2] = GEN_INT (-INTVAL (operands[2]));
6687           return "sub{w}\t{%2, %0|%0, %2}";
6688         }
6689       return "add{w}\t{%2, %0|%0, %2}";
6690     }
6692   [(set (attr "type")
6693      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6694         (const_string "incdec")
6695         (const_string "alu")))
6696    (set (attr "length_immediate")
6697       (if_then_else
6698         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6699         (const_string "1")
6700         (const_string "*")))
6701    (set_attr "mode" "HI")])
6703 (define_insn "*addqi_3"
6704   [(set (reg FLAGS_REG)
6705         (compare
6706           (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6707           (match_operand:QI 1 "nonimmediate_operand" "%0")))
6708    (clobber (match_scratch:QI 0 "=q"))]
6709   "ix86_match_ccmode (insn, CCZmode)
6710    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6712   switch (get_attr_type (insn))
6713     {
6714     case TYPE_INCDEC:
6715       if (operands[2] == const1_rtx)
6716         return "inc{b}\t%0";
6717       else
6718         {
6719           gcc_assert (operands[2] == constm1_rtx
6720                       || (CONST_INT_P (operands[2])
6721                           && INTVAL (operands[2]) == 255));
6722           return "dec{b}\t%0";
6723         }
6725     default:
6726       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
6727       if (CONST_INT_P (operands[2])
6728           && INTVAL (operands[2]) < 0)
6729         {
6730           operands[2] = GEN_INT (-INTVAL (operands[2]));
6731           return "sub{b}\t{%2, %0|%0, %2}";
6732         }
6733       return "add{b}\t{%2, %0|%0, %2}";
6734     }
6736   [(set (attr "type")
6737      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6738         (const_string "incdec")
6739         (const_string "alu")))
6740    (set_attr "mode" "QI")])
6742 ; For comparisons against 1, -1 and 128, we may generate better code
6743 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6744 ; is matched then.  We can't accept general immediate, because for
6745 ; case of overflows,  the result is messed up.
6746 ; This pattern also don't hold of 0x8000000000000000, since the value
6747 ; overflows when negated.
6748 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6749 ; only for comparisons not depending on it.
6751 (define_insn "*adddi_4"
6752   [(set (reg FLAGS_REG)
6753         (compare
6754           (match_operand:DI 1 "nonimmediate_operand" "0")
6755           (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6756    (clobber (match_scratch:DI 0 "=rm"))]
6757   "TARGET_64BIT
6758    && ix86_match_ccmode (insn, CCGCmode)"
6760   switch (get_attr_type (insn))
6761     {
6762     case TYPE_INCDEC:
6763       if (operands[2] == constm1_rtx)
6764         return "inc{q}\t%0";
6765       else
6766         {
6767           gcc_assert (operands[2] == const1_rtx);
6768           return "dec{q}\t%0";
6769         }
6771     default:
6772       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6773       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6774          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6775       if ((INTVAL (operands[2]) == -128
6776            || (INTVAL (operands[2]) > 0
6777                && INTVAL (operands[2]) != 128))
6778           /* Avoid overflows.  */
6779           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6780         return "sub{q}\t{%2, %0|%0, %2}";
6781       operands[2] = GEN_INT (-INTVAL (operands[2]));
6782       return "add{q}\t{%2, %0|%0, %2}";
6783     }
6785   [(set (attr "type")
6786      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6787         (const_string "incdec")
6788         (const_string "alu")))
6789    (set (attr "length_immediate")
6790       (if_then_else
6791         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6792         (const_string "1")
6793         (const_string "*")))
6794    (set_attr "mode" "DI")])
6796 ; For comparisons against 1, -1 and 128, we may generate better code
6797 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6798 ; is matched then.  We can't accept general immediate, because for
6799 ; case of overflows,  the result is messed up.
6800 ; This pattern also don't hold of 0x80000000, since the value overflows
6801 ; when negated.
6802 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6803 ; only for comparisons not depending on it.
6805 (define_insn "*addsi_4"
6806   [(set (reg FLAGS_REG)
6807         (compare
6808           (match_operand:SI 1 "nonimmediate_operand" "0")
6809           (match_operand:SI 2 "const_int_operand" "n")))
6810    (clobber (match_scratch:SI 0 "=rm"))]
6811   "ix86_match_ccmode (insn, CCGCmode)
6812    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6814   switch (get_attr_type (insn))
6815     {
6816     case TYPE_INCDEC:
6817       if (operands[2] == constm1_rtx)
6818         return "inc{l}\t%0";
6819       else
6820         {
6821           gcc_assert (operands[2] == const1_rtx);
6822           return "dec{l}\t%0";
6823         }
6825     default:
6826       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6827       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6828          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6829       if ((INTVAL (operands[2]) == -128
6830            || (INTVAL (operands[2]) > 0
6831                && INTVAL (operands[2]) != 128)))
6832         return "sub{l}\t{%2, %0|%0, %2}";
6833       operands[2] = GEN_INT (-INTVAL (operands[2]));
6834       return "add{l}\t{%2, %0|%0, %2}";
6835     }
6837   [(set (attr "type")
6838      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6839         (const_string "incdec")
6840         (const_string "alu")))
6841    (set (attr "length_immediate")
6842       (if_then_else
6843         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6844         (const_string "1")
6845         (const_string "*")))
6846    (set_attr "mode" "SI")])
6848 ; See comments above addsi_4 for details.
6850 (define_insn "*addhi_4"
6851   [(set (reg FLAGS_REG)
6852         (compare
6853           (match_operand:HI 1 "nonimmediate_operand" "0")
6854           (match_operand:HI 2 "const_int_operand" "n")))
6855    (clobber (match_scratch:HI 0 "=rm"))]
6856   "ix86_match_ccmode (insn, CCGCmode)
6857    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6859   switch (get_attr_type (insn))
6860     {
6861     case TYPE_INCDEC:
6862       if (operands[2] == constm1_rtx)
6863         return "inc{w}\t%0";
6864       else
6865         {
6866           gcc_assert (operands[2] == const1_rtx);
6867           return "dec{w}\t%0";
6868         }
6870     default:
6871       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6872       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6873          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6874       if ((INTVAL (operands[2]) == -128
6875            || (INTVAL (operands[2]) > 0
6876                && INTVAL (operands[2]) != 128)))
6877         return "sub{w}\t{%2, %0|%0, %2}";
6878       operands[2] = GEN_INT (-INTVAL (operands[2]));
6879       return "add{w}\t{%2, %0|%0, %2}";
6880     }
6882   [(set (attr "type")
6883      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6884         (const_string "incdec")
6885         (const_string "alu")))
6886    (set (attr "length_immediate")
6887       (if_then_else
6888         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6889         (const_string "1")
6890         (const_string "*")))
6891    (set_attr "mode" "HI")])
6893 ; See comments above addsi_4 for details.
6895 (define_insn "*addqi_4"
6896   [(set (reg FLAGS_REG)
6897         (compare
6898           (match_operand:QI 1 "nonimmediate_operand" "0")
6899           (match_operand:QI 2 "const_int_operand" "n")))
6900    (clobber (match_scratch:QI 0 "=qm"))]
6901   "ix86_match_ccmode (insn, CCGCmode)
6902    && (INTVAL (operands[2]) & 0xff) != 0x80"
6904   switch (get_attr_type (insn))
6905     {
6906     case TYPE_INCDEC:
6907       if (operands[2] == constm1_rtx
6908           || (CONST_INT_P (operands[2])
6909               && INTVAL (operands[2]) == 255))
6910         return "inc{b}\t%0";
6911       else
6912         {
6913           gcc_assert (operands[2] == const1_rtx);
6914           return "dec{b}\t%0";
6915         }
6917     default:
6918       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6919       if (INTVAL (operands[2]) < 0)
6920         {
6921           operands[2] = GEN_INT (-INTVAL (operands[2]));
6922           return "add{b}\t{%2, %0|%0, %2}";
6923         }
6924       return "sub{b}\t{%2, %0|%0, %2}";
6925     }
6927   [(set (attr "type")
6928      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6929         (const_string "incdec")
6930         (const_string "alu")))
6931    (set_attr "mode" "QI")])
6933 (define_insn "*add<mode>_5"
6934   [(set (reg FLAGS_REG)
6935         (compare
6936           (plus:SWI48
6937             (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6938             (match_operand:SWI48 2 "<general_operand>" "<g>"))
6939           (const_int 0)))
6940    (clobber (match_scratch:SWI48 0 "=r"))]
6941   "ix86_match_ccmode (insn, CCGOCmode)
6942    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6943    /* Current assemblers are broken and do not allow @GOTOFF in
6944       ought but a memory context.  */
6945    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6947   switch (get_attr_type (insn))
6948     {
6949     case TYPE_INCDEC:
6950       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6951       if (operands[2] == const1_rtx)
6952         return "inc{<imodesuffix>}\t%0";
6953       else
6954         {
6955           gcc_assert (operands[2] == constm1_rtx);
6956           return "dec{<imodesuffix>}\t%0";
6957         }
6959     default:
6960       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6961       /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6962          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6963       if (CONST_INT_P (operands[2])
6964           /* Avoid overflows.  */
6965           && (<MODE>mode != DImode
6966               || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6967           && (INTVAL (operands[2]) == 128
6968               || (INTVAL (operands[2]) < 0
6969                   && INTVAL (operands[2]) != -128)))
6970         {
6971           operands[2] = GEN_INT (-INTVAL (operands[2]));
6972           return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6973         }
6974       return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6975     }
6977   [(set (attr "type")
6978      (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6979         (const_string "incdec")
6980         (const_string "alu")))
6981    (set (attr "length_immediate")
6982       (if_then_else
6983         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6984         (const_string "1")
6985         (const_string "*")))
6986    (set_attr "mode" "<MODE>")])
6988 (define_insn "*addhi_5"
6989   [(set (reg FLAGS_REG)
6990         (compare
6991           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6992                    (match_operand:HI 2 "general_operand" "rmn"))
6993           (const_int 0)))
6994    (clobber (match_scratch:HI 0 "=r"))]
6995   "ix86_match_ccmode (insn, CCGOCmode)
6996    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6998   switch (get_attr_type (insn))
6999     {
7000     case TYPE_INCDEC:
7001       if (operands[2] == const1_rtx)
7002         return "inc{w}\t%0";
7003       else
7004         {
7005           gcc_assert (operands[2] == constm1_rtx);
7006           return "dec{w}\t%0";
7007         }
7009     default:
7010       /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
7011          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7012       if (CONST_INT_P (operands[2])
7013           && (INTVAL (operands[2]) == 128
7014               || (INTVAL (operands[2]) < 0
7015                   && INTVAL (operands[2]) != -128)))
7016         {
7017           operands[2] = GEN_INT (-INTVAL (operands[2]));
7018           return "sub{w}\t{%2, %0|%0, %2}";
7019         }
7020       return "add{w}\t{%2, %0|%0, %2}";
7021     }
7023   [(set (attr "type")
7024      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7025         (const_string "incdec")
7026         (const_string "alu")))
7027    (set (attr "length_immediate")
7028       (if_then_else
7029         (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7030         (const_string "1")
7031         (const_string "*")))
7032    (set_attr "mode" "HI")])
7034 (define_insn "*addqi_5"
7035   [(set (reg FLAGS_REG)
7036         (compare
7037           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7038                    (match_operand:QI 2 "general_operand" "qmn"))
7039           (const_int 0)))
7040    (clobber (match_scratch:QI 0 "=q"))]
7041   "ix86_match_ccmode (insn, CCGOCmode)
7042    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7044   switch (get_attr_type (insn))
7045     {
7046     case TYPE_INCDEC:
7047       if (operands[2] == const1_rtx)
7048         return "inc{b}\t%0";
7049       else
7050         {
7051           gcc_assert (operands[2] == constm1_rtx
7052                       || (CONST_INT_P (operands[2])
7053                           && INTVAL (operands[2]) == 255));
7054           return "dec{b}\t%0";
7055         }
7057     default:
7058       /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.  */
7059       if (CONST_INT_P (operands[2])
7060           && INTVAL (operands[2]) < 0)
7061         {
7062           operands[2] = GEN_INT (-INTVAL (operands[2]));
7063           return "sub{b}\t{%2, %0|%0, %2}";
7064         }
7065       return "add{b}\t{%2, %0|%0, %2}";
7066     }
7068   [(set (attr "type")
7069      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7070         (const_string "incdec")
7071         (const_string "alu")))
7072    (set_attr "mode" "QI")])
7074 (define_insn "*addqi_ext_1_rex64"
7075   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7076                          (const_int 8)
7077                          (const_int 8))
7078         (plus:SI
7079           (zero_extract:SI
7080             (match_operand 1 "ext_register_operand" "0")
7081             (const_int 8)
7082             (const_int 8))
7083           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7084    (clobber (reg:CC FLAGS_REG))]
7085   "TARGET_64BIT"
7087   switch (get_attr_type (insn))
7088     {
7089     case TYPE_INCDEC:
7090       if (operands[2] == const1_rtx)
7091         return "inc{b}\t%h0";
7092       else
7093         {
7094           gcc_assert (operands[2] == constm1_rtx
7095                       || (CONST_INT_P (operands[2])
7096                           && INTVAL (operands[2]) == 255));
7097           return "dec{b}\t%h0";
7098         }
7100     default:
7101       return "add{b}\t{%2, %h0|%h0, %2}";
7102     }
7104   [(set (attr "type")
7105      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7106         (const_string "incdec")
7107         (const_string "alu")))
7108    (set_attr "modrm" "1")
7109    (set_attr "mode" "QI")])
7111 (define_insn "addqi_ext_1"
7112   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7113                          (const_int 8)
7114                          (const_int 8))
7115         (plus:SI
7116           (zero_extract:SI
7117             (match_operand 1 "ext_register_operand" "0")
7118             (const_int 8)
7119             (const_int 8))
7120           (match_operand:QI 2 "general_operand" "Qmn")))
7121    (clobber (reg:CC FLAGS_REG))]
7122   "!TARGET_64BIT"
7124   switch (get_attr_type (insn))
7125     {
7126     case TYPE_INCDEC:
7127       if (operands[2] == const1_rtx)
7128         return "inc{b}\t%h0";
7129       else
7130         {
7131           gcc_assert (operands[2] == constm1_rtx
7132                       || (CONST_INT_P (operands[2])
7133                           && INTVAL (operands[2]) == 255));
7134           return "dec{b}\t%h0";
7135         }
7137     default:
7138       return "add{b}\t{%2, %h0|%h0, %2}";
7139     }
7141   [(set (attr "type")
7142      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7143         (const_string "incdec")
7144         (const_string "alu")))
7145    (set_attr "modrm" "1")
7146    (set_attr "mode" "QI")])
7148 (define_insn "*addqi_ext_2"
7149   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7150                          (const_int 8)
7151                          (const_int 8))
7152         (plus:SI
7153           (zero_extract:SI
7154             (match_operand 1 "ext_register_operand" "%0")
7155             (const_int 8)
7156             (const_int 8))
7157           (zero_extract:SI
7158             (match_operand 2 "ext_register_operand" "Q")
7159             (const_int 8)
7160             (const_int 8))))
7161    (clobber (reg:CC FLAGS_REG))]
7162   ""
7163   "add{b}\t{%h2, %h0|%h0, %h2}"
7164   [(set_attr "type" "alu")
7165    (set_attr "mode" "QI")])
7167 ;; The lea patterns for non-Pmodes needs to be matched by
7168 ;; several insns converted to real lea by splitters.
7170 (define_insn_and_split "*lea_general_1"
7171   [(set (match_operand 0 "register_operand" "=r")
7172         (plus (plus (match_operand 1 "index_register_operand" "l")
7173                     (match_operand 2 "register_operand" "r"))
7174               (match_operand 3 "immediate_operand" "i")))]
7175   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7176     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7177    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7178    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7179    && GET_MODE (operands[0]) == GET_MODE (operands[2])
7180    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7181        || GET_MODE (operands[3]) == VOIDmode)"
7182   "#"
7183   "&& reload_completed"
7184   [(const_int 0)]
7186   rtx pat;
7187   operands[0] = gen_lowpart (SImode, operands[0]);
7188   operands[1] = gen_lowpart (Pmode, operands[1]);
7189   operands[2] = gen_lowpart (Pmode, operands[2]);
7190   operands[3] = gen_lowpart (Pmode, operands[3]);
7191   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7192                       operands[3]);
7193   if (Pmode != SImode)
7194     pat = gen_rtx_SUBREG (SImode, pat, 0);
7195   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7196   DONE;
7198   [(set_attr "type" "lea")
7199    (set_attr "mode" "SI")])
7201 (define_insn_and_split "*lea_general_1_zext"
7202   [(set (match_operand:DI 0 "register_operand" "=r")
7203         (zero_extend:DI
7204           (plus:SI (plus:SI
7205                      (match_operand:SI 1 "index_register_operand" "l")
7206                      (match_operand:SI 2 "register_operand" "r"))
7207                    (match_operand:SI 3 "immediate_operand" "i"))))]
7208   "TARGET_64BIT"
7209   "#"
7210   "&& reload_completed"
7211   [(set (match_dup 0)
7212         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7213                                                      (match_dup 2))
7214                                             (match_dup 3)) 0)))]
7216   operands[1] = gen_lowpart (Pmode, operands[1]);
7217   operands[2] = gen_lowpart (Pmode, operands[2]);
7218   operands[3] = gen_lowpart (Pmode, operands[3]);
7220   [(set_attr "type" "lea")
7221    (set_attr "mode" "SI")])
7223 (define_insn_and_split "*lea_general_2"
7224   [(set (match_operand 0 "register_operand" "=r")
7225         (plus (mult (match_operand 1 "index_register_operand" "l")
7226                     (match_operand 2 "const248_operand" "i"))
7227               (match_operand 3 "nonmemory_operand" "ri")))]
7228   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7229     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7230    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7231    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7232    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7233        || GET_MODE (operands[3]) == VOIDmode)"
7234   "#"
7235   "&& reload_completed"
7236   [(const_int 0)]
7238   rtx pat;
7239   operands[0] = gen_lowpart (SImode, operands[0]);
7240   operands[1] = gen_lowpart (Pmode, operands[1]);
7241   operands[3] = gen_lowpart (Pmode, operands[3]);
7242   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7243                       operands[3]);
7244   if (Pmode != SImode)
7245     pat = gen_rtx_SUBREG (SImode, pat, 0);
7246   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7247   DONE;
7249   [(set_attr "type" "lea")
7250    (set_attr "mode" "SI")])
7252 (define_insn_and_split "*lea_general_2_zext"
7253   [(set (match_operand:DI 0 "register_operand" "=r")
7254         (zero_extend:DI
7255           (plus:SI (mult:SI
7256                      (match_operand:SI 1 "index_register_operand" "l")
7257                      (match_operand:SI 2 "const248_operand" "n"))
7258                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7259   "TARGET_64BIT"
7260   "#"
7261   "&& reload_completed"
7262   [(set (match_dup 0)
7263         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7264                                                      (match_dup 2))
7265                                             (match_dup 3)) 0)))]
7267   operands[1] = gen_lowpart (Pmode, operands[1]);
7268   operands[3] = gen_lowpart (Pmode, operands[3]);
7270   [(set_attr "type" "lea")
7271    (set_attr "mode" "SI")])
7273 (define_insn_and_split "*lea_general_3"
7274   [(set (match_operand 0 "register_operand" "=r")
7275         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7276                           (match_operand 2 "const248_operand" "i"))
7277                     (match_operand 3 "register_operand" "r"))
7278               (match_operand 4 "immediate_operand" "i")))]
7279   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7280     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7281    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7282    && GET_MODE (operands[0]) == GET_MODE (operands[1])
7283    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7284   "#"
7285   "&& reload_completed"
7286   [(const_int 0)]
7288   rtx pat;
7289   operands[0] = gen_lowpart (SImode, operands[0]);
7290   operands[1] = gen_lowpart (Pmode, operands[1]);
7291   operands[3] = gen_lowpart (Pmode, operands[3]);
7292   operands[4] = gen_lowpart (Pmode, operands[4]);
7293   pat = gen_rtx_PLUS (Pmode,
7294                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7295                                                          operands[2]),
7296                                     operands[3]),
7297                       operands[4]);
7298   if (Pmode != SImode)
7299     pat = gen_rtx_SUBREG (SImode, pat, 0);
7300   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7301   DONE;
7303   [(set_attr "type" "lea")
7304    (set_attr "mode" "SI")])
7306 (define_insn_and_split "*lea_general_3_zext"
7307   [(set (match_operand:DI 0 "register_operand" "=r")
7308         (zero_extend:DI
7309           (plus:SI (plus:SI
7310                      (mult:SI
7311                        (match_operand:SI 1 "index_register_operand" "l")
7312                        (match_operand:SI 2 "const248_operand" "n"))
7313                      (match_operand:SI 3 "register_operand" "r"))
7314                    (match_operand:SI 4 "immediate_operand" "i"))))]
7315   "TARGET_64BIT"
7316   "#"
7317   "&& reload_completed"
7318   [(set (match_dup 0)
7319         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7320                                                               (match_dup 2))
7321                                                      (match_dup 3))
7322                                             (match_dup 4)) 0)))]
7324   operands[1] = gen_lowpart (Pmode, operands[1]);
7325   operands[3] = gen_lowpart (Pmode, operands[3]);
7326   operands[4] = gen_lowpart (Pmode, operands[4]);
7328   [(set_attr "type" "lea")
7329    (set_attr "mode" "SI")])
7331 ;; Convert lea to the lea pattern to avoid flags dependency.
7332 (define_split
7333   [(set (match_operand:DI 0 "register_operand" "")
7334         (plus:DI (match_operand:DI 1 "register_operand" "")
7335                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7336    (clobber (reg:CC FLAGS_REG))]
7337   "TARGET_64BIT && reload_completed 
7338    && ix86_lea_for_add_ok (PLUS, insn, operands)"
7339   [(set (match_dup 0)
7340         (plus:DI (match_dup 1)
7341                  (match_dup 2)))]
7342   "")
7344 ;; Convert lea to the lea pattern to avoid flags dependency.
7345 (define_split
7346   [(set (match_operand 0 "register_operand" "")
7347         (plus (match_operand 1 "register_operand" "")
7348               (match_operand 2 "nonmemory_operand" "")))
7349    (clobber (reg:CC FLAGS_REG))]
7350   "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)" 
7351   [(const_int 0)]
7353   rtx pat;
7354   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7355      may confuse gen_lowpart.  */
7356   if (GET_MODE (operands[0]) != Pmode)
7357     {
7358       operands[1] = gen_lowpart (Pmode, operands[1]);
7359       operands[2] = gen_lowpart (Pmode, operands[2]);
7360     }
7361   operands[0] = gen_lowpart (SImode, operands[0]);
7362   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7363   if (Pmode != SImode)
7364     pat = gen_rtx_SUBREG (SImode, pat, 0);
7365   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7366   DONE;
7369 ;; Convert lea to the lea pattern to avoid flags dependency.
7370 (define_split
7371   [(set (match_operand:DI 0 "register_operand" "")
7372         (zero_extend:DI
7373           (plus:SI (match_operand:SI 1 "register_operand" "")
7374                    (match_operand:SI 2 "nonmemory_operand" ""))))
7375    (clobber (reg:CC FLAGS_REG))]
7376   "TARGET_64BIT && reload_completed
7377    && true_regnum (operands[0]) != true_regnum (operands[1])"
7378   [(set (match_dup 0)
7379         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7381   operands[1] = gen_lowpart (Pmode, operands[1]);
7382   operands[2] = gen_lowpart (Pmode, operands[2]);
7385 ;; Subtract instructions
7387 (define_expand "sub<mode>3"
7388   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7389         (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7390                      (match_operand:SDWIM 2 "<general_operand>" "")))]
7391   ""
7392   "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7394 (define_insn_and_split "*sub<dwi>3_doubleword"
7395   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7396         (minus:<DWI>
7397           (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7398           (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7399    (clobber (reg:CC FLAGS_REG))]
7400   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7401   "#"
7402   "reload_completed"
7403   [(parallel [(set (reg:CC FLAGS_REG)
7404                    (compare:CC (match_dup 1) (match_dup 2)))
7405               (set (match_dup 0)
7406                    (minus:DWIH (match_dup 1) (match_dup 2)))])
7407    (parallel [(set (match_dup 3)
7408                    (minus:DWIH
7409                      (match_dup 4)
7410                      (plus:DWIH
7411                        (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7412                        (match_dup 5))))
7413               (clobber (reg:CC FLAGS_REG))])]
7414   "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7416 (define_insn "*sub<mode>_1"
7417   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7418         (minus:SWI
7419           (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7420           (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7421    (clobber (reg:CC FLAGS_REG))]
7422   "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7423   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7424   [(set_attr "type" "alu")
7425    (set_attr "mode" "<MODE>")])
7427 (define_insn "*subsi_1_zext"
7428   [(set (match_operand:DI 0 "register_operand" "=r")
7429         (zero_extend:DI
7430           (minus:SI (match_operand:SI 1 "register_operand" "0")
7431                     (match_operand:SI 2 "general_operand" "g"))))
7432    (clobber (reg:CC FLAGS_REG))]
7433   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7434   "sub{l}\t{%2, %k0|%k0, %2}"
7435   [(set_attr "type" "alu")
7436    (set_attr "mode" "SI")])
7438 (define_insn "*subqi_1_slp"
7439   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7440         (minus:QI (match_dup 0)
7441                   (match_operand:QI 1 "general_operand" "qn,qm")))
7442    (clobber (reg:CC FLAGS_REG))]
7443   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7444    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7445   "sub{b}\t{%1, %0|%0, %1}"
7446   [(set_attr "type" "alu1")
7447    (set_attr "mode" "QI")])
7449 (define_insn "*sub<mode>_2"
7450   [(set (reg FLAGS_REG)
7451         (compare
7452           (minus:SWI
7453             (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7454             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7455           (const_int 0)))
7456    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7457         (minus:SWI (match_dup 1) (match_dup 2)))]
7458   "ix86_match_ccmode (insn, CCGOCmode)
7459    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7460   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7461   [(set_attr "type" "alu")
7462    (set_attr "mode" "<MODE>")])
7464 (define_insn "*subsi_2_zext"
7465   [(set (reg FLAGS_REG)
7466         (compare
7467           (minus:SI (match_operand:SI 1 "register_operand" "0")
7468                     (match_operand:SI 2 "general_operand" "g"))
7469           (const_int 0)))
7470    (set (match_operand:DI 0 "register_operand" "=r")
7471         (zero_extend:DI
7472           (minus:SI (match_dup 1)
7473                     (match_dup 2))))]
7474   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7475    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7476   "sub{l}\t{%2, %k0|%k0, %2}"
7477   [(set_attr "type" "alu")
7478    (set_attr "mode" "SI")])
7480 (define_insn "*sub<mode>_3"
7481   [(set (reg FLAGS_REG)
7482         (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7483                  (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7484    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7485         (minus:SWI (match_dup 1) (match_dup 2)))]
7486   "ix86_match_ccmode (insn, CCmode)
7487    && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7488   "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7489   [(set_attr "type" "alu")
7490    (set_attr "mode" "<MODE>")])
7492 (define_insn "*subsi_3_zext"
7493   [(set (reg FLAGS_REG)
7494         (compare (match_operand:SI 1 "register_operand" "0")
7495                  (match_operand:SI 2 "general_operand" "g")))
7496    (set (match_operand:DI 0 "register_operand" "=r")
7497         (zero_extend:DI
7498           (minus:SI (match_dup 1)
7499                     (match_dup 2))))]
7500   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7501    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7502   "sub{l}\t{%2, %1|%1, %2}"
7503   [(set_attr "type" "alu")
7504    (set_attr "mode" "SI")])
7506 ;; Add with carry and subtract with borrow
7508 (define_expand "<plusminus_insn><mode>3_carry"
7509   [(parallel
7510     [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7511           (plusminus:SWI
7512             (match_operand:SWI 1 "nonimmediate_operand" "")
7513             (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7514                        [(match_operand 3 "flags_reg_operand" "")
7515                         (const_int 0)])
7516                       (match_operand:SWI 2 "<general_operand>" ""))))
7517      (clobber (reg:CC FLAGS_REG))])]
7518   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7519   "")
7521 (define_insn "*<plusminus_insn><mode>3_carry"
7522   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7523         (plusminus:SWI
7524           (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7525           (plus:SWI
7526             (match_operator 3 "ix86_carry_flag_operator"
7527              [(reg FLAGS_REG) (const_int 0)])
7528             (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7529    (clobber (reg:CC FLAGS_REG))]
7530   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7531   "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7532   [(set_attr "type" "alu")
7533    (set_attr "use_carry" "1")
7534    (set_attr "pent_pair" "pu")
7535    (set_attr "mode" "<MODE>")])
7537 (define_insn "*addsi3_carry_zext"
7538   [(set (match_operand:DI 0 "register_operand" "=r")
7539         (zero_extend:DI
7540           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7541                    (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7542                              [(reg FLAGS_REG) (const_int 0)])
7543                             (match_operand:SI 2 "general_operand" "g")))))
7544    (clobber (reg:CC FLAGS_REG))]
7545   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7546   "adc{l}\t{%2, %k0|%k0, %2}"
7547   [(set_attr "type" "alu")
7548    (set_attr "use_carry" "1")
7549    (set_attr "pent_pair" "pu")
7550    (set_attr "mode" "SI")])
7552 (define_insn "*subsi3_carry_zext"
7553   [(set (match_operand:DI 0 "register_operand" "=r")
7554         (zero_extend:DI
7555           (minus:SI (match_operand:SI 1 "register_operand" "0")
7556                     (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7557                               [(reg FLAGS_REG) (const_int 0)])
7558                              (match_operand:SI 2 "general_operand" "g")))))
7559    (clobber (reg:CC FLAGS_REG))]
7560   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7561   "sbb{l}\t{%2, %k0|%k0, %2}"
7562   [(set_attr "type" "alu")
7563    (set_attr "pent_pair" "pu")
7564    (set_attr "mode" "SI")])
7566 ;; Overflow setting add and subtract instructions
7568 (define_insn "*add<mode>3_cconly_overflow"
7569   [(set (reg:CCC FLAGS_REG)
7570         (compare:CCC
7571           (plus:SWI
7572             (match_operand:SWI 1 "nonimmediate_operand" "%0")
7573             (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7574           (match_dup 1)))
7575    (clobber (match_scratch:SWI 0 "=<r>"))]
7576   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7577   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7578   [(set_attr "type" "alu")
7579    (set_attr "mode" "<MODE>")])
7581 (define_insn "*sub<mode>3_cconly_overflow"
7582   [(set (reg:CCC FLAGS_REG)
7583         (compare:CCC
7584           (minus:SWI
7585             (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7586             (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7587           (match_dup 0)))]
7588   ""
7589   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7590   [(set_attr "type" "icmp")
7591    (set_attr "mode" "<MODE>")])
7593 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7594   [(set (reg:CCC FLAGS_REG)
7595         (compare:CCC
7596             (plusminus:SWI
7597                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7598                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7599             (match_dup 1)))
7600    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7601         (plusminus:SWI (match_dup 1) (match_dup 2)))]
7602   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7603   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7604   [(set_attr "type" "alu")
7605    (set_attr "mode" "<MODE>")])
7607 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7608   [(set (reg:CCC FLAGS_REG)
7609         (compare:CCC
7610           (plusminus:SI
7611             (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7612             (match_operand:SI 2 "general_operand" "g"))
7613           (match_dup 1)))
7614    (set (match_operand:DI 0 "register_operand" "=r")
7615         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7616   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7617   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7618   [(set_attr "type" "alu")
7619    (set_attr "mode" "SI")])
7621 ;; The patterns that match these are at the end of this file.
7623 (define_expand "<plusminus_insn>xf3"
7624   [(set (match_operand:XF 0 "register_operand" "")
7625         (plusminus:XF
7626           (match_operand:XF 1 "register_operand" "")
7627           (match_operand:XF 2 "register_operand" "")))]
7628   "TARGET_80387"
7629   "")
7631 (define_expand "<plusminus_insn><mode>3"
7632   [(set (match_operand:MODEF 0 "register_operand" "")
7633         (plusminus:MODEF
7634           (match_operand:MODEF 1 "register_operand" "")
7635           (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7636   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7637     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7638   "")
7640 ;; Multiply instructions
7642 (define_expand "mul<mode>3"
7643   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7644                    (mult:SWIM248
7645                      (match_operand:SWIM248 1 "register_operand" "")
7646                      (match_operand:SWIM248 2 "<general_operand>" "")))
7647               (clobber (reg:CC FLAGS_REG))])]
7648   ""
7649   "")
7651 (define_expand "mulqi3"
7652   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7653                    (mult:QI
7654                      (match_operand:QI 1 "register_operand" "")
7655                      (match_operand:QI 2 "nonimmediate_operand" "")))
7656               (clobber (reg:CC FLAGS_REG))])]
7657   "TARGET_QIMODE_MATH"
7658   "")
7660 ;; On AMDFAM10
7661 ;; IMUL reg32/64, reg32/64, imm8        Direct
7662 ;; IMUL reg32/64, mem32/64, imm8        VectorPath
7663 ;; IMUL reg32/64, reg32/64, imm32       Direct
7664 ;; IMUL reg32/64, mem32/64, imm32       VectorPath
7665 ;; IMUL reg32/64, reg32/64              Direct
7666 ;; IMUL reg32/64, mem32/64              Direct
7668 (define_insn "*mul<mode>3_1"
7669   [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7670         (mult:SWI48
7671           (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7672           (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7673    (clobber (reg:CC FLAGS_REG))]
7674   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7675   "@
7676    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7677    imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7678    imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7679   [(set_attr "type" "imul")
7680    (set_attr "prefix_0f" "0,0,1")
7681    (set (attr "athlon_decode")
7682         (cond [(eq_attr "cpu" "athlon")
7683                   (const_string "vector")
7684                (eq_attr "alternative" "1")
7685                   (const_string "vector")
7686                (and (eq_attr "alternative" "2")
7687                     (match_operand 1 "memory_operand" ""))
7688                   (const_string "vector")]
7689               (const_string "direct")))
7690    (set (attr "amdfam10_decode")
7691         (cond [(and (eq_attr "alternative" "0,1")
7692                     (match_operand 1 "memory_operand" ""))
7693                   (const_string "vector")]
7694               (const_string "direct")))
7695    (set_attr "mode" "<MODE>")])
7697 (define_insn "*mulsi3_1_zext"
7698   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7699         (zero_extend:DI
7700           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7701                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7702    (clobber (reg:CC FLAGS_REG))]
7703   "TARGET_64BIT
7704    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7705   "@
7706    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7707    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7708    imul{l}\t{%2, %k0|%k0, %2}"
7709   [(set_attr "type" "imul")
7710    (set_attr "prefix_0f" "0,0,1")
7711    (set (attr "athlon_decode")
7712         (cond [(eq_attr "cpu" "athlon")
7713                   (const_string "vector")
7714                (eq_attr "alternative" "1")
7715                   (const_string "vector")
7716                (and (eq_attr "alternative" "2")
7717                     (match_operand 1 "memory_operand" ""))
7718                   (const_string "vector")]
7719               (const_string "direct")))
7720    (set (attr "amdfam10_decode")
7721         (cond [(and (eq_attr "alternative" "0,1")
7722                     (match_operand 1 "memory_operand" ""))
7723                   (const_string "vector")]
7724               (const_string "direct")))
7725    (set_attr "mode" "SI")])
7727 ;; On AMDFAM10
7728 ;; IMUL reg16, reg16, imm8      VectorPath
7729 ;; IMUL reg16, mem16, imm8      VectorPath
7730 ;; IMUL reg16, reg16, imm16     VectorPath
7731 ;; IMUL reg16, mem16, imm16     VectorPath
7732 ;; IMUL reg16, reg16            Direct
7733 ;; IMUL reg16, mem16            Direct
7735 (define_insn "*mulhi3_1"
7736   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7737         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7738                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7739    (clobber (reg:CC FLAGS_REG))]
7740   "TARGET_HIMODE_MATH
7741    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7742   "@
7743    imul{w}\t{%2, %1, %0|%0, %1, %2}
7744    imul{w}\t{%2, %1, %0|%0, %1, %2}
7745    imul{w}\t{%2, %0|%0, %2}"
7746   [(set_attr "type" "imul")
7747    (set_attr "prefix_0f" "0,0,1")
7748    (set (attr "athlon_decode")
7749         (cond [(eq_attr "cpu" "athlon")
7750                   (const_string "vector")
7751                (eq_attr "alternative" "1,2")
7752                   (const_string "vector")]
7753               (const_string "direct")))
7754    (set (attr "amdfam10_decode")
7755         (cond [(eq_attr "alternative" "0,1")
7756                   (const_string "vector")]
7757               (const_string "direct")))
7758    (set_attr "mode" "HI")])
7760 ;;On AMDFAM10
7761 ;; MUL reg8     Direct
7762 ;; MUL mem8     Direct
7764 (define_insn "*mulqi3_1"
7765   [(set (match_operand:QI 0 "register_operand" "=a")
7766         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7767                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7768    (clobber (reg:CC FLAGS_REG))]
7769   "TARGET_QIMODE_MATH
7770    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7771   "mul{b}\t%2"
7772   [(set_attr "type" "imul")
7773    (set_attr "length_immediate" "0")
7774    (set (attr "athlon_decode")
7775      (if_then_else (eq_attr "cpu" "athlon")
7776         (const_string "vector")
7777         (const_string "direct")))
7778    (set_attr "amdfam10_decode" "direct")
7779    (set_attr "mode" "QI")])
7781 (define_expand "<u>mul<mode><dwi>3"
7782   [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7783                    (mult:<DWI>
7784                      (any_extend:<DWI>
7785                        (match_operand:DWIH 1 "nonimmediate_operand" ""))
7786                      (any_extend:<DWI>
7787                        (match_operand:DWIH 2 "register_operand" ""))))
7788               (clobber (reg:CC FLAGS_REG))])]
7789   ""
7790   "")
7792 (define_expand "<u>mulqihi3"
7793   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7794                    (mult:HI
7795                      (any_extend:HI
7796                        (match_operand:QI 1 "nonimmediate_operand" ""))
7797                      (any_extend:HI
7798                        (match_operand:QI 2 "register_operand" ""))))
7799               (clobber (reg:CC FLAGS_REG))])]
7800   "TARGET_QIMODE_MATH"
7801   "")
7803 (define_insn "*<u>mul<mode><dwi>3_1"
7804   [(set (match_operand:<DWI> 0 "register_operand" "=A")
7805         (mult:<DWI>
7806           (any_extend:<DWI>
7807             (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7808           (any_extend:<DWI>
7809             (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7810    (clobber (reg:CC FLAGS_REG))]
7811   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7812   "<sgnprefix>mul{<imodesuffix>}\t%2"
7813   [(set_attr "type" "imul")
7814    (set_attr "length_immediate" "0")
7815    (set (attr "athlon_decode")
7816      (if_then_else (eq_attr "cpu" "athlon")
7817         (const_string "vector")
7818         (const_string "double")))
7819    (set_attr "amdfam10_decode" "double")
7820    (set_attr "mode" "<MODE>")])
7822 (define_insn "*<u>mulqihi3_1"
7823   [(set (match_operand:HI 0 "register_operand" "=a")
7824         (mult:HI
7825           (any_extend:HI
7826             (match_operand:QI 1 "nonimmediate_operand" "%0"))
7827           (any_extend:HI
7828             (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7829    (clobber (reg:CC FLAGS_REG))]
7830   "TARGET_QIMODE_MATH
7831    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7832   "<sgnprefix>mul{b}\t%2"
7833   [(set_attr "type" "imul")
7834    (set_attr "length_immediate" "0")
7835    (set (attr "athlon_decode")
7836      (if_then_else (eq_attr "cpu" "athlon")
7837         (const_string "vector")
7838         (const_string "direct")))
7839    (set_attr "amdfam10_decode" "direct")
7840    (set_attr "mode" "QI")])
7842 (define_expand "<s>mul<mode>3_highpart"
7843   [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7844                    (truncate:SWI48
7845                      (lshiftrt:<DWI>
7846                        (mult:<DWI>
7847                          (any_extend:<DWI>
7848                            (match_operand:SWI48 1 "nonimmediate_operand" ""))
7849                          (any_extend:<DWI>
7850                            (match_operand:SWI48 2 "register_operand" "")))
7851                        (match_dup 4))))
7852               (clobber (match_scratch:SWI48 3 ""))
7853               (clobber (reg:CC FLAGS_REG))])]
7854   ""
7855   "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7857 (define_insn "*<s>muldi3_highpart_1"
7858   [(set (match_operand:DI 0 "register_operand" "=d")
7859         (truncate:DI
7860           (lshiftrt:TI
7861             (mult:TI
7862               (any_extend:TI
7863                 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7864               (any_extend:TI
7865                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7866             (const_int 64))))
7867    (clobber (match_scratch:DI 3 "=1"))
7868    (clobber (reg:CC FLAGS_REG))]
7869   "TARGET_64BIT
7870    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7871   "<sgnprefix>mul{q}\t%2"
7872   [(set_attr "type" "imul")
7873    (set_attr "length_immediate" "0")
7874    (set (attr "athlon_decode")
7875      (if_then_else (eq_attr "cpu" "athlon")
7876         (const_string "vector")
7877         (const_string "double")))
7878    (set_attr "amdfam10_decode" "double")
7879    (set_attr "mode" "DI")])
7881 (define_insn "*<s>mulsi3_highpart_1"
7882   [(set (match_operand:SI 0 "register_operand" "=d")
7883         (truncate:SI
7884           (lshiftrt:DI
7885             (mult:DI
7886               (any_extend:DI
7887                 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7888               (any_extend:DI
7889                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7890             (const_int 32))))
7891    (clobber (match_scratch:SI 3 "=1"))
7892    (clobber (reg:CC FLAGS_REG))]
7893   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7894   "<sgnprefix>mul{l}\t%2"
7895   [(set_attr "type" "imul")
7896    (set_attr "length_immediate" "0")
7897    (set (attr "athlon_decode")
7898      (if_then_else (eq_attr "cpu" "athlon")
7899         (const_string "vector")
7900         (const_string "double")))
7901    (set_attr "amdfam10_decode" "double")
7902    (set_attr "mode" "SI")])
7904 (define_insn "*<s>mulsi3_highpart_zext"
7905   [(set (match_operand:DI 0 "register_operand" "=d")
7906         (zero_extend:DI (truncate:SI
7907           (lshiftrt:DI
7908             (mult:DI (any_extend:DI
7909                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7910                      (any_extend:DI
7911                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7912             (const_int 32)))))
7913    (clobber (match_scratch:SI 3 "=1"))
7914    (clobber (reg:CC FLAGS_REG))]
7915   "TARGET_64BIT
7916    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7917   "<sgnprefix>mul{l}\t%2"
7918   [(set_attr "type" "imul")
7919    (set_attr "length_immediate" "0")
7920    (set (attr "athlon_decode")
7921      (if_then_else (eq_attr "cpu" "athlon")
7922         (const_string "vector")
7923         (const_string "double")))
7924    (set_attr "amdfam10_decode" "double")
7925    (set_attr "mode" "SI")])
7927 ;; The patterns that match these are at the end of this file.
7929 (define_expand "mulxf3"
7930   [(set (match_operand:XF 0 "register_operand" "")
7931         (mult:XF (match_operand:XF 1 "register_operand" "")
7932                  (match_operand:XF 2 "register_operand" "")))]
7933   "TARGET_80387"
7934   "")
7936 (define_expand "mul<mode>3"
7937   [(set (match_operand:MODEF 0 "register_operand" "")
7938         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7939                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7940   "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7941     || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7942   "")
7944 ;; Divide instructions
7946 (define_insn "<u>divqi3"
7947   [(set (match_operand:QI 0 "register_operand" "=a")
7948         (any_div:QI
7949           (match_operand:HI 1 "register_operand" "0")
7950           (match_operand:QI 2 "nonimmediate_operand" "qm")))
7951    (clobber (reg:CC FLAGS_REG))]
7952   "TARGET_QIMODE_MATH"
7953   "<sgnprefix>div{b}\t%2"
7954   [(set_attr "type" "idiv")
7955    (set_attr "mode" "QI")])
7957 ;; The patterns that match these are at the end of this file.
7959 (define_expand "divxf3"
7960   [(set (match_operand:XF 0 "register_operand" "")
7961         (div:XF (match_operand:XF 1 "register_operand" "")
7962                 (match_operand:XF 2 "register_operand" "")))]
7963   "TARGET_80387"
7964   "")
7966 (define_expand "divdf3"
7967   [(set (match_operand:DF 0 "register_operand" "")
7968         (div:DF (match_operand:DF 1 "register_operand" "")
7969                 (match_operand:DF 2 "nonimmediate_operand" "")))]
7970    "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7971     || (TARGET_SSE2 && TARGET_SSE_MATH)"
7972    "")
7974 (define_expand "divsf3"
7975   [(set (match_operand:SF 0 "register_operand" "")
7976         (div:SF (match_operand:SF 1 "register_operand" "")
7977                 (match_operand:SF 2 "nonimmediate_operand" "")))]
7978   "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7979     || TARGET_SSE_MATH"
7981   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7982       && flag_finite_math_only && !flag_trapping_math
7983       && flag_unsafe_math_optimizations)
7984     {
7985       ix86_emit_swdivsf (operands[0], operands[1],
7986                          operands[2], SFmode);
7987       DONE;
7988     }
7991 ;; Divmod instructions.
7993 (define_expand "divmod<mode>4"
7994   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7995                    (div:SWIM248
7996                      (match_operand:SWIM248 1 "register_operand" "")
7997                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7998               (set (match_operand:SWIM248 3 "register_operand" "")
7999                    (mod:SWIM248 (match_dup 1) (match_dup 2)))
8000               (clobber (reg:CC FLAGS_REG))])]
8001   ""
8002   "")
8004 (define_insn_and_split "*divmod<mode>4"
8005   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8006         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8007                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8008    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8009         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8010    (clobber (reg:CC FLAGS_REG))]
8011   ""
8012   "#"
8013   "&& reload_completed"
8014   [(parallel [(set (match_dup 1)
8015                    (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8016               (clobber (reg:CC FLAGS_REG))])
8017    (parallel [(set (match_dup 0)
8018                    (div:SWIM248 (match_dup 2) (match_dup 3)))
8019               (set (match_dup 1)
8020                    (mod:SWIM248 (match_dup 2) (match_dup 3)))
8021               (use (match_dup 1))
8022               (clobber (reg:CC FLAGS_REG))])]
8024   operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
8026   if (<MODE>mode != HImode
8027       && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8028     operands[4] = operands[2];
8029   else
8030     {
8031       /* Avoid use of cltd in favor of a mov+shift.  */
8032       emit_move_insn (operands[1], operands[2]);
8033       operands[4] = operands[1];
8034     }
8036   [(set_attr "type" "multi")
8037    (set_attr "mode" "<MODE>")])
8039 (define_insn "*divmod<mode>4_noext"
8040   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8041         (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8042                     (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8043    (set (match_operand:SWIM248 1 "register_operand" "=d")
8044         (mod:SWIM248 (match_dup 2) (match_dup 3)))
8045    (use (match_operand:SWIM248 4 "register_operand" "1"))
8046    (clobber (reg:CC FLAGS_REG))]
8047   ""
8048   "idiv{<imodesuffix>}\t%3"
8049   [(set_attr "type" "idiv")
8050    (set_attr "mode" "<MODE>")])
8052 (define_expand "udivmod<mode>4"
8053   [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8054                    (udiv:SWIM248
8055                      (match_operand:SWIM248 1 "register_operand" "")
8056                      (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8057               (set (match_operand:SWIM248 3 "register_operand" "")
8058                    (umod:SWIM248 (match_dup 1) (match_dup 2)))
8059               (clobber (reg:CC FLAGS_REG))])]
8060   ""
8061   "")
8063 (define_insn_and_split "*udivmod<mode>4"
8064   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8065         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8066                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8067    (set (match_operand:SWIM248 1 "register_operand" "=&d")
8068         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8069    (clobber (reg:CC FLAGS_REG))]
8070   ""
8071   "#"
8072   "&& reload_completed"
8073   [(set (match_dup 1) (const_int 0))
8074    (parallel [(set (match_dup 0)
8075                    (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8076               (set (match_dup 1)
8077                    (umod:SWIM248 (match_dup 2) (match_dup 3)))
8078               (use (match_dup 1))
8079               (clobber (reg:CC FLAGS_REG))])]
8080   ""
8081   [(set_attr "type" "multi")
8082    (set_attr "mode" "<MODE>")])
8084 (define_insn "*udivmod<mode>4_noext"
8085   [(set (match_operand:SWIM248 0 "register_operand" "=a")
8086         (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8087                       (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8088    (set (match_operand:SWIM248 1 "register_operand" "=d")
8089         (umod:SWIM248 (match_dup 2) (match_dup 3)))
8090    (use (match_operand:SWIM248 4 "register_operand" "1"))
8091    (clobber (reg:CC FLAGS_REG))]
8092   ""
8093   "div{<imodesuffix>}\t%3"
8094   [(set_attr "type" "idiv")
8095    (set_attr "mode" "<MODE>")])
8097 ;; We cannot use div/idiv for double division, because it causes
8098 ;; "division by zero" on the overflow and that's not what we expect
8099 ;; from truncate.  Because true (non truncating) double division is
8100 ;; never generated, we can't create this insn anyway.
8102 ;(define_insn ""
8103 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8104 ;       (truncate:SI
8105 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8106 ;                  (zero_extend:DI
8107 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8108 ;   (set (match_operand:SI 3 "register_operand" "=d")
8109 ;       (truncate:SI
8110 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8111 ;   (clobber (reg:CC FLAGS_REG))]
8112 ;  ""
8113 ;  "div{l}\t{%2, %0|%0, %2}"
8114 ;  [(set_attr "type" "idiv")])
8116 ;;- Logical AND instructions
8118 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8119 ;; Note that this excludes ah.
8121 (define_expand "testsi_ccno_1"
8122   [(set (reg:CCNO FLAGS_REG)
8123         (compare:CCNO
8124           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8125                   (match_operand:SI 1 "nonmemory_operand" ""))
8126           (const_int 0)))]
8127   ""
8128   "")
8130 (define_expand "testqi_ccz_1"
8131   [(set (reg:CCZ FLAGS_REG)
8132         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8133                              (match_operand:QI 1 "nonmemory_operand" ""))
8134                  (const_int 0)))]
8135   ""
8136   "")
8138 (define_insn "*testdi_1"
8139   [(set (reg FLAGS_REG)
8140         (compare
8141          (and:DI
8142           (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8143           (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8144          (const_int 0)))]
8145   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8146    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8147   "@
8148    test{l}\t{%k1, %k0|%k0, %k1}
8149    test{l}\t{%k1, %k0|%k0, %k1}
8150    test{q}\t{%1, %0|%0, %1}
8151    test{q}\t{%1, %0|%0, %1}
8152    test{q}\t{%1, %0|%0, %1}"
8153   [(set_attr "type" "test")
8154    (set_attr "modrm" "0,1,0,1,1")
8155    (set_attr "mode" "SI,SI,DI,DI,DI")])
8157 (define_insn "*testqi_1_maybe_si"
8158   [(set (reg FLAGS_REG)
8159         (compare
8160           (and:QI
8161             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8162             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8163           (const_int 0)))]
8164    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8165     && ix86_match_ccmode (insn,
8166                          CONST_INT_P (operands[1])
8167                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8169   if (which_alternative == 3)
8170     {
8171       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8172         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8173       return "test{l}\t{%1, %k0|%k0, %1}";
8174     }
8175   return "test{b}\t{%1, %0|%0, %1}";
8177   [(set_attr "type" "test")
8178    (set_attr "modrm" "0,1,1,1")
8179    (set_attr "mode" "QI,QI,QI,SI")
8180    (set_attr "pent_pair" "uv,np,uv,np")])
8182 (define_insn "*test<mode>_1"
8183   [(set (reg FLAGS_REG)
8184         (compare
8185          (and:SWI124
8186           (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8187           (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8188          (const_int 0)))]
8189   "ix86_match_ccmode (insn, CCNOmode)
8190    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8191   "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8192   [(set_attr "type" "test")
8193    (set_attr "modrm" "0,1,1")
8194    (set_attr "mode" "<MODE>")
8195    (set_attr "pent_pair" "uv,np,uv")])
8197 (define_expand "testqi_ext_ccno_0"
8198   [(set (reg:CCNO FLAGS_REG)
8199         (compare:CCNO
8200           (and:SI
8201             (zero_extract:SI
8202               (match_operand 0 "ext_register_operand" "")
8203               (const_int 8)
8204               (const_int 8))
8205             (match_operand 1 "const_int_operand" ""))
8206           (const_int 0)))]
8207   ""
8208   "")
8210 (define_insn "*testqi_ext_0"
8211   [(set (reg FLAGS_REG)
8212         (compare
8213           (and:SI
8214             (zero_extract:SI
8215               (match_operand 0 "ext_register_operand" "Q")
8216               (const_int 8)
8217               (const_int 8))
8218             (match_operand 1 "const_int_operand" "n"))
8219           (const_int 0)))]
8220   "ix86_match_ccmode (insn, CCNOmode)"
8221   "test{b}\t{%1, %h0|%h0, %1}"
8222   [(set_attr "type" "test")
8223    (set_attr "mode" "QI")
8224    (set_attr "length_immediate" "1")
8225    (set_attr "modrm" "1")
8226    (set_attr "pent_pair" "np")])
8228 (define_insn "*testqi_ext_1_rex64"
8229   [(set (reg FLAGS_REG)
8230         (compare
8231           (and:SI
8232             (zero_extract:SI
8233               (match_operand 0 "ext_register_operand" "Q")
8234               (const_int 8)
8235               (const_int 8))
8236             (zero_extend:SI
8237               (match_operand:QI 1 "register_operand" "Q")))
8238           (const_int 0)))]
8239   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8240   "test{b}\t{%1, %h0|%h0, %1}"
8241   [(set_attr "type" "test")
8242    (set_attr "mode" "QI")])
8244 (define_insn "*testqi_ext_1"
8245   [(set (reg FLAGS_REG)
8246         (compare
8247           (and:SI
8248             (zero_extract:SI
8249               (match_operand 0 "ext_register_operand" "Q")
8250               (const_int 8)
8251               (const_int 8))
8252             (zero_extend:SI
8253               (match_operand:QI 1 "general_operand" "Qm")))
8254           (const_int 0)))]
8255   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8256   "test{b}\t{%1, %h0|%h0, %1}"
8257   [(set_attr "type" "test")
8258    (set_attr "mode" "QI")])
8260 (define_insn "*testqi_ext_2"
8261   [(set (reg FLAGS_REG)
8262         (compare
8263           (and:SI
8264             (zero_extract:SI
8265               (match_operand 0 "ext_register_operand" "Q")
8266               (const_int 8)
8267               (const_int 8))
8268             (zero_extract:SI
8269               (match_operand 1 "ext_register_operand" "Q")
8270               (const_int 8)
8271               (const_int 8)))
8272           (const_int 0)))]
8273   "ix86_match_ccmode (insn, CCNOmode)"
8274   "test{b}\t{%h1, %h0|%h0, %h1}"
8275   [(set_attr "type" "test")
8276    (set_attr "mode" "QI")])
8278 (define_insn "*testqi_ext_3_rex64"
8279   [(set (reg FLAGS_REG)
8280         (compare (zero_extract:DI
8281                    (match_operand 0 "nonimmediate_operand" "rm")
8282                    (match_operand:DI 1 "const_int_operand" "")
8283                    (match_operand:DI 2 "const_int_operand" ""))
8284                  (const_int 0)))]
8285   "TARGET_64BIT
8286    && ix86_match_ccmode (insn, CCNOmode)
8287    && INTVAL (operands[1]) > 0
8288    && INTVAL (operands[2]) >= 0
8289    /* Ensure that resulting mask is zero or sign extended operand.  */
8290    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8291        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8292            && INTVAL (operands[1]) > 32))
8293    && (GET_MODE (operands[0]) == SImode
8294        || GET_MODE (operands[0]) == DImode
8295        || GET_MODE (operands[0]) == HImode
8296        || GET_MODE (operands[0]) == QImode)"
8297   "#")
8299 ;; Combine likes to form bit extractions for some tests.  Humor it.
8300 (define_insn "*testqi_ext_3"
8301   [(set (reg FLAGS_REG)
8302         (compare (zero_extract:SI
8303                    (match_operand 0 "nonimmediate_operand" "rm")
8304                    (match_operand:SI 1 "const_int_operand" "")
8305                    (match_operand:SI 2 "const_int_operand" ""))
8306                  (const_int 0)))]
8307   "ix86_match_ccmode (insn, CCNOmode)
8308    && INTVAL (operands[1]) > 0
8309    && INTVAL (operands[2]) >= 0
8310    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8311    && (GET_MODE (operands[0]) == SImode
8312        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8313        || GET_MODE (operands[0]) == HImode
8314        || GET_MODE (operands[0]) == QImode)"
8315   "#")
8317 (define_split
8318   [(set (match_operand 0 "flags_reg_operand" "")
8319         (match_operator 1 "compare_operator"
8320           [(zero_extract
8321              (match_operand 2 "nonimmediate_operand" "")
8322              (match_operand 3 "const_int_operand" "")
8323              (match_operand 4 "const_int_operand" ""))
8324            (const_int 0)]))]
8325   "ix86_match_ccmode (insn, CCNOmode)"
8326   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8328   rtx val = operands[2];
8329   HOST_WIDE_INT len = INTVAL (operands[3]);
8330   HOST_WIDE_INT pos = INTVAL (operands[4]);
8331   HOST_WIDE_INT mask;
8332   enum machine_mode mode, submode;
8334   mode = GET_MODE (val);
8335   if (MEM_P (val))
8336     {
8337       /* ??? Combine likes to put non-volatile mem extractions in QImode
8338          no matter the size of the test.  So find a mode that works.  */
8339       if (! MEM_VOLATILE_P (val))
8340         {
8341           mode = smallest_mode_for_size (pos + len, MODE_INT);
8342           val = adjust_address (val, mode, 0);
8343         }
8344     }
8345   else if (GET_CODE (val) == SUBREG
8346            && (submode = GET_MODE (SUBREG_REG (val)),
8347                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8348            && pos + len <= GET_MODE_BITSIZE (submode)
8349            && GET_MODE_CLASS (submode) == MODE_INT)
8350     {
8351       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8352       mode = submode;
8353       val = SUBREG_REG (val);
8354     }
8355   else if (mode == HImode && pos + len <= 8)
8356     {
8357       /* Small HImode tests can be converted to QImode.  */
8358       mode = QImode;
8359       val = gen_lowpart (QImode, val);
8360     }
8362   if (len == HOST_BITS_PER_WIDE_INT)
8363     mask = -1;
8364   else
8365     mask = ((HOST_WIDE_INT)1 << len) - 1;
8366   mask <<= pos;
8368   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8371 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8372 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8373 ;; this is relatively important trick.
8374 ;; Do the conversion only post-reload to avoid limiting of the register class
8375 ;; to QI regs.
8376 (define_split
8377   [(set (match_operand 0 "flags_reg_operand" "")
8378         (match_operator 1 "compare_operator"
8379           [(and (match_operand 2 "register_operand" "")
8380                 (match_operand 3 "const_int_operand" ""))
8381            (const_int 0)]))]
8382    "reload_completed
8383     && QI_REG_P (operands[2])
8384     && GET_MODE (operands[2]) != QImode
8385     && ((ix86_match_ccmode (insn, CCZmode)
8386          && !(INTVAL (operands[3]) & ~(255 << 8)))
8387         || (ix86_match_ccmode (insn, CCNOmode)
8388             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8389   [(set (match_dup 0)
8390         (match_op_dup 1
8391           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8392                    (match_dup 3))
8393            (const_int 0)]))]
8394   "operands[2] = gen_lowpart (SImode, operands[2]);
8395    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8397 (define_split
8398   [(set (match_operand 0 "flags_reg_operand" "")
8399         (match_operator 1 "compare_operator"
8400           [(and (match_operand 2 "nonimmediate_operand" "")
8401                 (match_operand 3 "const_int_operand" ""))
8402            (const_int 0)]))]
8403    "reload_completed
8404     && GET_MODE (operands[2]) != QImode
8405     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8406     && ((ix86_match_ccmode (insn, CCZmode)
8407          && !(INTVAL (operands[3]) & ~255))
8408         || (ix86_match_ccmode (insn, CCNOmode)
8409             && !(INTVAL (operands[3]) & ~127)))"
8410   [(set (match_dup 0)
8411         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8412                          (const_int 0)]))]
8413   "operands[2] = gen_lowpart (QImode, operands[2]);
8414    operands[3] = gen_lowpart (QImode, operands[3]);")
8416 ;; %%% This used to optimize known byte-wide and operations to memory,
8417 ;; and sometimes to QImode registers.  If this is considered useful,
8418 ;; it should be done with splitters.
8420 (define_expand "and<mode>3"
8421   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8422         (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8423                   (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8424   ""
8425   "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8427 (define_insn "*anddi_1"
8428   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8429         (and:DI
8430          (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8431          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8432    (clobber (reg:CC FLAGS_REG))]
8433   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8435   switch (get_attr_type (insn))
8436     {
8437     case TYPE_IMOVX:
8438       {
8439         enum machine_mode mode;
8441         gcc_assert (CONST_INT_P (operands[2]));
8442         if (INTVAL (operands[2]) == 0xff)
8443           mode = QImode;
8444         else
8445           {
8446             gcc_assert (INTVAL (operands[2]) == 0xffff);
8447             mode = HImode;
8448           }
8450         operands[1] = gen_lowpart (mode, operands[1]);
8451         if (mode == QImode)
8452           return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8453         else
8454           return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8455       }
8457     default:
8458       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8459       if (get_attr_mode (insn) == MODE_SI)
8460         return "and{l}\t{%k2, %k0|%k0, %k2}";
8461       else
8462         return "and{q}\t{%2, %0|%0, %2}";
8463     }
8465   [(set_attr "type" "alu,alu,alu,imovx")
8466    (set_attr "length_immediate" "*,*,*,0")
8467    (set (attr "prefix_rex")
8468      (if_then_else
8469        (and (eq_attr "type" "imovx")
8470             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8471                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8472        (const_string "1")
8473        (const_string "*")))
8474    (set_attr "mode" "SI,DI,DI,SI")])
8476 (define_insn "*andsi_1"
8477   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8478         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8479                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8480    (clobber (reg:CC FLAGS_REG))]
8481   "ix86_binary_operator_ok (AND, SImode, operands)"
8483   switch (get_attr_type (insn))
8484     {
8485     case TYPE_IMOVX:
8486       {
8487         enum machine_mode mode;
8489         gcc_assert (CONST_INT_P (operands[2]));
8490         if (INTVAL (operands[2]) == 0xff)
8491           mode = QImode;
8492         else
8493           {
8494             gcc_assert (INTVAL (operands[2]) == 0xffff);
8495             mode = HImode;
8496           }
8498         operands[1] = gen_lowpart (mode, operands[1]);
8499         if (mode == QImode)
8500           return "movz{bl|x}\t{%1, %0|%0, %1}";
8501         else
8502           return "movz{wl|x}\t{%1, %0|%0, %1}";
8503       }
8505     default:
8506       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8507       return "and{l}\t{%2, %0|%0, %2}";
8508     }
8510   [(set_attr "type" "alu,alu,imovx")
8511    (set (attr "prefix_rex")
8512      (if_then_else
8513        (and (eq_attr "type" "imovx")
8514             (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8515                  (match_operand 1 "ext_QIreg_nomode_operand" "")))
8516        (const_string "1")
8517        (const_string "*")))
8518    (set_attr "length_immediate" "*,*,0")
8519    (set_attr "mode" "SI")])
8521 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8522 (define_insn "*andsi_1_zext"
8523   [(set (match_operand:DI 0 "register_operand" "=r")
8524         (zero_extend:DI
8525           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8526                   (match_operand:SI 2 "general_operand" "g"))))
8527    (clobber (reg:CC FLAGS_REG))]
8528   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8529   "and{l}\t{%2, %k0|%k0, %2}"
8530   [(set_attr "type" "alu")
8531    (set_attr "mode" "SI")])
8533 (define_insn "*andhi_1"
8534   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8535         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8536                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8537    (clobber (reg:CC FLAGS_REG))]
8538   "ix86_binary_operator_ok (AND, HImode, operands)"
8540   switch (get_attr_type (insn))
8541     {
8542     case TYPE_IMOVX:
8543       gcc_assert (CONST_INT_P (operands[2]));
8544       gcc_assert (INTVAL (operands[2]) == 0xff);
8545       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8547     default:
8548       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8550       return "and{w}\t{%2, %0|%0, %2}";
8551     }
8553   [(set_attr "type" "alu,alu,imovx")
8554    (set_attr "length_immediate" "*,*,0")
8555    (set (attr "prefix_rex")
8556      (if_then_else
8557        (and (eq_attr "type" "imovx")
8558             (match_operand 1 "ext_QIreg_nomode_operand" ""))
8559        (const_string "1")
8560        (const_string "*")))
8561    (set_attr "mode" "HI,HI,SI")])
8563 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8564 (define_insn "*andqi_1"
8565   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8566         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8567                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8568    (clobber (reg:CC FLAGS_REG))]
8569   "ix86_binary_operator_ok (AND, QImode, operands)"
8570   "@
8571    and{b}\t{%2, %0|%0, %2}
8572    and{b}\t{%2, %0|%0, %2}
8573    and{l}\t{%k2, %k0|%k0, %k2}"
8574   [(set_attr "type" "alu")
8575    (set_attr "mode" "QI,QI,SI")])
8577 (define_insn "*andqi_1_slp"
8578   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8579         (and:QI (match_dup 0)
8580                 (match_operand:QI 1 "general_operand" "qn,qmn")))
8581    (clobber (reg:CC FLAGS_REG))]
8582   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8583    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8584   "and{b}\t{%1, %0|%0, %1}"
8585   [(set_attr "type" "alu1")
8586    (set_attr "mode" "QI")])
8588 (define_split
8589   [(set (match_operand 0 "register_operand" "")
8590         (and (match_dup 0)
8591              (const_int -65536)))
8592    (clobber (reg:CC FLAGS_REG))]
8593   "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8594     || optimize_function_for_size_p (cfun)"
8595   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8596   "operands[1] = gen_lowpart (HImode, operands[0]);")
8598 (define_split
8599   [(set (match_operand 0 "ext_register_operand" "")
8600         (and (match_dup 0)
8601              (const_int -256)))
8602    (clobber (reg:CC FLAGS_REG))]
8603   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8604    && reload_completed"
8605   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8606   "operands[1] = gen_lowpart (QImode, operands[0]);")
8608 (define_split
8609   [(set (match_operand 0 "ext_register_operand" "")
8610         (and (match_dup 0)
8611              (const_int -65281)))
8612    (clobber (reg:CC FLAGS_REG))]
8613   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8614    && reload_completed"
8615   [(parallel [(set (zero_extract:SI (match_dup 0)
8616                                     (const_int 8)
8617                                     (const_int 8))
8618                    (xor:SI
8619                      (zero_extract:SI (match_dup 0)
8620                                       (const_int 8)
8621                                       (const_int 8))
8622                      (zero_extract:SI (match_dup 0)
8623                                       (const_int 8)
8624                                       (const_int 8))))
8625               (clobber (reg:CC FLAGS_REG))])]
8626   "operands[0] = gen_lowpart (SImode, operands[0]);")
8628 (define_insn "*anddi_2"
8629   [(set (reg FLAGS_REG)
8630         (compare
8631          (and:DI
8632           (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8633           (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8634          (const_int 0)))
8635    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8636         (and:DI (match_dup 1) (match_dup 2)))]
8637   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8638    && ix86_binary_operator_ok (AND, DImode, operands)"
8639   "@
8640    and{l}\t{%k2, %k0|%k0, %k2}
8641    and{q}\t{%2, %0|%0, %2}
8642    and{q}\t{%2, %0|%0, %2}"
8643   [(set_attr "type" "alu")
8644    (set_attr "mode" "SI,DI,DI")])
8646 (define_insn "*andqi_2_maybe_si"
8647   [(set (reg FLAGS_REG)
8648         (compare (and:QI
8649                   (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8650                   (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8651                  (const_int 0)))
8652    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8653         (and:QI (match_dup 1) (match_dup 2)))]
8654   "ix86_binary_operator_ok (AND, QImode, operands)
8655    && ix86_match_ccmode (insn,
8656                          CONST_INT_P (operands[2])
8657                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8659   if (which_alternative == 2)
8660     {
8661       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8662         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8663       return "and{l}\t{%2, %k0|%k0, %2}";
8664     }
8665   return "and{b}\t{%2, %0|%0, %2}";
8667   [(set_attr "type" "alu")
8668    (set_attr "mode" "QI,QI,SI")])
8670 (define_insn "*and<mode>_2"
8671   [(set (reg FLAGS_REG)
8672         (compare (and:SWI124
8673                   (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8674                   (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8675                  (const_int 0)))
8676    (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8677         (and:SWI124 (match_dup 1) (match_dup 2)))]
8678   "ix86_match_ccmode (insn, CCNOmode)
8679    && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8680   "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8681   [(set_attr "type" "alu")
8682    (set_attr "mode" "<MODE>")])
8684 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8685 (define_insn "*andsi_2_zext"
8686   [(set (reg FLAGS_REG)
8687         (compare (and:SI
8688                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8689                   (match_operand:SI 2 "general_operand" "g"))
8690                  (const_int 0)))
8691    (set (match_operand:DI 0 "register_operand" "=r")
8692         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8693   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8694    && ix86_binary_operator_ok (AND, SImode, operands)"
8695   "and{l}\t{%2, %k0|%k0, %2}"
8696   [(set_attr "type" "alu")
8697    (set_attr "mode" "SI")])
8699 (define_insn "*andqi_2_slp"
8700   [(set (reg FLAGS_REG)
8701         (compare (and:QI
8702                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8703                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8704                  (const_int 0)))
8705    (set (strict_low_part (match_dup 0))
8706         (and:QI (match_dup 0) (match_dup 1)))]
8707   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8708    && ix86_match_ccmode (insn, CCNOmode)
8709    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8710   "and{b}\t{%1, %0|%0, %1}"
8711   [(set_attr "type" "alu1")
8712    (set_attr "mode" "QI")])
8714 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8715 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
8716 ;; for a QImode operand, which of course failed.
8717 (define_insn "andqi_ext_0"
8718   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8719                          (const_int 8)
8720                          (const_int 8))
8721         (and:SI
8722           (zero_extract:SI
8723             (match_operand 1 "ext_register_operand" "0")
8724             (const_int 8)
8725             (const_int 8))
8726           (match_operand 2 "const_int_operand" "n")))
8727    (clobber (reg:CC FLAGS_REG))]
8728   ""
8729   "and{b}\t{%2, %h0|%h0, %2}"
8730   [(set_attr "type" "alu")
8731    (set_attr "length_immediate" "1")
8732    (set_attr "modrm" "1")
8733    (set_attr "mode" "QI")])
8735 ;; Generated by peephole translating test to and.  This shows up
8736 ;; often in fp comparisons.
8737 (define_insn "*andqi_ext_0_cc"
8738   [(set (reg FLAGS_REG)
8739         (compare
8740           (and:SI
8741             (zero_extract:SI
8742               (match_operand 1 "ext_register_operand" "0")
8743               (const_int 8)
8744               (const_int 8))
8745             (match_operand 2 "const_int_operand" "n"))
8746           (const_int 0)))
8747    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8748                          (const_int 8)
8749                          (const_int 8))
8750         (and:SI
8751           (zero_extract:SI
8752             (match_dup 1)
8753             (const_int 8)
8754             (const_int 8))
8755           (match_dup 2)))]
8756   "ix86_match_ccmode (insn, CCNOmode)"
8757   "and{b}\t{%2, %h0|%h0, %2}"
8758   [(set_attr "type" "alu")
8759    (set_attr "length_immediate" "1")
8760    (set_attr "modrm" "1")
8761    (set_attr "mode" "QI")])
8763 (define_insn "*andqi_ext_1_rex64"
8764   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8765                          (const_int 8)
8766                          (const_int 8))
8767         (and:SI
8768           (zero_extract:SI
8769             (match_operand 1 "ext_register_operand" "0")
8770             (const_int 8)
8771             (const_int 8))
8772           (zero_extend:SI
8773             (match_operand 2 "ext_register_operand" "Q"))))
8774    (clobber (reg:CC FLAGS_REG))]
8775   "TARGET_64BIT"
8776   "and{b}\t{%2, %h0|%h0, %2}"
8777   [(set_attr "type" "alu")
8778    (set_attr "length_immediate" "0")
8779    (set_attr "mode" "QI")])
8781 (define_insn "*andqi_ext_1"
8782   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8783                          (const_int 8)
8784                          (const_int 8))
8785         (and:SI
8786           (zero_extract:SI
8787             (match_operand 1 "ext_register_operand" "0")
8788             (const_int 8)
8789             (const_int 8))
8790           (zero_extend:SI
8791             (match_operand:QI 2 "general_operand" "Qm"))))
8792    (clobber (reg:CC FLAGS_REG))]
8793   "!TARGET_64BIT"
8794   "and{b}\t{%2, %h0|%h0, %2}"
8795   [(set_attr "type" "alu")
8796    (set_attr "length_immediate" "0")
8797    (set_attr "mode" "QI")])
8799 (define_insn "*andqi_ext_2"
8800   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8801                          (const_int 8)
8802                          (const_int 8))
8803         (and:SI
8804           (zero_extract:SI
8805             (match_operand 1 "ext_register_operand" "%0")
8806             (const_int 8)
8807             (const_int 8))
8808           (zero_extract:SI
8809             (match_operand 2 "ext_register_operand" "Q")
8810             (const_int 8)
8811             (const_int 8))))
8812    (clobber (reg:CC FLAGS_REG))]
8813   ""
8814   "and{b}\t{%h2, %h0|%h0, %h2}"
8815   [(set_attr "type" "alu")
8816    (set_attr "length_immediate" "0")
8817    (set_attr "mode" "QI")])
8819 ;; Convert wide AND instructions with immediate operand to shorter QImode
8820 ;; equivalents when possible.
8821 ;; Don't do the splitting with memory operands, since it introduces risk
8822 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
8823 ;; for size, but that can (should?) be handled by generic code instead.
8824 (define_split
8825   [(set (match_operand 0 "register_operand" "")
8826         (and (match_operand 1 "register_operand" "")
8827              (match_operand 2 "const_int_operand" "")))
8828    (clobber (reg:CC FLAGS_REG))]
8829    "reload_completed
8830     && QI_REG_P (operands[0])
8831     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8832     && !(~INTVAL (operands[2]) & ~(255 << 8))
8833     && GET_MODE (operands[0]) != QImode"
8834   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8835                    (and:SI (zero_extract:SI (match_dup 1)
8836                                             (const_int 8) (const_int 8))
8837                            (match_dup 2)))
8838               (clobber (reg:CC FLAGS_REG))])]
8839   "operands[0] = gen_lowpart (SImode, operands[0]);
8840    operands[1] = gen_lowpart (SImode, operands[1]);
8841    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8843 ;; Since AND can be encoded with sign extended immediate, this is only
8844 ;; profitable when 7th bit is not set.
8845 (define_split
8846   [(set (match_operand 0 "register_operand" "")
8847         (and (match_operand 1 "general_operand" "")
8848              (match_operand 2 "const_int_operand" "")))
8849    (clobber (reg:CC FLAGS_REG))]
8850    "reload_completed
8851     && ANY_QI_REG_P (operands[0])
8852     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8853     && !(~INTVAL (operands[2]) & ~255)
8854     && !(INTVAL (operands[2]) & 128)
8855     && GET_MODE (operands[0]) != QImode"
8856   [(parallel [(set (strict_low_part (match_dup 0))
8857                    (and:QI (match_dup 1)
8858                            (match_dup 2)))
8859               (clobber (reg:CC FLAGS_REG))])]
8860   "operands[0] = gen_lowpart (QImode, operands[0]);
8861    operands[1] = gen_lowpart (QImode, operands[1]);
8862    operands[2] = gen_lowpart (QImode, operands[2]);")
8864 ;; Logical inclusive and exclusive OR instructions
8866 ;; %%% This used to optimize known byte-wide and operations to memory.
8867 ;; If this is considered useful, it should be done with splitters.
8869 (define_expand "<code><mode>3"
8870   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8871         (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8872                      (match_operand:SWIM 2 "<general_operand>" "")))]
8873   ""
8874   "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8876 (define_insn "*<code><mode>_1"
8877   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8878         (any_or:SWI248
8879          (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8880          (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8881    (clobber (reg:CC FLAGS_REG))]
8882   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8883   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8884   [(set_attr "type" "alu")
8885    (set_attr "mode" "<MODE>")])
8887 ;; %%% Potential partial reg stall on alternative 2.  What to do?
8888 (define_insn "*<code>qi_1"
8889   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8890         (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8891                    (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8892    (clobber (reg:CC FLAGS_REG))]
8893   "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8894   "@
8895    <logicprefix>{b}\t{%2, %0|%0, %2}
8896    <logicprefix>{b}\t{%2, %0|%0, %2}
8897    <logicprefix>{l}\t{%k2, %k0|%k0, %k2}"
8898   [(set_attr "type" "alu")
8899    (set_attr "mode" "QI,QI,SI")])
8901 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8902 (define_insn "*<code>si_1_zext"
8903   [(set (match_operand:DI 0 "register_operand" "=r")
8904         (zero_extend:DI
8905          (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8906                     (match_operand:SI 2 "general_operand" "g"))))
8907    (clobber (reg:CC FLAGS_REG))]
8908   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8909   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8910   [(set_attr "type" "alu")
8911    (set_attr "mode" "SI")])
8913 (define_insn "*<code>si_1_zext_imm"
8914   [(set (match_operand:DI 0 "register_operand" "=r")
8915         (any_or:DI
8916          (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8917          (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8918    (clobber (reg:CC FLAGS_REG))]
8919   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8920   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8921   [(set_attr "type" "alu")
8922    (set_attr "mode" "SI")])
8924 (define_insn "*<code>qi_1_slp"
8925   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8926         (any_or:QI (match_dup 0)
8927                    (match_operand:QI 1 "general_operand" "qmn,qn")))
8928    (clobber (reg:CC FLAGS_REG))]
8929   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8930    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8931   "<logicprefix>{b}\t{%1, %0|%0, %1}"
8932   [(set_attr "type" "alu1")
8933    (set_attr "mode" "QI")])
8935 (define_insn "*<code><mode>_2"
8936   [(set (reg FLAGS_REG)
8937         (compare (any_or:SWI
8938                   (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8939                   (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8940                  (const_int 0)))
8941    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8942         (any_or:SWI (match_dup 1) (match_dup 2)))]
8943   "ix86_match_ccmode (insn, CCNOmode)
8944    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8945   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8946   [(set_attr "type" "alu")
8947    (set_attr "mode" "<MODE>")])
8949 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8950 ;; ??? Special case for immediate operand is missing - it is tricky.
8951 (define_insn "*<code>si_2_zext"
8952   [(set (reg FLAGS_REG)
8953         (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8954                             (match_operand:SI 2 "general_operand" "g"))
8955                  (const_int 0)))
8956    (set (match_operand:DI 0 "register_operand" "=r")
8957         (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8958   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8959    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8960   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8961   [(set_attr "type" "alu")
8962    (set_attr "mode" "SI")])
8964 (define_insn "*<code>si_2_zext_imm"
8965   [(set (reg FLAGS_REG)
8966         (compare (any_or:SI
8967                   (match_operand:SI 1 "nonimmediate_operand" "%0")
8968                   (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8969                  (const_int 0)))
8970    (set (match_operand:DI 0 "register_operand" "=r")
8971         (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8972   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8973    && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8974   "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8975   [(set_attr "type" "alu")
8976    (set_attr "mode" "SI")])
8978 (define_insn "*<code>qi_2_slp"
8979   [(set (reg FLAGS_REG)
8980         (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8981                             (match_operand:QI 1 "general_operand" "qmn,qn"))
8982                  (const_int 0)))
8983    (set (strict_low_part (match_dup 0))
8984         (any_or:QI (match_dup 0) (match_dup 1)))]
8985   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8986    && ix86_match_ccmode (insn, CCNOmode)
8987    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8988   "<logicprefix>{b}\t{%1, %0|%0, %1}"
8989   [(set_attr "type" "alu1")
8990    (set_attr "mode" "QI")])
8992 (define_insn "*<code><mode>_3"
8993   [(set (reg FLAGS_REG)
8994         (compare (any_or:SWI
8995                   (match_operand:SWI 1 "nonimmediate_operand" "%0")
8996                   (match_operand:SWI 2 "<general_operand>" "<g>"))
8997                  (const_int 0)))
8998    (clobber (match_scratch:SWI 0 "=<r>"))]
8999   "ix86_match_ccmode (insn, CCNOmode)
9000    && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9001   "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
9002   [(set_attr "type" "alu")
9003    (set_attr "mode" "<MODE>")])
9005 (define_insn "*<code>qi_ext_0"
9006   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9007                          (const_int 8)
9008                          (const_int 8))
9009         (any_or:SI
9010           (zero_extract:SI
9011             (match_operand 1 "ext_register_operand" "0")
9012             (const_int 8)
9013             (const_int 8))
9014           (match_operand 2 "const_int_operand" "n")))
9015    (clobber (reg:CC FLAGS_REG))]
9016   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9017   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
9018   [(set_attr "type" "alu")
9019    (set_attr "length_immediate" "1")
9020    (set_attr "modrm" "1")
9021    (set_attr "mode" "QI")])
9023 (define_insn "*<code>qi_ext_1_rex64"
9024   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9025                          (const_int 8)
9026                          (const_int 8))
9027         (any_or:SI
9028           (zero_extract:SI
9029             (match_operand 1 "ext_register_operand" "0")
9030             (const_int 8)
9031             (const_int 8))
9032           (zero_extend:SI
9033             (match_operand 2 "ext_register_operand" "Q"))))
9034    (clobber (reg:CC FLAGS_REG))]
9035   "TARGET_64BIT
9036    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9037   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
9038   [(set_attr "type" "alu")
9039    (set_attr "length_immediate" "0")
9040    (set_attr "mode" "QI")])
9042 (define_insn "*<code>qi_ext_1"
9043   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9044                          (const_int 8)
9045                          (const_int 8))
9046         (any_or:SI
9047           (zero_extract:SI
9048             (match_operand 1 "ext_register_operand" "0")
9049             (const_int 8)
9050             (const_int 8))
9051           (zero_extend:SI
9052             (match_operand:QI 2 "general_operand" "Qm"))))
9053    (clobber (reg:CC FLAGS_REG))]
9054   "!TARGET_64BIT
9055    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9056   "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
9057   [(set_attr "type" "alu")
9058    (set_attr "length_immediate" "0")
9059    (set_attr "mode" "QI")])
9061 (define_insn "*<code>qi_ext_2"
9062   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9063                          (const_int 8)
9064                          (const_int 8))
9065         (any_or:SI
9066           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9067                            (const_int 8)
9068                            (const_int 8))
9069           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9070                            (const_int 8)
9071                            (const_int 8))))
9072    (clobber (reg:CC FLAGS_REG))]
9073   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9074   "<logicprefix>{b}\t{%h2, %h0|%h0, %h2}"
9075   [(set_attr "type" "alu")
9076    (set_attr "length_immediate" "0")
9077    (set_attr "mode" "QI")])
9079 (define_split
9080   [(set (match_operand 0 "register_operand" "")
9081         (any_or (match_operand 1 "register_operand" "")
9082                 (match_operand 2 "const_int_operand" "")))
9083    (clobber (reg:CC FLAGS_REG))]
9084    "reload_completed
9085     && QI_REG_P (operands[0])
9086     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9087     && !(INTVAL (operands[2]) & ~(255 << 8))
9088     && GET_MODE (operands[0]) != QImode"
9089   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9090                    (any_or:SI (zero_extract:SI (match_dup 1)
9091                                                (const_int 8) (const_int 8))
9092                               (match_dup 2)))
9093               (clobber (reg:CC FLAGS_REG))])]
9094   "operands[0] = gen_lowpart (SImode, operands[0]);
9095    operands[1] = gen_lowpart (SImode, operands[1]);
9096    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9098 ;; Since OR can be encoded with sign extended immediate, this is only
9099 ;; profitable when 7th bit is set.
9100 (define_split
9101   [(set (match_operand 0 "register_operand" "")
9102         (any_or (match_operand 1 "general_operand" "")
9103                 (match_operand 2 "const_int_operand" "")))
9104    (clobber (reg:CC FLAGS_REG))]
9105    "reload_completed
9106     && ANY_QI_REG_P (operands[0])
9107     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9108     && !(INTVAL (operands[2]) & ~255)
9109     && (INTVAL (operands[2]) & 128)
9110     && GET_MODE (operands[0]) != QImode"
9111   [(parallel [(set (strict_low_part (match_dup 0))
9112                    (any_or:QI (match_dup 1)
9113                               (match_dup 2)))
9114               (clobber (reg:CC FLAGS_REG))])]
9115   "operands[0] = gen_lowpart (QImode, operands[0]);
9116    operands[1] = gen_lowpart (QImode, operands[1]);
9117    operands[2] = gen_lowpart (QImode, operands[2]);")
9119 (define_expand "xorqi_cc_ext_1"
9120   [(parallel [
9121      (set (reg:CCNO FLAGS_REG)
9122           (compare:CCNO
9123             (xor:SI
9124               (zero_extract:SI
9125                 (match_operand 1 "ext_register_operand" "")
9126                 (const_int 8)
9127                 (const_int 8))
9128               (match_operand:QI 2 "general_operand" ""))
9129             (const_int 0)))
9130      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9131                            (const_int 8)
9132                            (const_int 8))
9133           (xor:SI
9134             (zero_extract:SI
9135              (match_dup 1)
9136              (const_int 8)
9137              (const_int 8))
9138             (match_dup 2)))])]
9139   ""
9140   "")
9142 (define_insn "*xorqi_cc_ext_1_rex64"
9143   [(set (reg FLAGS_REG)
9144         (compare
9145           (xor:SI
9146             (zero_extract:SI
9147               (match_operand 1 "ext_register_operand" "0")
9148               (const_int 8)
9149               (const_int 8))
9150             (match_operand:QI 2 "nonmemory_operand" "Qn"))
9151           (const_int 0)))
9152    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9153                          (const_int 8)
9154                          (const_int 8))
9155         (xor:SI
9156           (zero_extract:SI
9157            (match_dup 1)
9158            (const_int 8)
9159            (const_int 8))
9160           (match_dup 2)))]
9161   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9162   "xor{b}\t{%2, %h0|%h0, %2}"
9163   [(set_attr "type" "alu")
9164    (set_attr "modrm" "1")
9165    (set_attr "mode" "QI")])
9167 (define_insn "*xorqi_cc_ext_1"
9168   [(set (reg FLAGS_REG)
9169         (compare
9170           (xor:SI
9171             (zero_extract:SI
9172               (match_operand 1 "ext_register_operand" "0")
9173               (const_int 8)
9174               (const_int 8))
9175             (match_operand:QI 2 "general_operand" "qmn"))
9176           (const_int 0)))
9177    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9178                          (const_int 8)
9179                          (const_int 8))
9180         (xor:SI
9181           (zero_extract:SI
9182            (match_dup 1)
9183            (const_int 8)
9184            (const_int 8))
9185           (match_dup 2)))]
9186   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9187   "xor{b}\t{%2, %h0|%h0, %2}"
9188   [(set_attr "type" "alu")
9189    (set_attr "modrm" "1")
9190    (set_attr "mode" "QI")])
9192 ;; Negation instructions
9194 (define_expand "neg<mode>2"
9195   [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9196         (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9197   ""
9198   "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9200 (define_insn_and_split "*neg<dwi>2_doubleword"
9201   [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9202         (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9203    (clobber (reg:CC FLAGS_REG))]
9204   "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9205   "#"
9206   "reload_completed"
9207   [(parallel
9208     [(set (reg:CCZ FLAGS_REG)
9209           (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9210      (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9211    (parallel
9212     [(set (match_dup 2)
9213           (plus:DWIH (match_dup 3)
9214                      (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9215                                 (const_int 0))))
9216      (clobber (reg:CC FLAGS_REG))])
9217    (parallel
9218     [(set (match_dup 2)
9219           (neg:DWIH (match_dup 2)))
9220      (clobber (reg:CC FLAGS_REG))])]
9221   "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9223 (define_insn "*neg<mode>2_1"
9224   [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9225         (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9226    (clobber (reg:CC FLAGS_REG))]
9227   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9228   "neg{<imodesuffix>}\t%0"
9229   [(set_attr "type" "negnot")
9230    (set_attr "mode" "<MODE>")])
9232 ;; Combine is quite creative about this pattern.
9233 (define_insn "*negsi2_1_zext"
9234   [(set (match_operand:DI 0 "register_operand" "=r")
9235         (lshiftrt:DI
9236           (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9237                              (const_int 32)))
9238         (const_int 32)))
9239    (clobber (reg:CC FLAGS_REG))]
9240   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9241   "neg{l}\t%k0"
9242   [(set_attr "type" "negnot")
9243    (set_attr "mode" "SI")])
9245 ;; The problem with neg is that it does not perform (compare x 0),
9246 ;; it really performs (compare 0 x), which leaves us with the zero
9247 ;; flag being the only useful item.
9249 (define_insn "*neg<mode>2_cmpz"
9250   [(set (reg:CCZ FLAGS_REG)
9251         (compare:CCZ
9252           (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9253                    (const_int 0)))
9254    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9255         (neg:SWI (match_dup 1)))]
9256   "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9257   "neg{<imodesuffix>}\t%0"
9258   [(set_attr "type" "negnot")
9259    (set_attr "mode" "<MODE>")])
9261 (define_insn "*negsi2_cmpz_zext"
9262   [(set (reg:CCZ FLAGS_REG)
9263         (compare:CCZ
9264           (lshiftrt:DI
9265             (neg:DI (ashift:DI
9266                       (match_operand:DI 1 "register_operand" "0")
9267                       (const_int 32)))
9268             (const_int 32))
9269           (const_int 0)))
9270    (set (match_operand:DI 0 "register_operand" "=r")
9271         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9272                                         (const_int 32)))
9273                      (const_int 32)))]
9274   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9275   "neg{l}\t%k0"
9276   [(set_attr "type" "negnot")
9277    (set_attr "mode" "SI")])
9279 ;; Changing of sign for FP values is doable using integer unit too.
9281 (define_expand "<code><mode>2"
9282   [(set (match_operand:X87MODEF 0 "register_operand" "")
9283         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9284   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9285   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9287 (define_insn "*absneg<mode>2_mixed"
9288   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9289         (match_operator:MODEF 3 "absneg_operator"
9290           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9291    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9292    (clobber (reg:CC FLAGS_REG))]
9293   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9294   "#")
9296 (define_insn "*absneg<mode>2_sse"
9297   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9298         (match_operator:MODEF 3 "absneg_operator"
9299           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9300    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9301    (clobber (reg:CC FLAGS_REG))]
9302   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9303   "#")
9305 (define_insn "*absneg<mode>2_i387"
9306   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9307         (match_operator:X87MODEF 3 "absneg_operator"
9308           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9309    (use (match_operand 2 "" ""))
9310    (clobber (reg:CC FLAGS_REG))]
9311   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9312   "#")
9314 (define_expand "<code>tf2"
9315   [(set (match_operand:TF 0 "register_operand" "")
9316         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9317   "TARGET_SSE2"
9318   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9320 (define_insn "*absnegtf2_sse"
9321   [(set (match_operand:TF 0 "register_operand" "=x,x")
9322         (match_operator:TF 3 "absneg_operator"
9323           [(match_operand:TF 1 "register_operand" "0,x")]))
9324    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9325    (clobber (reg:CC FLAGS_REG))]
9326   "TARGET_SSE2"
9327   "#")
9329 ;; Splitters for fp abs and neg.
9331 (define_split
9332   [(set (match_operand 0 "fp_register_operand" "")
9333         (match_operator 1 "absneg_operator" [(match_dup 0)]))
9334    (use (match_operand 2 "" ""))
9335    (clobber (reg:CC FLAGS_REG))]
9336   "reload_completed"
9337   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9339 (define_split
9340   [(set (match_operand 0 "register_operand" "")
9341         (match_operator 3 "absneg_operator"
9342           [(match_operand 1 "register_operand" "")]))
9343    (use (match_operand 2 "nonimmediate_operand" ""))
9344    (clobber (reg:CC FLAGS_REG))]
9345   "reload_completed && SSE_REG_P (operands[0])"
9346   [(set (match_dup 0) (match_dup 3))]
9348   enum machine_mode mode = GET_MODE (operands[0]);
9349   enum machine_mode vmode = GET_MODE (operands[2]);
9350   rtx tmp;
9352   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9353   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9354   if (operands_match_p (operands[0], operands[2]))
9355     {
9356       tmp = operands[1];
9357       operands[1] = operands[2];
9358       operands[2] = tmp;
9359     }
9360   if (GET_CODE (operands[3]) == ABS)
9361     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9362   else
9363     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9364   operands[3] = tmp;
9367 (define_split
9368   [(set (match_operand:SF 0 "register_operand" "")
9369         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9370    (use (match_operand:V4SF 2 "" ""))
9371    (clobber (reg:CC FLAGS_REG))]
9372   "reload_completed"
9373   [(parallel [(set (match_dup 0) (match_dup 1))
9374               (clobber (reg:CC FLAGS_REG))])]
9376   rtx tmp;
9377   operands[0] = gen_lowpart (SImode, operands[0]);
9378   if (GET_CODE (operands[1]) == ABS)
9379     {
9380       tmp = gen_int_mode (0x7fffffff, SImode);
9381       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9382     }
9383   else
9384     {
9385       tmp = gen_int_mode (0x80000000, SImode);
9386       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9387     }
9388   operands[1] = tmp;
9391 (define_split
9392   [(set (match_operand:DF 0 "register_operand" "")
9393         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9394    (use (match_operand 2 "" ""))
9395    (clobber (reg:CC FLAGS_REG))]
9396   "reload_completed"
9397   [(parallel [(set (match_dup 0) (match_dup 1))
9398               (clobber (reg:CC FLAGS_REG))])]
9400   rtx tmp;
9401   if (TARGET_64BIT)
9402     {
9403       tmp = gen_lowpart (DImode, operands[0]);
9404       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9405       operands[0] = tmp;
9407       if (GET_CODE (operands[1]) == ABS)
9408         tmp = const0_rtx;
9409       else
9410         tmp = gen_rtx_NOT (DImode, tmp);
9411     }
9412   else
9413     {
9414       operands[0] = gen_highpart (SImode, operands[0]);
9415       if (GET_CODE (operands[1]) == ABS)
9416         {
9417           tmp = gen_int_mode (0x7fffffff, SImode);
9418           tmp = gen_rtx_AND (SImode, operands[0], tmp);
9419         }
9420       else
9421         {
9422           tmp = gen_int_mode (0x80000000, SImode);
9423           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9424         }
9425     }
9426   operands[1] = tmp;
9429 (define_split
9430   [(set (match_operand:XF 0 "register_operand" "")
9431         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9432    (use (match_operand 2 "" ""))
9433    (clobber (reg:CC FLAGS_REG))]
9434   "reload_completed"
9435   [(parallel [(set (match_dup 0) (match_dup 1))
9436               (clobber (reg:CC FLAGS_REG))])]
9438   rtx tmp;
9439   operands[0] = gen_rtx_REG (SImode,
9440                              true_regnum (operands[0])
9441                              + (TARGET_64BIT ? 1 : 2));
9442   if (GET_CODE (operands[1]) == ABS)
9443     {
9444       tmp = GEN_INT (0x7fff);
9445       tmp = gen_rtx_AND (SImode, operands[0], tmp);
9446     }
9447   else
9448     {
9449       tmp = GEN_INT (0x8000);
9450       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9451     }
9452   operands[1] = tmp;
9455 ;; Conditionalize these after reload. If they match before reload, we
9456 ;; lose the clobber and ability to use integer instructions.
9458 (define_insn "*<code><mode>2_1"
9459   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9460         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9461   "TARGET_80387
9462    && (reload_completed
9463        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9464   "f<absnegprefix>"
9465   [(set_attr "type" "fsgn")
9466    (set_attr "mode" "<MODE>")])
9468 (define_insn "*<code>extendsfdf2"
9469   [(set (match_operand:DF 0 "register_operand" "=f")
9470         (absneg:DF (float_extend:DF
9471                      (match_operand:SF 1 "register_operand" "0"))))]
9472   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9473   "f<absnegprefix>"
9474   [(set_attr "type" "fsgn")
9475    (set_attr "mode" "DF")])
9477 (define_insn "*<code>extendsfxf2"
9478   [(set (match_operand:XF 0 "register_operand" "=f")
9479         (absneg:XF (float_extend:XF
9480                      (match_operand:SF 1 "register_operand" "0"))))]
9481   "TARGET_80387"
9482   "f<absnegprefix>"
9483   [(set_attr "type" "fsgn")
9484    (set_attr "mode" "XF")])
9486 (define_insn "*<code>extenddfxf2"
9487   [(set (match_operand:XF 0 "register_operand" "=f")
9488         (absneg:XF (float_extend:XF
9489                       (match_operand:DF 1 "register_operand" "0"))))]
9490   "TARGET_80387"
9491   "f<absnegprefix>"
9492   [(set_attr "type" "fsgn")
9493    (set_attr "mode" "XF")])
9495 ;; Copysign instructions
9497 (define_mode_iterator CSGNMODE [SF DF TF])
9498 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9500 (define_expand "copysign<mode>3"
9501   [(match_operand:CSGNMODE 0 "register_operand" "")
9502    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9503    (match_operand:CSGNMODE 2 "register_operand" "")]
9504   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9505    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9507   ix86_expand_copysign (operands);
9508   DONE;
9511 (define_insn_and_split "copysign<mode>3_const"
9512   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9513         (unspec:CSGNMODE
9514           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9515            (match_operand:CSGNMODE 2 "register_operand" "0")
9516            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9517           UNSPEC_COPYSIGN))]
9518   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9519    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9520   "#"
9521   "&& reload_completed"
9522   [(const_int 0)]
9524   ix86_split_copysign_const (operands);
9525   DONE;
9528 (define_insn "copysign<mode>3_var"
9529   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9530         (unspec:CSGNMODE
9531           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9532            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9533            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9534            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9535           UNSPEC_COPYSIGN))
9536    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9537   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9538    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9539   "#")
9541 (define_split
9542   [(set (match_operand:CSGNMODE 0 "register_operand" "")
9543         (unspec:CSGNMODE
9544           [(match_operand:CSGNMODE 2 "register_operand" "")
9545            (match_operand:CSGNMODE 3 "register_operand" "")
9546            (match_operand:<CSGNVMODE> 4 "" "")
9547            (match_operand:<CSGNVMODE> 5 "" "")]
9548           UNSPEC_COPYSIGN))
9549    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9550   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9551     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9552    && reload_completed"
9553   [(const_int 0)]
9555   ix86_split_copysign_var (operands);
9556   DONE;
9559 ;; One complement instructions
9561 (define_expand "one_cmpl<mode>2"
9562   [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9563         (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9564   ""
9565   "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9567 (define_insn "*one_cmpl<mode>2_1"
9568   [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9569         (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9570   "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9571   "not{<imodesuffix>}\t%0"
9572   [(set_attr "type" "negnot")
9573    (set_attr "mode" "<MODE>")])
9575 ;; %%% Potential partial reg stall on alternative 1.  What to do?
9576 (define_insn "*one_cmplqi2_1"
9577   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9578         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9579   "ix86_unary_operator_ok (NOT, QImode, operands)"
9580   "@
9581    not{b}\t%0
9582    not{l}\t%k0"
9583   [(set_attr "type" "negnot")
9584    (set_attr "mode" "QI,SI")])
9586 ;; ??? Currently never generated - xor is used instead.
9587 (define_insn "*one_cmplsi2_1_zext"
9588   [(set (match_operand:DI 0 "register_operand" "=r")
9589         (zero_extend:DI
9590           (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9591   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9592   "not{l}\t%k0"
9593   [(set_attr "type" "negnot")
9594    (set_attr "mode" "SI")])
9596 (define_insn "*one_cmpl<mode>2_2"
9597   [(set (reg FLAGS_REG)
9598         (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9599                  (const_int 0)))
9600    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9601         (not:SWI (match_dup 1)))]
9602   "ix86_match_ccmode (insn, CCNOmode)
9603    && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9604   "#"
9605   [(set_attr "type" "alu1")
9606    (set_attr "mode" "<MODE>")])
9608 (define_split
9609   [(set (match_operand 0 "flags_reg_operand" "")
9610         (match_operator 2 "compare_operator"
9611           [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9612            (const_int 0)]))
9613    (set (match_operand:SWI 1 "nonimmediate_operand" "")
9614         (not:SWI (match_dup 3)))]
9615   "ix86_match_ccmode (insn, CCNOmode)"
9616   [(parallel [(set (match_dup 0)
9617                    (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9618                                     (const_int 0)]))
9619               (set (match_dup 1)
9620                    (xor:SWI (match_dup 3) (const_int -1)))])]
9621   "")
9623 ;; ??? Currently never generated - xor is used instead.
9624 (define_insn "*one_cmplsi2_2_zext"
9625   [(set (reg FLAGS_REG)
9626         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9627                  (const_int 0)))
9628    (set (match_operand:DI 0 "register_operand" "=r")
9629         (zero_extend:DI (not:SI (match_dup 1))))]
9630   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9631    && ix86_unary_operator_ok (NOT, SImode, operands)"
9632   "#"
9633   [(set_attr "type" "alu1")
9634    (set_attr "mode" "SI")])
9636 (define_split
9637   [(set (match_operand 0 "flags_reg_operand" "")
9638         (match_operator 2 "compare_operator"
9639           [(not:SI (match_operand:SI 3 "register_operand" ""))
9640            (const_int 0)]))
9641    (set (match_operand:DI 1 "register_operand" "")
9642         (zero_extend:DI (not:SI (match_dup 3))))]
9643   "ix86_match_ccmode (insn, CCNOmode)"
9644   [(parallel [(set (match_dup 0)
9645                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9646                                     (const_int 0)]))
9647               (set (match_dup 1)
9648                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9649   "")
9651 ;; Arithmetic shift instructions
9653 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9654 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
9655 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9656 ;; from the assembler input.
9658 ;; This instruction shifts the target reg/mem as usual, but instead of
9659 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
9660 ;; is a left shift double, bits are taken from the high order bits of
9661 ;; reg, else if the insn is a shift right double, bits are taken from the
9662 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
9663 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9665 ;; Since sh[lr]d does not change the `reg' operand, that is done
9666 ;; separately, making all shifts emit pairs of shift double and normal
9667 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
9668 ;; support a 63 bit shift, each shift where the count is in a reg expands
9669 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9671 ;; If the shift count is a constant, we need never emit more than one
9672 ;; shift pair, instead using moves and sign extension for counts greater
9673 ;; than 31.
9675 (define_expand "ashlti3"
9676   [(set (match_operand:TI 0 "register_operand" "")
9677         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
9678                    (match_operand:QI 2 "nonmemory_operand" "")))]
9679   "TARGET_64BIT"
9680   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
9682 (define_insn "*ashlti3_1"
9683   [(set (match_operand:TI 0 "register_operand" "=&r,r")
9684         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
9685                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
9686    (clobber (reg:CC FLAGS_REG))]
9687   "TARGET_64BIT"
9688   "#"
9689   [(set_attr "type" "multi")])
9691 (define_peephole2
9692   [(match_scratch:DI 3 "r")
9693    (parallel [(set (match_operand:TI 0 "register_operand" "")
9694                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9695                               (match_operand:QI 2 "nonmemory_operand" "")))
9696               (clobber (reg:CC FLAGS_REG))])
9697    (match_dup 3)]
9698   "TARGET_64BIT"
9699   [(const_int 0)]
9700   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
9702 (define_split
9703   [(set (match_operand:TI 0 "register_operand" "")
9704         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9705                    (match_operand:QI 2 "nonmemory_operand" "")))
9706    (clobber (reg:CC FLAGS_REG))]
9707   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
9708                     ? epilogue_completed : reload_completed)"
9709   [(const_int 0)]
9710   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
9712 (define_insn "x86_64_shld"
9713   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9714         (ior:DI (ashift:DI (match_dup 0)
9715                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
9716                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9717                   (minus:QI (const_int 64) (match_dup 2)))))
9718    (clobber (reg:CC FLAGS_REG))]
9719   "TARGET_64BIT"
9720   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9721   [(set_attr "type" "ishift")
9722    (set_attr "prefix_0f" "1")
9723    (set_attr "mode" "DI")
9724    (set_attr "athlon_decode" "vector")
9725    (set_attr "amdfam10_decode" "vector")])
9727 (define_expand "x86_64_shift_adj_1"
9728   [(set (reg:CCZ FLAGS_REG)
9729         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9730                              (const_int 64))
9731                      (const_int 0)))
9732    (set (match_operand:DI 0 "register_operand" "")
9733         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9734                          (match_operand:DI 1 "register_operand" "")
9735                          (match_dup 0)))
9736    (set (match_dup 1)
9737         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9738                          (match_operand:DI 3 "register_operand" "r")
9739                          (match_dup 1)))]
9740   "TARGET_64BIT"
9741   "")
9743 (define_expand "x86_64_shift_adj_2"
9744   [(use (match_operand:DI 0 "register_operand" ""))
9745    (use (match_operand:DI 1 "register_operand" ""))
9746    (use (match_operand:QI 2 "register_operand" ""))]
9747   "TARGET_64BIT"
9749   rtx label = gen_label_rtx ();
9750   rtx tmp;
9752   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
9754   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9755   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9756   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9757                               gen_rtx_LABEL_REF (VOIDmode, label),
9758                               pc_rtx);
9759   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9760   JUMP_LABEL (tmp) = label;
9762   emit_move_insn (operands[0], operands[1]);
9763   ix86_expand_clear (operands[1]);
9765   emit_label (label);
9766   LABEL_NUSES (label) = 1;
9768   DONE;
9771 (define_expand "ashldi3"
9772   [(set (match_operand:DI 0 "shiftdi_operand" "")
9773         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
9774                    (match_operand:QI 2 "nonmemory_operand" "")))]
9775   ""
9776   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
9778 (define_insn "*ashldi3_1_rex64"
9779   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9780         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
9781                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
9782    (clobber (reg:CC FLAGS_REG))]
9783   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9785   switch (get_attr_type (insn))
9786     {
9787     case TYPE_ALU:
9788       gcc_assert (operands[2] == const1_rtx);
9789       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9790       return "add{q}\t%0, %0";
9792     case TYPE_LEA:
9793       gcc_assert (CONST_INT_P (operands[2]));
9794       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
9795       operands[1] = gen_rtx_MULT (DImode, operands[1],
9796                                   GEN_INT (1 << INTVAL (operands[2])));
9797       return "lea{q}\t{%a1, %0|%0, %a1}";
9799     default:
9800       if (REG_P (operands[2]))
9801         return "sal{q}\t{%b2, %0|%0, %b2}";
9802       else if (operands[2] == const1_rtx
9803                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9804         return "sal{q}\t%0";
9805       else
9806         return "sal{q}\t{%2, %0|%0, %2}";
9807     }
9809   [(set (attr "type")
9810      (cond [(eq_attr "alternative" "1")
9811               (const_string "lea")
9812             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9813                           (const_int 0))
9814                       (match_operand 0 "register_operand" ""))
9815                  (match_operand 2 "const1_operand" ""))
9816               (const_string "alu")
9817            ]
9818            (const_string "ishift")))
9819    (set (attr "length_immediate")
9820      (if_then_else
9821        (ior (eq_attr "type" "alu")
9822             (and (eq_attr "type" "ishift")
9823                  (and (match_operand 2 "const1_operand" "")
9824                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9825                           (const_int 0)))))
9826        (const_string "0")
9827        (const_string "*")))
9828    (set_attr "mode" "DI")])
9830 ;; Convert lea to the lea pattern to avoid flags dependency.
9831 (define_split
9832   [(set (match_operand:DI 0 "register_operand" "")
9833         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9834                    (match_operand:QI 2 "immediate_operand" "")))
9835    (clobber (reg:CC FLAGS_REG))]
9836   "TARGET_64BIT && reload_completed
9837    && true_regnum (operands[0]) != true_regnum (operands[1])"
9838   [(set (match_dup 0)
9839         (mult:DI (match_dup 1)
9840                  (match_dup 2)))]
9841   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9843 ;; This pattern can't accept a variable shift count, since shifts by
9844 ;; zero don't affect the flags.  We assume that shifts by constant
9845 ;; zero are optimized away.
9846 (define_insn "*ashldi3_cmp_rex64"
9847   [(set (reg FLAGS_REG)
9848         (compare
9849           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
9850                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
9851           (const_int 0)))
9852    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9853         (ashift:DI (match_dup 1) (match_dup 2)))]
9854   "TARGET_64BIT
9855    && (optimize_function_for_size_p (cfun)
9856        || !TARGET_PARTIAL_FLAG_REG_STALL
9857        || (operands[2] == const1_rtx
9858            && (TARGET_SHIFT1
9859                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9860    && ix86_match_ccmode (insn, CCGOCmode)
9861    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9863   switch (get_attr_type (insn))
9864     {
9865     case TYPE_ALU:
9866       gcc_assert (operands[2] == const1_rtx);
9867       return "add{q}\t%0, %0";
9869     default:
9870       if (REG_P (operands[2]))
9871         return "sal{q}\t{%b2, %0|%0, %b2}";
9872       else if (operands[2] == const1_rtx
9873                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9874         return "sal{q}\t%0";
9875       else
9876         return "sal{q}\t{%2, %0|%0, %2}";
9877     }
9879   [(set (attr "type")
9880      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9881                           (const_int 0))
9882                       (match_operand 0 "register_operand" ""))
9883                  (match_operand 2 "const1_operand" ""))
9884               (const_string "alu")
9885            ]
9886            (const_string "ishift")))
9887    (set (attr "length_immediate")
9888      (if_then_else
9889        (ior (eq_attr "type" "alu")
9890             (and (eq_attr "type" "ishift")
9891                  (and (match_operand 2 "const1_operand" "")
9892                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9893                           (const_int 0)))))
9894        (const_string "0")
9895        (const_string "*")))
9896    (set_attr "mode" "DI")])
9898 (define_insn "*ashldi3_cconly_rex64"
9899   [(set (reg FLAGS_REG)
9900         (compare
9901           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
9902                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
9903           (const_int 0)))
9904    (clobber (match_scratch:DI 0 "=r"))]
9905   "TARGET_64BIT
9906    && (optimize_function_for_size_p (cfun)
9907        || !TARGET_PARTIAL_FLAG_REG_STALL
9908        || (operands[2] == const1_rtx
9909            && (TARGET_SHIFT1
9910                || TARGET_DOUBLE_WITH_ADD)))
9911    && ix86_match_ccmode (insn, CCGOCmode)
9912    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9914   switch (get_attr_type (insn))
9915     {
9916     case TYPE_ALU:
9917       gcc_assert (operands[2] == const1_rtx);
9918       return "add{q}\t%0, %0";
9920     default:
9921       if (REG_P (operands[2]))
9922         return "sal{q}\t{%b2, %0|%0, %b2}";
9923       else if (operands[2] == const1_rtx
9924                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9925         return "sal{q}\t%0";
9926       else
9927         return "sal{q}\t{%2, %0|%0, %2}";
9928     }
9930   [(set (attr "type")
9931      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9932                           (const_int 0))
9933                       (match_operand 0 "register_operand" ""))
9934                  (match_operand 2 "const1_operand" ""))
9935               (const_string "alu")
9936            ]
9937            (const_string "ishift")))
9938    (set (attr "length_immediate")
9939      (if_then_else
9940        (ior (eq_attr "type" "alu")
9941             (and (eq_attr "type" "ishift")
9942                  (and (match_operand 2 "const1_operand" "")
9943                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9944                           (const_int 0)))))
9945        (const_string "0")
9946        (const_string "*")))
9947    (set_attr "mode" "DI")])
9949 (define_insn "*ashldi3_1"
9950   [(set (match_operand:DI 0 "register_operand" "=&r,r")
9951         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
9952                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
9953    (clobber (reg:CC FLAGS_REG))]
9954   "!TARGET_64BIT"
9955   "#"
9956   [(set_attr "type" "multi")])
9958 ;; By default we don't ask for a scratch register, because when DImode
9959 ;; values are manipulated, registers are already at a premium.  But if
9960 ;; we have one handy, we won't turn it away.
9961 (define_peephole2
9962   [(match_scratch:SI 3 "r")
9963    (parallel [(set (match_operand:DI 0 "register_operand" "")
9964                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
9965                               (match_operand:QI 2 "nonmemory_operand" "")))
9966               (clobber (reg:CC FLAGS_REG))])
9967    (match_dup 3)]
9968   "!TARGET_64BIT && TARGET_CMOVE"
9969   [(const_int 0)]
9970   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
9972 (define_split
9973   [(set (match_operand:DI 0 "register_operand" "")
9974         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
9975                    (match_operand:QI 2 "nonmemory_operand" "")))
9976    (clobber (reg:CC FLAGS_REG))]
9977   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
9978                      ? epilogue_completed : reload_completed)"
9979   [(const_int 0)]
9980   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
9982 (define_insn "x86_shld"
9983   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9984         (ior:SI (ashift:SI (match_dup 0)
9985                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
9986                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9987                   (minus:QI (const_int 32) (match_dup 2)))))
9988    (clobber (reg:CC FLAGS_REG))]
9989   ""
9990   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9991   [(set_attr "type" "ishift")
9992    (set_attr "prefix_0f" "1")
9993    (set_attr "mode" "SI")
9994    (set_attr "pent_pair" "np")
9995    (set_attr "athlon_decode" "vector")
9996    (set_attr "amdfam10_decode" "vector")])
9998 (define_expand "x86_shift_adj_1"
9999   [(set (reg:CCZ FLAGS_REG)
10000         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10001                              (const_int 32))
10002                      (const_int 0)))
10003    (set (match_operand:SI 0 "register_operand" "")
10004         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10005                          (match_operand:SI 1 "register_operand" "")
10006                          (match_dup 0)))
10007    (set (match_dup 1)
10008         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10009                          (match_operand:SI 3 "register_operand" "r")
10010                          (match_dup 1)))]
10011   "TARGET_CMOVE"
10012   "")
10014 (define_expand "x86_shift_adj_2"
10015   [(use (match_operand:SI 0 "register_operand" ""))
10016    (use (match_operand:SI 1 "register_operand" ""))
10017    (use (match_operand:QI 2 "register_operand" ""))]
10018   ""
10020   rtx label = gen_label_rtx ();
10021   rtx tmp;
10023   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10025   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10026   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10027   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10028                               gen_rtx_LABEL_REF (VOIDmode, label),
10029                               pc_rtx);
10030   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10031   JUMP_LABEL (tmp) = label;
10033   emit_move_insn (operands[0], operands[1]);
10034   ix86_expand_clear (operands[1]);
10036   emit_label (label);
10037   LABEL_NUSES (label) = 1;
10039   DONE;
10042 (define_expand "ashlsi3"
10043   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10044         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10045                    (match_operand:QI 2 "nonmemory_operand" "")))]
10046   ""
10047   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10049 (define_insn "*ashlsi3_1"
10050   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10051         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10052                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10053    (clobber (reg:CC FLAGS_REG))]
10054   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10056   switch (get_attr_type (insn))
10057     {
10058     case TYPE_ALU:
10059       gcc_assert (operands[2] == const1_rtx);
10060       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10061       return "add{l}\t%0, %0";
10063     case TYPE_LEA:
10064       return "#";
10066     default:
10067       if (REG_P (operands[2]))
10068         return "sal{l}\t{%b2, %0|%0, %b2}";
10069       else if (operands[2] == const1_rtx
10070                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10071         return "sal{l}\t%0";
10072       else
10073         return "sal{l}\t{%2, %0|%0, %2}";
10074     }
10076   [(set (attr "type")
10077      (cond [(eq_attr "alternative" "1")
10078               (const_string "lea")
10079             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10080                           (const_int 0))
10081                       (match_operand 0 "register_operand" ""))
10082                  (match_operand 2 "const1_operand" ""))
10083               (const_string "alu")
10084            ]
10085            (const_string "ishift")))
10086    (set (attr "length_immediate")
10087      (if_then_else
10088        (ior (eq_attr "type" "alu")
10089             (and (eq_attr "type" "ishift")
10090                  (and (match_operand 2 "const1_operand" "")
10091                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10092                           (const_int 0)))))
10093        (const_string "0")
10094        (const_string "*")))
10095    (set_attr "mode" "SI")])
10097 ;; Convert lea to the lea pattern to avoid flags dependency.
10098 (define_split
10099   [(set (match_operand 0 "register_operand" "")
10100         (ashift (match_operand 1 "index_register_operand" "")
10101                 (match_operand:QI 2 "const_int_operand" "")))
10102    (clobber (reg:CC FLAGS_REG))]
10103   "reload_completed
10104    && true_regnum (operands[0]) != true_regnum (operands[1])
10105    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10106   [(const_int 0)]
10108   rtx pat;
10109   enum machine_mode mode = GET_MODE (operands[0]);
10111   if (GET_MODE_SIZE (mode) < 4)
10112     operands[0] = gen_lowpart (SImode, operands[0]);
10113   if (mode != Pmode)
10114     operands[1] = gen_lowpart (Pmode, operands[1]);
10115   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10117   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10118   if (Pmode != SImode)
10119     pat = gen_rtx_SUBREG (SImode, pat, 0);
10120   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10121   DONE;
10124 ;; Rare case of shifting RSP is handled by generating move and shift
10125 (define_split
10126   [(set (match_operand 0 "register_operand" "")
10127         (ashift (match_operand 1 "register_operand" "")
10128                 (match_operand:QI 2 "const_int_operand" "")))
10129    (clobber (reg:CC FLAGS_REG))]
10130   "reload_completed
10131    && true_regnum (operands[0]) != true_regnum (operands[1])"
10132   [(const_int 0)]
10134   rtx pat, clob;
10135   emit_move_insn (operands[0], operands[1]);
10136   pat = gen_rtx_SET (VOIDmode, operands[0],
10137                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
10138                                      operands[0], operands[2]));
10139   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10140   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10141   DONE;
10144 (define_insn "*ashlsi3_1_zext"
10145   [(set (match_operand:DI 0 "register_operand" "=r,r")
10146         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10147                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10148    (clobber (reg:CC FLAGS_REG))]
10149   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10151   switch (get_attr_type (insn))
10152     {
10153     case TYPE_ALU:
10154       gcc_assert (operands[2] == const1_rtx);
10155       return "add{l}\t%k0, %k0";
10157     case TYPE_LEA:
10158       return "#";
10160     default:
10161       if (REG_P (operands[2]))
10162         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10163       else if (operands[2] == const1_rtx
10164                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10165         return "sal{l}\t%k0";
10166       else
10167         return "sal{l}\t{%2, %k0|%k0, %2}";
10168     }
10170   [(set (attr "type")
10171      (cond [(eq_attr "alternative" "1")
10172               (const_string "lea")
10173             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10174                      (const_int 0))
10175                  (match_operand 2 "const1_operand" ""))
10176               (const_string "alu")
10177            ]
10178            (const_string "ishift")))
10179    (set (attr "length_immediate")
10180      (if_then_else
10181        (ior (eq_attr "type" "alu")
10182             (and (eq_attr "type" "ishift")
10183                  (and (match_operand 2 "const1_operand" "")
10184                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10185                           (const_int 0)))))
10186        (const_string "0")
10187        (const_string "*")))
10188    (set_attr "mode" "SI")])
10190 ;; Convert lea to the lea pattern to avoid flags dependency.
10191 (define_split
10192   [(set (match_operand:DI 0 "register_operand" "")
10193         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10194                                 (match_operand:QI 2 "const_int_operand" ""))))
10195    (clobber (reg:CC FLAGS_REG))]
10196   "TARGET_64BIT && reload_completed
10197    && true_regnum (operands[0]) != true_regnum (operands[1])"
10198   [(set (match_dup 0) (zero_extend:DI
10199                         (subreg:SI (mult:SI (match_dup 1)
10200                                             (match_dup 2)) 0)))]
10202   operands[1] = gen_lowpart (Pmode, operands[1]);
10203   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10206 ;; This pattern can't accept a variable shift count, since shifts by
10207 ;; zero don't affect the flags.  We assume that shifts by constant
10208 ;; zero are optimized away.
10209 (define_insn "*ashlsi3_cmp"
10210   [(set (reg FLAGS_REG)
10211         (compare
10212           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10213                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10214           (const_int 0)))
10215    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10216         (ashift:SI (match_dup 1) (match_dup 2)))]
10217    "(optimize_function_for_size_p (cfun)
10218      || !TARGET_PARTIAL_FLAG_REG_STALL
10219      || (operands[2] == const1_rtx
10220          && (TARGET_SHIFT1
10221              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10222    && ix86_match_ccmode (insn, CCGOCmode)
10223    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10225   switch (get_attr_type (insn))
10226     {
10227     case TYPE_ALU:
10228       gcc_assert (operands[2] == const1_rtx);
10229       return "add{l}\t%0, %0";
10231     default:
10232       if (REG_P (operands[2]))
10233         return "sal{l}\t{%b2, %0|%0, %b2}";
10234       else if (operands[2] == const1_rtx
10235                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10236         return "sal{l}\t%0";
10237       else
10238         return "sal{l}\t{%2, %0|%0, %2}";
10239     }
10241   [(set (attr "type")
10242      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10243                           (const_int 0))
10244                       (match_operand 0 "register_operand" ""))
10245                  (match_operand 2 "const1_operand" ""))
10246               (const_string "alu")
10247            ]
10248            (const_string "ishift")))
10249    (set (attr "length_immediate")
10250      (if_then_else
10251        (ior (eq_attr "type" "alu")
10252             (and (eq_attr "type" "ishift")
10253                  (and (match_operand 2 "const1_operand" "")
10254                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10255                           (const_int 0)))))
10256        (const_string "0")
10257        (const_string "*")))
10258    (set_attr "mode" "SI")])
10260 (define_insn "*ashlsi3_cconly"
10261   [(set (reg FLAGS_REG)
10262         (compare
10263           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10264                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10265           (const_int 0)))
10266    (clobber (match_scratch:SI 0 "=r"))]
10267   "(optimize_function_for_size_p (cfun)
10268     || !TARGET_PARTIAL_FLAG_REG_STALL
10269     || (operands[2] == const1_rtx
10270         && (TARGET_SHIFT1
10271             || TARGET_DOUBLE_WITH_ADD)))
10272    && ix86_match_ccmode (insn, CCGOCmode)
10273    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10275   switch (get_attr_type (insn))
10276     {
10277     case TYPE_ALU:
10278       gcc_assert (operands[2] == const1_rtx);
10279       return "add{l}\t%0, %0";
10281     default:
10282       if (REG_P (operands[2]))
10283         return "sal{l}\t{%b2, %0|%0, %b2}";
10284       else if (operands[2] == const1_rtx
10285                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10286         return "sal{l}\t%0";
10287       else
10288         return "sal{l}\t{%2, %0|%0, %2}";
10289     }
10291   [(set (attr "type")
10292      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10293                           (const_int 0))
10294                       (match_operand 0 "register_operand" ""))
10295                  (match_operand 2 "const1_operand" ""))
10296               (const_string "alu")
10297            ]
10298            (const_string "ishift")))
10299    (set (attr "length_immediate")
10300      (if_then_else
10301        (ior (eq_attr "type" "alu")
10302             (and (eq_attr "type" "ishift")
10303                  (and (match_operand 2 "const1_operand" "")
10304                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10305                           (const_int 0)))))
10306        (const_string "0")
10307        (const_string "*")))
10308    (set_attr "mode" "SI")])
10310 (define_insn "*ashlsi3_cmp_zext"
10311   [(set (reg FLAGS_REG)
10312         (compare
10313           (ashift:SI (match_operand:SI 1 "register_operand" "0")
10314                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10315           (const_int 0)))
10316    (set (match_operand:DI 0 "register_operand" "=r")
10317         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10318   "TARGET_64BIT
10319    && (optimize_function_for_size_p (cfun)
10320        || !TARGET_PARTIAL_FLAG_REG_STALL
10321        || (operands[2] == const1_rtx
10322            && (TARGET_SHIFT1
10323                || TARGET_DOUBLE_WITH_ADD)))
10324    && ix86_match_ccmode (insn, CCGOCmode)
10325    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10327   switch (get_attr_type (insn))
10328     {
10329     case TYPE_ALU:
10330       gcc_assert (operands[2] == const1_rtx);
10331       return "add{l}\t%k0, %k0";
10333     default:
10334       if (REG_P (operands[2]))
10335         return "sal{l}\t{%b2, %k0|%k0, %b2}";
10336       else if (operands[2] == const1_rtx
10337                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10338         return "sal{l}\t%k0";
10339       else
10340         return "sal{l}\t{%2, %k0|%k0, %2}";
10341     }
10343   [(set (attr "type")
10344      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10345                      (const_int 0))
10346                  (match_operand 2 "const1_operand" ""))
10347               (const_string "alu")
10348            ]
10349            (const_string "ishift")))
10350    (set (attr "length_immediate")
10351      (if_then_else
10352        (ior (eq_attr "type" "alu")
10353             (and (eq_attr "type" "ishift")
10354                  (and (match_operand 2 "const1_operand" "")
10355                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10356                           (const_int 0)))))
10357        (const_string "0")
10358        (const_string "*")))
10359    (set_attr "mode" "SI")])
10361 (define_expand "ashlhi3"
10362   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10363         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10364                    (match_operand:QI 2 "nonmemory_operand" "")))]
10365   "TARGET_HIMODE_MATH"
10366   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10368 (define_insn "*ashlhi3_1_lea"
10369   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10370         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10371                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10372    (clobber (reg:CC FLAGS_REG))]
10373   "!TARGET_PARTIAL_REG_STALL
10374    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10376   switch (get_attr_type (insn))
10377     {
10378     case TYPE_LEA:
10379       return "#";
10380     case TYPE_ALU:
10381       gcc_assert (operands[2] == const1_rtx);
10382       return "add{w}\t%0, %0";
10384     default:
10385       if (REG_P (operands[2]))
10386         return "sal{w}\t{%b2, %0|%0, %b2}";
10387       else if (operands[2] == const1_rtx
10388                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10389         return "sal{w}\t%0";
10390       else
10391         return "sal{w}\t{%2, %0|%0, %2}";
10392     }
10394   [(set (attr "type")
10395      (cond [(eq_attr "alternative" "1")
10396               (const_string "lea")
10397             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10398                           (const_int 0))
10399                       (match_operand 0 "register_operand" ""))
10400                  (match_operand 2 "const1_operand" ""))
10401               (const_string "alu")
10402            ]
10403            (const_string "ishift")))
10404    (set (attr "length_immediate")
10405      (if_then_else
10406        (ior (eq_attr "type" "alu")
10407             (and (eq_attr "type" "ishift")
10408                  (and (match_operand 2 "const1_operand" "")
10409                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10410                           (const_int 0)))))
10411        (const_string "0")
10412        (const_string "*")))
10413    (set_attr "mode" "HI,SI")])
10415 (define_insn "*ashlhi3_1"
10416   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10417         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10418                    (match_operand:QI 2 "nonmemory_operand" "cI")))
10419    (clobber (reg:CC FLAGS_REG))]
10420   "TARGET_PARTIAL_REG_STALL
10421    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10423   switch (get_attr_type (insn))
10424     {
10425     case TYPE_ALU:
10426       gcc_assert (operands[2] == const1_rtx);
10427       return "add{w}\t%0, %0";
10429     default:
10430       if (REG_P (operands[2]))
10431         return "sal{w}\t{%b2, %0|%0, %b2}";
10432       else if (operands[2] == const1_rtx
10433                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10434         return "sal{w}\t%0";
10435       else
10436         return "sal{w}\t{%2, %0|%0, %2}";
10437     }
10439   [(set (attr "type")
10440      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10441                           (const_int 0))
10442                       (match_operand 0 "register_operand" ""))
10443                  (match_operand 2 "const1_operand" ""))
10444               (const_string "alu")
10445            ]
10446            (const_string "ishift")))
10447    (set (attr "length_immediate")
10448      (if_then_else
10449        (ior (eq_attr "type" "alu")
10450             (and (eq_attr "type" "ishift")
10451                  (and (match_operand 2 "const1_operand" "")
10452                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10453                           (const_int 0)))))
10454        (const_string "0")
10455        (const_string "*")))
10456    (set_attr "mode" "HI")])
10458 ;; This pattern can't accept a variable shift count, since shifts by
10459 ;; zero don't affect the flags.  We assume that shifts by constant
10460 ;; zero are optimized away.
10461 (define_insn "*ashlhi3_cmp"
10462   [(set (reg FLAGS_REG)
10463         (compare
10464           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10465                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10466           (const_int 0)))
10467    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10468         (ashift:HI (match_dup 1) (match_dup 2)))]
10469   "(optimize_function_for_size_p (cfun)
10470     || !TARGET_PARTIAL_FLAG_REG_STALL
10471     || (operands[2] == const1_rtx
10472         && (TARGET_SHIFT1
10473             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10474    && ix86_match_ccmode (insn, CCGOCmode)
10475    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10477   switch (get_attr_type (insn))
10478     {
10479     case TYPE_ALU:
10480       gcc_assert (operands[2] == const1_rtx);
10481       return "add{w}\t%0, %0";
10483     default:
10484       if (REG_P (operands[2]))
10485         return "sal{w}\t{%b2, %0|%0, %b2}";
10486       else if (operands[2] == const1_rtx
10487                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10488         return "sal{w}\t%0";
10489       else
10490         return "sal{w}\t{%2, %0|%0, %2}";
10491     }
10493   [(set (attr "type")
10494      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10495                           (const_int 0))
10496                       (match_operand 0 "register_operand" ""))
10497                  (match_operand 2 "const1_operand" ""))
10498               (const_string "alu")
10499            ]
10500            (const_string "ishift")))
10501    (set (attr "length_immediate")
10502      (if_then_else
10503        (ior (eq_attr "type" "alu")
10504             (and (eq_attr "type" "ishift")
10505                  (and (match_operand 2 "const1_operand" "")
10506                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10507                           (const_int 0)))))
10508        (const_string "0")
10509        (const_string "*")))
10510    (set_attr "mode" "HI")])
10512 (define_insn "*ashlhi3_cconly"
10513   [(set (reg FLAGS_REG)
10514         (compare
10515           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10516                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10517           (const_int 0)))
10518    (clobber (match_scratch:HI 0 "=r"))]
10519   "(optimize_function_for_size_p (cfun)
10520     || !TARGET_PARTIAL_FLAG_REG_STALL
10521     || (operands[2] == const1_rtx
10522         && (TARGET_SHIFT1
10523             || TARGET_DOUBLE_WITH_ADD)))
10524    && ix86_match_ccmode (insn, CCGOCmode)
10525    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10527   switch (get_attr_type (insn))
10528     {
10529     case TYPE_ALU:
10530       gcc_assert (operands[2] == const1_rtx);
10531       return "add{w}\t%0, %0";
10533     default:
10534       if (REG_P (operands[2]))
10535         return "sal{w}\t{%b2, %0|%0, %b2}";
10536       else if (operands[2] == const1_rtx
10537                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10538         return "sal{w}\t%0";
10539       else
10540         return "sal{w}\t{%2, %0|%0, %2}";
10541     }
10543   [(set (attr "type")
10544      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10545                           (const_int 0))
10546                       (match_operand 0 "register_operand" ""))
10547                  (match_operand 2 "const1_operand" ""))
10548               (const_string "alu")
10549            ]
10550            (const_string "ishift")))
10551    (set (attr "length_immediate")
10552      (if_then_else
10553        (ior (eq_attr "type" "alu")
10554             (and (eq_attr "type" "ishift")
10555                  (and (match_operand 2 "const1_operand" "")
10556                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10557                           (const_int 0)))))
10558        (const_string "0")
10559        (const_string "*")))
10560    (set_attr "mode" "HI")])
10562 (define_expand "ashlqi3"
10563   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10564         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10565                    (match_operand:QI 2 "nonmemory_operand" "")))]
10566   "TARGET_QIMODE_MATH"
10567   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10569 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10571 (define_insn "*ashlqi3_1_lea"
10572   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10573         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10574                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10575    (clobber (reg:CC FLAGS_REG))]
10576   "!TARGET_PARTIAL_REG_STALL
10577    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10579   switch (get_attr_type (insn))
10580     {
10581     case TYPE_LEA:
10582       return "#";
10583     case TYPE_ALU:
10584       gcc_assert (operands[2] == const1_rtx);
10585       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10586         return "add{l}\t%k0, %k0";
10587       else
10588         return "add{b}\t%0, %0";
10590     default:
10591       if (REG_P (operands[2]))
10592         {
10593           if (get_attr_mode (insn) == MODE_SI)
10594             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10595           else
10596             return "sal{b}\t{%b2, %0|%0, %b2}";
10597         }
10598       else if (operands[2] == const1_rtx
10599                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10600         {
10601           if (get_attr_mode (insn) == MODE_SI)
10602             return "sal{l}\t%0";
10603           else
10604             return "sal{b}\t%0";
10605         }
10606       else
10607         {
10608           if (get_attr_mode (insn) == MODE_SI)
10609             return "sal{l}\t{%2, %k0|%k0, %2}";
10610           else
10611             return "sal{b}\t{%2, %0|%0, %2}";
10612         }
10613     }
10615   [(set (attr "type")
10616      (cond [(eq_attr "alternative" "2")
10617               (const_string "lea")
10618             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10619                           (const_int 0))
10620                       (match_operand 0 "register_operand" ""))
10621                  (match_operand 2 "const1_operand" ""))
10622               (const_string "alu")
10623            ]
10624            (const_string "ishift")))
10625    (set (attr "length_immediate")
10626      (if_then_else
10627        (ior (eq_attr "type" "alu")
10628             (and (eq_attr "type" "ishift")
10629                  (and (match_operand 2 "const1_operand" "")
10630                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10631                           (const_int 0)))))
10632        (const_string "0")
10633        (const_string "*")))
10634    (set_attr "mode" "QI,SI,SI")])
10636 (define_insn "*ashlqi3_1"
10637   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10638         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10639                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10640    (clobber (reg:CC FLAGS_REG))]
10641   "TARGET_PARTIAL_REG_STALL
10642    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10644   switch (get_attr_type (insn))
10645     {
10646     case TYPE_ALU:
10647       gcc_assert (operands[2] == const1_rtx);
10648       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10649         return "add{l}\t%k0, %k0";
10650       else
10651         return "add{b}\t%0, %0";
10653     default:
10654       if (REG_P (operands[2]))
10655         {
10656           if (get_attr_mode (insn) == MODE_SI)
10657             return "sal{l}\t{%b2, %k0|%k0, %b2}";
10658           else
10659             return "sal{b}\t{%b2, %0|%0, %b2}";
10660         }
10661       else if (operands[2] == const1_rtx
10662                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10663         {
10664           if (get_attr_mode (insn) == MODE_SI)
10665             return "sal{l}\t%0";
10666           else
10667             return "sal{b}\t%0";
10668         }
10669       else
10670         {
10671           if (get_attr_mode (insn) == MODE_SI)
10672             return "sal{l}\t{%2, %k0|%k0, %2}";
10673           else
10674             return "sal{b}\t{%2, %0|%0, %2}";
10675         }
10676     }
10678   [(set (attr "type")
10679      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10680                           (const_int 0))
10681                       (match_operand 0 "register_operand" ""))
10682                  (match_operand 2 "const1_operand" ""))
10683               (const_string "alu")
10684            ]
10685            (const_string "ishift")))
10686    (set (attr "length_immediate")
10687      (if_then_else
10688        (ior (eq_attr "type" "alu")
10689             (and (eq_attr "type" "ishift")
10690                  (and (match_operand 2 "const1_operand" "")
10691                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10692                           (const_int 0)))))
10693        (const_string "0")
10694        (const_string "*")))
10695    (set_attr "mode" "QI,SI")])
10697 ;; This pattern can't accept a variable shift count, since shifts by
10698 ;; zero don't affect the flags.  We assume that shifts by constant
10699 ;; zero are optimized away.
10700 (define_insn "*ashlqi3_cmp"
10701   [(set (reg FLAGS_REG)
10702         (compare
10703           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10704                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10705           (const_int 0)))
10706    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10707         (ashift:QI (match_dup 1) (match_dup 2)))]
10708   "(optimize_function_for_size_p (cfun)
10709     || !TARGET_PARTIAL_FLAG_REG_STALL
10710     || (operands[2] == const1_rtx
10711         && (TARGET_SHIFT1
10712             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10713    && ix86_match_ccmode (insn, CCGOCmode)
10714    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10716   switch (get_attr_type (insn))
10717     {
10718     case TYPE_ALU:
10719       gcc_assert (operands[2] == const1_rtx);
10720       return "add{b}\t%0, %0";
10722     default:
10723       if (REG_P (operands[2]))
10724         return "sal{b}\t{%b2, %0|%0, %b2}";
10725       else if (operands[2] == const1_rtx
10726                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10727         return "sal{b}\t%0";
10728       else
10729         return "sal{b}\t{%2, %0|%0, %2}";
10730     }
10732   [(set (attr "type")
10733      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10734                           (const_int 0))
10735                       (match_operand 0 "register_operand" ""))
10736                  (match_operand 2 "const1_operand" ""))
10737               (const_string "alu")
10738            ]
10739            (const_string "ishift")))
10740    (set (attr "length_immediate")
10741      (if_then_else
10742        (ior (eq_attr "type" "alu")
10743             (and (eq_attr "type" "ishift")
10744                  (and (match_operand 2 "const1_operand" "")
10745                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10746                           (const_int 0)))))
10747        (const_string "0")
10748        (const_string "*")))
10749    (set_attr "mode" "QI")])
10751 (define_insn "*ashlqi3_cconly"
10752   [(set (reg FLAGS_REG)
10753         (compare
10754           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10755                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
10756           (const_int 0)))
10757    (clobber (match_scratch:QI 0 "=q"))]
10758   "(optimize_function_for_size_p (cfun)
10759     || !TARGET_PARTIAL_FLAG_REG_STALL
10760     || (operands[2] == const1_rtx
10761         && (TARGET_SHIFT1
10762             || TARGET_DOUBLE_WITH_ADD)))
10763    && ix86_match_ccmode (insn, CCGOCmode)
10764    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10766   switch (get_attr_type (insn))
10767     {
10768     case TYPE_ALU:
10769       gcc_assert (operands[2] == const1_rtx);
10770       return "add{b}\t%0, %0";
10772     default:
10773       if (REG_P (operands[2]))
10774         return "sal{b}\t{%b2, %0|%0, %b2}";
10775       else if (operands[2] == const1_rtx
10776                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10777         return "sal{b}\t%0";
10778       else
10779         return "sal{b}\t{%2, %0|%0, %2}";
10780     }
10782   [(set (attr "type")
10783      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10784                           (const_int 0))
10785                       (match_operand 0 "register_operand" ""))
10786                  (match_operand 2 "const1_operand" ""))
10787               (const_string "alu")
10788            ]
10789            (const_string "ishift")))
10790    (set (attr "length_immediate")
10791      (if_then_else
10792        (ior (eq_attr "type" "alu")
10793             (and (eq_attr "type" "ishift")
10794                  (and (match_operand 2 "const1_operand" "")
10795                       (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10796                           (const_int 0)))))
10797        (const_string "0")
10798        (const_string "*")))
10799    (set_attr "mode" "QI")])
10801 ;; See comment above `ashldi3' about how this works.
10803 (define_expand "ashrti3"
10804   [(set (match_operand:TI 0 "register_operand" "")
10805         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10806                      (match_operand:QI 2 "nonmemory_operand" "")))]
10807   "TARGET_64BIT"
10808   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
10810 (define_insn "*ashrti3_1"
10811   [(set (match_operand:TI 0 "register_operand" "=r")
10812         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
10813                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
10814    (clobber (reg:CC FLAGS_REG))]
10815   "TARGET_64BIT"
10816   "#"
10817   [(set_attr "type" "multi")])
10819 (define_peephole2
10820   [(match_scratch:DI 3 "r")
10821    (parallel [(set (match_operand:TI 0 "register_operand" "")
10822                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10823                                 (match_operand:QI 2 "nonmemory_operand" "")))
10824               (clobber (reg:CC FLAGS_REG))])
10825    (match_dup 3)]
10826   "TARGET_64BIT"
10827   [(const_int 0)]
10828   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
10830 (define_split
10831   [(set (match_operand:TI 0 "register_operand" "")
10832         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10833                      (match_operand:QI 2 "nonmemory_operand" "")))
10834    (clobber (reg:CC FLAGS_REG))]
10835   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10836                     ? epilogue_completed : reload_completed)"
10837   [(const_int 0)]
10838   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
10840 (define_insn "x86_64_shrd"
10841   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10842         (ior:DI (ashiftrt:DI (match_dup 0)
10843                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10844                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10845                   (minus:QI (const_int 64) (match_dup 2)))))
10846    (clobber (reg:CC FLAGS_REG))]
10847   "TARGET_64BIT"
10848   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10849   [(set_attr "type" "ishift")
10850    (set_attr "prefix_0f" "1")
10851    (set_attr "mode" "DI")
10852    (set_attr "athlon_decode" "vector")
10853    (set_attr "amdfam10_decode" "vector")])
10855 (define_expand "ashrdi3"
10856   [(set (match_operand:DI 0 "shiftdi_operand" "")
10857         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10858                      (match_operand:QI 2 "nonmemory_operand" "")))]
10859   ""
10860   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10862 (define_expand "x86_64_shift_adj_3"
10863   [(use (match_operand:DI 0 "register_operand" ""))
10864    (use (match_operand:DI 1 "register_operand" ""))
10865    (use (match_operand:QI 2 "register_operand" ""))]
10866   ""
10868   rtx label = gen_label_rtx ();
10869   rtx tmp;
10871   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10873   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10874   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10875   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10876                               gen_rtx_LABEL_REF (VOIDmode, label),
10877                               pc_rtx);
10878   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10879   JUMP_LABEL (tmp) = label;
10881   emit_move_insn (operands[0], operands[1]);
10882   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
10884   emit_label (label);
10885   LABEL_NUSES (label) = 1;
10887   DONE;
10890 (define_insn "ashrdi3_63_rex64"
10891   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10892         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10893                      (match_operand:DI 2 "const_int_operand" "i,i")))
10894    (clobber (reg:CC FLAGS_REG))]
10895   "TARGET_64BIT && INTVAL (operands[2]) == 63
10896    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10897    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10898   "@
10899    {cqto|cqo}
10900    sar{q}\t{%2, %0|%0, %2}"
10901   [(set_attr "type" "imovx,ishift")
10902    (set_attr "prefix_0f" "0,*")
10903    (set_attr "length_immediate" "0,*")
10904    (set_attr "modrm" "0,1")
10905    (set_attr "mode" "DI")])
10907 (define_insn "*ashrdi3_1_one_bit_rex64"
10908   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10909         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10910                      (match_operand:QI 2 "const1_operand" "")))
10911    (clobber (reg:CC FLAGS_REG))]
10912   "TARGET_64BIT
10913    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10914    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10915   "sar{q}\t%0"
10916   [(set_attr "type" "ishift")
10917    (set_attr "length_immediate" "0")
10918    (set_attr "mode" "DI")])
10920 (define_insn "*ashrdi3_1_rex64"
10921   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10922         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10923                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
10924    (clobber (reg:CC FLAGS_REG))]
10925   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10926   "@
10927    sar{q}\t{%2, %0|%0, %2}
10928    sar{q}\t{%b2, %0|%0, %b2}"
10929   [(set_attr "type" "ishift")
10930    (set_attr "mode" "DI")])
10932 ;; This pattern can't accept a variable shift count, since shifts by
10933 ;; zero don't affect the flags.  We assume that shifts by constant
10934 ;; zero are optimized away.
10935 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10936   [(set (reg FLAGS_REG)
10937         (compare
10938           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10939                        (match_operand:QI 2 "const1_operand" ""))
10940           (const_int 0)))
10941    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10942         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10943   "TARGET_64BIT
10944    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10945    && ix86_match_ccmode (insn, CCGOCmode)
10946    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10947   "sar{q}\t%0"
10948   [(set_attr "type" "ishift")
10949    (set_attr "length_immediate" "0")
10950    (set_attr "mode" "DI")])
10952 (define_insn "*ashrdi3_one_bit_cconly_rex64"
10953   [(set (reg FLAGS_REG)
10954         (compare
10955           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10956                        (match_operand:QI 2 "const1_operand" ""))
10957           (const_int 0)))
10958    (clobber (match_scratch:DI 0 "=r"))]
10959   "TARGET_64BIT
10960    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10961    && ix86_match_ccmode (insn, CCGOCmode)
10962    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10963   "sar{q}\t%0"
10964   [(set_attr "type" "ishift")
10965    (set_attr "length_immediate" "0")
10966    (set_attr "mode" "DI")])
10968 ;; This pattern can't accept a variable shift count, since shifts by
10969 ;; zero don't affect the flags.  We assume that shifts by constant
10970 ;; zero are optimized away.
10971 (define_insn "*ashrdi3_cmp_rex64"
10972   [(set (reg FLAGS_REG)
10973         (compare
10974           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10975                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
10976           (const_int 0)))
10977    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10978         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10979   "TARGET_64BIT
10980    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10981    && ix86_match_ccmode (insn, CCGOCmode)
10982    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10983   "sar{q}\t{%2, %0|%0, %2}"
10984   [(set_attr "type" "ishift")
10985    (set_attr "mode" "DI")])
10987 (define_insn "*ashrdi3_cconly_rex64"
10988   [(set (reg FLAGS_REG)
10989         (compare
10990           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10991                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
10992           (const_int 0)))
10993    (clobber (match_scratch:DI 0 "=r"))]
10994   "TARGET_64BIT
10995    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10996    && ix86_match_ccmode (insn, CCGOCmode)
10997    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10998   "sar{q}\t{%2, %0|%0, %2}"
10999   [(set_attr "type" "ishift")
11000    (set_attr "mode" "DI")])
11002 (define_insn "*ashrdi3_1"
11003   [(set (match_operand:DI 0 "register_operand" "=r")
11004         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11005                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11006    (clobber (reg:CC FLAGS_REG))]
11007   "!TARGET_64BIT"
11008   "#"
11009   [(set_attr "type" "multi")])
11011 ;; By default we don't ask for a scratch register, because when DImode
11012 ;; values are manipulated, registers are already at a premium.  But if
11013 ;; we have one handy, we won't turn it away.
11014 (define_peephole2
11015   [(match_scratch:SI 3 "r")
11016    (parallel [(set (match_operand:DI 0 "register_operand" "")
11017                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11018                                 (match_operand:QI 2 "nonmemory_operand" "")))
11019               (clobber (reg:CC FLAGS_REG))])
11020    (match_dup 3)]
11021   "!TARGET_64BIT && TARGET_CMOVE"
11022   [(const_int 0)]
11023   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11025 (define_split
11026   [(set (match_operand:DI 0 "register_operand" "")
11027         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11028                      (match_operand:QI 2 "nonmemory_operand" "")))
11029    (clobber (reg:CC FLAGS_REG))]
11030   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11031                      ? epilogue_completed : reload_completed)"
11032   [(const_int 0)]
11033   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11035 (define_insn "x86_shrd"
11036   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11037         (ior:SI (ashiftrt:SI (match_dup 0)
11038                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11039                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11040                   (minus:QI (const_int 32) (match_dup 2)))))
11041    (clobber (reg:CC FLAGS_REG))]
11042   ""
11043   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11044   [(set_attr "type" "ishift")
11045    (set_attr "prefix_0f" "1")
11046    (set_attr "pent_pair" "np")
11047    (set_attr "mode" "SI")])
11049 (define_expand "x86_shift_adj_3"
11050   [(use (match_operand:SI 0 "register_operand" ""))
11051    (use (match_operand:SI 1 "register_operand" ""))
11052    (use (match_operand:QI 2 "register_operand" ""))]
11053   ""
11055   rtx label = gen_label_rtx ();
11056   rtx tmp;
11058   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11060   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11061   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11062   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11063                               gen_rtx_LABEL_REF (VOIDmode, label),
11064                               pc_rtx);
11065   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11066   JUMP_LABEL (tmp) = label;
11068   emit_move_insn (operands[0], operands[1]);
11069   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11071   emit_label (label);
11072   LABEL_NUSES (label) = 1;
11074   DONE;
11077 (define_expand "ashrsi3_31"
11078   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11079                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11080                                 (match_operand:SI 2 "const_int_operand" "i,i")))
11081               (clobber (reg:CC FLAGS_REG))])]
11082   "")
11084 (define_insn "*ashrsi3_31"
11085   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11086         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11087                      (match_operand:SI 2 "const_int_operand" "i,i")))
11088    (clobber (reg:CC FLAGS_REG))]
11089   "INTVAL (operands[2]) == 31
11090    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11091    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11092   "@
11093    {cltd|cdq}
11094    sar{l}\t{%2, %0|%0, %2}"
11095   [(set_attr "type" "imovx,ishift")
11096    (set_attr "prefix_0f" "0,*")
11097    (set_attr "length_immediate" "0,*")
11098    (set_attr "modrm" "0,1")
11099    (set_attr "mode" "SI")])
11101 (define_insn "*ashrsi3_31_zext"
11102   [(set (match_operand:DI 0 "register_operand" "=*d,r")
11103         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11104                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
11105    (clobber (reg:CC FLAGS_REG))]
11106   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11107    && INTVAL (operands[2]) == 31
11108    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11109   "@
11110    {cltd|cdq}
11111    sar{l}\t{%2, %k0|%k0, %2}"
11112   [(set_attr "type" "imovx,ishift")
11113    (set_attr "prefix_0f" "0,*")
11114    (set_attr "length_immediate" "0,*")
11115    (set_attr "modrm" "0,1")
11116    (set_attr "mode" "SI")])
11118 (define_expand "ashrsi3"
11119   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11120         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11121                      (match_operand:QI 2 "nonmemory_operand" "")))]
11122   ""
11123   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11125 (define_insn "*ashrsi3_1_one_bit"
11126   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11127         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11128                      (match_operand:QI 2 "const1_operand" "")))
11129    (clobber (reg:CC FLAGS_REG))]
11130   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11131    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11132   "sar{l}\t%0"
11133   [(set_attr "type" "ishift")
11134    (set_attr "length_immediate" "0")
11135    (set_attr "mode" "SI")])
11137 (define_insn "*ashrsi3_1_one_bit_zext"
11138   [(set (match_operand:DI 0 "register_operand" "=r")
11139         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11140                                      (match_operand:QI 2 "const1_operand" ""))))
11141    (clobber (reg:CC FLAGS_REG))]
11142   "TARGET_64BIT
11143    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11144    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11145   "sar{l}\t%k0"
11146   [(set_attr "type" "ishift")
11147    (set_attr "length_immediate" "0")
11148    (set_attr "mode" "SI")])
11150 (define_insn "*ashrsi3_1"
11151   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11152         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11153                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11154    (clobber (reg:CC FLAGS_REG))]
11155   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11156   "@
11157    sar{l}\t{%2, %0|%0, %2}
11158    sar{l}\t{%b2, %0|%0, %b2}"
11159   [(set_attr "type" "ishift")
11160    (set_attr "mode" "SI")])
11162 (define_insn "*ashrsi3_1_zext"
11163   [(set (match_operand:DI 0 "register_operand" "=r,r")
11164         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11165                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11166    (clobber (reg:CC FLAGS_REG))]
11167   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11168   "@
11169    sar{l}\t{%2, %k0|%k0, %2}
11170    sar{l}\t{%b2, %k0|%k0, %b2}"
11171   [(set_attr "type" "ishift")
11172    (set_attr "mode" "SI")])
11174 ;; This pattern can't accept a variable shift count, since shifts by
11175 ;; zero don't affect the flags.  We assume that shifts by constant
11176 ;; zero are optimized away.
11177 (define_insn "*ashrsi3_one_bit_cmp"
11178   [(set (reg FLAGS_REG)
11179         (compare
11180           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11181                        (match_operand:QI 2 "const1_operand" ""))
11182           (const_int 0)))
11183    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11184         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11185   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11186    && ix86_match_ccmode (insn, CCGOCmode)
11187    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11188   "sar{l}\t%0"
11189   [(set_attr "type" "ishift")
11190    (set_attr "length_immediate" "0")
11191    (set_attr "mode" "SI")])
11193 (define_insn "*ashrsi3_one_bit_cconly"
11194   [(set (reg FLAGS_REG)
11195         (compare
11196           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11197                        (match_operand:QI 2 "const1_operand" ""))
11198           (const_int 0)))
11199    (clobber (match_scratch:SI 0 "=r"))]
11200   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11201    && ix86_match_ccmode (insn, CCGOCmode)
11202    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11203   "sar{l}\t%0"
11204   [(set_attr "type" "ishift")
11205    (set_attr "length_immediate" "0")
11206    (set_attr "mode" "SI")])
11208 (define_insn "*ashrsi3_one_bit_cmp_zext"
11209   [(set (reg FLAGS_REG)
11210         (compare
11211           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11212                        (match_operand:QI 2 "const1_operand" ""))
11213           (const_int 0)))
11214    (set (match_operand:DI 0 "register_operand" "=r")
11215         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11216   "TARGET_64BIT
11217    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11218    && ix86_match_ccmode (insn, CCmode)
11219    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11220   "sar{l}\t%k0"
11221   [(set_attr "type" "ishift")
11222    (set_attr "length_immediate" "0")
11223    (set_attr "mode" "SI")])
11225 ;; This pattern can't accept a variable shift count, since shifts by
11226 ;; zero don't affect the flags.  We assume that shifts by constant
11227 ;; zero are optimized away.
11228 (define_insn "*ashrsi3_cmp"
11229   [(set (reg FLAGS_REG)
11230         (compare
11231           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11232                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11233           (const_int 0)))
11234    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11235         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11236   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11237    && ix86_match_ccmode (insn, CCGOCmode)
11238    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11239   "sar{l}\t{%2, %0|%0, %2}"
11240   [(set_attr "type" "ishift")
11241    (set_attr "mode" "SI")])
11243 (define_insn "*ashrsi3_cconly"
11244   [(set (reg FLAGS_REG)
11245         (compare
11246           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11247                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11248           (const_int 0)))
11249    (clobber (match_scratch:SI 0 "=r"))]
11250   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11251    && ix86_match_ccmode (insn, CCGOCmode)
11252    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11253   "sar{l}\t{%2, %0|%0, %2}"
11254   [(set_attr "type" "ishift")
11255    (set_attr "mode" "SI")])
11257 (define_insn "*ashrsi3_cmp_zext"
11258   [(set (reg FLAGS_REG)
11259         (compare
11260           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11261                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11262           (const_int 0)))
11263    (set (match_operand:DI 0 "register_operand" "=r")
11264         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11265   "TARGET_64BIT
11266    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11267    && ix86_match_ccmode (insn, CCGOCmode)
11268    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11269   "sar{l}\t{%2, %k0|%k0, %2}"
11270   [(set_attr "type" "ishift")
11271    (set_attr "mode" "SI")])
11273 (define_expand "ashrhi3"
11274   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11275         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11276                      (match_operand:QI 2 "nonmemory_operand" "")))]
11277   "TARGET_HIMODE_MATH"
11278   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11280 (define_insn "*ashrhi3_1_one_bit"
11281   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11282         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11283                      (match_operand:QI 2 "const1_operand" "")))
11284    (clobber (reg:CC FLAGS_REG))]
11285   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11286    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11287   "sar{w}\t%0"
11288   [(set_attr "type" "ishift")
11289    (set_attr "length_immediate" "0")
11290    (set_attr "mode" "HI")])
11292 (define_insn "*ashrhi3_1"
11293   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11294         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11295                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11296    (clobber (reg:CC FLAGS_REG))]
11297   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11298   "@
11299    sar{w}\t{%2, %0|%0, %2}
11300    sar{w}\t{%b2, %0|%0, %b2}"
11301   [(set_attr "type" "ishift")
11302    (set_attr "mode" "HI")])
11304 ;; This pattern can't accept a variable shift count, since shifts by
11305 ;; zero don't affect the flags.  We assume that shifts by constant
11306 ;; zero are optimized away.
11307 (define_insn "*ashrhi3_one_bit_cmp"
11308   [(set (reg FLAGS_REG)
11309         (compare
11310           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11311                        (match_operand:QI 2 "const1_operand" ""))
11312           (const_int 0)))
11313    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11314         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11315   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11316    && ix86_match_ccmode (insn, CCGOCmode)
11317    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11318   "sar{w}\t%0"
11319   [(set_attr "type" "ishift")
11320    (set_attr "length_immediate" "0")
11321    (set_attr "mode" "HI")])
11323 (define_insn "*ashrhi3_one_bit_cconly"
11324   [(set (reg FLAGS_REG)
11325         (compare
11326           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11327                        (match_operand:QI 2 "const1_operand" ""))
11328           (const_int 0)))
11329    (clobber (match_scratch:HI 0 "=r"))]
11330   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11331    && ix86_match_ccmode (insn, CCGOCmode)
11332    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11333   "sar{w}\t%0"
11334   [(set_attr "type" "ishift")
11335    (set_attr "length_immediate" "0")
11336    (set_attr "mode" "HI")])
11338 ;; This pattern can't accept a variable shift count, since shifts by
11339 ;; zero don't affect the flags.  We assume that shifts by constant
11340 ;; zero are optimized away.
11341 (define_insn "*ashrhi3_cmp"
11342   [(set (reg FLAGS_REG)
11343         (compare
11344           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11345                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11346           (const_int 0)))
11347    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11348         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11349   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11350    && ix86_match_ccmode (insn, CCGOCmode)
11351    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11352   "sar{w}\t{%2, %0|%0, %2}"
11353   [(set_attr "type" "ishift")
11354    (set_attr "mode" "HI")])
11356 (define_insn "*ashrhi3_cconly"
11357   [(set (reg FLAGS_REG)
11358         (compare
11359           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11360                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11361           (const_int 0)))
11362    (clobber (match_scratch:HI 0 "=r"))]
11363   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11364    && ix86_match_ccmode (insn, CCGOCmode)
11365    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11366   "sar{w}\t{%2, %0|%0, %2}"
11367   [(set_attr "type" "ishift")
11368    (set_attr "mode" "HI")])
11370 (define_expand "ashrqi3"
11371   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11372         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11373                      (match_operand:QI 2 "nonmemory_operand" "")))]
11374   "TARGET_QIMODE_MATH"
11375   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11377 (define_insn "*ashrqi3_1_one_bit"
11378   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11379         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11380                      (match_operand:QI 2 "const1_operand" "")))
11381    (clobber (reg:CC FLAGS_REG))]
11382   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11383    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11384   "sar{b}\t%0"
11385   [(set_attr "type" "ishift")
11386    (set_attr "length_immediate" "0")
11387    (set_attr "mode" "QI")])
11389 (define_insn "*ashrqi3_1_one_bit_slp"
11390   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11391         (ashiftrt:QI (match_dup 0)
11392                      (match_operand:QI 1 "const1_operand" "")))
11393    (clobber (reg:CC FLAGS_REG))]
11394   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11395    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11396    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11397   "sar{b}\t%0"
11398   [(set_attr "type" "ishift1")
11399    (set_attr "length_immediate" "0")
11400    (set_attr "mode" "QI")])
11402 (define_insn "*ashrqi3_1"
11403   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11404         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11405                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11406    (clobber (reg:CC FLAGS_REG))]
11407   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11408   "@
11409    sar{b}\t{%2, %0|%0, %2}
11410    sar{b}\t{%b2, %0|%0, %b2}"
11411   [(set_attr "type" "ishift")
11412    (set_attr "mode" "QI")])
11414 (define_insn "*ashrqi3_1_slp"
11415   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11416         (ashiftrt:QI (match_dup 0)
11417                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11418    (clobber (reg:CC FLAGS_REG))]
11419   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11420    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11421   "@
11422    sar{b}\t{%1, %0|%0, %1}
11423    sar{b}\t{%b1, %0|%0, %b1}"
11424   [(set_attr "type" "ishift1")
11425    (set_attr "mode" "QI")])
11427 ;; This pattern can't accept a variable shift count, since shifts by
11428 ;; zero don't affect the flags.  We assume that shifts by constant
11429 ;; zero are optimized away.
11430 (define_insn "*ashrqi3_one_bit_cmp"
11431   [(set (reg FLAGS_REG)
11432         (compare
11433           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11434                        (match_operand:QI 2 "const1_operand" "I"))
11435           (const_int 0)))
11436    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11437         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11438   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11439    && ix86_match_ccmode (insn, CCGOCmode)
11440    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11441   "sar{b}\t%0"
11442   [(set_attr "type" "ishift")
11443    (set_attr "length_immediate" "0")
11444    (set_attr "mode" "QI")])
11446 (define_insn "*ashrqi3_one_bit_cconly"
11447   [(set (reg FLAGS_REG)
11448         (compare
11449           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11450                        (match_operand:QI 2 "const1_operand" ""))
11451           (const_int 0)))
11452    (clobber (match_scratch:QI 0 "=q"))]
11453   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11454    && ix86_match_ccmode (insn, CCGOCmode)
11455    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11456   "sar{b}\t%0"
11457   [(set_attr "type" "ishift")
11458    (set_attr "length_immediate" "0")
11459    (set_attr "mode" "QI")])
11461 ;; This pattern can't accept a variable shift count, since shifts by
11462 ;; zero don't affect the flags.  We assume that shifts by constant
11463 ;; zero are optimized away.
11464 (define_insn "*ashrqi3_cmp"
11465   [(set (reg FLAGS_REG)
11466         (compare
11467           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11468                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11469           (const_int 0)))
11470    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11471         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11472   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11473    && ix86_match_ccmode (insn, CCGOCmode)
11474    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11475   "sar{b}\t{%2, %0|%0, %2}"
11476   [(set_attr "type" "ishift")
11477    (set_attr "mode" "QI")])
11479 (define_insn "*ashrqi3_cconly"
11480   [(set (reg FLAGS_REG)
11481         (compare
11482           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11483                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11484           (const_int 0)))
11485    (clobber (match_scratch:QI 0 "=q"))]
11486   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11487    && ix86_match_ccmode (insn, CCGOCmode)
11488    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11489   "sar{b}\t{%2, %0|%0, %2}"
11490   [(set_attr "type" "ishift")
11491    (set_attr "mode" "QI")])
11494 ;; Logical shift instructions
11496 ;; See comment above `ashldi3' about how this works.
11498 (define_expand "lshrti3"
11499   [(set (match_operand:TI 0 "register_operand" "")
11500         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11501                      (match_operand:QI 2 "nonmemory_operand" "")))]
11502   "TARGET_64BIT"
11503   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
11505 (define_insn "*lshrti3_1"
11506   [(set (match_operand:TI 0 "register_operand" "=r")
11507         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11508                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
11509    (clobber (reg:CC FLAGS_REG))]
11510   "TARGET_64BIT"
11511   "#"
11512   [(set_attr "type" "multi")])
11514 (define_peephole2
11515   [(match_scratch:DI 3 "r")
11516    (parallel [(set (match_operand:TI 0 "register_operand" "")
11517                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11518                                 (match_operand:QI 2 "nonmemory_operand" "")))
11519               (clobber (reg:CC FLAGS_REG))])
11520    (match_dup 3)]
11521   "TARGET_64BIT"
11522   [(const_int 0)]
11523   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11525 (define_split
11526   [(set (match_operand:TI 0 "register_operand" "")
11527         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11528                      (match_operand:QI 2 "nonmemory_operand" "")))
11529    (clobber (reg:CC FLAGS_REG))]
11530   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11531                     ? epilogue_completed : reload_completed)"
11532   [(const_int 0)]
11533   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11535 (define_expand "lshrdi3"
11536   [(set (match_operand:DI 0 "shiftdi_operand" "")
11537         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11538                      (match_operand:QI 2 "nonmemory_operand" "")))]
11539   ""
11540   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11542 (define_insn "*lshrdi3_1_one_bit_rex64"
11543   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11544         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11545                      (match_operand:QI 2 "const1_operand" "")))
11546    (clobber (reg:CC FLAGS_REG))]
11547   "TARGET_64BIT
11548    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11549    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11550   "shr{q}\t%0"
11551   [(set_attr "type" "ishift")
11552    (set_attr "length_immediate" "0")
11553    (set_attr "mode" "DI")])
11555 (define_insn "*lshrdi3_1_rex64"
11556   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11557         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11558                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11559    (clobber (reg:CC FLAGS_REG))]
11560   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11561   "@
11562    shr{q}\t{%2, %0|%0, %2}
11563    shr{q}\t{%b2, %0|%0, %b2}"
11564   [(set_attr "type" "ishift")
11565    (set_attr "mode" "DI")])
11567 ;; This pattern can't accept a variable shift count, since shifts by
11568 ;; zero don't affect the flags.  We assume that shifts by constant
11569 ;; zero are optimized away.
11570 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11571   [(set (reg FLAGS_REG)
11572         (compare
11573           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11574                        (match_operand:QI 2 "const1_operand" ""))
11575           (const_int 0)))
11576    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11577         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11578   "TARGET_64BIT
11579    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11580    && ix86_match_ccmode (insn, CCGOCmode)
11581    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11582   "shr{q}\t%0"
11583   [(set_attr "type" "ishift")
11584    (set_attr "length_immediate" "0")
11585    (set_attr "mode" "DI")])
11587 (define_insn "*lshrdi3_cconly_one_bit_rex64"
11588   [(set (reg FLAGS_REG)
11589         (compare
11590           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11591                        (match_operand:QI 2 "const1_operand" ""))
11592           (const_int 0)))
11593    (clobber (match_scratch:DI 0 "=r"))]
11594   "TARGET_64BIT
11595    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11596    && ix86_match_ccmode (insn, CCGOCmode)
11597    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11598   "shr{q}\t%0"
11599   [(set_attr "type" "ishift")
11600    (set_attr "length_immediate" "0")
11601    (set_attr "mode" "DI")])
11603 ;; This pattern can't accept a variable shift count, since shifts by
11604 ;; zero don't affect the flags.  We assume that shifts by constant
11605 ;; zero are optimized away.
11606 (define_insn "*lshrdi3_cmp_rex64"
11607   [(set (reg FLAGS_REG)
11608         (compare
11609           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11610                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11611           (const_int 0)))
11612    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11613         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11614   "TARGET_64BIT
11615    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11616    && ix86_match_ccmode (insn, CCGOCmode)
11617    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11618   "shr{q}\t{%2, %0|%0, %2}"
11619   [(set_attr "type" "ishift")
11620    (set_attr "mode" "DI")])
11622 (define_insn "*lshrdi3_cconly_rex64"
11623   [(set (reg FLAGS_REG)
11624         (compare
11625           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11626                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11627           (const_int 0)))
11628    (clobber (match_scratch:DI 0 "=r"))]
11629   "TARGET_64BIT
11630    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11631    && ix86_match_ccmode (insn, CCGOCmode)
11632    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11633   "shr{q}\t{%2, %0|%0, %2}"
11634   [(set_attr "type" "ishift")
11635    (set_attr "mode" "DI")])
11637 (define_insn "*lshrdi3_1"
11638   [(set (match_operand:DI 0 "register_operand" "=r")
11639         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11640                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11641    (clobber (reg:CC FLAGS_REG))]
11642   "!TARGET_64BIT"
11643   "#"
11644   [(set_attr "type" "multi")])
11646 ;; By default we don't ask for a scratch register, because when DImode
11647 ;; values are manipulated, registers are already at a premium.  But if
11648 ;; we have one handy, we won't turn it away.
11649 (define_peephole2
11650   [(match_scratch:SI 3 "r")
11651    (parallel [(set (match_operand:DI 0 "register_operand" "")
11652                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11653                                 (match_operand:QI 2 "nonmemory_operand" "")))
11654               (clobber (reg:CC FLAGS_REG))])
11655    (match_dup 3)]
11656   "!TARGET_64BIT && TARGET_CMOVE"
11657   [(const_int 0)]
11658   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11660 (define_split
11661   [(set (match_operand:DI 0 "register_operand" "")
11662         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11663                      (match_operand:QI 2 "nonmemory_operand" "")))
11664    (clobber (reg:CC FLAGS_REG))]
11665   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11666                      ? epilogue_completed : reload_completed)"
11667   [(const_int 0)]
11668   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11670 (define_expand "lshrsi3"
11671   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11672         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11673                      (match_operand:QI 2 "nonmemory_operand" "")))]
11674   ""
11675   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11677 (define_insn "*lshrsi3_1_one_bit"
11678   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11679         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11680                      (match_operand:QI 2 "const1_operand" "")))
11681    (clobber (reg:CC FLAGS_REG))]
11682   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11683    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11684   "shr{l}\t%0"
11685   [(set_attr "type" "ishift")
11686    (set_attr "length_immediate" "0")
11687    (set_attr "mode" "SI")])
11689 (define_insn "*lshrsi3_1_one_bit_zext"
11690   [(set (match_operand:DI 0 "register_operand" "=r")
11691         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11692                      (match_operand:QI 2 "const1_operand" "")))
11693    (clobber (reg:CC FLAGS_REG))]
11694   "TARGET_64BIT
11695    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11696    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11697   "shr{l}\t%k0"
11698   [(set_attr "type" "ishift")
11699    (set_attr "length_immediate" "0")
11700    (set_attr "mode" "SI")])
11702 (define_insn "*lshrsi3_1"
11703   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11704         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11705                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11706    (clobber (reg:CC FLAGS_REG))]
11707   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11708   "@
11709    shr{l}\t{%2, %0|%0, %2}
11710    shr{l}\t{%b2, %0|%0, %b2}"
11711   [(set_attr "type" "ishift")
11712    (set_attr "mode" "SI")])
11714 (define_insn "*lshrsi3_1_zext"
11715   [(set (match_operand:DI 0 "register_operand" "=r,r")
11716         (zero_extend:DI
11717           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11718                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11719    (clobber (reg:CC FLAGS_REG))]
11720   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11721   "@
11722    shr{l}\t{%2, %k0|%k0, %2}
11723    shr{l}\t{%b2, %k0|%k0, %b2}"
11724   [(set_attr "type" "ishift")
11725    (set_attr "mode" "SI")])
11727 ;; This pattern can't accept a variable shift count, since shifts by
11728 ;; zero don't affect the flags.  We assume that shifts by constant
11729 ;; zero are optimized away.
11730 (define_insn "*lshrsi3_one_bit_cmp"
11731   [(set (reg FLAGS_REG)
11732         (compare
11733           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11734                        (match_operand:QI 2 "const1_operand" ""))
11735           (const_int 0)))
11736    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11737         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11738   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11739    && ix86_match_ccmode (insn, CCGOCmode)
11740    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11741   "shr{l}\t%0"
11742   [(set_attr "type" "ishift")
11743    (set_attr "length_immediate" "0")
11744    (set_attr "mode" "SI")])
11746 (define_insn "*lshrsi3_one_bit_cconly"
11747   [(set (reg FLAGS_REG)
11748         (compare
11749           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11750                        (match_operand:QI 2 "const1_operand" ""))
11751           (const_int 0)))
11752    (clobber (match_scratch:SI 0 "=r"))]
11753   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11754    && ix86_match_ccmode (insn, CCGOCmode)
11755    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11756   "shr{l}\t%0"
11757   [(set_attr "type" "ishift")
11758    (set_attr "length_immediate" "0")
11759    (set_attr "mode" "SI")])
11761 (define_insn "*lshrsi3_cmp_one_bit_zext"
11762   [(set (reg FLAGS_REG)
11763         (compare
11764           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11765                        (match_operand:QI 2 "const1_operand" ""))
11766           (const_int 0)))
11767    (set (match_operand:DI 0 "register_operand" "=r")
11768         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11769   "TARGET_64BIT
11770    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11771    && ix86_match_ccmode (insn, CCGOCmode)
11772    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11773   "shr{l}\t%k0"
11774   [(set_attr "type" "ishift")
11775    (set_attr "length_immediate" "0")
11776    (set_attr "mode" "SI")])
11778 ;; This pattern can't accept a variable shift count, since shifts by
11779 ;; zero don't affect the flags.  We assume that shifts by constant
11780 ;; zero are optimized away.
11781 (define_insn "*lshrsi3_cmp"
11782   [(set (reg FLAGS_REG)
11783         (compare
11784           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11785                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11786           (const_int 0)))
11787    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11788         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11789   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11790    && ix86_match_ccmode (insn, CCGOCmode)
11791    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11792   "shr{l}\t{%2, %0|%0, %2}"
11793   [(set_attr "type" "ishift")
11794    (set_attr "mode" "SI")])
11796 (define_insn "*lshrsi3_cconly"
11797   [(set (reg FLAGS_REG)
11798       (compare
11799         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11800                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11801         (const_int 0)))
11802    (clobber (match_scratch:SI 0 "=r"))]
11803   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11804    && ix86_match_ccmode (insn, CCGOCmode)
11805    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11806   "shr{l}\t{%2, %0|%0, %2}"
11807   [(set_attr "type" "ishift")
11808    (set_attr "mode" "SI")])
11810 (define_insn "*lshrsi3_cmp_zext"
11811   [(set (reg FLAGS_REG)
11812         (compare
11813           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11814                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11815           (const_int 0)))
11816    (set (match_operand:DI 0 "register_operand" "=r")
11817         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11818   "TARGET_64BIT
11819    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11820    && ix86_match_ccmode (insn, CCGOCmode)
11821    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11822   "shr{l}\t{%2, %k0|%k0, %2}"
11823   [(set_attr "type" "ishift")
11824    (set_attr "mode" "SI")])
11826 (define_expand "lshrhi3"
11827   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11828         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11829                      (match_operand:QI 2 "nonmemory_operand" "")))]
11830   "TARGET_HIMODE_MATH"
11831   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11833 (define_insn "*lshrhi3_1_one_bit"
11834   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11835         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11836                      (match_operand:QI 2 "const1_operand" "")))
11837    (clobber (reg:CC FLAGS_REG))]
11838   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11839    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11840   "shr{w}\t%0"
11841   [(set_attr "type" "ishift")
11842    (set_attr "length_immediate" "0")
11843    (set_attr "mode" "HI")])
11845 (define_insn "*lshrhi3_1"
11846   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11847         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11848                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11849    (clobber (reg:CC FLAGS_REG))]
11850   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11851   "@
11852    shr{w}\t{%2, %0|%0, %2}
11853    shr{w}\t{%b2, %0|%0, %b2}"
11854   [(set_attr "type" "ishift")
11855    (set_attr "mode" "HI")])
11857 ;; This pattern can't accept a variable shift count, since shifts by
11858 ;; zero don't affect the flags.  We assume that shifts by constant
11859 ;; zero are optimized away.
11860 (define_insn "*lshrhi3_one_bit_cmp"
11861   [(set (reg FLAGS_REG)
11862         (compare
11863           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11864                        (match_operand:QI 2 "const1_operand" ""))
11865           (const_int 0)))
11866    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11867         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11868   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11869    && ix86_match_ccmode (insn, CCGOCmode)
11870    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11871   "shr{w}\t%0"
11872   [(set_attr "type" "ishift")
11873    (set_attr "length_immediate" "0")
11874    (set_attr "mode" "HI")])
11876 (define_insn "*lshrhi3_one_bit_cconly"
11877   [(set (reg FLAGS_REG)
11878         (compare
11879           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11880                        (match_operand:QI 2 "const1_operand" ""))
11881           (const_int 0)))
11882    (clobber (match_scratch:HI 0 "=r"))]
11883   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11884    && ix86_match_ccmode (insn, CCGOCmode)
11885    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11886   "shr{w}\t%0"
11887   [(set_attr "type" "ishift")
11888    (set_attr "length_immediate" "0")
11889    (set_attr "mode" "HI")])
11891 ;; This pattern can't accept a variable shift count, since shifts by
11892 ;; zero don't affect the flags.  We assume that shifts by constant
11893 ;; zero are optimized away.
11894 (define_insn "*lshrhi3_cmp"
11895   [(set (reg FLAGS_REG)
11896         (compare
11897           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11898                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11899           (const_int 0)))
11900    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11901         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11902   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11903    && ix86_match_ccmode (insn, CCGOCmode)
11904    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11905   "shr{w}\t{%2, %0|%0, %2}"
11906   [(set_attr "type" "ishift")
11907    (set_attr "mode" "HI")])
11909 (define_insn "*lshrhi3_cconly"
11910   [(set (reg FLAGS_REG)
11911         (compare
11912           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11913                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
11914           (const_int 0)))
11915    (clobber (match_scratch:HI 0 "=r"))]
11916   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11917    && ix86_match_ccmode (insn, CCGOCmode)
11918    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11919   "shr{w}\t{%2, %0|%0, %2}"
11920   [(set_attr "type" "ishift")
11921    (set_attr "mode" "HI")])
11923 (define_expand "lshrqi3"
11924   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11925         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11926                      (match_operand:QI 2 "nonmemory_operand" "")))]
11927   "TARGET_QIMODE_MATH"
11928   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11930 (define_insn "*lshrqi3_1_one_bit"
11931   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11932         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11933                      (match_operand:QI 2 "const1_operand" "")))
11934    (clobber (reg:CC FLAGS_REG))]
11935   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11936    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11937   "shr{b}\t%0"
11938   [(set_attr "type" "ishift")
11939    (set_attr "length_immediate" "0")
11940    (set_attr "mode" "QI")])
11942 (define_insn "*lshrqi3_1_one_bit_slp"
11943   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11944         (lshiftrt:QI (match_dup 0)
11945                      (match_operand:QI 1 "const1_operand" "")))
11946    (clobber (reg:CC FLAGS_REG))]
11947   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11948    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
11949   "shr{b}\t%0"
11950   [(set_attr "type" "ishift1")
11951    (set_attr "length_immediate" "0")
11952    (set_attr "mode" "QI")])
11954 (define_insn "*lshrqi3_1"
11955   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11956         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11957                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
11958    (clobber (reg:CC FLAGS_REG))]
11959   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11960   "@
11961    shr{b}\t{%2, %0|%0, %2}
11962    shr{b}\t{%b2, %0|%0, %b2}"
11963   [(set_attr "type" "ishift")
11964    (set_attr "mode" "QI")])
11966 (define_insn "*lshrqi3_1_slp"
11967   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11968         (lshiftrt:QI (match_dup 0)
11969                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
11970    (clobber (reg:CC FLAGS_REG))]
11971   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11972    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11973   "@
11974    shr{b}\t{%1, %0|%0, %1}
11975    shr{b}\t{%b1, %0|%0, %b1}"
11976   [(set_attr "type" "ishift1")
11977    (set_attr "mode" "QI")])
11979 ;; This pattern can't accept a variable shift count, since shifts by
11980 ;; zero don't affect the flags.  We assume that shifts by constant
11981 ;; zero are optimized away.
11982 (define_insn "*lshrqi2_one_bit_cmp"
11983   [(set (reg FLAGS_REG)
11984         (compare
11985           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11986                        (match_operand:QI 2 "const1_operand" ""))
11987           (const_int 0)))
11988    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11989         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11990   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11991    && ix86_match_ccmode (insn, CCGOCmode)
11992    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11993   "shr{b}\t%0"
11994   [(set_attr "type" "ishift")
11995    (set_attr "length_immediate" "0")
11996    (set_attr "mode" "QI")])
11998 (define_insn "*lshrqi2_one_bit_cconly"
11999   [(set (reg FLAGS_REG)
12000         (compare
12001           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12002                        (match_operand:QI 2 "const1_operand" ""))
12003           (const_int 0)))
12004    (clobber (match_scratch:QI 0 "=q"))]
12005   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12006    && ix86_match_ccmode (insn, CCGOCmode)
12007    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12008   "shr{b}\t%0"
12009   [(set_attr "type" "ishift")
12010    (set_attr "length_immediate" "0")
12011    (set_attr "mode" "QI")])
12013 ;; This pattern can't accept a variable shift count, since shifts by
12014 ;; zero don't affect the flags.  We assume that shifts by constant
12015 ;; zero are optimized away.
12016 (define_insn "*lshrqi2_cmp"
12017   [(set (reg FLAGS_REG)
12018         (compare
12019           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12020                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12021           (const_int 0)))
12022    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12023         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12024   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12025    && ix86_match_ccmode (insn, CCGOCmode)
12026    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12027   "shr{b}\t{%2, %0|%0, %2}"
12028   [(set_attr "type" "ishift")
12029    (set_attr "mode" "QI")])
12031 (define_insn "*lshrqi2_cconly"
12032   [(set (reg FLAGS_REG)
12033         (compare
12034           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12035                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12036           (const_int 0)))
12037    (clobber (match_scratch:QI 0 "=q"))]
12038   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12039    && ix86_match_ccmode (insn, CCGOCmode)
12040    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12041   "shr{b}\t{%2, %0|%0, %2}"
12042   [(set_attr "type" "ishift")
12043    (set_attr "mode" "QI")])
12045 ;; Rotate instructions
12047 (define_expand "rotldi3"
12048   [(set (match_operand:DI 0 "shiftdi_operand" "")
12049         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12050                    (match_operand:QI 2 "nonmemory_operand" "")))]
12051  ""
12053   if (TARGET_64BIT)
12054     {
12055       ix86_expand_binary_operator (ROTATE, DImode, operands);
12056       DONE;
12057     }
12058   if (!const_1_to_31_operand (operands[2], VOIDmode))
12059     FAIL;
12060   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12061   DONE;
12064 ;; Implement rotation using two double-precision shift instructions
12065 ;; and a scratch register.
12066 (define_insn_and_split "ix86_rotldi3"
12067  [(set (match_operand:DI 0 "register_operand" "=r")
12068        (rotate:DI (match_operand:DI 1 "register_operand" "0")
12069                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
12070   (clobber (reg:CC FLAGS_REG))
12071   (clobber (match_scratch:SI 3 "=&r"))]
12072  "!TARGET_64BIT"
12073  ""
12074  "&& reload_completed"
12075  [(set (match_dup 3) (match_dup 4))
12076   (parallel
12077    [(set (match_dup 4)
12078          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12079                  (lshiftrt:SI (match_dup 5)
12080                               (minus:QI (const_int 32) (match_dup 2)))))
12081     (clobber (reg:CC FLAGS_REG))])
12082   (parallel
12083    [(set (match_dup 5)
12084          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12085                  (lshiftrt:SI (match_dup 3)
12086                               (minus:QI (const_int 32) (match_dup 2)))))
12087     (clobber (reg:CC FLAGS_REG))])]
12088  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12090 (define_insn "*rotlsi3_1_one_bit_rex64"
12091   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12092         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12093                    (match_operand:QI 2 "const1_operand" "")))
12094    (clobber (reg:CC FLAGS_REG))]
12095   "TARGET_64BIT
12096    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12097    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12098   "rol{q}\t%0"
12099   [(set_attr "type" "rotate")
12100    (set_attr "length_immediate" "0")
12101    (set_attr "mode" "DI")])
12103 (define_insn "*rotldi3_1_rex64"
12104   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12105         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12106                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
12107    (clobber (reg:CC FLAGS_REG))]
12108   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12109   "@
12110    rol{q}\t{%2, %0|%0, %2}
12111    rol{q}\t{%b2, %0|%0, %b2}"
12112   [(set_attr "type" "rotate")
12113    (set_attr "mode" "DI")])
12115 (define_expand "rotlsi3"
12116   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12117         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12118                    (match_operand:QI 2 "nonmemory_operand" "")))]
12119   ""
12120   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12122 (define_insn "*rotlsi3_1_one_bit"
12123   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12124         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12125                    (match_operand:QI 2 "const1_operand" "")))
12126    (clobber (reg:CC FLAGS_REG))]
12127   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12128    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12129   "rol{l}\t%0"
12130   [(set_attr "type" "rotate")
12131    (set_attr "length_immediate" "0")
12132    (set_attr "mode" "SI")])
12134 (define_insn "*rotlsi3_1_one_bit_zext"
12135   [(set (match_operand:DI 0 "register_operand" "=r")
12136         (zero_extend:DI
12137           (rotate:SI (match_operand:SI 1 "register_operand" "0")
12138                      (match_operand:QI 2 "const1_operand" ""))))
12139    (clobber (reg:CC FLAGS_REG))]
12140   "TARGET_64BIT
12141    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12142    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12143   "rol{l}\t%k0"
12144   [(set_attr "type" "rotate")
12145    (set_attr "length_immediate" "0")
12146    (set_attr "mode" "SI")])
12148 (define_insn "*rotlsi3_1"
12149   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12150         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12151                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12152    (clobber (reg:CC FLAGS_REG))]
12153   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12154   "@
12155    rol{l}\t{%2, %0|%0, %2}
12156    rol{l}\t{%b2, %0|%0, %b2}"
12157   [(set_attr "type" "rotate")
12158    (set_attr "mode" "SI")])
12160 (define_insn "*rotlsi3_1_zext"
12161   [(set (match_operand:DI 0 "register_operand" "=r,r")
12162         (zero_extend:DI
12163           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12164                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12165    (clobber (reg:CC FLAGS_REG))]
12166   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12167   "@
12168    rol{l}\t{%2, %k0|%k0, %2}
12169    rol{l}\t{%b2, %k0|%k0, %b2}"
12170   [(set_attr "type" "rotate")
12171    (set_attr "mode" "SI")])
12173 (define_expand "rotlhi3"
12174   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12175         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12176                    (match_operand:QI 2 "nonmemory_operand" "")))]
12177   "TARGET_HIMODE_MATH"
12178   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12180 (define_insn "*rotlhi3_1_one_bit"
12181   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12182         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12183                    (match_operand:QI 2 "const1_operand" "")))
12184    (clobber (reg:CC FLAGS_REG))]
12185   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12186    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
12187   "rol{w}\t%0"
12188   [(set_attr "type" "rotate")
12189    (set_attr "length_immediate" "0")
12190    (set_attr "mode" "HI")])
12192 (define_insn "*rotlhi3_1"
12193   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12194         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12195                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12196    (clobber (reg:CC FLAGS_REG))]
12197   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12198   "@
12199    rol{w}\t{%2, %0|%0, %2}
12200    rol{w}\t{%b2, %0|%0, %b2}"
12201   [(set_attr "type" "rotate")
12202    (set_attr "mode" "HI")])
12204 (define_split
12205  [(set (match_operand:HI 0 "register_operand" "")
12206        (rotate:HI (match_dup 0) (const_int 8)))
12207   (clobber (reg:CC FLAGS_REG))]
12208  "reload_completed"
12209  [(parallel [(set (strict_low_part (match_dup 0))
12210                   (bswap:HI (match_dup 0)))
12211              (clobber (reg:CC FLAGS_REG))])]
12212  "")
12214 (define_expand "rotlqi3"
12215   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12216         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12217                    (match_operand:QI 2 "nonmemory_operand" "")))]
12218   "TARGET_QIMODE_MATH"
12219   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12221 (define_insn "*rotlqi3_1_one_bit_slp"
12222   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12223         (rotate:QI (match_dup 0)
12224                    (match_operand:QI 1 "const1_operand" "")))
12225    (clobber (reg:CC FLAGS_REG))]
12226   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12227    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12228   "rol{b}\t%0"
12229   [(set_attr "type" "rotate1")
12230    (set_attr "length_immediate" "0")
12231    (set_attr "mode" "QI")])
12233 (define_insn "*rotlqi3_1_one_bit"
12234   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12235         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12236                    (match_operand:QI 2 "const1_operand" "")))
12237    (clobber (reg:CC FLAGS_REG))]
12238   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12239    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
12240   "rol{b}\t%0"
12241   [(set_attr "type" "rotate")
12242    (set_attr "length_immediate" "0")
12243    (set_attr "mode" "QI")])
12245 (define_insn "*rotlqi3_1_slp"
12246   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12247         (rotate:QI (match_dup 0)
12248                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
12249    (clobber (reg:CC FLAGS_REG))]
12250   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12251    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12252   "@
12253    rol{b}\t{%1, %0|%0, %1}
12254    rol{b}\t{%b1, %0|%0, %b1}"
12255   [(set_attr "type" "rotate1")
12256    (set_attr "mode" "QI")])
12258 (define_insn "*rotlqi3_1"
12259   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12260         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12261                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
12262    (clobber (reg:CC FLAGS_REG))]
12263   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12264   "@
12265    rol{b}\t{%2, %0|%0, %2}
12266    rol{b}\t{%b2, %0|%0, %b2}"
12267   [(set_attr "type" "rotate")
12268    (set_attr "mode" "QI")])
12270 (define_expand "rotrdi3"
12271   [(set (match_operand:DI 0 "shiftdi_operand" "")
12272         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12273                    (match_operand:QI 2 "nonmemory_operand" "")))]
12274  ""
12276   if (TARGET_64BIT)
12277     {
12278       ix86_expand_binary_operator (ROTATERT, DImode, operands);
12279       DONE;
12280     }
12281   if (!const_1_to_31_operand (operands[2], VOIDmode))
12282     FAIL;
12283   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12284   DONE;
12287 ;; Implement rotation using two double-precision shift instructions
12288 ;; and a scratch register.
12289 (define_insn_and_split "ix86_rotrdi3"
12290  [(set (match_operand:DI 0 "register_operand" "=r")
12291        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12292                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
12293   (clobber (reg:CC FLAGS_REG))
12294   (clobber (match_scratch:SI 3 "=&r"))]
12295  "!TARGET_64BIT"
12296  ""
12297  "&& reload_completed"
12298  [(set (match_dup 3) (match_dup 4))
12299   (parallel
12300    [(set (match_dup 4)
12301          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12302                  (ashift:SI (match_dup 5)
12303                             (minus:QI (const_int 32) (match_dup 2)))))
12304     (clobber (reg:CC FLAGS_REG))])
12305   (parallel
12306    [(set (match_dup 5)
12307          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12308                  (ashift:SI (match_dup 3)
12309                             (minus:QI (const_int 32) (match_dup 2)))))
12310     (clobber (reg:CC FLAGS_REG))])]
12311  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12313 (define_insn "*rotrdi3_1_one_bit_rex64"
12314   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12315         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12316                      (match_operand:QI 2 "const1_operand" "")))
12317    (clobber (reg:CC FLAGS_REG))]
12318   "TARGET_64BIT
12319    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12320    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12321   "ror{q}\t%0"
12322   [(set_attr "type" "rotate")
12323    (set_attr "length_immediate" "0")
12324    (set_attr "mode" "DI")])
12326 (define_insn "*rotrdi3_1_rex64"
12327   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12328         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12329                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12330    (clobber (reg:CC FLAGS_REG))]
12331   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12332   "@
12333    ror{q}\t{%2, %0|%0, %2}
12334    ror{q}\t{%b2, %0|%0, %b2}"
12335   [(set_attr "type" "rotate")
12336    (set_attr "mode" "DI")])
12338 (define_expand "rotrsi3"
12339   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12340         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12341                      (match_operand:QI 2 "nonmemory_operand" "")))]
12342   ""
12343   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12345 (define_insn "*rotrsi3_1_one_bit"
12346   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12347         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12348                      (match_operand:QI 2 "const1_operand" "")))
12349    (clobber (reg:CC FLAGS_REG))]
12350   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12351    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12352   "ror{l}\t%0"
12353   [(set_attr "type" "rotate")
12354    (set_attr "length_immediate" "0")
12355    (set_attr "mode" "SI")])
12357 (define_insn "*rotrsi3_1_one_bit_zext"
12358   [(set (match_operand:DI 0 "register_operand" "=r")
12359         (zero_extend:DI
12360           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12361                        (match_operand:QI 2 "const1_operand" ""))))
12362    (clobber (reg:CC FLAGS_REG))]
12363   "TARGET_64BIT
12364    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12365    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12366   "ror{l}\t%k0"
12367   [(set_attr "type" "rotate")
12368    (set_attr "length_immediate" "0")
12369    (set_attr "mode" "SI")])
12371 (define_insn "*rotrsi3_1"
12372   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12373         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12374                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12375    (clobber (reg:CC FLAGS_REG))]
12376   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12377   "@
12378    ror{l}\t{%2, %0|%0, %2}
12379    ror{l}\t{%b2, %0|%0, %b2}"
12380   [(set_attr "type" "rotate")
12381    (set_attr "mode" "SI")])
12383 (define_insn "*rotrsi3_1_zext"
12384   [(set (match_operand:DI 0 "register_operand" "=r,r")
12385         (zero_extend:DI
12386           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12387                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12388    (clobber (reg:CC FLAGS_REG))]
12389   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12390   "@
12391    ror{l}\t{%2, %k0|%k0, %2}
12392    ror{l}\t{%b2, %k0|%k0, %b2}"
12393   [(set_attr "type" "rotate")
12394    (set_attr "mode" "SI")])
12396 (define_expand "rotrhi3"
12397   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12398         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12399                      (match_operand:QI 2 "nonmemory_operand" "")))]
12400   "TARGET_HIMODE_MATH"
12401   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12403 (define_insn "*rotrhi3_one_bit"
12404   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12405         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12406                      (match_operand:QI 2 "const1_operand" "")))
12407    (clobber (reg:CC FLAGS_REG))]
12408   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12409    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12410   "ror{w}\t%0"
12411   [(set_attr "type" "rotate")
12412    (set_attr "length_immediate" "0")
12413    (set_attr "mode" "HI")])
12415 (define_insn "*rotrhi3_1"
12416   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12417         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12418                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12419    (clobber (reg:CC FLAGS_REG))]
12420   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12421   "@
12422    ror{w}\t{%2, %0|%0, %2}
12423    ror{w}\t{%b2, %0|%0, %b2}"
12424   [(set_attr "type" "rotate")
12425    (set_attr "mode" "HI")])
12427 (define_split
12428  [(set (match_operand:HI 0 "register_operand" "")
12429        (rotatert:HI (match_dup 0) (const_int 8)))
12430   (clobber (reg:CC FLAGS_REG))]
12431  "reload_completed"
12432  [(parallel [(set (strict_low_part (match_dup 0))
12433                   (bswap:HI (match_dup 0)))
12434              (clobber (reg:CC FLAGS_REG))])]
12435  "")
12437 (define_expand "rotrqi3"
12438   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12439         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12440                      (match_operand:QI 2 "nonmemory_operand" "")))]
12441   "TARGET_QIMODE_MATH"
12442   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12444 (define_insn "*rotrqi3_1_one_bit"
12445   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12446         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12447                      (match_operand:QI 2 "const1_operand" "")))
12448    (clobber (reg:CC FLAGS_REG))]
12449   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12450    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12451   "ror{b}\t%0"
12452   [(set_attr "type" "rotate")
12453    (set_attr "length_immediate" "0")
12454    (set_attr "mode" "QI")])
12456 (define_insn "*rotrqi3_1_one_bit_slp"
12457   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12458         (rotatert:QI (match_dup 0)
12459                      (match_operand:QI 1 "const1_operand" "")))
12460    (clobber (reg:CC FLAGS_REG))]
12461   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12462    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12463   "ror{b}\t%0"
12464   [(set_attr "type" "rotate1")
12465    (set_attr "length_immediate" "0")
12466    (set_attr "mode" "QI")])
12468 (define_insn "*rotrqi3_1"
12469   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12470         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12471                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12472    (clobber (reg:CC FLAGS_REG))]
12473   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12474   "@
12475    ror{b}\t{%2, %0|%0, %2}
12476    ror{b}\t{%b2, %0|%0, %b2}"
12477   [(set_attr "type" "rotate")
12478    (set_attr "mode" "QI")])
12480 (define_insn "*rotrqi3_1_slp"
12481   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12482         (rotatert:QI (match_dup 0)
12483                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12484    (clobber (reg:CC FLAGS_REG))]
12485   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12486    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12487   "@
12488    ror{b}\t{%1, %0|%0, %1}
12489    ror{b}\t{%b1, %0|%0, %b1}"
12490   [(set_attr "type" "rotate1")
12491    (set_attr "mode" "QI")])
12493 ;; Bit set / bit test instructions
12495 (define_expand "extv"
12496   [(set (match_operand:SI 0 "register_operand" "")
12497         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12498                          (match_operand:SI 2 "const8_operand" "")
12499                          (match_operand:SI 3 "const8_operand" "")))]
12500   ""
12502   /* Handle extractions from %ah et al.  */
12503   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12504     FAIL;
12506   /* From mips.md: extract_bit_field doesn't verify that our source
12507      matches the predicate, so check it again here.  */
12508   if (! ext_register_operand (operands[1], VOIDmode))
12509     FAIL;
12512 (define_expand "extzv"
12513   [(set (match_operand:SI 0 "register_operand" "")
12514         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12515                          (match_operand:SI 2 "const8_operand" "")
12516                          (match_operand:SI 3 "const8_operand" "")))]
12517   ""
12519   /* Handle extractions from %ah et al.  */
12520   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12521     FAIL;
12523   /* From mips.md: extract_bit_field doesn't verify that our source
12524      matches the predicate, so check it again here.  */
12525   if (! ext_register_operand (operands[1], VOIDmode))
12526     FAIL;
12529 (define_expand "insv"
12530   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12531                       (match_operand 1 "const8_operand" "")
12532                       (match_operand 2 "const8_operand" ""))
12533         (match_operand 3 "register_operand" ""))]
12534   ""
12536   /* Handle insertions to %ah et al.  */
12537   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12538     FAIL;
12540   /* From mips.md: insert_bit_field doesn't verify that our source
12541      matches the predicate, so check it again here.  */
12542   if (! ext_register_operand (operands[0], VOIDmode))
12543     FAIL;
12545   if (TARGET_64BIT)
12546     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12547   else
12548     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12550   DONE;
12553 ;; %%% bts, btr, btc, bt.
12554 ;; In general these instructions are *slow* when applied to memory,
12555 ;; since they enforce atomic operation.  When applied to registers,
12556 ;; it depends on the cpu implementation.  They're never faster than
12557 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12558 ;; no point.  But in 64-bit, we can't hold the relevant immediates
12559 ;; within the instruction itself, so operating on bits in the high
12560 ;; 32-bits of a register becomes easier.
12562 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
12563 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12564 ;; negdf respectively, so they can never be disabled entirely.
12566 (define_insn "*btsq"
12567   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12568                          (const_int 1)
12569                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12570         (const_int 1))
12571    (clobber (reg:CC FLAGS_REG))]
12572   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12573   "bts{q}\t{%1, %0|%0, %1}"
12574   [(set_attr "type" "alu1")
12575    (set_attr "prefix_0f" "1")
12576    (set_attr "mode" "DI")])
12578 (define_insn "*btrq"
12579   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12580                          (const_int 1)
12581                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12582         (const_int 0))
12583    (clobber (reg:CC FLAGS_REG))]
12584   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12585   "btr{q}\t{%1, %0|%0, %1}"
12586   [(set_attr "type" "alu1")
12587    (set_attr "prefix_0f" "1")
12588    (set_attr "mode" "DI")])
12590 (define_insn "*btcq"
12591   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12592                          (const_int 1)
12593                          (match_operand:DI 1 "const_0_to_63_operand" ""))
12594         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12595    (clobber (reg:CC FLAGS_REG))]
12596   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12597   "btc{q}\t{%1, %0|%0, %1}"
12598   [(set_attr "type" "alu1")
12599    (set_attr "prefix_0f" "1")
12600    (set_attr "mode" "DI")])
12602 ;; Allow Nocona to avoid these instructions if a register is available.
12604 (define_peephole2
12605   [(match_scratch:DI 2 "r")
12606    (parallel [(set (zero_extract:DI
12607                      (match_operand:DI 0 "register_operand" "")
12608                      (const_int 1)
12609                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12610                    (const_int 1))
12611               (clobber (reg:CC FLAGS_REG))])]
12612   "TARGET_64BIT && !TARGET_USE_BT"
12613   [(const_int 0)]
12615   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12616   rtx op1;
12618   if (HOST_BITS_PER_WIDE_INT >= 64)
12619     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12620   else if (i < HOST_BITS_PER_WIDE_INT)
12621     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12622   else
12623     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12625   op1 = immed_double_const (lo, hi, DImode);
12626   if (i >= 31)
12627     {
12628       emit_move_insn (operands[2], op1);
12629       op1 = operands[2];
12630     }
12632   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12633   DONE;
12636 (define_peephole2
12637   [(match_scratch:DI 2 "r")
12638    (parallel [(set (zero_extract:DI
12639                      (match_operand:DI 0 "register_operand" "")
12640                      (const_int 1)
12641                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12642                    (const_int 0))
12643               (clobber (reg:CC FLAGS_REG))])]
12644   "TARGET_64BIT && !TARGET_USE_BT"
12645   [(const_int 0)]
12647   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12648   rtx op1;
12650   if (HOST_BITS_PER_WIDE_INT >= 64)
12651     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12652   else if (i < HOST_BITS_PER_WIDE_INT)
12653     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12654   else
12655     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12657   op1 = immed_double_const (~lo, ~hi, DImode);
12658   if (i >= 32)
12659     {
12660       emit_move_insn (operands[2], op1);
12661       op1 = operands[2];
12662     }
12664   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12665   DONE;
12668 (define_peephole2
12669   [(match_scratch:DI 2 "r")
12670    (parallel [(set (zero_extract:DI
12671                      (match_operand:DI 0 "register_operand" "")
12672                      (const_int 1)
12673                      (match_operand:DI 1 "const_0_to_63_operand" ""))
12674               (not:DI (zero_extract:DI
12675                         (match_dup 0) (const_int 1) (match_dup 1))))
12676               (clobber (reg:CC FLAGS_REG))])]
12677   "TARGET_64BIT && !TARGET_USE_BT"
12678   [(const_int 0)]
12680   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12681   rtx op1;
12683   if (HOST_BITS_PER_WIDE_INT >= 64)
12684     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12685   else if (i < HOST_BITS_PER_WIDE_INT)
12686     lo = (HOST_WIDE_INT)1 << i, hi = 0;
12687   else
12688     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12690   op1 = immed_double_const (lo, hi, DImode);
12691   if (i >= 31)
12692     {
12693       emit_move_insn (operands[2], op1);
12694       op1 = operands[2];
12695     }
12697   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12698   DONE;
12701 (define_insn "*btdi_rex64"
12702   [(set (reg:CCC FLAGS_REG)
12703         (compare:CCC
12704           (zero_extract:DI
12705             (match_operand:DI 0 "register_operand" "r")
12706             (const_int 1)
12707             (match_operand:DI 1 "nonmemory_operand" "rN"))
12708           (const_int 0)))]
12709   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
12710   "bt{q}\t{%1, %0|%0, %1}"
12711   [(set_attr "type" "alu1")
12712    (set_attr "prefix_0f" "1")
12713    (set_attr "mode" "DI")])
12715 (define_insn "*btsi"
12716   [(set (reg:CCC FLAGS_REG)
12717         (compare:CCC
12718           (zero_extract:SI
12719             (match_operand:SI 0 "register_operand" "r")
12720             (const_int 1)
12721             (match_operand:SI 1 "nonmemory_operand" "rN"))
12722           (const_int 0)))]
12723   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
12724   "bt{l}\t{%1, %0|%0, %1}"
12725   [(set_attr "type" "alu1")
12726    (set_attr "prefix_0f" "1")
12727    (set_attr "mode" "SI")])
12729 ;; Store-flag instructions.
12731 ;; For all sCOND expanders, also expand the compare or test insn that
12732 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
12734 (define_insn_and_split "*setcc_di_1"
12735   [(set (match_operand:DI 0 "register_operand" "=q")
12736         (match_operator:DI 1 "ix86_comparison_operator"
12737           [(reg FLAGS_REG) (const_int 0)]))]
12738   "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12739   "#"
12740   "&& reload_completed"
12741   [(set (match_dup 2) (match_dup 1))
12742    (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12744   PUT_MODE (operands[1], QImode);
12745   operands[2] = gen_lowpart (QImode, operands[0]);
12748 (define_insn_and_split "*setcc_si_1_and"
12749   [(set (match_operand:SI 0 "register_operand" "=q")
12750         (match_operator:SI 1 "ix86_comparison_operator"
12751           [(reg FLAGS_REG) (const_int 0)]))
12752    (clobber (reg:CC FLAGS_REG))]
12753   "!TARGET_PARTIAL_REG_STALL
12754    && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12755   "#"
12756   "&& reload_completed"
12757   [(set (match_dup 2) (match_dup 1))
12758    (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12759               (clobber (reg:CC FLAGS_REG))])]
12761   PUT_MODE (operands[1], QImode);
12762   operands[2] = gen_lowpart (QImode, operands[0]);
12765 (define_insn_and_split "*setcc_si_1_movzbl"
12766   [(set (match_operand:SI 0 "register_operand" "=q")
12767         (match_operator:SI 1 "ix86_comparison_operator"
12768           [(reg FLAGS_REG) (const_int 0)]))]
12769   "!TARGET_PARTIAL_REG_STALL
12770    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12771   "#"
12772   "&& reload_completed"
12773   [(set (match_dup 2) (match_dup 1))
12774    (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12776   PUT_MODE (operands[1], QImode);
12777   operands[2] = gen_lowpart (QImode, operands[0]);
12780 (define_insn "*setcc_qi"
12781   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12782         (match_operator:QI 1 "ix86_comparison_operator"
12783           [(reg FLAGS_REG) (const_int 0)]))]
12784   ""
12785   "set%C1\t%0"
12786   [(set_attr "type" "setcc")
12787    (set_attr "mode" "QI")])
12789 (define_insn "*setcc_qi_slp"
12790   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12791         (match_operator:QI 1 "ix86_comparison_operator"
12792           [(reg FLAGS_REG) (const_int 0)]))]
12793   ""
12794   "set%C1\t%0"
12795   [(set_attr "type" "setcc")
12796    (set_attr "mode" "QI")])
12798 ;; In general it is not safe to assume too much about CCmode registers,
12799 ;; so simplify-rtx stops when it sees a second one.  Under certain
12800 ;; conditions this is safe on x86, so help combine not create
12802 ;;      seta    %al
12803 ;;      testb   %al, %al
12804 ;;      sete    %al
12806 (define_split
12807   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12808         (ne:QI (match_operator 1 "ix86_comparison_operator"
12809                  [(reg FLAGS_REG) (const_int 0)])
12810             (const_int 0)))]
12811   ""
12812   [(set (match_dup 0) (match_dup 1))]
12814   PUT_MODE (operands[1], QImode);
12817 (define_split
12818   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12819         (ne:QI (match_operator 1 "ix86_comparison_operator"
12820                  [(reg FLAGS_REG) (const_int 0)])
12821             (const_int 0)))]
12822   ""
12823   [(set (match_dup 0) (match_dup 1))]
12825   PUT_MODE (operands[1], QImode);
12828 (define_split
12829   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12830         (eq:QI (match_operator 1 "ix86_comparison_operator"
12831                  [(reg FLAGS_REG) (const_int 0)])
12832             (const_int 0)))]
12833   ""
12834   [(set (match_dup 0) (match_dup 1))]
12836   rtx new_op1 = copy_rtx (operands[1]);
12837   operands[1] = new_op1;
12838   PUT_MODE (new_op1, QImode);
12839   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12840                                              GET_MODE (XEXP (new_op1, 0))));
12842   /* Make sure that (a) the CCmode we have for the flags is strong
12843      enough for the reversed compare or (b) we have a valid FP compare.  */
12844   if (! ix86_comparison_operator (new_op1, VOIDmode))
12845     FAIL;
12848 (define_split
12849   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12850         (eq:QI (match_operator 1 "ix86_comparison_operator"
12851                  [(reg FLAGS_REG) (const_int 0)])
12852             (const_int 0)))]
12853   ""
12854   [(set (match_dup 0) (match_dup 1))]
12856   rtx new_op1 = copy_rtx (operands[1]);
12857   operands[1] = new_op1;
12858   PUT_MODE (new_op1, QImode);
12859   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12860                                              GET_MODE (XEXP (new_op1, 0))));
12862   /* Make sure that (a) the CCmode we have for the flags is strong
12863      enough for the reversed compare or (b) we have a valid FP compare.  */
12864   if (! ix86_comparison_operator (new_op1, VOIDmode))
12865     FAIL;
12868 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12869 ;; subsequent logical operations are used to imitate conditional moves.
12870 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12871 ;; it directly.
12873 (define_insn "*avx_setcc<mode>"
12874   [(set (match_operand:MODEF 0 "register_operand" "=x")
12875         (match_operator:MODEF 1 "avx_comparison_float_operator"
12876           [(match_operand:MODEF 2 "register_operand" "x")
12877            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12878   "TARGET_AVX"
12879   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
12880   [(set_attr "type" "ssecmp")
12881    (set_attr "prefix" "vex")
12882    (set_attr "length_immediate" "1")
12883    (set_attr "mode" "<MODE>")])
12885 (define_insn "*sse_setcc<mode>"
12886   [(set (match_operand:MODEF 0 "register_operand" "=x")
12887         (match_operator:MODEF 1 "sse_comparison_operator"
12888           [(match_operand:MODEF 2 "register_operand" "0")
12889            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12890   "SSE_FLOAT_MODE_P (<MODE>mode)"
12891   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
12892   [(set_attr "type" "ssecmp")
12893    (set_attr "length_immediate" "1")
12894    (set_attr "mode" "<MODE>")])
12896 ;; Basic conditional jump instructions.
12897 ;; We ignore the overflow flag for signed branch instructions.
12899 (define_insn "*jcc_1"
12900   [(set (pc)
12901         (if_then_else (match_operator 1 "ix86_comparison_operator"
12902                                       [(reg FLAGS_REG) (const_int 0)])
12903                       (label_ref (match_operand 0 "" ""))
12904                       (pc)))]
12905   ""
12906   "%+j%C1\t%l0"
12907   [(set_attr "type" "ibr")
12908    (set_attr "modrm" "0")
12909    (set (attr "length")
12910            (if_then_else (and (ge (minus (match_dup 0) (pc))
12911                                   (const_int -126))
12912                               (lt (minus (match_dup 0) (pc))
12913                                   (const_int 128)))
12914              (const_int 2)
12915              (const_int 6)))])
12917 (define_insn "*jcc_2"
12918   [(set (pc)
12919         (if_then_else (match_operator 1 "ix86_comparison_operator"
12920                                       [(reg FLAGS_REG) (const_int 0)])
12921                       (pc)
12922                       (label_ref (match_operand 0 "" ""))))]
12923   ""
12924   "%+j%c1\t%l0"
12925   [(set_attr "type" "ibr")
12926    (set_attr "modrm" "0")
12927    (set (attr "length")
12928            (if_then_else (and (ge (minus (match_dup 0) (pc))
12929                                   (const_int -126))
12930                               (lt (minus (match_dup 0) (pc))
12931                                   (const_int 128)))
12932              (const_int 2)
12933              (const_int 6)))])
12935 ;; In general it is not safe to assume too much about CCmode registers,
12936 ;; so simplify-rtx stops when it sees a second one.  Under certain
12937 ;; conditions this is safe on x86, so help combine not create
12939 ;;      seta    %al
12940 ;;      testb   %al, %al
12941 ;;      je      Lfoo
12943 (define_split
12944   [(set (pc)
12945         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12946                                       [(reg FLAGS_REG) (const_int 0)])
12947                           (const_int 0))
12948                       (label_ref (match_operand 1 "" ""))
12949                       (pc)))]
12950   ""
12951   [(set (pc)
12952         (if_then_else (match_dup 0)
12953                       (label_ref (match_dup 1))
12954                       (pc)))]
12956   PUT_MODE (operands[0], VOIDmode);
12959 (define_split
12960   [(set (pc)
12961         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12962                                       [(reg FLAGS_REG) (const_int 0)])
12963                           (const_int 0))
12964                       (label_ref (match_operand 1 "" ""))
12965                       (pc)))]
12966   ""
12967   [(set (pc)
12968         (if_then_else (match_dup 0)
12969                       (label_ref (match_dup 1))
12970                       (pc)))]
12972   rtx new_op0 = copy_rtx (operands[0]);
12973   operands[0] = new_op0;
12974   PUT_MODE (new_op0, VOIDmode);
12975   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12976                                              GET_MODE (XEXP (new_op0, 0))));
12978   /* Make sure that (a) the CCmode we have for the flags is strong
12979      enough for the reversed compare or (b) we have a valid FP compare.  */
12980   if (! ix86_comparison_operator (new_op0, VOIDmode))
12981     FAIL;
12984 ;; zero_extend in SImode is correct, since this is what combine pass
12985 ;; generates from shift insn with QImode operand.  Actually, the mode of
12986 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
12987 ;; appropriate modulo of the bit offset value.
12989 (define_insn_and_split "*jcc_btdi_rex64"
12990   [(set (pc)
12991         (if_then_else (match_operator 0 "bt_comparison_operator"
12992                         [(zero_extract:DI
12993                            (match_operand:DI 1 "register_operand" "r")
12994                            (const_int 1)
12995                            (zero_extend:SI
12996                              (match_operand:QI 2 "register_operand" "r")))
12997                          (const_int 0)])
12998                       (label_ref (match_operand 3 "" ""))
12999                       (pc)))
13000    (clobber (reg:CC FLAGS_REG))]
13001   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13002   "#"
13003   "&& 1"
13004   [(set (reg:CCC FLAGS_REG)
13005         (compare:CCC
13006           (zero_extract:DI
13007             (match_dup 1)
13008             (const_int 1)
13009             (match_dup 2))
13010           (const_int 0)))
13011    (set (pc)
13012         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13013                       (label_ref (match_dup 3))
13014                       (pc)))]
13016   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
13018   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13021 ;; avoid useless masking of bit offset operand
13022 (define_insn_and_split "*jcc_btdi_mask_rex64"
13023   [(set (pc)
13024         (if_then_else (match_operator 0 "bt_comparison_operator"
13025                         [(zero_extract:DI
13026                            (match_operand:DI 1 "register_operand" "r")
13027                            (const_int 1)
13028                            (and:SI
13029                              (match_operand:SI 2 "register_operand" "r")
13030                              (match_operand:SI 3 "const_int_operand" "n")))])
13031                       (label_ref (match_operand 4 "" ""))
13032                       (pc)))
13033    (clobber (reg:CC FLAGS_REG))]
13034   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
13035    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
13036   "#"
13037   "&& 1"
13038   [(set (reg:CCC FLAGS_REG)
13039         (compare:CCC
13040           (zero_extract:DI
13041             (match_dup 1)
13042             (const_int 1)
13043             (match_dup 2))
13044           (const_int 0)))
13045    (set (pc)
13046         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13047                       (label_ref (match_dup 4))
13048                       (pc)))]
13050   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
13052   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13055 (define_insn_and_split "*jcc_btsi"
13056   [(set (pc)
13057         (if_then_else (match_operator 0 "bt_comparison_operator"
13058                         [(zero_extract:SI
13059                            (match_operand:SI 1 "register_operand" "r")
13060                            (const_int 1)
13061                            (zero_extend:SI
13062                              (match_operand:QI 2 "register_operand" "r")))
13063                          (const_int 0)])
13064                       (label_ref (match_operand 3 "" ""))
13065                       (pc)))
13066    (clobber (reg:CC FLAGS_REG))]
13067   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13068   "#"
13069   "&& 1"
13070   [(set (reg:CCC FLAGS_REG)
13071         (compare:CCC
13072           (zero_extract:SI
13073             (match_dup 1)
13074             (const_int 1)
13075             (match_dup 2))
13076           (const_int 0)))
13077    (set (pc)
13078         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13079                       (label_ref (match_dup 3))
13080                       (pc)))]
13082   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13084   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13087 ;; avoid useless masking of bit offset operand
13088 (define_insn_and_split "*jcc_btsi_mask"
13089   [(set (pc)
13090         (if_then_else (match_operator 0 "bt_comparison_operator"
13091                         [(zero_extract:SI
13092                            (match_operand:SI 1 "register_operand" "r")
13093                            (const_int 1)
13094                            (and:SI
13095                              (match_operand:SI 2 "register_operand" "r")
13096                              (match_operand:SI 3 "const_int_operand" "n")))])
13097                       (label_ref (match_operand 4 "" ""))
13098                       (pc)))
13099    (clobber (reg:CC FLAGS_REG))]
13100   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13101    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13102   "#"
13103   "&& 1"
13104   [(set (reg:CCC FLAGS_REG)
13105         (compare:CCC
13106           (zero_extract:SI
13107             (match_dup 1)
13108             (const_int 1)
13109             (match_dup 2))
13110           (const_int 0)))
13111    (set (pc)
13112         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13113                       (label_ref (match_dup 4))
13114                       (pc)))]
13115   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13117 (define_insn_and_split "*jcc_btsi_1"
13118   [(set (pc)
13119         (if_then_else (match_operator 0 "bt_comparison_operator"
13120                         [(and:SI
13121                            (lshiftrt:SI
13122                              (match_operand:SI 1 "register_operand" "r")
13123                              (match_operand:QI 2 "register_operand" "r"))
13124                            (const_int 1))
13125                          (const_int 0)])
13126                       (label_ref (match_operand 3 "" ""))
13127                       (pc)))
13128    (clobber (reg:CC FLAGS_REG))]
13129   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13130   "#"
13131   "&& 1"
13132   [(set (reg:CCC FLAGS_REG)
13133         (compare:CCC
13134           (zero_extract:SI
13135             (match_dup 1)
13136             (const_int 1)
13137             (match_dup 2))
13138           (const_int 0)))
13139    (set (pc)
13140         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13141                       (label_ref (match_dup 3))
13142                       (pc)))]
13144   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13146   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13149 ;; avoid useless masking of bit offset operand
13150 (define_insn_and_split "*jcc_btsi_mask_1"
13151   [(set (pc)
13152         (if_then_else
13153           (match_operator 0 "bt_comparison_operator"
13154             [(and:SI
13155                (lshiftrt:SI
13156                  (match_operand:SI 1 "register_operand" "r")
13157                  (subreg:QI
13158                    (and:SI
13159                      (match_operand:SI 2 "register_operand" "r")
13160                      (match_operand:SI 3 "const_int_operand" "n")) 0))
13161                (const_int 1))
13162              (const_int 0)])
13163           (label_ref (match_operand 4 "" ""))
13164           (pc)))
13165    (clobber (reg:CC FLAGS_REG))]
13166   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13167    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13168   "#"
13169   "&& 1"
13170   [(set (reg:CCC FLAGS_REG)
13171         (compare:CCC
13172           (zero_extract:SI
13173             (match_dup 1)
13174             (const_int 1)
13175             (match_dup 2))
13176           (const_int 0)))
13177    (set (pc)
13178         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13179                       (label_ref (match_dup 4))
13180                       (pc)))]
13181   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13183 ;; Define combination compare-and-branch fp compare instructions to help
13184 ;; combine.
13186 (define_insn "*fp_jcc_3_387"
13187   [(set (pc)
13188         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13189                         [(match_operand 1 "register_operand" "f")
13190                          (match_operand 2 "nonimmediate_operand" "fm")])
13191           (label_ref (match_operand 3 "" ""))
13192           (pc)))
13193    (clobber (reg:CCFP FPSR_REG))
13194    (clobber (reg:CCFP FLAGS_REG))
13195    (clobber (match_scratch:HI 4 "=a"))]
13196   "TARGET_80387
13197    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13198    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13199    && SELECT_CC_MODE (GET_CODE (operands[0]),
13200                       operands[1], operands[2]) == CCFPmode
13201    && !TARGET_CMOVE"
13202   "#")
13204 (define_insn "*fp_jcc_4_387"
13205   [(set (pc)
13206         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13207                         [(match_operand 1 "register_operand" "f")
13208                          (match_operand 2 "nonimmediate_operand" "fm")])
13209           (pc)
13210           (label_ref (match_operand 3 "" ""))))
13211    (clobber (reg:CCFP FPSR_REG))
13212    (clobber (reg:CCFP FLAGS_REG))
13213    (clobber (match_scratch:HI 4 "=a"))]
13214   "TARGET_80387
13215    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13216    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13217    && SELECT_CC_MODE (GET_CODE (operands[0]),
13218                       operands[1], operands[2]) == CCFPmode
13219    && !TARGET_CMOVE"
13220   "#")
13222 (define_insn "*fp_jcc_5_387"
13223   [(set (pc)
13224         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13225                         [(match_operand 1 "register_operand" "f")
13226                          (match_operand 2 "register_operand" "f")])
13227           (label_ref (match_operand 3 "" ""))
13228           (pc)))
13229    (clobber (reg:CCFP FPSR_REG))
13230    (clobber (reg:CCFP FLAGS_REG))
13231    (clobber (match_scratch:HI 4 "=a"))]
13232   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13233    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13234    && !TARGET_CMOVE"
13235   "#")
13237 (define_insn "*fp_jcc_6_387"
13238   [(set (pc)
13239         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13240                         [(match_operand 1 "register_operand" "f")
13241                          (match_operand 2 "register_operand" "f")])
13242           (pc)
13243           (label_ref (match_operand 3 "" ""))))
13244    (clobber (reg:CCFP FPSR_REG))
13245    (clobber (reg:CCFP FLAGS_REG))
13246    (clobber (match_scratch:HI 4 "=a"))]
13247   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13248    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13249    && !TARGET_CMOVE"
13250   "#")
13252 (define_insn "*fp_jcc_7_387"
13253   [(set (pc)
13254         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13255                         [(match_operand 1 "register_operand" "f")
13256                          (match_operand 2 "const0_operand" "")])
13257           (label_ref (match_operand 3 "" ""))
13258           (pc)))
13259    (clobber (reg:CCFP FPSR_REG))
13260    (clobber (reg:CCFP FLAGS_REG))
13261    (clobber (match_scratch:HI 4 "=a"))]
13262   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13263    && GET_MODE (operands[1]) == GET_MODE (operands[2])
13264    && SELECT_CC_MODE (GET_CODE (operands[0]),
13265                       operands[1], operands[2]) == CCFPmode
13266    && !TARGET_CMOVE"
13267   "#")
13269 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13270 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13271 ;; with a precedence over other operators and is always put in the first
13272 ;; place. Swap condition and operands to match ficom instruction.
13274 (define_insn "*fp_jcc_8<mode>_387"
13275   [(set (pc)
13276         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13277                         [(match_operator 1 "float_operator"
13278                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13279                            (match_operand 3 "register_operand" "f,f")])
13280           (label_ref (match_operand 4 "" ""))
13281           (pc)))
13282    (clobber (reg:CCFP FPSR_REG))
13283    (clobber (reg:CCFP FLAGS_REG))
13284    (clobber (match_scratch:HI 5 "=a,a"))]
13285   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13286    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
13287    && GET_MODE (operands[1]) == GET_MODE (operands[3])
13288    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13289    && !TARGET_CMOVE"
13290   "#")
13292 (define_split
13293   [(set (pc)
13294         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13295                         [(match_operand 1 "register_operand" "")
13296                          (match_operand 2 "nonimmediate_operand" "")])
13297           (match_operand 3 "" "")
13298           (match_operand 4 "" "")))
13299    (clobber (reg:CCFP FPSR_REG))
13300    (clobber (reg:CCFP FLAGS_REG))]
13301   "reload_completed"
13302   [(const_int 0)]
13304   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13305                         operands[3], operands[4], NULL_RTX, NULL_RTX);
13306   DONE;
13309 (define_split
13310   [(set (pc)
13311         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13312                         [(match_operand 1 "register_operand" "")
13313                          (match_operand 2 "general_operand" "")])
13314           (match_operand 3 "" "")
13315           (match_operand 4 "" "")))
13316    (clobber (reg:CCFP FPSR_REG))
13317    (clobber (reg:CCFP FLAGS_REG))
13318    (clobber (match_scratch:HI 5 "=a"))]
13319   "reload_completed"
13320   [(const_int 0)]
13322   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13323                         operands[3], operands[4], operands[5], NULL_RTX);
13324   DONE;
13327 (define_split
13328   [(set (pc)
13329         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13330                         [(match_operator 1 "float_operator"
13331                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
13332                            (match_operand 3 "register_operand" "")])
13333           (match_operand 4 "" "")
13334           (match_operand 5 "" "")))
13335    (clobber (reg:CCFP FPSR_REG))
13336    (clobber (reg:CCFP FLAGS_REG))
13337    (clobber (match_scratch:HI 6 "=a"))]
13338   "reload_completed"
13339   [(const_int 0)]
13341   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13342   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13343                         operands[3], operands[7],
13344                         operands[4], operands[5], operands[6], NULL_RTX);
13345   DONE;
13348 ;; %%% Kill this when reload knows how to do it.
13349 (define_split
13350   [(set (pc)
13351         (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13352                         [(match_operator 1 "float_operator"
13353                            [(match_operand:X87MODEI12 2 "register_operand" "")])
13354                            (match_operand 3 "register_operand" "")])
13355           (match_operand 4 "" "")
13356           (match_operand 5 "" "")))
13357    (clobber (reg:CCFP FPSR_REG))
13358    (clobber (reg:CCFP FLAGS_REG))
13359    (clobber (match_scratch:HI 6 "=a"))]
13360   "reload_completed"
13361   [(const_int 0)]
13363   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13364   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13365   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13366                         operands[3], operands[7],
13367                         operands[4], operands[5], operands[6], operands[2]);
13368   DONE;
13371 ;; Unconditional and other jump instructions
13373 (define_insn "jump"
13374   [(set (pc)
13375         (label_ref (match_operand 0 "" "")))]
13376   ""
13377   "jmp\t%l0"
13378   [(set_attr "type" "ibr")
13379    (set (attr "length")
13380            (if_then_else (and (ge (minus (match_dup 0) (pc))
13381                                   (const_int -126))
13382                               (lt (minus (match_dup 0) (pc))
13383                                   (const_int 128)))
13384              (const_int 2)
13385              (const_int 5)))
13386    (set_attr "modrm" "0")])
13388 (define_expand "indirect_jump"
13389   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
13390   ""
13391   "")
13393 (define_insn "*indirect_jump"
13394   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
13395   ""
13396   "jmp\t%A0"
13397   [(set_attr "type" "ibr")
13398    (set_attr "length_immediate" "0")])
13400 (define_expand "tablejump"
13401   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
13402               (use (label_ref (match_operand 1 "" "")))])]
13403   ""
13405   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13406      relative.  Convert the relative address to an absolute address.  */
13407   if (flag_pic)
13408     {
13409       rtx op0, op1;
13410       enum rtx_code code;
13412       /* We can't use @GOTOFF for text labels on VxWorks;
13413          see gotoff_operand.  */
13414       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
13415         {
13416           code = PLUS;
13417           op0 = operands[0];
13418           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13419         }
13420       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13421         {
13422           code = PLUS;
13423           op0 = operands[0];
13424           op1 = pic_offset_table_rtx;
13425         }
13426       else
13427         {
13428           code = MINUS;
13429           op0 = pic_offset_table_rtx;
13430           op1 = operands[0];
13431         }
13433       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13434                                          OPTAB_DIRECT);
13435     }
13438 (define_insn "*tablejump_1"
13439   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
13440    (use (label_ref (match_operand 1 "" "")))]
13441   ""
13442   "jmp\t%A0"
13443   [(set_attr "type" "ibr")
13444    (set_attr "length_immediate" "0")])
13446 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13448 (define_peephole2
13449   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13450    (set (match_operand:QI 1 "register_operand" "")
13451         (match_operator:QI 2 "ix86_comparison_operator"
13452           [(reg FLAGS_REG) (const_int 0)]))
13453    (set (match_operand 3 "q_regs_operand" "")
13454         (zero_extend (match_dup 1)))]
13455   "(peep2_reg_dead_p (3, operands[1])
13456     || operands_match_p (operands[1], operands[3]))
13457    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13458   [(set (match_dup 4) (match_dup 0))
13459    (set (strict_low_part (match_dup 5))
13460         (match_dup 2))]
13462   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13463   operands[5] = gen_lowpart (QImode, operands[3]);
13464   ix86_expand_clear (operands[3]);
13467 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13469 (define_peephole2
13470   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13471    (set (match_operand:QI 1 "register_operand" "")
13472         (match_operator:QI 2 "ix86_comparison_operator"
13473           [(reg FLAGS_REG) (const_int 0)]))
13474    (parallel [(set (match_operand 3 "q_regs_operand" "")
13475                    (zero_extend (match_dup 1)))
13476               (clobber (reg:CC FLAGS_REG))])]
13477   "(peep2_reg_dead_p (3, operands[1])
13478     || operands_match_p (operands[1], operands[3]))
13479    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13480   [(set (match_dup 4) (match_dup 0))
13481    (set (strict_low_part (match_dup 5))
13482         (match_dup 2))]
13484   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13485   operands[5] = gen_lowpart (QImode, operands[3]);
13486   ix86_expand_clear (operands[3]);
13489 ;; Call instructions.
13491 ;; The predicates normally associated with named expanders are not properly
13492 ;; checked for calls.  This is a bug in the generic code, but it isn't that
13493 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
13495 ;; P6 processors will jump to the address after the decrement when %esp
13496 ;; is used as a call operand, so they will execute return address as a code.
13497 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
13499 ;; Call subroutine returning no value.
13501 (define_expand "call_pop"
13502   [(parallel [(call (match_operand:QI 0 "" "")
13503                     (match_operand:SI 1 "" ""))
13504               (set (reg:SI SP_REG)
13505                    (plus:SI (reg:SI SP_REG)
13506                             (match_operand:SI 3 "" "")))])]
13507   "!TARGET_64BIT"
13509   ix86_expand_call (NULL, operands[0], operands[1],
13510                     operands[2], operands[3], 0);
13511   DONE;
13514 (define_insn "*call_pop_0"
13515   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13516          (match_operand:SI 1 "" ""))
13517    (set (reg:SI SP_REG)
13518         (plus:SI (reg:SI SP_REG)
13519                  (match_operand:SI 2 "immediate_operand" "")))]
13520   "!TARGET_64BIT"
13522   if (SIBLING_CALL_P (insn))
13523     return "jmp\t%P0";
13524   else
13525     return "call\t%P0";
13527   [(set_attr "type" "call")])
13529 (define_insn "*call_pop_1"
13530   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13531          (match_operand:SI 1 "" ""))
13532    (set (reg:SI SP_REG)
13533         (plus:SI (reg:SI SP_REG)
13534                  (match_operand:SI 2 "immediate_operand" "i")))]
13535   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13537   if (constant_call_address_operand (operands[0], Pmode))
13538     return "call\t%P0";
13539   return "call\t%A0";
13541   [(set_attr "type" "call")])
13543 (define_insn "*sibcall_pop_1"
13544   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13545          (match_operand:SI 1 "" ""))
13546    (set (reg:SI SP_REG)
13547         (plus:SI (reg:SI SP_REG)
13548                  (match_operand:SI 2 "immediate_operand" "i,i")))]
13549   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13550   "@
13551    jmp\t%P0
13552    jmp\t%A0"
13553   [(set_attr "type" "call")])
13555 (define_expand "call"
13556   [(call (match_operand:QI 0 "" "")
13557          (match_operand 1 "" ""))
13558    (use (match_operand 2 "" ""))]
13559   ""
13561   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13562   DONE;
13565 (define_expand "sibcall"
13566   [(call (match_operand:QI 0 "" "")
13567          (match_operand 1 "" ""))
13568    (use (match_operand 2 "" ""))]
13569   ""
13571   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13572   DONE;
13575 (define_insn "*call_0"
13576   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13577          (match_operand 1 "" ""))]
13578   ""
13580   if (SIBLING_CALL_P (insn))
13581     return "jmp\t%P0";
13582   else
13583     return "call\t%P0";
13585   [(set_attr "type" "call")])
13587 (define_insn "*call_1"
13588   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13589          (match_operand 1 "" ""))]
13590   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13592   if (constant_call_address_operand (operands[0], Pmode))
13593     return "call\t%P0";
13594   return "call\t%A0";
13596   [(set_attr "type" "call")])
13598 (define_insn "*sibcall_1"
13599   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13600          (match_operand 1 "" ""))]
13601   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13602   "@
13603    jmp\t%P0
13604    jmp\t%A0"
13605   [(set_attr "type" "call")])
13607 (define_insn "*call_1_rex64"
13608   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13609          (match_operand 1 "" ""))]
13610   "TARGET_64BIT && !SIBLING_CALL_P (insn)
13611    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
13613   if (constant_call_address_operand (operands[0], Pmode))
13614     return "call\t%P0";
13615   return "call\t%A0";
13617   [(set_attr "type" "call")])
13619 (define_insn "*call_1_rex64_ms_sysv"
13620   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13621          (match_operand 1 "" ""))
13622    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
13623    (clobber (reg:TI XMM6_REG))
13624    (clobber (reg:TI XMM7_REG))
13625    (clobber (reg:TI XMM8_REG))
13626    (clobber (reg:TI XMM9_REG))
13627    (clobber (reg:TI XMM10_REG))
13628    (clobber (reg:TI XMM11_REG))
13629    (clobber (reg:TI XMM12_REG))
13630    (clobber (reg:TI XMM13_REG))
13631    (clobber (reg:TI XMM14_REG))
13632    (clobber (reg:TI XMM15_REG))
13633    (clobber (reg:DI SI_REG))
13634    (clobber (reg:DI DI_REG))]
13635   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13637   if (constant_call_address_operand (operands[0], Pmode))
13638     return "call\t%P0";
13639   return "call\t%A0";
13641   [(set_attr "type" "call")])
13643 (define_insn "*call_1_rex64_large"
13644   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
13645          (match_operand 1 "" ""))]
13646   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13647   "call\t%A0"
13648   [(set_attr "type" "call")])
13650 (define_insn "*sibcall_1_rex64"
13651   [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
13652          (match_operand 1 "" ""))]
13653   "TARGET_64BIT && SIBLING_CALL_P (insn)"
13654   "@
13655    jmp\t%P0
13656    jmp\t%A0"
13657   [(set_attr "type" "call")])
13659 ;; Call subroutine, returning value in operand 0
13660 (define_expand "call_value_pop"
13661   [(parallel [(set (match_operand 0 "" "")
13662                    (call (match_operand:QI 1 "" "")
13663                          (match_operand:SI 2 "" "")))
13664               (set (reg:SI SP_REG)
13665                    (plus:SI (reg:SI SP_REG)
13666                             (match_operand:SI 4 "" "")))])]
13667   "!TARGET_64BIT"
13669   ix86_expand_call (operands[0], operands[1], operands[2],
13670                     operands[3], operands[4], 0);
13671   DONE;
13674 (define_expand "call_value"
13675   [(set (match_operand 0 "" "")
13676         (call (match_operand:QI 1 "" "")
13677               (match_operand:SI 2 "" "")))
13678    (use (match_operand:SI 3 "" ""))]
13679   ;; Operand 3 is not used on the i386.
13680   ""
13682   ix86_expand_call (operands[0], operands[1], operands[2],
13683                     operands[3], NULL, 0);
13684   DONE;
13687 (define_expand "sibcall_value"
13688   [(set (match_operand 0 "" "")
13689         (call (match_operand:QI 1 "" "")
13690               (match_operand:SI 2 "" "")))
13691    (use (match_operand:SI 3 "" ""))]
13692   ;; Operand 3 is not used on the i386.
13693   ""
13695   ix86_expand_call (operands[0], operands[1], operands[2],
13696                     operands[3], NULL, 1);
13697   DONE;
13700 ;; Call subroutine returning any type.
13702 (define_expand "untyped_call"
13703   [(parallel [(call (match_operand 0 "" "")
13704                     (const_int 0))
13705               (match_operand 1 "" "")
13706               (match_operand 2 "" "")])]
13707   ""
13709   int i;
13711   /* In order to give reg-stack an easier job in validating two
13712      coprocessor registers as containing a possible return value,
13713      simply pretend the untyped call returns a complex long double
13714      value. 
13716      We can't use SSE_REGPARM_MAX here since callee is unprototyped
13717      and should have the default ABI.  */
13719   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13720                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13721                     operands[0], const0_rtx,
13722                     GEN_INT ((TARGET_64BIT
13723                               ? (ix86_abi == SYSV_ABI
13724                                  ? X86_64_SSE_REGPARM_MAX
13725                                  : X86_64_MS_SSE_REGPARM_MAX)
13726                               : X86_32_SSE_REGPARM_MAX)
13727                              - 1),
13728                     NULL, 0);
13730   for (i = 0; i < XVECLEN (operands[2], 0); i++)
13731     {
13732       rtx set = XVECEXP (operands[2], 0, i);
13733       emit_move_insn (SET_DEST (set), SET_SRC (set));
13734     }
13736   /* The optimizer does not know that the call sets the function value
13737      registers we stored in the result block.  We avoid problems by
13738      claiming that all hard registers are used and clobbered at this
13739      point.  */
13740   emit_insn (gen_blockage ());
13742   DONE;
13745 ;; Prologue and epilogue instructions
13747 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13748 ;; all of memory.  This blocks insns from being moved across this point.
13750 (define_insn "blockage"
13751   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13752   ""
13753   ""
13754   [(set_attr "length" "0")])
13756 ;; Do not schedule instructions accessing memory across this point.
13758 (define_expand "memory_blockage"
13759   [(set (match_dup 0)
13760         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13761   ""
13763   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13764   MEM_VOLATILE_P (operands[0]) = 1;
13767 (define_insn "*memory_blockage"
13768   [(set (match_operand:BLK 0 "" "")
13769         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13770   ""
13771   ""
13772   [(set_attr "length" "0")])
13774 ;; As USE insns aren't meaningful after reload, this is used instead
13775 ;; to prevent deleting instructions setting registers for PIC code
13776 (define_insn "prologue_use"
13777   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
13778   ""
13779   ""
13780   [(set_attr "length" "0")])
13782 ;; Insn emitted into the body of a function to return from a function.
13783 ;; This is only done if the function's epilogue is known to be simple.
13784 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13786 (define_expand "return"
13787   [(return)]
13788   "ix86_can_use_return_insn_p ()"
13790   if (crtl->args.pops_args)
13791     {
13792       rtx popc = GEN_INT (crtl->args.pops_args);
13793       emit_jump_insn (gen_return_pop_internal (popc));
13794       DONE;
13795     }
13798 (define_insn "return_internal"
13799   [(return)]
13800   "reload_completed"
13801   "ret"
13802   [(set_attr "length" "1")
13803    (set_attr "atom_unit" "jeu")
13804    (set_attr "length_immediate" "0")
13805    (set_attr "modrm" "0")])
13807 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13808 ;; instruction Athlon and K8 have.
13810 (define_insn "return_internal_long"
13811   [(return)
13812    (unspec [(const_int 0)] UNSPEC_REP)]
13813   "reload_completed"
13814   "rep\;ret"
13815   [(set_attr "length" "2")
13816    (set_attr "atom_unit" "jeu")
13817    (set_attr "length_immediate" "0")
13818    (set_attr "prefix_rep" "1")
13819    (set_attr "modrm" "0")])
13821 (define_insn "return_pop_internal"
13822   [(return)
13823    (use (match_operand:SI 0 "const_int_operand" ""))]
13824   "reload_completed"
13825   "ret\t%0"
13826   [(set_attr "length" "3")
13827    (set_attr "atom_unit" "jeu")
13828    (set_attr "length_immediate" "2")
13829    (set_attr "modrm" "0")])
13831 (define_insn "return_indirect_internal"
13832   [(return)
13833    (use (match_operand:SI 0 "register_operand" "r"))]
13834   "reload_completed"
13835   "jmp\t%A0"
13836   [(set_attr "type" "ibr")
13837    (set_attr "length_immediate" "0")])
13839 (define_insn "nop"
13840   [(const_int 0)]
13841   ""
13842   "nop"
13843   [(set_attr "length" "1")
13844    (set_attr "length_immediate" "0")
13845    (set_attr "modrm" "0")])
13847 (define_insn "vswapmov"
13848   [(set (match_operand:SI 0 "register_operand" "=r")
13849         (match_operand:SI 1 "register_operand" "r"))
13850    (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
13851   ""
13852   "movl.s\t{%1, %0|%0, %1}"
13853   [(set_attr "length" "2")
13854    (set_attr "length_immediate" "0")
13855    (set_attr "modrm" "0")])
13857 ;; Pad to 16-byte boundary, max skip in op0.  Used to avoid
13858 ;; branch prediction penalty for the third jump in a 16-byte
13859 ;; block on K8.
13861 (define_insn "pad"
13862   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13863   ""
13865 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13866   ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13867 #else
13868   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13869      The align insn is used to avoid 3 jump instructions in the row to improve
13870      branch prediction and the benefits hardly outweigh the cost of extra 8
13871      nops on the average inserted by full alignment pseudo operation.  */
13872 #endif
13873   return "";
13875   [(set_attr "length" "16")])
13877 (define_expand "prologue"
13878   [(const_int 0)]
13879   ""
13880   "ix86_expand_prologue (); DONE;")
13882 (define_insn "set_got"
13883   [(set (match_operand:SI 0 "register_operand" "=r")
13884         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13885    (clobber (reg:CC FLAGS_REG))]
13886   "!TARGET_64BIT"
13887   { return output_set_got (operands[0], NULL_RTX); }
13888   [(set_attr "type" "multi")
13889    (set_attr "length" "12")])
13891 (define_insn "set_got_labelled"
13892   [(set (match_operand:SI 0 "register_operand" "=r")
13893         (unspec:SI [(label_ref (match_operand 1 "" ""))]
13894          UNSPEC_SET_GOT))
13895    (clobber (reg:CC FLAGS_REG))]
13896   "!TARGET_64BIT"
13897   { return output_set_got (operands[0], operands[1]); }
13898   [(set_attr "type" "multi")
13899    (set_attr "length" "12")])
13901 (define_insn "set_got_rex64"
13902   [(set (match_operand:DI 0 "register_operand" "=r")
13903         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13904   "TARGET_64BIT"
13905   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13906   [(set_attr "type" "lea")
13907    (set_attr "length_address" "4")
13908    (set_attr "mode" "DI")])
13910 (define_insn "set_rip_rex64"
13911   [(set (match_operand:DI 0 "register_operand" "=r")
13912         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
13913   "TARGET_64BIT"
13914   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13915   [(set_attr "type" "lea")
13916    (set_attr "length_address" "4")
13917    (set_attr "mode" "DI")])
13919 (define_insn "set_got_offset_rex64"
13920   [(set (match_operand:DI 0 "register_operand" "=r")
13921         (unspec:DI
13922           [(label_ref (match_operand 1 "" ""))]
13923           UNSPEC_SET_GOT_OFFSET))]
13924   "TARGET_64BIT"
13925   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13926   [(set_attr "type" "imov")
13927    (set_attr "length_immediate" "0")
13928    (set_attr "length_address" "8")
13929    (set_attr "mode" "DI")])
13931 (define_expand "epilogue"
13932   [(const_int 0)]
13933   ""
13934   "ix86_expand_epilogue (1); DONE;")
13936 (define_expand "sibcall_epilogue"
13937   [(const_int 0)]
13938   ""
13939   "ix86_expand_epilogue (0); DONE;")
13941 (define_expand "eh_return"
13942   [(use (match_operand 0 "register_operand" ""))]
13943   ""
13945   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13947   /* Tricky bit: we write the address of the handler to which we will
13948      be returning into someone else's stack frame, one word below the
13949      stack address we wish to restore.  */
13950   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13951   tmp = plus_constant (tmp, -UNITS_PER_WORD);
13952   tmp = gen_rtx_MEM (Pmode, tmp);
13953   emit_move_insn (tmp, ra);
13955   emit_jump_insn (gen_eh_return_internal ());
13956   emit_barrier ();
13957   DONE;
13960 (define_insn_and_split "eh_return_internal"
13961   [(eh_return)]
13962   ""
13963   "#"
13964   "epilogue_completed"
13965   [(const_int 0)]
13966   "ix86_expand_epilogue (2); DONE;")
13968 (define_insn "leave"
13969   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13970    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13971    (clobber (mem:BLK (scratch)))]
13972   "!TARGET_64BIT"
13973   "leave"
13974   [(set_attr "type" "leave")])
13976 (define_insn "leave_rex64"
13977   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13978    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13979    (clobber (mem:BLK (scratch)))]
13980   "TARGET_64BIT"
13981   "leave"
13982   [(set_attr "type" "leave")])
13984 (define_expand "ffssi2"
13985   [(parallel
13986      [(set (match_operand:SI 0 "register_operand" "")
13987            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13988       (clobber (match_scratch:SI 2 ""))
13989       (clobber (reg:CC FLAGS_REG))])]
13990   ""
13992   if (TARGET_CMOVE)
13993     {
13994       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
13995       DONE;
13996     }
13999 (define_expand "ffs_cmove"
14000   [(set (match_dup 2) (const_int -1))
14001    (parallel [(set (reg:CCZ FLAGS_REG)
14002                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
14003                                 (const_int 0)))
14004               (set (match_operand:SI 0 "register_operand" "")
14005                    (ctz:SI (match_dup 1)))])
14006    (set (match_dup 0) (if_then_else:SI
14007                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14008                         (match_dup 2)
14009                         (match_dup 0)))
14010    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14011               (clobber (reg:CC FLAGS_REG))])]
14012   "TARGET_CMOVE"
14013   "operands[2] = gen_reg_rtx (SImode);")
14015 (define_insn_and_split "*ffs_no_cmove"
14016   [(set (match_operand:SI 0 "register_operand" "=r")
14017         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14018    (clobber (match_scratch:SI 2 "=&q"))
14019    (clobber (reg:CC FLAGS_REG))]
14020   "!TARGET_CMOVE"
14021   "#"
14022   "&& reload_completed"
14023   [(parallel [(set (reg:CCZ FLAGS_REG)
14024                    (compare:CCZ (match_dup 1) (const_int 0)))
14025               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14026    (set (strict_low_part (match_dup 3))
14027         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14028    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14029               (clobber (reg:CC FLAGS_REG))])
14030    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14031               (clobber (reg:CC FLAGS_REG))])
14032    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14033               (clobber (reg:CC FLAGS_REG))])]
14035   operands[3] = gen_lowpart (QImode, operands[2]);
14036   ix86_expand_clear (operands[2]);
14039 (define_insn "*ffssi_1"
14040   [(set (reg:CCZ FLAGS_REG)
14041         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14042                      (const_int 0)))
14043    (set (match_operand:SI 0 "register_operand" "=r")
14044         (ctz:SI (match_dup 1)))]
14045   ""
14046   "bsf{l}\t{%1, %0|%0, %1}"
14047   [(set_attr "type" "alu1")
14048    (set_attr "prefix_0f" "1")
14049    (set_attr "mode" "SI")])
14051 (define_expand "ffsdi2"
14052   [(set (match_dup 2) (const_int -1))
14053    (parallel [(set (reg:CCZ FLAGS_REG)
14054                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
14055                                 (const_int 0)))
14056               (set (match_operand:DI 0 "register_operand" "")
14057                    (ctz:DI (match_dup 1)))])
14058    (set (match_dup 0) (if_then_else:DI
14059                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14060                         (match_dup 2)
14061                         (match_dup 0)))
14062    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14063               (clobber (reg:CC FLAGS_REG))])]
14064   "TARGET_64BIT"
14065   "operands[2] = gen_reg_rtx (DImode);")
14067 (define_insn "*ffsdi_1"
14068   [(set (reg:CCZ FLAGS_REG)
14069         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14070                      (const_int 0)))
14071    (set (match_operand:DI 0 "register_operand" "=r")
14072         (ctz:DI (match_dup 1)))]
14073   "TARGET_64BIT"
14074   "bsf{q}\t{%1, %0|%0, %1}"
14075   [(set_attr "type" "alu1")
14076    (set_attr "prefix_0f" "1")
14077    (set_attr "mode" "DI")])
14079 (define_insn "ctzsi2"
14080   [(set (match_operand:SI 0 "register_operand" "=r")
14081         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14082    (clobber (reg:CC FLAGS_REG))]
14083   ""
14084   "bsf{l}\t{%1, %0|%0, %1}"
14085   [(set_attr "type" "alu1")
14086    (set_attr "prefix_0f" "1")
14087    (set_attr "mode" "SI")])
14089 (define_insn "ctzdi2"
14090   [(set (match_operand:DI 0 "register_operand" "=r")
14091         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14092    (clobber (reg:CC FLAGS_REG))]
14093   "TARGET_64BIT"
14094   "bsf{q}\t{%1, %0|%0, %1}"
14095   [(set_attr "type" "alu1")
14096    (set_attr "prefix_0f" "1")
14097    (set_attr "mode" "DI")])
14099 (define_expand "clzsi2"
14100   [(parallel
14101      [(set (match_operand:SI 0 "register_operand" "")
14102            (minus:SI (const_int 31)
14103                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14104       (clobber (reg:CC FLAGS_REG))])
14105    (parallel
14106      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14107       (clobber (reg:CC FLAGS_REG))])]
14108   ""
14110   if (TARGET_ABM)
14111     {
14112       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14113       DONE;
14114     }
14117 (define_insn "clzsi2_abm"
14118   [(set (match_operand:SI 0 "register_operand" "=r")
14119         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14120    (clobber (reg:CC FLAGS_REG))]
14121   "TARGET_ABM"
14122   "lzcnt{l}\t{%1, %0|%0, %1}"
14123   [(set_attr "prefix_rep" "1")
14124    (set_attr "type" "bitmanip")
14125    (set_attr "mode" "SI")])
14127 (define_insn "bsr"
14128   [(set (match_operand:SI 0 "register_operand" "=r")
14129         (minus:SI (const_int 31)
14130                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14131    (clobber (reg:CC FLAGS_REG))]
14132   ""
14133   "bsr{l}\t{%1, %0|%0, %1}"
14134   [(set_attr "type" "alu1")
14135    (set_attr "prefix_0f" "1")
14136    (set_attr "mode" "SI")])
14138 (define_insn "popcount<mode>2"
14139   [(set (match_operand:SWI248 0 "register_operand" "=r")
14140         (popcount:SWI248
14141           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
14142    (clobber (reg:CC FLAGS_REG))]
14143   "TARGET_POPCNT"
14145 #if TARGET_MACHO
14146   return "popcnt\t{%1, %0|%0, %1}";
14147 #else
14148   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14149 #endif
14151   [(set_attr "prefix_rep" "1")
14152    (set_attr "type" "bitmanip")
14153    (set_attr "mode" "<MODE>")])
14155 (define_insn "*popcount<mode>2_cmp"
14156   [(set (reg FLAGS_REG)
14157         (compare
14158           (popcount:SWI248
14159             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
14160           (const_int 0)))
14161    (set (match_operand:SWI248 0 "register_operand" "=r")
14162         (popcount:SWI248 (match_dup 1)))]
14163   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14165 #if TARGET_MACHO
14166   return "popcnt\t{%1, %0|%0, %1}";
14167 #else
14168   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14169 #endif
14171   [(set_attr "prefix_rep" "1")
14172    (set_attr "type" "bitmanip")
14173    (set_attr "mode" "<MODE>")])
14175 (define_insn "*popcountsi2_cmp_zext"
14176   [(set (reg FLAGS_REG)
14177         (compare
14178           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14179           (const_int 0)))
14180    (set (match_operand:DI 0 "register_operand" "=r")
14181         (zero_extend:DI(popcount:SI (match_dup 1))))]
14182   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14184 #if TARGET_MACHO
14185   return "popcnt\t{%1, %0|%0, %1}";
14186 #else
14187   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14188 #endif
14190   [(set_attr "prefix_rep" "1")
14191    (set_attr "type" "bitmanip")
14192    (set_attr "mode" "SI")])
14194 (define_expand "bswapsi2"
14195   [(set (match_operand:SI 0 "register_operand" "")
14196         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14197   ""
14199   if (!(TARGET_BSWAP || TARGET_MOVBE))
14200     {
14201       rtx x = operands[0];
14203       emit_move_insn (x, operands[1]);
14204       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14205       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14206       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14207       DONE;
14208     }
14211 (define_insn "*bswapsi_movbe"
14212   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
14213         (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
14214   "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14215   "@
14216     bswap\t%0
14217     movbe\t{%1, %0|%0, %1}
14218     movbe\t{%1, %0|%0, %1}"
14219   [(set_attr "type" "*,imov,imov")
14220    (set_attr "modrm" "*,1,1")
14221    (set_attr "prefix_0f" "1")
14222    (set_attr "prefix_extra" "*,1,1")
14223    (set_attr "length" "2,*,*")
14224    (set_attr "mode" "SI")])
14226 (define_insn "*bswapsi_1"
14227   [(set (match_operand:SI 0 "register_operand" "=r")
14228         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14229   "TARGET_BSWAP"
14230   "bswap\t%0"
14231   [(set_attr "prefix_0f" "1")
14232    (set_attr "length" "2")])
14234 (define_insn "*bswaphi_lowpart_1"
14235   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14236         (bswap:HI (match_dup 0)))
14237    (clobber (reg:CC FLAGS_REG))]
14238   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
14239   "@
14240     xchg{b}\t{%h0, %b0|%b0, %h0}
14241     rol{w}\t{$8, %0|%0, 8}"
14242   [(set_attr "length" "2,4")
14243    (set_attr "mode" "QI,HI")])
14245 (define_insn "bswaphi_lowpart"
14246   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14247         (bswap:HI (match_dup 0)))
14248    (clobber (reg:CC FLAGS_REG))]
14249   ""
14250   "rol{w}\t{$8, %0|%0, 8}"
14251   [(set_attr "length" "4")
14252    (set_attr "mode" "HI")])
14254 (define_expand "bswapdi2"
14255   [(set (match_operand:DI 0 "register_operand" "")
14256         (bswap:DI (match_operand:DI 1 "register_operand" "")))]
14257   "TARGET_64BIT"
14258   "")
14260 (define_insn "*bswapdi_movbe"
14261   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
14262         (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
14263   "TARGET_64BIT && TARGET_MOVBE
14264    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14265   "@
14266     bswap\t%0
14267     movbe\t{%1, %0|%0, %1}
14268     movbe\t{%1, %0|%0, %1}"
14269   [(set_attr "type" "*,imov,imov")
14270    (set_attr "modrm" "*,1,1")
14271    (set_attr "prefix_0f" "1")
14272    (set_attr "prefix_extra" "*,1,1")
14273    (set_attr "length" "3,*,*")
14274    (set_attr "mode" "DI")])
14276 (define_insn "*bswapdi_1"
14277   [(set (match_operand:DI 0 "register_operand" "=r")
14278         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14279   "TARGET_64BIT"
14280   "bswap\t%0"
14281   [(set_attr "prefix_0f" "1")
14282    (set_attr "length" "3")])
14284 (define_expand "clzdi2"
14285   [(parallel
14286      [(set (match_operand:DI 0 "register_operand" "")
14287            (minus:DI (const_int 63)
14288                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14289       (clobber (reg:CC FLAGS_REG))])
14290    (parallel
14291      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14292       (clobber (reg:CC FLAGS_REG))])]
14293   "TARGET_64BIT"
14295   if (TARGET_ABM)
14296     {
14297       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14298       DONE;
14299     }
14302 (define_insn "clzdi2_abm"
14303   [(set (match_operand:DI 0 "register_operand" "=r")
14304         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14305    (clobber (reg:CC FLAGS_REG))]
14306   "TARGET_64BIT && TARGET_ABM"
14307   "lzcnt{q}\t{%1, %0|%0, %1}"
14308   [(set_attr "prefix_rep" "1")
14309    (set_attr "type" "bitmanip")
14310    (set_attr "mode" "DI")])
14312 (define_insn "bsr_rex64"
14313   [(set (match_operand:DI 0 "register_operand" "=r")
14314         (minus:DI (const_int 63)
14315                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14316    (clobber (reg:CC FLAGS_REG))]
14317   "TARGET_64BIT"
14318   "bsr{q}\t{%1, %0|%0, %1}"
14319   [(set_attr "type" "alu1")
14320    (set_attr "prefix_0f" "1")
14321    (set_attr "mode" "DI")])
14323 (define_expand "clzhi2"
14324   [(parallel
14325      [(set (match_operand:HI 0 "register_operand" "")
14326            (minus:HI (const_int 15)
14327                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14328       (clobber (reg:CC FLAGS_REG))])
14329    (parallel
14330      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14331       (clobber (reg:CC FLAGS_REG))])]
14332   ""
14334   if (TARGET_ABM)
14335     {
14336       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14337       DONE;
14338     }
14341 (define_insn "clzhi2_abm"
14342   [(set (match_operand:HI 0 "register_operand" "=r")
14343         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
14344    (clobber (reg:CC FLAGS_REG))]
14345   "TARGET_ABM"
14346   "lzcnt{w}\t{%1, %0|%0, %1}"
14347   [(set_attr "prefix_rep" "1")
14348    (set_attr "type" "bitmanip")
14349    (set_attr "mode" "HI")])
14351 (define_insn "*bsrhi"
14352   [(set (match_operand:HI 0 "register_operand" "=r")
14353         (minus:HI (const_int 15)
14354                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14355    (clobber (reg:CC FLAGS_REG))]
14356   ""
14357   "bsr{w}\t{%1, %0|%0, %1}"
14358   [(set_attr "type" "alu1")
14359    (set_attr "prefix_0f" "1")
14360    (set_attr "mode" "HI")])
14362 (define_expand "paritydi2"
14363   [(set (match_operand:DI 0 "register_operand" "")
14364         (parity:DI (match_operand:DI 1 "register_operand" "")))]
14365   "! TARGET_POPCNT"
14367   rtx scratch = gen_reg_rtx (QImode);
14368   rtx cond;
14370   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14371                                 NULL_RTX, operands[1]));
14373   cond = gen_rtx_fmt_ee (ORDERED, QImode,
14374                          gen_rtx_REG (CCmode, FLAGS_REG),
14375                          const0_rtx);
14376   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14378   if (TARGET_64BIT)
14379     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14380   else
14381     {
14382       rtx tmp = gen_reg_rtx (SImode);
14384       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14385       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14386     }
14387   DONE;
14390 (define_insn_and_split "paritydi2_cmp"
14391   [(set (reg:CC FLAGS_REG)
14392         (parity:CC (match_operand:DI 3 "register_operand" "0")))
14393    (clobber (match_scratch:DI 0 "=r"))
14394    (clobber (match_scratch:SI 1 "=&r"))
14395    (clobber (match_scratch:HI 2 "=Q"))]
14396   "! TARGET_POPCNT"
14397   "#"
14398   "&& reload_completed"
14399   [(parallel
14400      [(set (match_dup 1)
14401            (xor:SI (match_dup 1) (match_dup 4)))
14402       (clobber (reg:CC FLAGS_REG))])
14403    (parallel
14404      [(set (reg:CC FLAGS_REG)
14405            (parity:CC (match_dup 1)))
14406       (clobber (match_dup 1))
14407       (clobber (match_dup 2))])]
14409   operands[4] = gen_lowpart (SImode, operands[3]);
14411   if (TARGET_64BIT)
14412     {
14413       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14414       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14415     }
14416   else
14417     operands[1] = gen_highpart (SImode, operands[3]);
14420 (define_expand "paritysi2"
14421   [(set (match_operand:SI 0 "register_operand" "")
14422         (parity:SI (match_operand:SI 1 "register_operand" "")))]
14423   "! TARGET_POPCNT"
14425   rtx scratch = gen_reg_rtx (QImode);
14426   rtx cond;
14428   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14430   cond = gen_rtx_fmt_ee (ORDERED, QImode,
14431                          gen_rtx_REG (CCmode, FLAGS_REG),
14432                          const0_rtx);
14433   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14435   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14436   DONE;
14439 (define_insn_and_split "paritysi2_cmp"
14440   [(set (reg:CC FLAGS_REG)
14441         (parity:CC (match_operand:SI 2 "register_operand" "0")))
14442    (clobber (match_scratch:SI 0 "=r"))
14443    (clobber (match_scratch:HI 1 "=&Q"))]
14444   "! TARGET_POPCNT"
14445   "#"
14446   "&& reload_completed"
14447   [(parallel
14448      [(set (match_dup 1)
14449            (xor:HI (match_dup 1) (match_dup 3)))
14450       (clobber (reg:CC FLAGS_REG))])
14451    (parallel
14452      [(set (reg:CC FLAGS_REG)
14453            (parity:CC (match_dup 1)))
14454       (clobber (match_dup 1))])]
14456   operands[3] = gen_lowpart (HImode, operands[2]);
14458   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14459   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14462 (define_insn "*parityhi2_cmp"
14463   [(set (reg:CC FLAGS_REG)
14464         (parity:CC (match_operand:HI 1 "register_operand" "0")))
14465    (clobber (match_scratch:HI 0 "=Q"))]
14466   "! TARGET_POPCNT"
14467   "xor{b}\t{%h0, %b0|%b0, %h0}"
14468   [(set_attr "length" "2")
14469    (set_attr "mode" "HI")])
14471 (define_insn "*parityqi2_cmp"
14472   [(set (reg:CC FLAGS_REG)
14473         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
14474   "! TARGET_POPCNT"
14475   "test{b}\t%0, %0"
14476   [(set_attr "length" "2")
14477    (set_attr "mode" "QI")])
14479 ;; Thread-local storage patterns for ELF.
14481 ;; Note that these code sequences must appear exactly as shown
14482 ;; in order to allow linker relaxation.
14484 (define_insn "*tls_global_dynamic_32_gnu"
14485   [(set (match_operand:SI 0 "register_operand" "=a")
14486         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14487                     (match_operand:SI 2 "tls_symbolic_operand" "")
14488                     (match_operand:SI 3 "call_insn_operand" "")]
14489                     UNSPEC_TLS_GD))
14490    (clobber (match_scratch:SI 4 "=d"))
14491    (clobber (match_scratch:SI 5 "=c"))
14492    (clobber (reg:CC FLAGS_REG))]
14493   "!TARGET_64BIT && TARGET_GNU_TLS"
14494   "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
14495   [(set_attr "type" "multi")
14496    (set_attr "length" "12")])
14498 (define_expand "tls_global_dynamic_32"
14499   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14500                    (unspec:SI
14501                     [(match_dup 2)
14502                      (match_operand:SI 1 "tls_symbolic_operand" "")
14503                      (match_dup 3)]
14504                     UNSPEC_TLS_GD))
14505               (clobber (match_scratch:SI 4 ""))
14506               (clobber (match_scratch:SI 5 ""))
14507               (clobber (reg:CC FLAGS_REG))])]
14508   ""
14510   if (flag_pic)
14511     operands[2] = pic_offset_table_rtx;
14512   else
14513     {
14514       operands[2] = gen_reg_rtx (Pmode);
14515       emit_insn (gen_set_got (operands[2]));
14516     }
14517   if (TARGET_GNU2_TLS)
14518     {
14519        emit_insn (gen_tls_dynamic_gnu2_32
14520                   (operands[0], operands[1], operands[2]));
14521        DONE;
14522     }
14523   operands[3] = ix86_tls_get_addr ();
14526 (define_insn "*tls_global_dynamic_64"
14527   [(set (match_operand:DI 0 "register_operand" "=a")
14528         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14529                  (match_operand:DI 3 "" "")))
14530    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14531               UNSPEC_TLS_GD)]
14532   "TARGET_64BIT"
14533   { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
14534   [(set_attr "type" "multi")
14535    (set_attr "length" "16")])
14537 (define_expand "tls_global_dynamic_64"
14538   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14539                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14540               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14541                          UNSPEC_TLS_GD)])]
14542   ""
14544   if (TARGET_GNU2_TLS)
14545     {
14546        emit_insn (gen_tls_dynamic_gnu2_64
14547                   (operands[0], operands[1]));
14548        DONE;
14549     }
14550   operands[2] = ix86_tls_get_addr ();
14553 (define_insn "*tls_local_dynamic_base_32_gnu"
14554   [(set (match_operand:SI 0 "register_operand" "=a")
14555         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14556                     (match_operand:SI 2 "call_insn_operand" "")]
14557                    UNSPEC_TLS_LD_BASE))
14558    (clobber (match_scratch:SI 3 "=d"))
14559    (clobber (match_scratch:SI 4 "=c"))
14560    (clobber (reg:CC FLAGS_REG))]
14561   "!TARGET_64BIT && TARGET_GNU_TLS"
14562   "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
14563   [(set_attr "type" "multi")
14564    (set_attr "length" "11")])
14566 (define_expand "tls_local_dynamic_base_32"
14567   [(parallel [(set (match_operand:SI 0 "register_operand" "")
14568                    (unspec:SI [(match_dup 1) (match_dup 2)]
14569                               UNSPEC_TLS_LD_BASE))
14570               (clobber (match_scratch:SI 3 ""))
14571               (clobber (match_scratch:SI 4 ""))
14572               (clobber (reg:CC FLAGS_REG))])]
14573   ""
14575   if (flag_pic)
14576     operands[1] = pic_offset_table_rtx;
14577   else
14578     {
14579       operands[1] = gen_reg_rtx (Pmode);
14580       emit_insn (gen_set_got (operands[1]));
14581     }
14582   if (TARGET_GNU2_TLS)
14583     {
14584        emit_insn (gen_tls_dynamic_gnu2_32
14585                   (operands[0], ix86_tls_module_base (), operands[1]));
14586        DONE;
14587     }
14588   operands[2] = ix86_tls_get_addr ();
14591 (define_insn "*tls_local_dynamic_base_64"
14592   [(set (match_operand:DI 0 "register_operand" "=a")
14593         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14594                  (match_operand:DI 2 "" "")))
14595    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14596   "TARGET_64BIT"
14597   "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
14598   [(set_attr "type" "multi")
14599    (set_attr "length" "12")])
14601 (define_expand "tls_local_dynamic_base_64"
14602   [(parallel [(set (match_operand:DI 0 "register_operand" "")
14603                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14604               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14605   ""
14607   if (TARGET_GNU2_TLS)
14608     {
14609        emit_insn (gen_tls_dynamic_gnu2_64
14610                   (operands[0], ix86_tls_module_base ()));
14611        DONE;
14612     }
14613   operands[1] = ix86_tls_get_addr ();
14616 ;; Local dynamic of a single variable is a lose.  Show combine how
14617 ;; to convert that back to global dynamic.
14619 (define_insn_and_split "*tls_local_dynamic_32_once"
14620   [(set (match_operand:SI 0 "register_operand" "=a")
14621         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14622                              (match_operand:SI 2 "call_insn_operand" "")]
14623                             UNSPEC_TLS_LD_BASE)
14624                  (const:SI (unspec:SI
14625                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
14626                             UNSPEC_DTPOFF))))
14627    (clobber (match_scratch:SI 4 "=d"))
14628    (clobber (match_scratch:SI 5 "=c"))
14629    (clobber (reg:CC FLAGS_REG))]
14630   ""
14631   "#"
14632   ""
14633   [(parallel [(set (match_dup 0)
14634                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14635                               UNSPEC_TLS_GD))
14636               (clobber (match_dup 4))
14637               (clobber (match_dup 5))
14638               (clobber (reg:CC FLAGS_REG))])]
14639   "")
14641 ;; Load and add the thread base pointer from %gs:0.
14643 (define_insn "*load_tp_si"
14644   [(set (match_operand:SI 0 "register_operand" "=r")
14645         (unspec:SI [(const_int 0)] UNSPEC_TP))]
14646   "!TARGET_64BIT"
14647   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14648   [(set_attr "type" "imov")
14649    (set_attr "modrm" "0")
14650    (set_attr "length" "7")
14651    (set_attr "memory" "load")
14652    (set_attr "imm_disp" "false")])
14654 (define_insn "*add_tp_si"
14655   [(set (match_operand:SI 0 "register_operand" "=r")
14656         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14657                  (match_operand:SI 1 "register_operand" "0")))
14658    (clobber (reg:CC FLAGS_REG))]
14659   "!TARGET_64BIT"
14660   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14661   [(set_attr "type" "alu")
14662    (set_attr "modrm" "0")
14663    (set_attr "length" "7")
14664    (set_attr "memory" "load")
14665    (set_attr "imm_disp" "false")])
14667 (define_insn "*load_tp_di"
14668   [(set (match_operand:DI 0 "register_operand" "=r")
14669         (unspec:DI [(const_int 0)] UNSPEC_TP))]
14670   "TARGET_64BIT"
14671   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14672   [(set_attr "type" "imov")
14673    (set_attr "modrm" "0")
14674    (set_attr "length" "7")
14675    (set_attr "memory" "load")
14676    (set_attr "imm_disp" "false")])
14678 (define_insn "*add_tp_di"
14679   [(set (match_operand:DI 0 "register_operand" "=r")
14680         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14681                  (match_operand:DI 1 "register_operand" "0")))
14682    (clobber (reg:CC FLAGS_REG))]
14683   "TARGET_64BIT"
14684   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14685   [(set_attr "type" "alu")
14686    (set_attr "modrm" "0")
14687    (set_attr "length" "7")
14688    (set_attr "memory" "load")
14689    (set_attr "imm_disp" "false")])
14691 ;; GNU2 TLS patterns can be split.
14693 (define_expand "tls_dynamic_gnu2_32"
14694   [(set (match_dup 3)
14695         (plus:SI (match_operand:SI 2 "register_operand" "")
14696                  (const:SI
14697                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14698                              UNSPEC_TLSDESC))))
14699    (parallel
14700     [(set (match_operand:SI 0 "register_operand" "")
14701           (unspec:SI [(match_dup 1) (match_dup 3)
14702                       (match_dup 2) (reg:SI SP_REG)]
14703                       UNSPEC_TLSDESC))
14704      (clobber (reg:CC FLAGS_REG))])]
14705   "!TARGET_64BIT && TARGET_GNU2_TLS"
14707   operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14708   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14711 (define_insn "*tls_dynamic_lea_32"
14712   [(set (match_operand:SI 0 "register_operand" "=r")
14713         (plus:SI (match_operand:SI 1 "register_operand" "b")
14714                  (const:SI
14715                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14716                               UNSPEC_TLSDESC))))]
14717   "!TARGET_64BIT && TARGET_GNU2_TLS"
14718   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14719   [(set_attr "type" "lea")
14720    (set_attr "mode" "SI")
14721    (set_attr "length" "6")
14722    (set_attr "length_address" "4")])
14724 (define_insn "*tls_dynamic_call_32"
14725   [(set (match_operand:SI 0 "register_operand" "=a")
14726         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14727                     (match_operand:SI 2 "register_operand" "0")
14728                     ;; we have to make sure %ebx still points to the GOT
14729                     (match_operand:SI 3 "register_operand" "b")
14730                     (reg:SI SP_REG)]
14731                    UNSPEC_TLSDESC))
14732    (clobber (reg:CC FLAGS_REG))]
14733   "!TARGET_64BIT && TARGET_GNU2_TLS"
14734   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14735   [(set_attr "type" "call")
14736    (set_attr "length" "2")
14737    (set_attr "length_address" "0")])
14739 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14740   [(set (match_operand:SI 0 "register_operand" "=&a")
14741         (plus:SI
14742          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14743                      (match_operand:SI 4 "" "")
14744                      (match_operand:SI 2 "register_operand" "b")
14745                      (reg:SI SP_REG)]
14746                     UNSPEC_TLSDESC)
14747          (const:SI (unspec:SI
14748                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
14749                     UNSPEC_DTPOFF))))
14750    (clobber (reg:CC FLAGS_REG))]
14751   "!TARGET_64BIT && TARGET_GNU2_TLS"
14752   "#"
14753   ""
14754   [(set (match_dup 0) (match_dup 5))]
14756   operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14757   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14760 (define_expand "tls_dynamic_gnu2_64"
14761   [(set (match_dup 2)
14762         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14763                    UNSPEC_TLSDESC))
14764    (parallel
14765     [(set (match_operand:DI 0 "register_operand" "")
14766           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14767                      UNSPEC_TLSDESC))
14768      (clobber (reg:CC FLAGS_REG))])]
14769   "TARGET_64BIT && TARGET_GNU2_TLS"
14771   operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14772   ix86_tls_descriptor_calls_expanded_in_cfun = true;
14775 (define_insn "*tls_dynamic_lea_64"
14776   [(set (match_operand:DI 0 "register_operand" "=r")
14777         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14778                    UNSPEC_TLSDESC))]
14779   "TARGET_64BIT && TARGET_GNU2_TLS"
14780   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
14781   [(set_attr "type" "lea")
14782    (set_attr "mode" "DI")
14783    (set_attr "length" "7")
14784    (set_attr "length_address" "4")])
14786 (define_insn "*tls_dynamic_call_64"
14787   [(set (match_operand:DI 0 "register_operand" "=a")
14788         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14789                     (match_operand:DI 2 "register_operand" "0")
14790                     (reg:DI SP_REG)]
14791                    UNSPEC_TLSDESC))
14792    (clobber (reg:CC FLAGS_REG))]
14793   "TARGET_64BIT && TARGET_GNU2_TLS"
14794   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14795   [(set_attr "type" "call")
14796    (set_attr "length" "2")
14797    (set_attr "length_address" "0")])
14799 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14800   [(set (match_operand:DI 0 "register_operand" "=&a")
14801         (plus:DI
14802          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14803                      (match_operand:DI 3 "" "")
14804                      (reg:DI SP_REG)]
14805                     UNSPEC_TLSDESC)
14806          (const:DI (unspec:DI
14807                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
14808                     UNSPEC_DTPOFF))))
14809    (clobber (reg:CC FLAGS_REG))]
14810   "TARGET_64BIT && TARGET_GNU2_TLS"
14811   "#"
14812   ""
14813   [(set (match_dup 0) (match_dup 4))]
14815   operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14816   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14821 ;; These patterns match the binary 387 instructions for addM3, subM3,
14822 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
14823 ;; SFmode.  The first is the normal insn, the second the same insn but
14824 ;; with one operand a conversion, and the third the same insn but with
14825 ;; the other operand a conversion.  The conversion may be SFmode or
14826 ;; SImode if the target mode DFmode, but only SImode if the target mode
14827 ;; is SFmode.
14829 ;; Gcc is slightly more smart about handling normal two address instructions
14830 ;; so use special patterns for add and mull.
14832 (define_insn "*fop_<mode>_comm_mixed_avx"
14833   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14834         (match_operator:MODEF 3 "binary_fp_operator"
14835           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
14836            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14837   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14838    && COMMUTATIVE_ARITH_P (operands[3])
14839    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14840   "* return output_387_binary_op (insn, operands);"
14841   [(set (attr "type")
14842         (if_then_else (eq_attr "alternative" "1")
14843            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14844               (const_string "ssemul")
14845               (const_string "sseadd"))
14846            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14847               (const_string "fmul")
14848               (const_string "fop"))))
14849    (set_attr "prefix" "orig,maybe_vex")
14850    (set_attr "mode" "<MODE>")])
14852 (define_insn "*fop_<mode>_comm_mixed"
14853   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14854         (match_operator:MODEF 3 "binary_fp_operator"
14855           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
14856            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14857   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14858    && COMMUTATIVE_ARITH_P (operands[3])
14859    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14860   "* return output_387_binary_op (insn, operands);"
14861   [(set (attr "type")
14862         (if_then_else (eq_attr "alternative" "1")
14863            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14864               (const_string "ssemul")
14865               (const_string "sseadd"))
14866            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14867               (const_string "fmul")
14868               (const_string "fop"))))
14869    (set_attr "mode" "<MODE>")])
14871 (define_insn "*fop_<mode>_comm_avx"
14872   [(set (match_operand:MODEF 0 "register_operand" "=x")
14873         (match_operator:MODEF 3 "binary_fp_operator"
14874           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
14875            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14876   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14877    && COMMUTATIVE_ARITH_P (operands[3])
14878    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14879   "* return output_387_binary_op (insn, operands);"
14880   [(set (attr "type")
14881         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14882            (const_string "ssemul")
14883            (const_string "sseadd")))
14884    (set_attr "prefix" "vex")
14885    (set_attr "mode" "<MODE>")])
14887 (define_insn "*fop_<mode>_comm_sse"
14888   [(set (match_operand:MODEF 0 "register_operand" "=x")
14889         (match_operator:MODEF 3 "binary_fp_operator"
14890           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14891            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14892   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14893    && COMMUTATIVE_ARITH_P (operands[3])
14894    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14895   "* return output_387_binary_op (insn, operands);"
14896   [(set (attr "type")
14897         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14898            (const_string "ssemul")
14899            (const_string "sseadd")))
14900    (set_attr "mode" "<MODE>")])
14902 (define_insn "*fop_<mode>_comm_i387"
14903   [(set (match_operand:MODEF 0 "register_operand" "=f")
14904         (match_operator:MODEF 3 "binary_fp_operator"
14905           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14906            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
14907   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14908    && COMMUTATIVE_ARITH_P (operands[3])
14909    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14910   "* return output_387_binary_op (insn, operands);"
14911   [(set (attr "type")
14912         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14913            (const_string "fmul")
14914            (const_string "fop")))
14915    (set_attr "mode" "<MODE>")])
14917 (define_insn "*fop_<mode>_1_mixed_avx"
14918   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14919         (match_operator:MODEF 3 "binary_fp_operator"
14920           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
14921            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14922   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14923    && !COMMUTATIVE_ARITH_P (operands[3])
14924    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14925   "* return output_387_binary_op (insn, operands);"
14926   [(set (attr "type")
14927         (cond [(and (eq_attr "alternative" "2")
14928                     (match_operand:MODEF 3 "mult_operator" ""))
14929                  (const_string "ssemul")
14930                (and (eq_attr "alternative" "2")
14931                     (match_operand:MODEF 3 "div_operator" ""))
14932                  (const_string "ssediv")
14933                (eq_attr "alternative" "2")
14934                  (const_string "sseadd")
14935                (match_operand:MODEF 3 "mult_operator" "")
14936                  (const_string "fmul")
14937                (match_operand:MODEF 3 "div_operator" "")
14938                  (const_string "fdiv")
14939               ]
14940               (const_string "fop")))
14941    (set_attr "prefix" "orig,orig,maybe_vex")
14942    (set_attr "mode" "<MODE>")])
14944 (define_insn "*fop_<mode>_1_mixed"
14945   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14946         (match_operator:MODEF 3 "binary_fp_operator"
14947           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
14948            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14949   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14950    && !COMMUTATIVE_ARITH_P (operands[3])
14951    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14952   "* return output_387_binary_op (insn, operands);"
14953   [(set (attr "type")
14954         (cond [(and (eq_attr "alternative" "2")
14955                     (match_operand:MODEF 3 "mult_operator" ""))
14956                  (const_string "ssemul")
14957                (and (eq_attr "alternative" "2")
14958                     (match_operand:MODEF 3 "div_operator" ""))
14959                  (const_string "ssediv")
14960                (eq_attr "alternative" "2")
14961                  (const_string "sseadd")
14962                (match_operand:MODEF 3 "mult_operator" "")
14963                  (const_string "fmul")
14964                (match_operand:MODEF 3 "div_operator" "")
14965                  (const_string "fdiv")
14966               ]
14967               (const_string "fop")))
14968    (set_attr "mode" "<MODE>")])
14970 (define_insn "*rcpsf2_sse"
14971   [(set (match_operand:SF 0 "register_operand" "=x")
14972         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14973                    UNSPEC_RCP))]
14974   "TARGET_SSE_MATH"
14975   "%vrcpss\t{%1, %d0|%d0, %1}"
14976   [(set_attr "type" "sse")
14977    (set_attr "atom_sse_attr" "rcp")
14978    (set_attr "prefix" "maybe_vex")
14979    (set_attr "mode" "SF")])
14981 (define_insn "*fop_<mode>_1_avx"
14982   [(set (match_operand:MODEF 0 "register_operand" "=x")
14983         (match_operator:MODEF 3 "binary_fp_operator"
14984           [(match_operand:MODEF 1 "register_operand" "x")
14985            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14986   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14987    && !COMMUTATIVE_ARITH_P (operands[3])"
14988   "* return output_387_binary_op (insn, operands);"
14989   [(set (attr "type")
14990         (cond [(match_operand:MODEF 3 "mult_operator" "")
14991                  (const_string "ssemul")
14992                (match_operand:MODEF 3 "div_operator" "")
14993                  (const_string "ssediv")
14994               ]
14995               (const_string "sseadd")))
14996    (set_attr "prefix" "vex")
14997    (set_attr "mode" "<MODE>")])
14999 (define_insn "*fop_<mode>_1_sse"
15000   [(set (match_operand:MODEF 0 "register_operand" "=x")
15001         (match_operator:MODEF 3 "binary_fp_operator"
15002           [(match_operand:MODEF 1 "register_operand" "0")
15003            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15004   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15005    && !COMMUTATIVE_ARITH_P (operands[3])"
15006   "* return output_387_binary_op (insn, operands);"
15007   [(set (attr "type")
15008         (cond [(match_operand:MODEF 3 "mult_operator" "")
15009                  (const_string "ssemul")
15010                (match_operand:MODEF 3 "div_operator" "")
15011                  (const_string "ssediv")
15012               ]
15013               (const_string "sseadd")))
15014    (set_attr "mode" "<MODE>")])
15016 ;; This pattern is not fully shadowed by the pattern above.
15017 (define_insn "*fop_<mode>_1_i387"
15018   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15019         (match_operator:MODEF 3 "binary_fp_operator"
15020           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
15021            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
15022   "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15023    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15024    && !COMMUTATIVE_ARITH_P (operands[3])
15025    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15026   "* return output_387_binary_op (insn, operands);"
15027   [(set (attr "type")
15028         (cond [(match_operand:MODEF 3 "mult_operator" "")
15029                  (const_string "fmul")
15030                (match_operand:MODEF 3 "div_operator" "")
15031                  (const_string "fdiv")
15032               ]
15033               (const_string "fop")))
15034    (set_attr "mode" "<MODE>")])
15036 ;; ??? Add SSE splitters for these!
15037 (define_insn "*fop_<MODEF:mode>_2_i387"
15038   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15039         (match_operator:MODEF 3 "binary_fp_operator"
15040           [(float:MODEF
15041              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15042            (match_operand:MODEF 2 "register_operand" "0,0")]))]
15043   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15044    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15045    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15046   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15047   [(set (attr "type")
15048         (cond [(match_operand:MODEF 3 "mult_operator" "")
15049                  (const_string "fmul")
15050                (match_operand:MODEF 3 "div_operator" "")
15051                  (const_string "fdiv")
15052               ]
15053               (const_string "fop")))
15054    (set_attr "fp_int_src" "true")
15055    (set_attr "mode" "<X87MODEI12:MODE>")])
15057 (define_insn "*fop_<MODEF:mode>_3_i387"
15058   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15059         (match_operator:MODEF 3 "binary_fp_operator"
15060           [(match_operand:MODEF 1 "register_operand" "0,0")
15061            (float:MODEF
15062              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15063   "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15064    && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15065    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15066   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15067   [(set (attr "type")
15068         (cond [(match_operand:MODEF 3 "mult_operator" "")
15069                  (const_string "fmul")
15070                (match_operand:MODEF 3 "div_operator" "")
15071                  (const_string "fdiv")
15072               ]
15073               (const_string "fop")))
15074    (set_attr "fp_int_src" "true")
15075    (set_attr "mode" "<MODE>")])
15077 (define_insn "*fop_df_4_i387"
15078   [(set (match_operand:DF 0 "register_operand" "=f,f")
15079         (match_operator:DF 3 "binary_fp_operator"
15080            [(float_extend:DF
15081              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15082             (match_operand:DF 2 "register_operand" "0,f")]))]
15083   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15084    && !(TARGET_SSE2 && TARGET_SSE_MATH)
15085    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15086   "* return output_387_binary_op (insn, operands);"
15087   [(set (attr "type")
15088         (cond [(match_operand:DF 3 "mult_operator" "")
15089                  (const_string "fmul")
15090                (match_operand:DF 3 "div_operator" "")
15091                  (const_string "fdiv")
15092               ]
15093               (const_string "fop")))
15094    (set_attr "mode" "SF")])
15096 (define_insn "*fop_df_5_i387"
15097   [(set (match_operand:DF 0 "register_operand" "=f,f")
15098         (match_operator:DF 3 "binary_fp_operator"
15099           [(match_operand:DF 1 "register_operand" "0,f")
15100            (float_extend:DF
15101             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15102   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15103    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15104   "* return output_387_binary_op (insn, operands);"
15105   [(set (attr "type")
15106         (cond [(match_operand:DF 3 "mult_operator" "")
15107                  (const_string "fmul")
15108                (match_operand:DF 3 "div_operator" "")
15109                  (const_string "fdiv")
15110               ]
15111               (const_string "fop")))
15112    (set_attr "mode" "SF")])
15114 (define_insn "*fop_df_6_i387"
15115   [(set (match_operand:DF 0 "register_operand" "=f,f")
15116         (match_operator:DF 3 "binary_fp_operator"
15117           [(float_extend:DF
15118             (match_operand:SF 1 "register_operand" "0,f"))
15119            (float_extend:DF
15120             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15121   "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15122    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15123   "* return output_387_binary_op (insn, operands);"
15124   [(set (attr "type")
15125         (cond [(match_operand:DF 3 "mult_operator" "")
15126                  (const_string "fmul")
15127                (match_operand:DF 3 "div_operator" "")
15128                  (const_string "fdiv")
15129               ]
15130               (const_string "fop")))
15131    (set_attr "mode" "SF")])
15133 (define_insn "*fop_xf_comm_i387"
15134   [(set (match_operand:XF 0 "register_operand" "=f")
15135         (match_operator:XF 3 "binary_fp_operator"
15136                         [(match_operand:XF 1 "register_operand" "%0")
15137                          (match_operand:XF 2 "register_operand" "f")]))]
15138   "TARGET_80387
15139    && COMMUTATIVE_ARITH_P (operands[3])"
15140   "* return output_387_binary_op (insn, operands);"
15141   [(set (attr "type")
15142         (if_then_else (match_operand:XF 3 "mult_operator" "")
15143            (const_string "fmul")
15144            (const_string "fop")))
15145    (set_attr "mode" "XF")])
15147 (define_insn "*fop_xf_1_i387"
15148   [(set (match_operand:XF 0 "register_operand" "=f,f")
15149         (match_operator:XF 3 "binary_fp_operator"
15150                         [(match_operand:XF 1 "register_operand" "0,f")
15151                          (match_operand:XF 2 "register_operand" "f,0")]))]
15152   "TARGET_80387
15153    && !COMMUTATIVE_ARITH_P (operands[3])"
15154   "* return output_387_binary_op (insn, operands);"
15155   [(set (attr "type")
15156         (cond [(match_operand:XF 3 "mult_operator" "")
15157                  (const_string "fmul")
15158                (match_operand:XF 3 "div_operator" "")
15159                  (const_string "fdiv")
15160               ]
15161               (const_string "fop")))
15162    (set_attr "mode" "XF")])
15164 (define_insn "*fop_xf_2_i387"
15165   [(set (match_operand:XF 0 "register_operand" "=f,f")
15166         (match_operator:XF 3 "binary_fp_operator"
15167           [(float:XF
15168              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15169            (match_operand:XF 2 "register_operand" "0,0")]))]
15170   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15171   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15172   [(set (attr "type")
15173         (cond [(match_operand:XF 3 "mult_operator" "")
15174                  (const_string "fmul")
15175                (match_operand:XF 3 "div_operator" "")
15176                  (const_string "fdiv")
15177               ]
15178               (const_string "fop")))
15179    (set_attr "fp_int_src" "true")
15180    (set_attr "mode" "<MODE>")])
15182 (define_insn "*fop_xf_3_i387"
15183   [(set (match_operand:XF 0 "register_operand" "=f,f")
15184         (match_operator:XF 3 "binary_fp_operator"
15185           [(match_operand:XF 1 "register_operand" "0,0")
15186            (float:XF
15187              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15188   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15189   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15190   [(set (attr "type")
15191         (cond [(match_operand:XF 3 "mult_operator" "")
15192                  (const_string "fmul")
15193                (match_operand:XF 3 "div_operator" "")
15194                  (const_string "fdiv")
15195               ]
15196               (const_string "fop")))
15197    (set_attr "fp_int_src" "true")
15198    (set_attr "mode" "<MODE>")])
15200 (define_insn "*fop_xf_4_i387"
15201   [(set (match_operand:XF 0 "register_operand" "=f,f")
15202         (match_operator:XF 3 "binary_fp_operator"
15203            [(float_extend:XF
15204               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15205             (match_operand:XF 2 "register_operand" "0,f")]))]
15206   "TARGET_80387"
15207   "* return output_387_binary_op (insn, operands);"
15208   [(set (attr "type")
15209         (cond [(match_operand:XF 3 "mult_operator" "")
15210                  (const_string "fmul")
15211                (match_operand:XF 3 "div_operator" "")
15212                  (const_string "fdiv")
15213               ]
15214               (const_string "fop")))
15215    (set_attr "mode" "<MODE>")])
15217 (define_insn "*fop_xf_5_i387"
15218   [(set (match_operand:XF 0 "register_operand" "=f,f")
15219         (match_operator:XF 3 "binary_fp_operator"
15220           [(match_operand:XF 1 "register_operand" "0,f")
15221            (float_extend:XF
15222              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15223   "TARGET_80387"
15224   "* return output_387_binary_op (insn, operands);"
15225   [(set (attr "type")
15226         (cond [(match_operand:XF 3 "mult_operator" "")
15227                  (const_string "fmul")
15228                (match_operand:XF 3 "div_operator" "")
15229                  (const_string "fdiv")
15230               ]
15231               (const_string "fop")))
15232    (set_attr "mode" "<MODE>")])
15234 (define_insn "*fop_xf_6_i387"
15235   [(set (match_operand:XF 0 "register_operand" "=f,f")
15236         (match_operator:XF 3 "binary_fp_operator"
15237           [(float_extend:XF
15238              (match_operand:MODEF 1 "register_operand" "0,f"))
15239            (float_extend:XF
15240              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15241   "TARGET_80387"
15242   "* return output_387_binary_op (insn, operands);"
15243   [(set (attr "type")
15244         (cond [(match_operand:XF 3 "mult_operator" "")
15245                  (const_string "fmul")
15246                (match_operand:XF 3 "div_operator" "")
15247                  (const_string "fdiv")
15248               ]
15249               (const_string "fop")))
15250    (set_attr "mode" "<MODE>")])
15252 (define_split
15253   [(set (match_operand 0 "register_operand" "")
15254         (match_operator 3 "binary_fp_operator"
15255            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15256             (match_operand 2 "register_operand" "")]))]
15257   "reload_completed
15258    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15259    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
15260   [(const_int 0)]
15262   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15263   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15264   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15265                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15266                                           GET_MODE (operands[3]),
15267                                           operands[4],
15268                                           operands[2])));
15269   ix86_free_from_memory (GET_MODE (operands[1]));
15270   DONE;
15273 (define_split
15274   [(set (match_operand 0 "register_operand" "")
15275         (match_operator 3 "binary_fp_operator"
15276            [(match_operand 1 "register_operand" "")
15277             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15278   "reload_completed
15279    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15280    && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
15281   [(const_int 0)]
15283   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15284   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15285   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15286                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
15287                                           GET_MODE (operands[3]),
15288                                           operands[1],
15289                                           operands[4])));
15290   ix86_free_from_memory (GET_MODE (operands[2]));
15291   DONE;
15294 ;; FPU special functions.
15296 ;; This pattern implements a no-op XFmode truncation for
15297 ;; all fancy i386 XFmode math functions.
15299 (define_insn "truncxf<mode>2_i387_noop_unspec"
15300   [(set (match_operand:MODEF 0 "register_operand" "=f")
15301         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15302         UNSPEC_TRUNC_NOOP))]
15303   "TARGET_USE_FANCY_MATH_387"
15304   "* return output_387_reg_move (insn, operands);"
15305   [(set_attr "type" "fmov")
15306    (set_attr "mode" "<MODE>")])
15308 (define_insn "sqrtxf2"
15309   [(set (match_operand:XF 0 "register_operand" "=f")
15310         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15311   "TARGET_USE_FANCY_MATH_387"
15312   "fsqrt"
15313   [(set_attr "type" "fpspc")
15314    (set_attr "mode" "XF")
15315    (set_attr "athlon_decode" "direct")
15316    (set_attr "amdfam10_decode" "direct")])
15318 (define_insn "sqrt_extend<mode>xf2_i387"
15319   [(set (match_operand:XF 0 "register_operand" "=f")
15320         (sqrt:XF
15321           (float_extend:XF
15322             (match_operand:MODEF 1 "register_operand" "0"))))]
15323   "TARGET_USE_FANCY_MATH_387"
15324   "fsqrt"
15325   [(set_attr "type" "fpspc")
15326    (set_attr "mode" "XF")
15327    (set_attr "athlon_decode" "direct")
15328    (set_attr "amdfam10_decode" "direct")])
15330 (define_insn "*rsqrtsf2_sse"
15331   [(set (match_operand:SF 0 "register_operand" "=x")
15332         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15333                    UNSPEC_RSQRT))]
15334   "TARGET_SSE_MATH"
15335   "%vrsqrtss\t{%1, %d0|%d0, %1}"
15336   [(set_attr "type" "sse")
15337    (set_attr "atom_sse_attr" "rcp")
15338    (set_attr "prefix" "maybe_vex")
15339    (set_attr "mode" "SF")])
15341 (define_expand "rsqrtsf2"
15342   [(set (match_operand:SF 0 "register_operand" "")
15343         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
15344                    UNSPEC_RSQRT))]
15345   "TARGET_SSE_MATH"
15347   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15348   DONE;
15351 (define_insn "*sqrt<mode>2_sse"
15352   [(set (match_operand:MODEF 0 "register_operand" "=x")
15353         (sqrt:MODEF
15354           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
15355   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15356   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
15357   [(set_attr "type" "sse")
15358    (set_attr "atom_sse_attr" "sqrt")
15359    (set_attr "prefix" "maybe_vex")
15360    (set_attr "mode" "<MODE>")
15361    (set_attr "athlon_decode" "*")
15362    (set_attr "amdfam10_decode" "*")])
15364 (define_expand "sqrt<mode>2"
15365   [(set (match_operand:MODEF 0 "register_operand" "")
15366         (sqrt:MODEF
15367           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
15368   "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15369    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15371   if (<MODE>mode == SFmode
15372       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
15373       && flag_finite_math_only && !flag_trapping_math
15374       && flag_unsafe_math_optimizations)
15375     {
15376       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15377       DONE;
15378     }
15380   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15381     {
15382       rtx op0 = gen_reg_rtx (XFmode);
15383       rtx op1 = force_reg (<MODE>mode, operands[1]);
15385       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15386       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15387       DONE;
15388    }
15391 (define_insn "fpremxf4_i387"
15392   [(set (match_operand:XF 0 "register_operand" "=f")
15393         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15394                     (match_operand:XF 3 "register_operand" "1")]
15395                    UNSPEC_FPREM_F))
15396    (set (match_operand:XF 1 "register_operand" "=u")
15397         (unspec:XF [(match_dup 2) (match_dup 3)]
15398                    UNSPEC_FPREM_U))
15399    (set (reg:CCFP FPSR_REG)
15400         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15401                      UNSPEC_C2_FLAG))]
15402   "TARGET_USE_FANCY_MATH_387"
15403   "fprem"
15404   [(set_attr "type" "fpspc")
15405    (set_attr "mode" "XF")])
15407 (define_expand "fmodxf3"
15408   [(use (match_operand:XF 0 "register_operand" ""))
15409    (use (match_operand:XF 1 "general_operand" ""))
15410    (use (match_operand:XF 2 "general_operand" ""))]
15411   "TARGET_USE_FANCY_MATH_387"
15413   rtx label = gen_label_rtx ();
15415   rtx op1 = gen_reg_rtx (XFmode);
15416   rtx op2 = gen_reg_rtx (XFmode);
15418   emit_move_insn (op2, operands[2]);
15419   emit_move_insn (op1, operands[1]);
15421   emit_label (label);
15422   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15423   ix86_emit_fp_unordered_jump (label);
15424   LABEL_NUSES (label) = 1;
15426   emit_move_insn (operands[0], op1);
15427   DONE;
15430 (define_expand "fmod<mode>3"
15431   [(use (match_operand:MODEF 0 "register_operand" ""))
15432    (use (match_operand:MODEF 1 "general_operand" ""))
15433    (use (match_operand:MODEF 2 "general_operand" ""))]
15434   "TARGET_USE_FANCY_MATH_387"
15436   rtx label = gen_label_rtx ();
15438   rtx op1 = gen_reg_rtx (XFmode);
15439   rtx op2 = gen_reg_rtx (XFmode);
15441   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15442   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15444   emit_label (label);
15445   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15446   ix86_emit_fp_unordered_jump (label);
15447   LABEL_NUSES (label) = 1;
15449   /* Truncate the result properly for strict SSE math.  */
15450   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15451       && !TARGET_MIX_SSE_I387)
15452     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15453   else
15454     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15456   DONE;
15459 (define_insn "fprem1xf4_i387"
15460   [(set (match_operand:XF 0 "register_operand" "=f")
15461         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15462                     (match_operand:XF 3 "register_operand" "1")]
15463                    UNSPEC_FPREM1_F))
15464    (set (match_operand:XF 1 "register_operand" "=u")
15465         (unspec:XF [(match_dup 2) (match_dup 3)]
15466                    UNSPEC_FPREM1_U))
15467    (set (reg:CCFP FPSR_REG)
15468         (unspec:CCFP [(match_dup 2) (match_dup 3)]
15469                      UNSPEC_C2_FLAG))]
15470   "TARGET_USE_FANCY_MATH_387"
15471   "fprem1"
15472   [(set_attr "type" "fpspc")
15473    (set_attr "mode" "XF")])
15475 (define_expand "remainderxf3"
15476   [(use (match_operand:XF 0 "register_operand" ""))
15477    (use (match_operand:XF 1 "general_operand" ""))
15478    (use (match_operand:XF 2 "general_operand" ""))]
15479   "TARGET_USE_FANCY_MATH_387"
15481   rtx label = gen_label_rtx ();
15483   rtx op1 = gen_reg_rtx (XFmode);
15484   rtx op2 = gen_reg_rtx (XFmode);
15486   emit_move_insn (op2, operands[2]);
15487   emit_move_insn (op1, operands[1]);
15489   emit_label (label);
15490   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15491   ix86_emit_fp_unordered_jump (label);
15492   LABEL_NUSES (label) = 1;
15494   emit_move_insn (operands[0], op1);
15495   DONE;
15498 (define_expand "remainder<mode>3"
15499   [(use (match_operand:MODEF 0 "register_operand" ""))
15500    (use (match_operand:MODEF 1 "general_operand" ""))
15501    (use (match_operand:MODEF 2 "general_operand" ""))]
15502   "TARGET_USE_FANCY_MATH_387"
15504   rtx label = gen_label_rtx ();
15506   rtx op1 = gen_reg_rtx (XFmode);
15507   rtx op2 = gen_reg_rtx (XFmode);
15509   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15510   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15512   emit_label (label);
15514   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15515   ix86_emit_fp_unordered_jump (label);
15516   LABEL_NUSES (label) = 1;
15518   /* Truncate the result properly for strict SSE math.  */
15519   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15520       && !TARGET_MIX_SSE_I387)
15521     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15522   else
15523     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15525   DONE;
15528 (define_insn "*sinxf2_i387"
15529   [(set (match_operand:XF 0 "register_operand" "=f")
15530         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15531   "TARGET_USE_FANCY_MATH_387
15532    && flag_unsafe_math_optimizations"
15533   "fsin"
15534   [(set_attr "type" "fpspc")
15535    (set_attr "mode" "XF")])
15537 (define_insn "*sin_extend<mode>xf2_i387"
15538   [(set (match_operand:XF 0 "register_operand" "=f")
15539         (unspec:XF [(float_extend:XF
15540                       (match_operand:MODEF 1 "register_operand" "0"))]
15541                    UNSPEC_SIN))]
15542   "TARGET_USE_FANCY_MATH_387
15543    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15544        || TARGET_MIX_SSE_I387)
15545    && flag_unsafe_math_optimizations"
15546   "fsin"
15547   [(set_attr "type" "fpspc")
15548    (set_attr "mode" "XF")])
15550 (define_insn "*cosxf2_i387"
15551   [(set (match_operand:XF 0 "register_operand" "=f")
15552         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15553   "TARGET_USE_FANCY_MATH_387
15554    && flag_unsafe_math_optimizations"
15555   "fcos"
15556   [(set_attr "type" "fpspc")
15557    (set_attr "mode" "XF")])
15559 (define_insn "*cos_extend<mode>xf2_i387"
15560   [(set (match_operand:XF 0 "register_operand" "=f")
15561         (unspec:XF [(float_extend:XF
15562                       (match_operand:MODEF 1 "register_operand" "0"))]
15563                    UNSPEC_COS))]
15564   "TARGET_USE_FANCY_MATH_387
15565    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15566        || TARGET_MIX_SSE_I387)
15567    && flag_unsafe_math_optimizations"
15568   "fcos"
15569   [(set_attr "type" "fpspc")
15570    (set_attr "mode" "XF")])
15572 ;; When sincos pattern is defined, sin and cos builtin functions will be
15573 ;; expanded to sincos pattern with one of its outputs left unused.
15574 ;; CSE pass will figure out if two sincos patterns can be combined,
15575 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15576 ;; depending on the unused output.
15578 (define_insn "sincosxf3"
15579   [(set (match_operand:XF 0 "register_operand" "=f")
15580         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15581                    UNSPEC_SINCOS_COS))
15582    (set (match_operand:XF 1 "register_operand" "=u")
15583         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15584   "TARGET_USE_FANCY_MATH_387
15585    && flag_unsafe_math_optimizations"
15586   "fsincos"
15587   [(set_attr "type" "fpspc")
15588    (set_attr "mode" "XF")])
15590 (define_split
15591   [(set (match_operand:XF 0 "register_operand" "")
15592         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15593                    UNSPEC_SINCOS_COS))
15594    (set (match_operand:XF 1 "register_operand" "")
15595         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15596   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15597    && !(reload_completed || reload_in_progress)"
15598   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15599   "")
15601 (define_split
15602   [(set (match_operand:XF 0 "register_operand" "")
15603         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15604                    UNSPEC_SINCOS_COS))
15605    (set (match_operand:XF 1 "register_operand" "")
15606         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15607   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15608    && !(reload_completed || reload_in_progress)"
15609   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15610   "")
15612 (define_insn "sincos_extend<mode>xf3_i387"
15613   [(set (match_operand:XF 0 "register_operand" "=f")
15614         (unspec:XF [(float_extend:XF
15615                       (match_operand:MODEF 2 "register_operand" "0"))]
15616                    UNSPEC_SINCOS_COS))
15617    (set (match_operand:XF 1 "register_operand" "=u")
15618         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15619   "TARGET_USE_FANCY_MATH_387
15620    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15621        || TARGET_MIX_SSE_I387)
15622    && flag_unsafe_math_optimizations"
15623   "fsincos"
15624   [(set_attr "type" "fpspc")
15625    (set_attr "mode" "XF")])
15627 (define_split
15628   [(set (match_operand:XF 0 "register_operand" "")
15629         (unspec:XF [(float_extend:XF
15630                       (match_operand:MODEF 2 "register_operand" ""))]
15631                    UNSPEC_SINCOS_COS))
15632    (set (match_operand:XF 1 "register_operand" "")
15633         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15634   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15635    && !(reload_completed || reload_in_progress)"
15636   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15637   "")
15639 (define_split
15640   [(set (match_operand:XF 0 "register_operand" "")
15641         (unspec:XF [(float_extend:XF
15642                       (match_operand:MODEF 2 "register_operand" ""))]
15643                    UNSPEC_SINCOS_COS))
15644    (set (match_operand:XF 1 "register_operand" "")
15645         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15646   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15647    && !(reload_completed || reload_in_progress)"
15648   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15649   "")
15651 (define_expand "sincos<mode>3"
15652   [(use (match_operand:MODEF 0 "register_operand" ""))
15653    (use (match_operand:MODEF 1 "register_operand" ""))
15654    (use (match_operand:MODEF 2 "register_operand" ""))]
15655   "TARGET_USE_FANCY_MATH_387
15656    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15657        || TARGET_MIX_SSE_I387)
15658    && flag_unsafe_math_optimizations"
15660   rtx op0 = gen_reg_rtx (XFmode);
15661   rtx op1 = gen_reg_rtx (XFmode);
15663   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15664   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15665   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15666   DONE;
15669 (define_insn "fptanxf4_i387"
15670   [(set (match_operand:XF 0 "register_operand" "=f")
15671         (match_operand:XF 3 "const_double_operand" "F"))
15672    (set (match_operand:XF 1 "register_operand" "=u")
15673         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15674                    UNSPEC_TAN))]
15675   "TARGET_USE_FANCY_MATH_387
15676    && flag_unsafe_math_optimizations
15677    && standard_80387_constant_p (operands[3]) == 2"
15678   "fptan"
15679   [(set_attr "type" "fpspc")
15680    (set_attr "mode" "XF")])
15682 (define_insn "fptan_extend<mode>xf4_i387"
15683   [(set (match_operand:MODEF 0 "register_operand" "=f")
15684         (match_operand:MODEF 3 "const_double_operand" "F"))
15685    (set (match_operand:XF 1 "register_operand" "=u")
15686         (unspec:XF [(float_extend:XF
15687                       (match_operand:MODEF 2 "register_operand" "0"))]
15688                    UNSPEC_TAN))]
15689   "TARGET_USE_FANCY_MATH_387
15690    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15691        || TARGET_MIX_SSE_I387)
15692    && flag_unsafe_math_optimizations
15693    && standard_80387_constant_p (operands[3]) == 2"
15694   "fptan"
15695   [(set_attr "type" "fpspc")
15696    (set_attr "mode" "XF")])
15698 (define_expand "tanxf2"
15699   [(use (match_operand:XF 0 "register_operand" ""))
15700    (use (match_operand:XF 1 "register_operand" ""))]
15701   "TARGET_USE_FANCY_MATH_387
15702    && flag_unsafe_math_optimizations"
15704   rtx one = gen_reg_rtx (XFmode);
15705   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15707   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15708   DONE;
15711 (define_expand "tan<mode>2"
15712   [(use (match_operand:MODEF 0 "register_operand" ""))
15713    (use (match_operand:MODEF 1 "register_operand" ""))]
15714   "TARGET_USE_FANCY_MATH_387
15715    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15716        || TARGET_MIX_SSE_I387)
15717    && flag_unsafe_math_optimizations"
15719   rtx op0 = gen_reg_rtx (XFmode);
15721   rtx one = gen_reg_rtx (<MODE>mode);
15722   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15724   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15725                                              operands[1], op2));
15726   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15727   DONE;
15730 (define_insn "*fpatanxf3_i387"
15731   [(set (match_operand:XF 0 "register_operand" "=f")
15732         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15733                     (match_operand:XF 2 "register_operand" "u")]
15734                    UNSPEC_FPATAN))
15735    (clobber (match_scratch:XF 3 "=2"))]
15736   "TARGET_USE_FANCY_MATH_387
15737    && flag_unsafe_math_optimizations"
15738   "fpatan"
15739   [(set_attr "type" "fpspc")
15740    (set_attr "mode" "XF")])
15742 (define_insn "fpatan_extend<mode>xf3_i387"
15743   [(set (match_operand:XF 0 "register_operand" "=f")
15744         (unspec:XF [(float_extend:XF
15745                       (match_operand:MODEF 1 "register_operand" "0"))
15746                     (float_extend:XF
15747                       (match_operand:MODEF 2 "register_operand" "u"))]
15748                    UNSPEC_FPATAN))
15749    (clobber (match_scratch:XF 3 "=2"))]
15750   "TARGET_USE_FANCY_MATH_387
15751    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15752        || TARGET_MIX_SSE_I387)
15753    && flag_unsafe_math_optimizations"
15754   "fpatan"
15755   [(set_attr "type" "fpspc")
15756    (set_attr "mode" "XF")])
15758 (define_expand "atan2xf3"
15759   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15760                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
15761                                (match_operand:XF 1 "register_operand" "")]
15762                               UNSPEC_FPATAN))
15763               (clobber (match_scratch:XF 3 ""))])]
15764   "TARGET_USE_FANCY_MATH_387
15765    && flag_unsafe_math_optimizations"
15766   "")
15768 (define_expand "atan2<mode>3"
15769   [(use (match_operand:MODEF 0 "register_operand" ""))
15770    (use (match_operand:MODEF 1 "register_operand" ""))
15771    (use (match_operand:MODEF 2 "register_operand" ""))]
15772   "TARGET_USE_FANCY_MATH_387
15773    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15774        || TARGET_MIX_SSE_I387)
15775    && flag_unsafe_math_optimizations"
15777   rtx op0 = gen_reg_rtx (XFmode);
15779   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15780   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15781   DONE;
15784 (define_expand "atanxf2"
15785   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15786                    (unspec:XF [(match_dup 2)
15787                                (match_operand:XF 1 "register_operand" "")]
15788                               UNSPEC_FPATAN))
15789               (clobber (match_scratch:XF 3 ""))])]
15790   "TARGET_USE_FANCY_MATH_387
15791    && flag_unsafe_math_optimizations"
15793   operands[2] = gen_reg_rtx (XFmode);
15794   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
15797 (define_expand "atan<mode>2"
15798   [(use (match_operand:MODEF 0 "register_operand" ""))
15799    (use (match_operand:MODEF 1 "register_operand" ""))]
15800   "TARGET_USE_FANCY_MATH_387
15801    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15802        || TARGET_MIX_SSE_I387)
15803    && flag_unsafe_math_optimizations"
15805   rtx op0 = gen_reg_rtx (XFmode);
15807   rtx op2 = gen_reg_rtx (<MODE>mode);
15808   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
15810   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15811   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15812   DONE;
15815 (define_expand "asinxf2"
15816   [(set (match_dup 2)
15817         (mult:XF (match_operand:XF 1 "register_operand" "")
15818                  (match_dup 1)))
15819    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15820    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15821    (parallel [(set (match_operand:XF 0 "register_operand" "")
15822                    (unspec:XF [(match_dup 5) (match_dup 1)]
15823                               UNSPEC_FPATAN))
15824               (clobber (match_scratch:XF 6 ""))])]
15825   "TARGET_USE_FANCY_MATH_387
15826    && flag_unsafe_math_optimizations"
15828   int i;
15830   if (optimize_insn_for_size_p ())
15831     FAIL;
15833   for (i = 2; i < 6; i++)
15834     operands[i] = gen_reg_rtx (XFmode);
15836   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15839 (define_expand "asin<mode>2"
15840   [(use (match_operand:MODEF 0 "register_operand" ""))
15841    (use (match_operand:MODEF 1 "general_operand" ""))]
15842  "TARGET_USE_FANCY_MATH_387
15843    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15844        || TARGET_MIX_SSE_I387)
15845    && flag_unsafe_math_optimizations"
15847   rtx op0 = gen_reg_rtx (XFmode);
15848   rtx op1 = gen_reg_rtx (XFmode);
15850   if (optimize_insn_for_size_p ())
15851     FAIL;
15853   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15854   emit_insn (gen_asinxf2 (op0, op1));
15855   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15856   DONE;
15859 (define_expand "acosxf2"
15860   [(set (match_dup 2)
15861         (mult:XF (match_operand:XF 1 "register_operand" "")
15862                  (match_dup 1)))
15863    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15864    (set (match_dup 5) (sqrt:XF (match_dup 4)))
15865    (parallel [(set (match_operand:XF 0 "register_operand" "")
15866                    (unspec:XF [(match_dup 1) (match_dup 5)]
15867                               UNSPEC_FPATAN))
15868               (clobber (match_scratch:XF 6 ""))])]
15869   "TARGET_USE_FANCY_MATH_387
15870    && flag_unsafe_math_optimizations"
15872   int i;
15874   if (optimize_insn_for_size_p ())
15875     FAIL;
15877   for (i = 2; i < 6; i++)
15878     operands[i] = gen_reg_rtx (XFmode);
15880   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
15883 (define_expand "acos<mode>2"
15884   [(use (match_operand:MODEF 0 "register_operand" ""))
15885    (use (match_operand:MODEF 1 "general_operand" ""))]
15886  "TARGET_USE_FANCY_MATH_387
15887    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15888        || TARGET_MIX_SSE_I387)
15889    && flag_unsafe_math_optimizations"
15891   rtx op0 = gen_reg_rtx (XFmode);
15892   rtx op1 = gen_reg_rtx (XFmode);
15894   if (optimize_insn_for_size_p ())
15895     FAIL;
15897   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15898   emit_insn (gen_acosxf2 (op0, op1));
15899   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15900   DONE;
15903 (define_insn "fyl2xxf3_i387"
15904   [(set (match_operand:XF 0 "register_operand" "=f")
15905         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15906                     (match_operand:XF 2 "register_operand" "u")]
15907                    UNSPEC_FYL2X))
15908    (clobber (match_scratch:XF 3 "=2"))]
15909   "TARGET_USE_FANCY_MATH_387
15910    && flag_unsafe_math_optimizations"
15911   "fyl2x"
15912   [(set_attr "type" "fpspc")
15913    (set_attr "mode" "XF")])
15915 (define_insn "fyl2x_extend<mode>xf3_i387"
15916   [(set (match_operand:XF 0 "register_operand" "=f")
15917         (unspec:XF [(float_extend:XF
15918                       (match_operand:MODEF 1 "register_operand" "0"))
15919                     (match_operand:XF 2 "register_operand" "u")]
15920                    UNSPEC_FYL2X))
15921    (clobber (match_scratch:XF 3 "=2"))]
15922   "TARGET_USE_FANCY_MATH_387
15923    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15924        || TARGET_MIX_SSE_I387)
15925    && flag_unsafe_math_optimizations"
15926   "fyl2x"
15927   [(set_attr "type" "fpspc")
15928    (set_attr "mode" "XF")])
15930 (define_expand "logxf2"
15931   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15932                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15933                                (match_dup 2)] UNSPEC_FYL2X))
15934               (clobber (match_scratch:XF 3 ""))])]
15935   "TARGET_USE_FANCY_MATH_387
15936    && flag_unsafe_math_optimizations"
15938   operands[2] = gen_reg_rtx (XFmode);
15939   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15942 (define_expand "log<mode>2"
15943   [(use (match_operand:MODEF 0 "register_operand" ""))
15944    (use (match_operand:MODEF 1 "register_operand" ""))]
15945   "TARGET_USE_FANCY_MATH_387
15946    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15947        || TARGET_MIX_SSE_I387)
15948    && flag_unsafe_math_optimizations"
15950   rtx op0 = gen_reg_rtx (XFmode);
15952   rtx op2 = gen_reg_rtx (XFmode);
15953   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15955   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15956   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15957   DONE;
15960 (define_expand "log10xf2"
15961   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15962                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15963                                (match_dup 2)] UNSPEC_FYL2X))
15964               (clobber (match_scratch:XF 3 ""))])]
15965   "TARGET_USE_FANCY_MATH_387
15966    && flag_unsafe_math_optimizations"
15968   operands[2] = gen_reg_rtx (XFmode);
15969   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15972 (define_expand "log10<mode>2"
15973   [(use (match_operand:MODEF 0 "register_operand" ""))
15974    (use (match_operand:MODEF 1 "register_operand" ""))]
15975   "TARGET_USE_FANCY_MATH_387
15976    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15977        || TARGET_MIX_SSE_I387)
15978    && flag_unsafe_math_optimizations"
15980   rtx op0 = gen_reg_rtx (XFmode);
15982   rtx op2 = gen_reg_rtx (XFmode);
15983   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15985   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15986   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15987   DONE;
15990 (define_expand "log2xf2"
15991   [(parallel [(set (match_operand:XF 0 "register_operand" "")
15992                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
15993                                (match_dup 2)] UNSPEC_FYL2X))
15994               (clobber (match_scratch:XF 3 ""))])]
15995   "TARGET_USE_FANCY_MATH_387
15996    && flag_unsafe_math_optimizations"
15998   operands[2] = gen_reg_rtx (XFmode);
15999   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16002 (define_expand "log2<mode>2"
16003   [(use (match_operand:MODEF 0 "register_operand" ""))
16004    (use (match_operand:MODEF 1 "register_operand" ""))]
16005   "TARGET_USE_FANCY_MATH_387
16006    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16007        || TARGET_MIX_SSE_I387)
16008    && flag_unsafe_math_optimizations"
16010   rtx op0 = gen_reg_rtx (XFmode);
16012   rtx op2 = gen_reg_rtx (XFmode);
16013   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16015   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16016   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16017   DONE;
16020 (define_insn "fyl2xp1xf3_i387"
16021   [(set (match_operand:XF 0 "register_operand" "=f")
16022         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16023                     (match_operand:XF 2 "register_operand" "u")]
16024                    UNSPEC_FYL2XP1))
16025    (clobber (match_scratch:XF 3 "=2"))]
16026   "TARGET_USE_FANCY_MATH_387
16027    && flag_unsafe_math_optimizations"
16028   "fyl2xp1"
16029   [(set_attr "type" "fpspc")
16030    (set_attr "mode" "XF")])
16032 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16033   [(set (match_operand:XF 0 "register_operand" "=f")
16034         (unspec:XF [(float_extend:XF
16035                       (match_operand:MODEF 1 "register_operand" "0"))
16036                     (match_operand:XF 2 "register_operand" "u")]
16037                    UNSPEC_FYL2XP1))
16038    (clobber (match_scratch:XF 3 "=2"))]
16039   "TARGET_USE_FANCY_MATH_387
16040    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16041        || TARGET_MIX_SSE_I387)
16042    && flag_unsafe_math_optimizations"
16043   "fyl2xp1"
16044   [(set_attr "type" "fpspc")
16045    (set_attr "mode" "XF")])
16047 (define_expand "log1pxf2"
16048   [(use (match_operand:XF 0 "register_operand" ""))
16049    (use (match_operand:XF 1 "register_operand" ""))]
16050   "TARGET_USE_FANCY_MATH_387
16051    && flag_unsafe_math_optimizations"
16053   if (optimize_insn_for_size_p ())
16054     FAIL;
16056   ix86_emit_i387_log1p (operands[0], operands[1]);
16057   DONE;
16060 (define_expand "log1p<mode>2"
16061   [(use (match_operand:MODEF 0 "register_operand" ""))
16062    (use (match_operand:MODEF 1 "register_operand" ""))]
16063   "TARGET_USE_FANCY_MATH_387
16064    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16065        || TARGET_MIX_SSE_I387)
16066    && flag_unsafe_math_optimizations"
16068   rtx op0;
16070   if (optimize_insn_for_size_p ())
16071     FAIL;
16073   op0 = gen_reg_rtx (XFmode);
16075   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16077   ix86_emit_i387_log1p (op0, operands[1]);
16078   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16079   DONE;
16082 (define_insn "fxtractxf3_i387"
16083   [(set (match_operand:XF 0 "register_operand" "=f")
16084         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16085                    UNSPEC_XTRACT_FRACT))
16086    (set (match_operand:XF 1 "register_operand" "=u")
16087         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16088   "TARGET_USE_FANCY_MATH_387
16089    && flag_unsafe_math_optimizations"
16090   "fxtract"
16091   [(set_attr "type" "fpspc")
16092    (set_attr "mode" "XF")])
16094 (define_insn "fxtract_extend<mode>xf3_i387"
16095   [(set (match_operand:XF 0 "register_operand" "=f")
16096         (unspec:XF [(float_extend:XF
16097                       (match_operand:MODEF 2 "register_operand" "0"))]
16098                    UNSPEC_XTRACT_FRACT))
16099    (set (match_operand:XF 1 "register_operand" "=u")
16100         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16101   "TARGET_USE_FANCY_MATH_387
16102    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16103        || TARGET_MIX_SSE_I387)
16104    && flag_unsafe_math_optimizations"
16105   "fxtract"
16106   [(set_attr "type" "fpspc")
16107    (set_attr "mode" "XF")])
16109 (define_expand "logbxf2"
16110   [(parallel [(set (match_dup 2)
16111                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16112                               UNSPEC_XTRACT_FRACT))
16113               (set (match_operand:XF 0 "register_operand" "")
16114                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16115   "TARGET_USE_FANCY_MATH_387
16116    && flag_unsafe_math_optimizations"
16118   operands[2] = gen_reg_rtx (XFmode);
16121 (define_expand "logb<mode>2"
16122   [(use (match_operand:MODEF 0 "register_operand" ""))
16123    (use (match_operand:MODEF 1 "register_operand" ""))]
16124   "TARGET_USE_FANCY_MATH_387
16125    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16126        || TARGET_MIX_SSE_I387)
16127    && flag_unsafe_math_optimizations"
16129   rtx op0 = gen_reg_rtx (XFmode);
16130   rtx op1 = gen_reg_rtx (XFmode);
16132   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16133   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16134   DONE;
16137 (define_expand "ilogbxf2"
16138   [(use (match_operand:SI 0 "register_operand" ""))
16139    (use (match_operand:XF 1 "register_operand" ""))]
16140   "TARGET_USE_FANCY_MATH_387
16141    && flag_unsafe_math_optimizations"
16143   rtx op0, op1;
16145   if (optimize_insn_for_size_p ())
16146     FAIL;
16148   op0 = gen_reg_rtx (XFmode);
16149   op1 = gen_reg_rtx (XFmode);
16151   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16152   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16153   DONE;
16156 (define_expand "ilogb<mode>2"
16157   [(use (match_operand:SI 0 "register_operand" ""))
16158    (use (match_operand:MODEF 1 "register_operand" ""))]
16159   "TARGET_USE_FANCY_MATH_387
16160    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16161        || TARGET_MIX_SSE_I387)
16162    && flag_unsafe_math_optimizations"
16164   rtx op0, op1;
16166   if (optimize_insn_for_size_p ())
16167     FAIL;
16169   op0 = gen_reg_rtx (XFmode);
16170   op1 = gen_reg_rtx (XFmode);
16172   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16173   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16174   DONE;
16177 (define_insn "*f2xm1xf2_i387"
16178   [(set (match_operand:XF 0 "register_operand" "=f")
16179         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16180                    UNSPEC_F2XM1))]
16181   "TARGET_USE_FANCY_MATH_387
16182    && flag_unsafe_math_optimizations"
16183   "f2xm1"
16184   [(set_attr "type" "fpspc")
16185    (set_attr "mode" "XF")])
16187 (define_insn "*fscalexf4_i387"
16188   [(set (match_operand:XF 0 "register_operand" "=f")
16189         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16190                     (match_operand:XF 3 "register_operand" "1")]
16191                    UNSPEC_FSCALE_FRACT))
16192    (set (match_operand:XF 1 "register_operand" "=u")
16193         (unspec:XF [(match_dup 2) (match_dup 3)]
16194                    UNSPEC_FSCALE_EXP))]
16195   "TARGET_USE_FANCY_MATH_387
16196    && flag_unsafe_math_optimizations"
16197   "fscale"
16198   [(set_attr "type" "fpspc")
16199    (set_attr "mode" "XF")])
16201 (define_expand "expNcorexf3"
16202   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16203                                (match_operand:XF 2 "register_operand" "")))
16204    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16205    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16206    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16207    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16208    (parallel [(set (match_operand:XF 0 "register_operand" "")
16209                    (unspec:XF [(match_dup 8) (match_dup 4)]
16210                               UNSPEC_FSCALE_FRACT))
16211               (set (match_dup 9)
16212                    (unspec:XF [(match_dup 8) (match_dup 4)]
16213                               UNSPEC_FSCALE_EXP))])]
16214   "TARGET_USE_FANCY_MATH_387
16215    && flag_unsafe_math_optimizations"
16217   int i;
16219   if (optimize_insn_for_size_p ())
16220     FAIL;
16222   for (i = 3; i < 10; i++)
16223     operands[i] = gen_reg_rtx (XFmode);
16225   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
16228 (define_expand "expxf2"
16229   [(use (match_operand:XF 0 "register_operand" ""))
16230    (use (match_operand:XF 1 "register_operand" ""))]
16231   "TARGET_USE_FANCY_MATH_387
16232    && flag_unsafe_math_optimizations"
16234   rtx op2;
16236   if (optimize_insn_for_size_p ())
16237     FAIL;
16239   op2 = gen_reg_rtx (XFmode);
16240   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16242   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16243   DONE;
16246 (define_expand "exp<mode>2"
16247   [(use (match_operand:MODEF 0 "register_operand" ""))
16248    (use (match_operand:MODEF 1 "general_operand" ""))]
16249  "TARGET_USE_FANCY_MATH_387
16250    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16251        || TARGET_MIX_SSE_I387)
16252    && flag_unsafe_math_optimizations"
16254   rtx op0, op1;
16256   if (optimize_insn_for_size_p ())
16257     FAIL;
16259   op0 = gen_reg_rtx (XFmode);
16260   op1 = gen_reg_rtx (XFmode);
16262   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16263   emit_insn (gen_expxf2 (op0, op1));
16264   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16265   DONE;
16268 (define_expand "exp10xf2"
16269   [(use (match_operand:XF 0 "register_operand" ""))
16270    (use (match_operand:XF 1 "register_operand" ""))]
16271   "TARGET_USE_FANCY_MATH_387
16272    && flag_unsafe_math_optimizations"
16274   rtx op2;
16276   if (optimize_insn_for_size_p ())
16277     FAIL;
16279   op2 = gen_reg_rtx (XFmode);
16280   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16282   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16283   DONE;
16286 (define_expand "exp10<mode>2"
16287   [(use (match_operand:MODEF 0 "register_operand" ""))
16288    (use (match_operand:MODEF 1 "general_operand" ""))]
16289  "TARGET_USE_FANCY_MATH_387
16290    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16291        || TARGET_MIX_SSE_I387)
16292    && flag_unsafe_math_optimizations"
16294   rtx op0, op1;
16296   if (optimize_insn_for_size_p ())
16297     FAIL;
16299   op0 = gen_reg_rtx (XFmode);
16300   op1 = gen_reg_rtx (XFmode);
16302   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16303   emit_insn (gen_exp10xf2 (op0, op1));
16304   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16305   DONE;
16308 (define_expand "exp2xf2"
16309   [(use (match_operand:XF 0 "register_operand" ""))
16310    (use (match_operand:XF 1 "register_operand" ""))]
16311   "TARGET_USE_FANCY_MATH_387
16312    && flag_unsafe_math_optimizations"
16314   rtx op2;
16316   if (optimize_insn_for_size_p ())
16317     FAIL;
16319   op2 = gen_reg_rtx (XFmode);
16320   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
16322   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16323   DONE;
16326 (define_expand "exp2<mode>2"
16327   [(use (match_operand:MODEF 0 "register_operand" ""))
16328    (use (match_operand:MODEF 1 "general_operand" ""))]
16329  "TARGET_USE_FANCY_MATH_387
16330    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16331        || TARGET_MIX_SSE_I387)
16332    && flag_unsafe_math_optimizations"
16334   rtx op0, op1;
16336   if (optimize_insn_for_size_p ())
16337     FAIL;
16339   op0 = gen_reg_rtx (XFmode);
16340   op1 = gen_reg_rtx (XFmode);
16342   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16343   emit_insn (gen_exp2xf2 (op0, op1));
16344   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16345   DONE;
16348 (define_expand "expm1xf2"
16349   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16350                                (match_dup 2)))
16351    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16352    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16353    (set (match_dup 9) (float_extend:XF (match_dup 13)))
16354    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16355    (parallel [(set (match_dup 7)
16356                    (unspec:XF [(match_dup 6) (match_dup 4)]
16357                               UNSPEC_FSCALE_FRACT))
16358               (set (match_dup 8)
16359                    (unspec:XF [(match_dup 6) (match_dup 4)]
16360                               UNSPEC_FSCALE_EXP))])
16361    (parallel [(set (match_dup 10)
16362                    (unspec:XF [(match_dup 9) (match_dup 8)]
16363                               UNSPEC_FSCALE_FRACT))
16364               (set (match_dup 11)
16365                    (unspec:XF [(match_dup 9) (match_dup 8)]
16366                               UNSPEC_FSCALE_EXP))])
16367    (set (match_dup 12) (minus:XF (match_dup 10)
16368                                  (float_extend:XF (match_dup 13))))
16369    (set (match_operand:XF 0 "register_operand" "")
16370         (plus:XF (match_dup 12) (match_dup 7)))]
16371   "TARGET_USE_FANCY_MATH_387
16372    && flag_unsafe_math_optimizations"
16374   int i;
16376   if (optimize_insn_for_size_p ())
16377     FAIL;
16379   for (i = 2; i < 13; i++)
16380     operands[i] = gen_reg_rtx (XFmode);
16382   operands[13]
16383     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16385   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16388 (define_expand "expm1<mode>2"
16389   [(use (match_operand:MODEF 0 "register_operand" ""))
16390    (use (match_operand:MODEF 1 "general_operand" ""))]
16391  "TARGET_USE_FANCY_MATH_387
16392    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16393        || TARGET_MIX_SSE_I387)
16394    && flag_unsafe_math_optimizations"
16396   rtx op0, op1;
16398   if (optimize_insn_for_size_p ())
16399     FAIL;
16401   op0 = gen_reg_rtx (XFmode);
16402   op1 = gen_reg_rtx (XFmode);
16404   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16405   emit_insn (gen_expm1xf2 (op0, op1));
16406   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16407   DONE;
16410 (define_expand "ldexpxf3"
16411   [(set (match_dup 3)
16412         (float:XF (match_operand:SI 2 "register_operand" "")))
16413    (parallel [(set (match_operand:XF 0 " register_operand" "")
16414                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16415                                (match_dup 3)]
16416                               UNSPEC_FSCALE_FRACT))
16417               (set (match_dup 4)
16418                    (unspec:XF [(match_dup 1) (match_dup 3)]
16419                               UNSPEC_FSCALE_EXP))])]
16420   "TARGET_USE_FANCY_MATH_387
16421    && flag_unsafe_math_optimizations"
16423   if (optimize_insn_for_size_p ())
16424     FAIL;
16426   operands[3] = gen_reg_rtx (XFmode);
16427   operands[4] = gen_reg_rtx (XFmode);
16430 (define_expand "ldexp<mode>3"
16431   [(use (match_operand:MODEF 0 "register_operand" ""))
16432    (use (match_operand:MODEF 1 "general_operand" ""))
16433    (use (match_operand:SI 2 "register_operand" ""))]
16434  "TARGET_USE_FANCY_MATH_387
16435    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16436        || TARGET_MIX_SSE_I387)
16437    && flag_unsafe_math_optimizations"
16439   rtx op0, op1;
16441   if (optimize_insn_for_size_p ())
16442     FAIL;
16444   op0 = gen_reg_rtx (XFmode);
16445   op1 = gen_reg_rtx (XFmode);
16447   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16448   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16449   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16450   DONE;
16453 (define_expand "scalbxf3"
16454   [(parallel [(set (match_operand:XF 0 " register_operand" "")
16455                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16456                                (match_operand:XF 2 "register_operand" "")]
16457                               UNSPEC_FSCALE_FRACT))
16458               (set (match_dup 3)
16459                    (unspec:XF [(match_dup 1) (match_dup 2)]
16460                               UNSPEC_FSCALE_EXP))])]
16461   "TARGET_USE_FANCY_MATH_387
16462    && flag_unsafe_math_optimizations"
16464   if (optimize_insn_for_size_p ())
16465     FAIL;
16467   operands[3] = gen_reg_rtx (XFmode);
16470 (define_expand "scalb<mode>3"
16471   [(use (match_operand:MODEF 0 "register_operand" ""))
16472    (use (match_operand:MODEF 1 "general_operand" ""))
16473    (use (match_operand:MODEF 2 "general_operand" ""))]
16474  "TARGET_USE_FANCY_MATH_387
16475    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16476        || TARGET_MIX_SSE_I387)
16477    && flag_unsafe_math_optimizations"
16479   rtx op0, op1, op2;
16481   if (optimize_insn_for_size_p ())
16482     FAIL;
16484   op0 = gen_reg_rtx (XFmode);
16485   op1 = gen_reg_rtx (XFmode);
16486   op2 = gen_reg_rtx (XFmode);
16488   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16489   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16490   emit_insn (gen_scalbxf3 (op0, op1, op2));
16491   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16492   DONE;
16495 (define_expand "significandxf2"
16496   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16497                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16498                               UNSPEC_XTRACT_FRACT))
16499               (set (match_dup 2)
16500                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16501   "TARGET_USE_FANCY_MATH_387
16502    && flag_unsafe_math_optimizations"
16504   operands[2] = gen_reg_rtx (XFmode);
16507 (define_expand "significand<mode>2"
16508   [(use (match_operand:MODEF 0 "register_operand" ""))
16509    (use (match_operand:MODEF 1 "register_operand" ""))]
16510   "TARGET_USE_FANCY_MATH_387
16511    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16512        || TARGET_MIX_SSE_I387)
16513    && flag_unsafe_math_optimizations"
16515   rtx op0 = gen_reg_rtx (XFmode);
16516   rtx op1 = gen_reg_rtx (XFmode);
16518   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16519   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16520   DONE;
16524 (define_insn "sse4_1_round<mode>2"
16525   [(set (match_operand:MODEF 0 "register_operand" "=x")
16526         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
16527                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
16528                       UNSPEC_ROUND))]
16529   "TARGET_ROUND"
16530   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16531   [(set_attr "type" "ssecvt")
16532    (set_attr "prefix_extra" "1")
16533    (set_attr "prefix" "maybe_vex")
16534    (set_attr "mode" "<MODE>")])
16536 (define_insn "rintxf2"
16537   [(set (match_operand:XF 0 "register_operand" "=f")
16538         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16539                    UNSPEC_FRNDINT))]
16540   "TARGET_USE_FANCY_MATH_387
16541    && flag_unsafe_math_optimizations"
16542   "frndint"
16543   [(set_attr "type" "fpspc")
16544    (set_attr "mode" "XF")])
16546 (define_expand "rint<mode>2"
16547   [(use (match_operand:MODEF 0 "register_operand" ""))
16548    (use (match_operand:MODEF 1 "register_operand" ""))]
16549   "(TARGET_USE_FANCY_MATH_387
16550     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16551         || TARGET_MIX_SSE_I387)
16552     && flag_unsafe_math_optimizations)
16553    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16554        && !flag_trapping_math)"
16556   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16557       && !flag_trapping_math)
16558     {
16559       if (!TARGET_ROUND && optimize_insn_for_size_p ())
16560         FAIL;
16561       if (TARGET_ROUND)
16562         emit_insn (gen_sse4_1_round<mode>2
16563                    (operands[0], operands[1], GEN_INT (0x04)));
16564       else
16565         ix86_expand_rint (operand0, operand1);
16566     }
16567   else
16568     {
16569       rtx op0 = gen_reg_rtx (XFmode);
16570       rtx op1 = gen_reg_rtx (XFmode);
16572       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16573       emit_insn (gen_rintxf2 (op0, op1));
16575       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16576     }
16577   DONE;
16580 (define_expand "round<mode>2"
16581   [(match_operand:MODEF 0 "register_operand" "")
16582    (match_operand:MODEF 1 "nonimmediate_operand" "")]
16583   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16584    && !flag_trapping_math && !flag_rounding_math"
16586   if (optimize_insn_for_size_p ())
16587     FAIL;
16588   if (TARGET_64BIT || (<MODE>mode != DFmode))
16589     ix86_expand_round (operand0, operand1);
16590   else
16591     ix86_expand_rounddf_32 (operand0, operand1);
16592   DONE;
16595 (define_insn_and_split "*fistdi2_1"
16596   [(set (match_operand:DI 0 "nonimmediate_operand" "")
16597         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16598                    UNSPEC_FIST))]
16599   "TARGET_USE_FANCY_MATH_387
16600    && can_create_pseudo_p ()"
16601   "#"
16602   "&& 1"
16603   [(const_int 0)]
16605   if (memory_operand (operands[0], VOIDmode))
16606     emit_insn (gen_fistdi2 (operands[0], operands[1]));
16607   else
16608     {
16609       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16610       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16611                                          operands[2]));
16612     }
16613   DONE;
16615   [(set_attr "type" "fpspc")
16616    (set_attr "mode" "DI")])
16618 (define_insn "fistdi2"
16619   [(set (match_operand:DI 0 "memory_operand" "=m")
16620         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16621                    UNSPEC_FIST))
16622    (clobber (match_scratch:XF 2 "=&1f"))]
16623   "TARGET_USE_FANCY_MATH_387"
16624   "* return output_fix_trunc (insn, operands, 0);"
16625   [(set_attr "type" "fpspc")
16626    (set_attr "mode" "DI")])
16628 (define_insn "fistdi2_with_temp"
16629   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16630         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16631                    UNSPEC_FIST))
16632    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16633    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16634   "TARGET_USE_FANCY_MATH_387"
16635   "#"
16636   [(set_attr "type" "fpspc")
16637    (set_attr "mode" "DI")])
16639 (define_split
16640   [(set (match_operand:DI 0 "register_operand" "")
16641         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16642                    UNSPEC_FIST))
16643    (clobber (match_operand:DI 2 "memory_operand" ""))
16644    (clobber (match_scratch 3 ""))]
16645   "reload_completed"
16646   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16647               (clobber (match_dup 3))])
16648    (set (match_dup 0) (match_dup 2))]
16649   "")
16651 (define_split
16652   [(set (match_operand:DI 0 "memory_operand" "")
16653         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16654                    UNSPEC_FIST))
16655    (clobber (match_operand:DI 2 "memory_operand" ""))
16656    (clobber (match_scratch 3 ""))]
16657   "reload_completed"
16658   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16659               (clobber (match_dup 3))])]
16660   "")
16662 (define_insn_and_split "*fist<mode>2_1"
16663   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16664         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16665                            UNSPEC_FIST))]
16666   "TARGET_USE_FANCY_MATH_387
16667    && can_create_pseudo_p ()"
16668   "#"
16669   "&& 1"
16670   [(const_int 0)]
16672   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16673   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16674                                         operands[2]));
16675   DONE;
16677   [(set_attr "type" "fpspc")
16678    (set_attr "mode" "<MODE>")])
16680 (define_insn "fist<mode>2"
16681   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16682         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16683                            UNSPEC_FIST))]
16684   "TARGET_USE_FANCY_MATH_387"
16685   "* return output_fix_trunc (insn, operands, 0);"
16686   [(set_attr "type" "fpspc")
16687    (set_attr "mode" "<MODE>")])
16689 (define_insn "fist<mode>2_with_temp"
16690   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16691         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16692                            UNSPEC_FIST))
16693    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16694   "TARGET_USE_FANCY_MATH_387"
16695   "#"
16696   [(set_attr "type" "fpspc")
16697    (set_attr "mode" "<MODE>")])
16699 (define_split
16700   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16701         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16702                            UNSPEC_FIST))
16703    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16704   "reload_completed"
16705   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
16706    (set (match_dup 0) (match_dup 2))]
16707   "")
16709 (define_split
16710   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16711         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16712                            UNSPEC_FIST))
16713    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16714   "reload_completed"
16715   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
16716   "")
16718 (define_expand "lrintxf<mode>2"
16719   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16720      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16721                       UNSPEC_FIST))]
16722   "TARGET_USE_FANCY_MATH_387"
16723   "")
16725 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
16726   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16727      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
16728                         UNSPEC_FIX_NOTRUNC))]
16729   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16730    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
16731   "")
16733 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
16734   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16735    (match_operand:MODEF 1 "register_operand" "")]
16736   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16737    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
16738    && !flag_trapping_math && !flag_rounding_math"
16740   if (optimize_insn_for_size_p ())
16741     FAIL;
16742   ix86_expand_lround (operand0, operand1);
16743   DONE;
16746 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16747 (define_insn_and_split "frndintxf2_floor"
16748   [(set (match_operand:XF 0 "register_operand" "")
16749         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16750          UNSPEC_FRNDINT_FLOOR))
16751    (clobber (reg:CC FLAGS_REG))]
16752   "TARGET_USE_FANCY_MATH_387
16753    && flag_unsafe_math_optimizations
16754    && can_create_pseudo_p ()"
16755   "#"
16756   "&& 1"
16757   [(const_int 0)]
16759   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16761   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16762   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16764   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16765                                         operands[2], operands[3]));
16766   DONE;
16768   [(set_attr "type" "frndint")
16769    (set_attr "i387_cw" "floor")
16770    (set_attr "mode" "XF")])
16772 (define_insn "frndintxf2_floor_i387"
16773   [(set (match_operand:XF 0 "register_operand" "=f")
16774         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16775          UNSPEC_FRNDINT_FLOOR))
16776    (use (match_operand:HI 2 "memory_operand" "m"))
16777    (use (match_operand:HI 3 "memory_operand" "m"))]
16778   "TARGET_USE_FANCY_MATH_387
16779    && flag_unsafe_math_optimizations"
16780   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16781   [(set_attr "type" "frndint")
16782    (set_attr "i387_cw" "floor")
16783    (set_attr "mode" "XF")])
16785 (define_expand "floorxf2"
16786   [(use (match_operand:XF 0 "register_operand" ""))
16787    (use (match_operand:XF 1 "register_operand" ""))]
16788   "TARGET_USE_FANCY_MATH_387
16789    && flag_unsafe_math_optimizations"
16791   if (optimize_insn_for_size_p ())
16792     FAIL;
16793   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16794   DONE;
16797 (define_expand "floor<mode>2"
16798   [(use (match_operand:MODEF 0 "register_operand" ""))
16799    (use (match_operand:MODEF 1 "register_operand" ""))]
16800   "(TARGET_USE_FANCY_MATH_387
16801     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16802         || TARGET_MIX_SSE_I387)
16803     && flag_unsafe_math_optimizations)
16804    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16805        && !flag_trapping_math)"
16807   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16808       && !flag_trapping_math
16809       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
16810     {
16811       if (!TARGET_ROUND && optimize_insn_for_size_p ())
16812         FAIL;
16813       if (TARGET_ROUND)
16814         emit_insn (gen_sse4_1_round<mode>2
16815                    (operands[0], operands[1], GEN_INT (0x01)));
16816       else if (TARGET_64BIT || (<MODE>mode != DFmode))
16817         ix86_expand_floorceil (operand0, operand1, true);
16818       else
16819         ix86_expand_floorceildf_32 (operand0, operand1, true);
16820     }
16821   else
16822     {
16823       rtx op0, op1;
16825       if (optimize_insn_for_size_p ())
16826         FAIL;
16828       op0 = gen_reg_rtx (XFmode);
16829       op1 = gen_reg_rtx (XFmode);
16830       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16831       emit_insn (gen_frndintxf2_floor (op0, op1));
16833       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16834     }
16835   DONE;
16838 (define_insn_and_split "*fist<mode>2_floor_1"
16839   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16840         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16841          UNSPEC_FIST_FLOOR))
16842    (clobber (reg:CC FLAGS_REG))]
16843   "TARGET_USE_FANCY_MATH_387
16844    && flag_unsafe_math_optimizations
16845    && can_create_pseudo_p ()"
16846   "#"
16847   "&& 1"
16848   [(const_int 0)]
16850   ix86_optimize_mode_switching[I387_FLOOR] = 1;
16852   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16853   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16854   if (memory_operand (operands[0], VOIDmode))
16855     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16856                                       operands[2], operands[3]));
16857   else
16858     {
16859       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16860       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16861                                                   operands[2], operands[3],
16862                                                   operands[4]));
16863     }
16864   DONE;
16866   [(set_attr "type" "fistp")
16867    (set_attr "i387_cw" "floor")
16868    (set_attr "mode" "<MODE>")])
16870 (define_insn "fistdi2_floor"
16871   [(set (match_operand:DI 0 "memory_operand" "=m")
16872         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16873          UNSPEC_FIST_FLOOR))
16874    (use (match_operand:HI 2 "memory_operand" "m"))
16875    (use (match_operand:HI 3 "memory_operand" "m"))
16876    (clobber (match_scratch:XF 4 "=&1f"))]
16877   "TARGET_USE_FANCY_MATH_387
16878    && flag_unsafe_math_optimizations"
16879   "* return output_fix_trunc (insn, operands, 0);"
16880   [(set_attr "type" "fistp")
16881    (set_attr "i387_cw" "floor")
16882    (set_attr "mode" "DI")])
16884 (define_insn "fistdi2_floor_with_temp"
16885   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16886         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16887          UNSPEC_FIST_FLOOR))
16888    (use (match_operand:HI 2 "memory_operand" "m,m"))
16889    (use (match_operand:HI 3 "memory_operand" "m,m"))
16890    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16891    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16892   "TARGET_USE_FANCY_MATH_387
16893    && flag_unsafe_math_optimizations"
16894   "#"
16895   [(set_attr "type" "fistp")
16896    (set_attr "i387_cw" "floor")
16897    (set_attr "mode" "DI")])
16899 (define_split
16900   [(set (match_operand:DI 0 "register_operand" "")
16901         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16902          UNSPEC_FIST_FLOOR))
16903    (use (match_operand:HI 2 "memory_operand" ""))
16904    (use (match_operand:HI 3 "memory_operand" ""))
16905    (clobber (match_operand:DI 4 "memory_operand" ""))
16906    (clobber (match_scratch 5 ""))]
16907   "reload_completed"
16908   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16909               (use (match_dup 2))
16910               (use (match_dup 3))
16911               (clobber (match_dup 5))])
16912    (set (match_dup 0) (match_dup 4))]
16913   "")
16915 (define_split
16916   [(set (match_operand:DI 0 "memory_operand" "")
16917         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16918          UNSPEC_FIST_FLOOR))
16919    (use (match_operand:HI 2 "memory_operand" ""))
16920    (use (match_operand:HI 3 "memory_operand" ""))
16921    (clobber (match_operand:DI 4 "memory_operand" ""))
16922    (clobber (match_scratch 5 ""))]
16923   "reload_completed"
16924   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16925               (use (match_dup 2))
16926               (use (match_dup 3))
16927               (clobber (match_dup 5))])]
16928   "")
16930 (define_insn "fist<mode>2_floor"
16931   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16932         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16933          UNSPEC_FIST_FLOOR))
16934    (use (match_operand:HI 2 "memory_operand" "m"))
16935    (use (match_operand:HI 3 "memory_operand" "m"))]
16936   "TARGET_USE_FANCY_MATH_387
16937    && flag_unsafe_math_optimizations"
16938   "* return output_fix_trunc (insn, operands, 0);"
16939   [(set_attr "type" "fistp")
16940    (set_attr "i387_cw" "floor")
16941    (set_attr "mode" "<MODE>")])
16943 (define_insn "fist<mode>2_floor_with_temp"
16944   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16945         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16946          UNSPEC_FIST_FLOOR))
16947    (use (match_operand:HI 2 "memory_operand" "m,m"))
16948    (use (match_operand:HI 3 "memory_operand" "m,m"))
16949    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
16950   "TARGET_USE_FANCY_MATH_387
16951    && flag_unsafe_math_optimizations"
16952   "#"
16953   [(set_attr "type" "fistp")
16954    (set_attr "i387_cw" "floor")
16955    (set_attr "mode" "<MODE>")])
16957 (define_split
16958   [(set (match_operand:X87MODEI12 0 "register_operand" "")
16959         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16960          UNSPEC_FIST_FLOOR))
16961    (use (match_operand:HI 2 "memory_operand" ""))
16962    (use (match_operand:HI 3 "memory_operand" ""))
16963    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16964   "reload_completed"
16965   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16966                                   UNSPEC_FIST_FLOOR))
16967               (use (match_dup 2))
16968               (use (match_dup 3))])
16969    (set (match_dup 0) (match_dup 4))]
16970   "")
16972 (define_split
16973   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16974         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16975          UNSPEC_FIST_FLOOR))
16976    (use (match_operand:HI 2 "memory_operand" ""))
16977    (use (match_operand:HI 3 "memory_operand" ""))
16978    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16979   "reload_completed"
16980   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16981                                   UNSPEC_FIST_FLOOR))
16982               (use (match_dup 2))
16983               (use (match_dup 3))])]
16984   "")
16986 (define_expand "lfloorxf<mode>2"
16987   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16988                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16989                     UNSPEC_FIST_FLOOR))
16990               (clobber (reg:CC FLAGS_REG))])]
16991   "TARGET_USE_FANCY_MATH_387
16992    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16993    && flag_unsafe_math_optimizations"
16994   "")
16996 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
16997   [(match_operand:SWI48 0 "nonimmediate_operand" "")
16998    (match_operand:MODEF 1 "register_operand" "")]
16999   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17000    && !flag_trapping_math"
17002   if (TARGET_64BIT && optimize_insn_for_size_p ())
17003     FAIL;
17004   ix86_expand_lfloorceil (operand0, operand1, true);
17005   DONE;
17008 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17009 (define_insn_and_split "frndintxf2_ceil"
17010   [(set (match_operand:XF 0 "register_operand" "")
17011         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17012          UNSPEC_FRNDINT_CEIL))
17013    (clobber (reg:CC FLAGS_REG))]
17014   "TARGET_USE_FANCY_MATH_387
17015    && flag_unsafe_math_optimizations
17016    && can_create_pseudo_p ()"
17017   "#"
17018   "&& 1"
17019   [(const_int 0)]
17021   ix86_optimize_mode_switching[I387_CEIL] = 1;
17023   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17024   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17026   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17027                                        operands[2], operands[3]));
17028   DONE;
17030   [(set_attr "type" "frndint")
17031    (set_attr "i387_cw" "ceil")
17032    (set_attr "mode" "XF")])
17034 (define_insn "frndintxf2_ceil_i387"
17035   [(set (match_operand:XF 0 "register_operand" "=f")
17036         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17037          UNSPEC_FRNDINT_CEIL))
17038    (use (match_operand:HI 2 "memory_operand" "m"))
17039    (use (match_operand:HI 3 "memory_operand" "m"))]
17040   "TARGET_USE_FANCY_MATH_387
17041    && flag_unsafe_math_optimizations"
17042   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17043   [(set_attr "type" "frndint")
17044    (set_attr "i387_cw" "ceil")
17045    (set_attr "mode" "XF")])
17047 (define_expand "ceilxf2"
17048   [(use (match_operand:XF 0 "register_operand" ""))
17049    (use (match_operand:XF 1 "register_operand" ""))]
17050   "TARGET_USE_FANCY_MATH_387
17051    && flag_unsafe_math_optimizations"
17053   if (optimize_insn_for_size_p ())
17054     FAIL;
17055   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17056   DONE;
17059 (define_expand "ceil<mode>2"
17060   [(use (match_operand:MODEF 0 "register_operand" ""))
17061    (use (match_operand:MODEF 1 "register_operand" ""))]
17062   "(TARGET_USE_FANCY_MATH_387
17063     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17064         || TARGET_MIX_SSE_I387)
17065     && flag_unsafe_math_optimizations)
17066    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17067        && !flag_trapping_math)"
17069   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17070       && !flag_trapping_math
17071       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17072     {
17073       if (TARGET_ROUND)
17074         emit_insn (gen_sse4_1_round<mode>2
17075                    (operands[0], operands[1], GEN_INT (0x02)));
17076       else if (optimize_insn_for_size_p ())
17077         FAIL;
17078       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17079         ix86_expand_floorceil (operand0, operand1, false);
17080       else
17081         ix86_expand_floorceildf_32 (operand0, operand1, false);
17082     }
17083   else
17084     {
17085       rtx op0, op1;
17087       if (optimize_insn_for_size_p ())
17088         FAIL;
17090       op0 = gen_reg_rtx (XFmode);
17091       op1 = gen_reg_rtx (XFmode);
17092       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17093       emit_insn (gen_frndintxf2_ceil (op0, op1));
17095       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17096     }
17097   DONE;
17100 (define_insn_and_split "*fist<mode>2_ceil_1"
17101   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17102         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17103          UNSPEC_FIST_CEIL))
17104    (clobber (reg:CC FLAGS_REG))]
17105   "TARGET_USE_FANCY_MATH_387
17106    && flag_unsafe_math_optimizations
17107    && can_create_pseudo_p ()"
17108   "#"
17109   "&& 1"
17110   [(const_int 0)]
17112   ix86_optimize_mode_switching[I387_CEIL] = 1;
17114   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17115   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17116   if (memory_operand (operands[0], VOIDmode))
17117     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17118                                      operands[2], operands[3]));
17119   else
17120     {
17121       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17122       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17123                                                  operands[2], operands[3],
17124                                                  operands[4]));
17125     }
17126   DONE;
17128   [(set_attr "type" "fistp")
17129    (set_attr "i387_cw" "ceil")
17130    (set_attr "mode" "<MODE>")])
17132 (define_insn "fistdi2_ceil"
17133   [(set (match_operand:DI 0 "memory_operand" "=m")
17134         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17135          UNSPEC_FIST_CEIL))
17136    (use (match_operand:HI 2 "memory_operand" "m"))
17137    (use (match_operand:HI 3 "memory_operand" "m"))
17138    (clobber (match_scratch:XF 4 "=&1f"))]
17139   "TARGET_USE_FANCY_MATH_387
17140    && flag_unsafe_math_optimizations"
17141   "* return output_fix_trunc (insn, operands, 0);"
17142   [(set_attr "type" "fistp")
17143    (set_attr "i387_cw" "ceil")
17144    (set_attr "mode" "DI")])
17146 (define_insn "fistdi2_ceil_with_temp"
17147   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17148         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17149          UNSPEC_FIST_CEIL))
17150    (use (match_operand:HI 2 "memory_operand" "m,m"))
17151    (use (match_operand:HI 3 "memory_operand" "m,m"))
17152    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17153    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17154   "TARGET_USE_FANCY_MATH_387
17155    && flag_unsafe_math_optimizations"
17156   "#"
17157   [(set_attr "type" "fistp")
17158    (set_attr "i387_cw" "ceil")
17159    (set_attr "mode" "DI")])
17161 (define_split
17162   [(set (match_operand:DI 0 "register_operand" "")
17163         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17164          UNSPEC_FIST_CEIL))
17165    (use (match_operand:HI 2 "memory_operand" ""))
17166    (use (match_operand:HI 3 "memory_operand" ""))
17167    (clobber (match_operand:DI 4 "memory_operand" ""))
17168    (clobber (match_scratch 5 ""))]
17169   "reload_completed"
17170   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17171               (use (match_dup 2))
17172               (use (match_dup 3))
17173               (clobber (match_dup 5))])
17174    (set (match_dup 0) (match_dup 4))]
17175   "")
17177 (define_split
17178   [(set (match_operand:DI 0 "memory_operand" "")
17179         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17180          UNSPEC_FIST_CEIL))
17181    (use (match_operand:HI 2 "memory_operand" ""))
17182    (use (match_operand:HI 3 "memory_operand" ""))
17183    (clobber (match_operand:DI 4 "memory_operand" ""))
17184    (clobber (match_scratch 5 ""))]
17185   "reload_completed"
17186   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17187               (use (match_dup 2))
17188               (use (match_dup 3))
17189               (clobber (match_dup 5))])]
17190   "")
17192 (define_insn "fist<mode>2_ceil"
17193   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17194         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17195          UNSPEC_FIST_CEIL))
17196    (use (match_operand:HI 2 "memory_operand" "m"))
17197    (use (match_operand:HI 3 "memory_operand" "m"))]
17198   "TARGET_USE_FANCY_MATH_387
17199    && flag_unsafe_math_optimizations"
17200   "* return output_fix_trunc (insn, operands, 0);"
17201   [(set_attr "type" "fistp")
17202    (set_attr "i387_cw" "ceil")
17203    (set_attr "mode" "<MODE>")])
17205 (define_insn "fist<mode>2_ceil_with_temp"
17206   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17207         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17208          UNSPEC_FIST_CEIL))
17209    (use (match_operand:HI 2 "memory_operand" "m,m"))
17210    (use (match_operand:HI 3 "memory_operand" "m,m"))
17211    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17212   "TARGET_USE_FANCY_MATH_387
17213    && flag_unsafe_math_optimizations"
17214   "#"
17215   [(set_attr "type" "fistp")
17216    (set_attr "i387_cw" "ceil")
17217    (set_attr "mode" "<MODE>")])
17219 (define_split
17220   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17221         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17222          UNSPEC_FIST_CEIL))
17223    (use (match_operand:HI 2 "memory_operand" ""))
17224    (use (match_operand:HI 3 "memory_operand" ""))
17225    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17226   "reload_completed"
17227   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17228                                   UNSPEC_FIST_CEIL))
17229               (use (match_dup 2))
17230               (use (match_dup 3))])
17231    (set (match_dup 0) (match_dup 4))]
17232   "")
17234 (define_split
17235   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17236         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17237          UNSPEC_FIST_CEIL))
17238    (use (match_operand:HI 2 "memory_operand" ""))
17239    (use (match_operand:HI 3 "memory_operand" ""))
17240    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17241   "reload_completed"
17242   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17243                                   UNSPEC_FIST_CEIL))
17244               (use (match_dup 2))
17245               (use (match_dup 3))])]
17246   "")
17248 (define_expand "lceilxf<mode>2"
17249   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17250                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17251                     UNSPEC_FIST_CEIL))
17252               (clobber (reg:CC FLAGS_REG))])]
17253   "TARGET_USE_FANCY_MATH_387
17254    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17255    && flag_unsafe_math_optimizations"
17256   "")
17258 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
17259   [(match_operand:SWI48 0 "nonimmediate_operand" "")
17260    (match_operand:MODEF 1 "register_operand" "")]
17261   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17262    && !flag_trapping_math"
17264   ix86_expand_lfloorceil (operand0, operand1, false);
17265   DONE;
17268 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17269 (define_insn_and_split "frndintxf2_trunc"
17270   [(set (match_operand:XF 0 "register_operand" "")
17271         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17272          UNSPEC_FRNDINT_TRUNC))
17273    (clobber (reg:CC FLAGS_REG))]
17274   "TARGET_USE_FANCY_MATH_387
17275    && flag_unsafe_math_optimizations
17276    && can_create_pseudo_p ()"
17277   "#"
17278   "&& 1"
17279   [(const_int 0)]
17281   ix86_optimize_mode_switching[I387_TRUNC] = 1;
17283   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17284   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17286   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17287                                         operands[2], operands[3]));
17288   DONE;
17290   [(set_attr "type" "frndint")
17291    (set_attr "i387_cw" "trunc")
17292    (set_attr "mode" "XF")])
17294 (define_insn "frndintxf2_trunc_i387"
17295   [(set (match_operand:XF 0 "register_operand" "=f")
17296         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17297          UNSPEC_FRNDINT_TRUNC))
17298    (use (match_operand:HI 2 "memory_operand" "m"))
17299    (use (match_operand:HI 3 "memory_operand" "m"))]
17300   "TARGET_USE_FANCY_MATH_387
17301    && flag_unsafe_math_optimizations"
17302   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17303   [(set_attr "type" "frndint")
17304    (set_attr "i387_cw" "trunc")
17305    (set_attr "mode" "XF")])
17307 (define_expand "btruncxf2"
17308   [(use (match_operand:XF 0 "register_operand" ""))
17309    (use (match_operand:XF 1 "register_operand" ""))]
17310   "TARGET_USE_FANCY_MATH_387
17311    && flag_unsafe_math_optimizations"
17313   if (optimize_insn_for_size_p ())
17314     FAIL;
17315   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17316   DONE;
17319 (define_expand "btrunc<mode>2"
17320   [(use (match_operand:MODEF 0 "register_operand" ""))
17321    (use (match_operand:MODEF 1 "register_operand" ""))]
17322   "(TARGET_USE_FANCY_MATH_387
17323     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17324         || TARGET_MIX_SSE_I387)
17325     && flag_unsafe_math_optimizations)
17326    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17327        && !flag_trapping_math)"
17329   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17330       && !flag_trapping_math
17331       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17332     {
17333       if (TARGET_ROUND)
17334         emit_insn (gen_sse4_1_round<mode>2
17335                    (operands[0], operands[1], GEN_INT (0x03)));
17336       else if (optimize_insn_for_size_p ())
17337         FAIL;
17338       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17339         ix86_expand_trunc (operand0, operand1);
17340       else
17341         ix86_expand_truncdf_32 (operand0, operand1);
17342     }
17343   else
17344     {
17345       rtx op0, op1;
17347       if (optimize_insn_for_size_p ())
17348         FAIL;
17350       op0 = gen_reg_rtx (XFmode);
17351       op1 = gen_reg_rtx (XFmode);
17352       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17353       emit_insn (gen_frndintxf2_trunc (op0, op1));
17355       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17356     }
17357   DONE;
17360 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17361 (define_insn_and_split "frndintxf2_mask_pm"
17362   [(set (match_operand:XF 0 "register_operand" "")
17363         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17364          UNSPEC_FRNDINT_MASK_PM))
17365    (clobber (reg:CC FLAGS_REG))]
17366   "TARGET_USE_FANCY_MATH_387
17367    && flag_unsafe_math_optimizations
17368    && can_create_pseudo_p ()"
17369   "#"
17370   "&& 1"
17371   [(const_int 0)]
17373   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17375   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17376   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17378   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17379                                           operands[2], operands[3]));
17380   DONE;
17382   [(set_attr "type" "frndint")
17383    (set_attr "i387_cw" "mask_pm")
17384    (set_attr "mode" "XF")])
17386 (define_insn "frndintxf2_mask_pm_i387"
17387   [(set (match_operand:XF 0 "register_operand" "=f")
17388         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17389          UNSPEC_FRNDINT_MASK_PM))
17390    (use (match_operand:HI 2 "memory_operand" "m"))
17391    (use (match_operand:HI 3 "memory_operand" "m"))]
17392   "TARGET_USE_FANCY_MATH_387
17393    && flag_unsafe_math_optimizations"
17394   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17395   [(set_attr "type" "frndint")
17396    (set_attr "i387_cw" "mask_pm")
17397    (set_attr "mode" "XF")])
17399 (define_expand "nearbyintxf2"
17400   [(use (match_operand:XF 0 "register_operand" ""))
17401    (use (match_operand:XF 1 "register_operand" ""))]
17402   "TARGET_USE_FANCY_MATH_387
17403    && flag_unsafe_math_optimizations"
17405   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17407   DONE;
17410 (define_expand "nearbyint<mode>2"
17411   [(use (match_operand:MODEF 0 "register_operand" ""))
17412    (use (match_operand:MODEF 1 "register_operand" ""))]
17413   "TARGET_USE_FANCY_MATH_387
17414    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17415        || TARGET_MIX_SSE_I387)
17416    && flag_unsafe_math_optimizations"
17418   rtx op0 = gen_reg_rtx (XFmode);
17419   rtx op1 = gen_reg_rtx (XFmode);
17421   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17422   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17424   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17425   DONE;
17428 (define_insn "fxam<mode>2_i387"
17429   [(set (match_operand:HI 0 "register_operand" "=a")
17430         (unspec:HI
17431           [(match_operand:X87MODEF 1 "register_operand" "f")]
17432           UNSPEC_FXAM))]
17433   "TARGET_USE_FANCY_MATH_387"
17434   "fxam\n\tfnstsw\t%0"
17435   [(set_attr "type" "multi")
17436    (set_attr "length" "4")
17437    (set_attr "unit" "i387")
17438    (set_attr "mode" "<MODE>")])
17440 (define_insn_and_split "fxam<mode>2_i387_with_temp"
17441   [(set (match_operand:HI 0 "register_operand" "")
17442         (unspec:HI
17443           [(match_operand:MODEF 1 "memory_operand" "")]
17444           UNSPEC_FXAM_MEM))]
17445   "TARGET_USE_FANCY_MATH_387
17446    && can_create_pseudo_p ()"
17447   "#"
17448   "&& 1"
17449   [(set (match_dup 2)(match_dup 1))
17450    (set (match_dup 0)
17451         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
17453   operands[2] = gen_reg_rtx (<MODE>mode);
17455   MEM_VOLATILE_P (operands[1]) = 1;
17457   [(set_attr "type" "multi")
17458    (set_attr "unit" "i387")
17459    (set_attr "mode" "<MODE>")])
17461 (define_expand "isinfxf2"
17462   [(use (match_operand:SI 0 "register_operand" ""))
17463    (use (match_operand:XF 1 "register_operand" ""))]
17464   "TARGET_USE_FANCY_MATH_387
17465    && TARGET_C99_FUNCTIONS"
17467   rtx mask = GEN_INT (0x45);
17468   rtx val = GEN_INT (0x05);
17470   rtx cond;
17472   rtx scratch = gen_reg_rtx (HImode);
17473   rtx res = gen_reg_rtx (QImode);
17475   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17477   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17478   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17479   cond = gen_rtx_fmt_ee (EQ, QImode,
17480                          gen_rtx_REG (CCmode, FLAGS_REG),
17481                          const0_rtx);
17482   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17483   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17484   DONE;
17487 (define_expand "isinf<mode>2"
17488   [(use (match_operand:SI 0 "register_operand" ""))
17489    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
17490   "TARGET_USE_FANCY_MATH_387
17491    && TARGET_C99_FUNCTIONS
17492    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17494   rtx mask = GEN_INT (0x45);
17495   rtx val = GEN_INT (0x05);
17497   rtx cond;
17499   rtx scratch = gen_reg_rtx (HImode);
17500   rtx res = gen_reg_rtx (QImode);
17502   /* Remove excess precision by forcing value through memory. */
17503   if (memory_operand (operands[1], VOIDmode))
17504     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17505   else
17506     {
17507       enum ix86_stack_slot slot = (virtuals_instantiated
17508                                    ? SLOT_TEMP
17509                                    : SLOT_VIRTUAL);
17510       rtx temp = assign_386_stack_local (<MODE>mode, slot);
17512       emit_move_insn (temp, operands[1]);
17513       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17514     }
17516   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17517   emit_insn (gen_cmpqi_ext_3 (scratch, val));
17518   cond = gen_rtx_fmt_ee (EQ, QImode,
17519                          gen_rtx_REG (CCmode, FLAGS_REG),
17520                          const0_rtx);
17521   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17522   emit_insn (gen_zero_extendqisi2 (operands[0], res));
17523   DONE;
17526 (define_expand "signbit<mode>2"
17527   [(use (match_operand:SI 0 "register_operand" ""))
17528    (use (match_operand:X87MODEF 1 "register_operand" ""))]
17529   "TARGET_USE_FANCY_MATH_387
17530    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17532   rtx mask = GEN_INT (0x0200);
17534   rtx scratch = gen_reg_rtx (HImode);
17536   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17537   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
17538   DONE;
17541 ;; Block operation instructions
17543 (define_insn "cld"
17544   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17545   ""
17546   "cld"
17547   [(set_attr "length" "1")
17548    (set_attr "length_immediate" "0")
17549    (set_attr "modrm" "0")])
17551 (define_expand "movmemsi"
17552   [(use (match_operand:BLK 0 "memory_operand" ""))
17553    (use (match_operand:BLK 1 "memory_operand" ""))
17554    (use (match_operand:SI 2 "nonmemory_operand" ""))
17555    (use (match_operand:SI 3 "const_int_operand" ""))
17556    (use (match_operand:SI 4 "const_int_operand" ""))
17557    (use (match_operand:SI 5 "const_int_operand" ""))]
17558   ""
17560  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17561                          operands[4], operands[5]))
17562    DONE;
17563  else
17564    FAIL;
17567 (define_expand "movmemdi"
17568   [(use (match_operand:BLK 0 "memory_operand" ""))
17569    (use (match_operand:BLK 1 "memory_operand" ""))
17570    (use (match_operand:DI 2 "nonmemory_operand" ""))
17571    (use (match_operand:DI 3 "const_int_operand" ""))
17572    (use (match_operand:SI 4 "const_int_operand" ""))
17573    (use (match_operand:SI 5 "const_int_operand" ""))]
17574   "TARGET_64BIT"
17576  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17577                          operands[4], operands[5]))
17578    DONE;
17579  else
17580    FAIL;
17583 ;; Most CPUs don't like single string operations
17584 ;; Handle this case here to simplify previous expander.
17586 (define_expand "strmov"
17587   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17588    (set (match_operand 1 "memory_operand" "") (match_dup 4))
17589    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17590               (clobber (reg:CC FLAGS_REG))])
17591    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17592               (clobber (reg:CC FLAGS_REG))])]
17593   ""
17595   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17597   /* If .md ever supports :P for Pmode, these can be directly
17598      in the pattern above.  */
17599   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17600   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17602   /* Can't use this if the user has appropriated esi or edi.  */
17603   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17604       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17605     {
17606       emit_insn (gen_strmov_singleop (operands[0], operands[1],
17607                                       operands[2], operands[3],
17608                                       operands[5], operands[6]));
17609       DONE;
17610     }
17612   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17615 (define_expand "strmov_singleop"
17616   [(parallel [(set (match_operand 1 "memory_operand" "")
17617                    (match_operand 3 "memory_operand" ""))
17618               (set (match_operand 0 "register_operand" "")
17619                    (match_operand 4 "" ""))
17620               (set (match_operand 2 "register_operand" "")
17621                    (match_operand 5 "" ""))])]
17622   ""
17623   "ix86_current_function_needs_cld = 1;")
17625 (define_insn "*strmovdi_rex_1"
17626   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17627         (mem:DI (match_operand:DI 3 "register_operand" "1")))
17628    (set (match_operand:DI 0 "register_operand" "=D")
17629         (plus:DI (match_dup 2)
17630                  (const_int 8)))
17631    (set (match_operand:DI 1 "register_operand" "=S")
17632         (plus:DI (match_dup 3)
17633                  (const_int 8)))]
17634   "TARGET_64BIT"
17635   "movsq"
17636   [(set_attr "type" "str")
17637    (set_attr "mode" "DI")
17638    (set_attr "memory" "both")])
17640 (define_insn "*strmovsi_1"
17641   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17642         (mem:SI (match_operand:SI 3 "register_operand" "1")))
17643    (set (match_operand:SI 0 "register_operand" "=D")
17644         (plus:SI (match_dup 2)
17645                  (const_int 4)))
17646    (set (match_operand:SI 1 "register_operand" "=S")
17647         (plus:SI (match_dup 3)
17648                  (const_int 4)))]
17649   "!TARGET_64BIT"
17650   "movs{l|d}"
17651   [(set_attr "type" "str")
17652    (set_attr "mode" "SI")
17653    (set_attr "memory" "both")])
17655 (define_insn "*strmovsi_rex_1"
17656   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17657         (mem:SI (match_operand:DI 3 "register_operand" "1")))
17658    (set (match_operand:DI 0 "register_operand" "=D")
17659         (plus:DI (match_dup 2)
17660                  (const_int 4)))
17661    (set (match_operand:DI 1 "register_operand" "=S")
17662         (plus:DI (match_dup 3)
17663                  (const_int 4)))]
17664   "TARGET_64BIT"
17665   "movs{l|d}"
17666   [(set_attr "type" "str")
17667    (set_attr "mode" "SI")
17668    (set_attr "memory" "both")])
17670 (define_insn "*strmovhi_1"
17671   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17672         (mem:HI (match_operand:SI 3 "register_operand" "1")))
17673    (set (match_operand:SI 0 "register_operand" "=D")
17674         (plus:SI (match_dup 2)
17675                  (const_int 2)))
17676    (set (match_operand:SI 1 "register_operand" "=S")
17677         (plus:SI (match_dup 3)
17678                  (const_int 2)))]
17679   "!TARGET_64BIT"
17680   "movsw"
17681   [(set_attr "type" "str")
17682    (set_attr "memory" "both")
17683    (set_attr "mode" "HI")])
17685 (define_insn "*strmovhi_rex_1"
17686   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17687         (mem:HI (match_operand:DI 3 "register_operand" "1")))
17688    (set (match_operand:DI 0 "register_operand" "=D")
17689         (plus:DI (match_dup 2)
17690                  (const_int 2)))
17691    (set (match_operand:DI 1 "register_operand" "=S")
17692         (plus:DI (match_dup 3)
17693                  (const_int 2)))]
17694   "TARGET_64BIT"
17695   "movsw"
17696   [(set_attr "type" "str")
17697    (set_attr "memory" "both")
17698    (set_attr "mode" "HI")])
17700 (define_insn "*strmovqi_1"
17701   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17702         (mem:QI (match_operand:SI 3 "register_operand" "1")))
17703    (set (match_operand:SI 0 "register_operand" "=D")
17704         (plus:SI (match_dup 2)
17705                  (const_int 1)))
17706    (set (match_operand:SI 1 "register_operand" "=S")
17707         (plus:SI (match_dup 3)
17708                  (const_int 1)))]
17709   "!TARGET_64BIT"
17710   "movsb"
17711   [(set_attr "type" "str")
17712    (set_attr "memory" "both")
17713    (set_attr "mode" "QI")])
17715 (define_insn "*strmovqi_rex_1"
17716   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17717         (mem:QI (match_operand:DI 3 "register_operand" "1")))
17718    (set (match_operand:DI 0 "register_operand" "=D")
17719         (plus:DI (match_dup 2)
17720                  (const_int 1)))
17721    (set (match_operand:DI 1 "register_operand" "=S")
17722         (plus:DI (match_dup 3)
17723                  (const_int 1)))]
17724   "TARGET_64BIT"
17725   "movsb"
17726   [(set_attr "type" "str")
17727    (set_attr "memory" "both")
17728    (set_attr "prefix_rex" "0")
17729    (set_attr "mode" "QI")])
17731 (define_expand "rep_mov"
17732   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17733               (set (match_operand 0 "register_operand" "")
17734                    (match_operand 5 "" ""))
17735               (set (match_operand 2 "register_operand" "")
17736                    (match_operand 6 "" ""))
17737               (set (match_operand 1 "memory_operand" "")
17738                    (match_operand 3 "memory_operand" ""))
17739               (use (match_dup 4))])]
17740   ""
17741   "ix86_current_function_needs_cld = 1;")
17743 (define_insn "*rep_movdi_rex64"
17744   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17745    (set (match_operand:DI 0 "register_operand" "=D")
17746         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17747                             (const_int 3))
17748                  (match_operand:DI 3 "register_operand" "0")))
17749    (set (match_operand:DI 1 "register_operand" "=S")
17750         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17751                  (match_operand:DI 4 "register_operand" "1")))
17752    (set (mem:BLK (match_dup 3))
17753         (mem:BLK (match_dup 4)))
17754    (use (match_dup 5))]
17755   "TARGET_64BIT"
17756   "rep movsq"
17757   [(set_attr "type" "str")
17758    (set_attr "prefix_rep" "1")
17759    (set_attr "memory" "both")
17760    (set_attr "mode" "DI")])
17762 (define_insn "*rep_movsi"
17763   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17764    (set (match_operand:SI 0 "register_operand" "=D")
17765         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17766                             (const_int 2))
17767                  (match_operand:SI 3 "register_operand" "0")))
17768    (set (match_operand:SI 1 "register_operand" "=S")
17769         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17770                  (match_operand:SI 4 "register_operand" "1")))
17771    (set (mem:BLK (match_dup 3))
17772         (mem:BLK (match_dup 4)))
17773    (use (match_dup 5))]
17774   "!TARGET_64BIT"
17775   "rep movs{l|d}"
17776   [(set_attr "type" "str")
17777    (set_attr "prefix_rep" "1")
17778    (set_attr "memory" "both")
17779    (set_attr "mode" "SI")])
17781 (define_insn "*rep_movsi_rex64"
17782   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17783    (set (match_operand:DI 0 "register_operand" "=D")
17784         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17785                             (const_int 2))
17786                  (match_operand:DI 3 "register_operand" "0")))
17787    (set (match_operand:DI 1 "register_operand" "=S")
17788         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17789                  (match_operand:DI 4 "register_operand" "1")))
17790    (set (mem:BLK (match_dup 3))
17791         (mem:BLK (match_dup 4)))
17792    (use (match_dup 5))]
17793   "TARGET_64BIT"
17794   "rep movs{l|d}"
17795   [(set_attr "type" "str")
17796    (set_attr "prefix_rep" "1")
17797    (set_attr "memory" "both")
17798    (set_attr "mode" "SI")])
17800 (define_insn "*rep_movqi"
17801   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17802    (set (match_operand:SI 0 "register_operand" "=D")
17803         (plus:SI (match_operand:SI 3 "register_operand" "0")
17804                  (match_operand:SI 5 "register_operand" "2")))
17805    (set (match_operand:SI 1 "register_operand" "=S")
17806         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17807    (set (mem:BLK (match_dup 3))
17808         (mem:BLK (match_dup 4)))
17809    (use (match_dup 5))]
17810   "!TARGET_64BIT"
17811   "rep movsb"
17812   [(set_attr "type" "str")
17813    (set_attr "prefix_rep" "1")
17814    (set_attr "memory" "both")
17815    (set_attr "mode" "SI")])
17817 (define_insn "*rep_movqi_rex64"
17818   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17819    (set (match_operand:DI 0 "register_operand" "=D")
17820         (plus:DI (match_operand:DI 3 "register_operand" "0")
17821                  (match_operand:DI 5 "register_operand" "2")))
17822    (set (match_operand:DI 1 "register_operand" "=S")
17823         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17824    (set (mem:BLK (match_dup 3))
17825         (mem:BLK (match_dup 4)))
17826    (use (match_dup 5))]
17827   "TARGET_64BIT"
17828   "rep movsb"
17829   [(set_attr "type" "str")
17830    (set_attr "prefix_rep" "1")
17831    (set_attr "memory" "both")
17832    (set_attr "mode" "SI")])
17834 (define_expand "setmemsi"
17835    [(use (match_operand:BLK 0 "memory_operand" ""))
17836     (use (match_operand:SI 1 "nonmemory_operand" ""))
17837     (use (match_operand 2 "const_int_operand" ""))
17838     (use (match_operand 3 "const_int_operand" ""))
17839     (use (match_operand:SI 4 "const_int_operand" ""))
17840     (use (match_operand:SI 5 "const_int_operand" ""))]
17841   ""
17843  if (ix86_expand_setmem (operands[0], operands[1],
17844                          operands[2], operands[3],
17845                          operands[4], operands[5]))
17846    DONE;
17847  else
17848    FAIL;
17851 (define_expand "setmemdi"
17852    [(use (match_operand:BLK 0 "memory_operand" ""))
17853     (use (match_operand:DI 1 "nonmemory_operand" ""))
17854     (use (match_operand 2 "const_int_operand" ""))
17855     (use (match_operand 3 "const_int_operand" ""))
17856     (use (match_operand 4 "const_int_operand" ""))
17857     (use (match_operand 5 "const_int_operand" ""))]
17858   "TARGET_64BIT"
17860  if (ix86_expand_setmem (operands[0], operands[1],
17861                          operands[2], operands[3],
17862                          operands[4], operands[5]))
17863    DONE;
17864  else
17865    FAIL;
17868 ;; Most CPUs don't like single string operations
17869 ;; Handle this case here to simplify previous expander.
17871 (define_expand "strset"
17872   [(set (match_operand 1 "memory_operand" "")
17873         (match_operand 2 "register_operand" ""))
17874    (parallel [(set (match_operand 0 "register_operand" "")
17875                    (match_dup 3))
17876               (clobber (reg:CC FLAGS_REG))])]
17877   ""
17879   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17880     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17882   /* If .md ever supports :P for Pmode, this can be directly
17883      in the pattern above.  */
17884   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17885                               GEN_INT (GET_MODE_SIZE (GET_MODE
17886                                                       (operands[2]))));
17887   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17888     {
17889       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17890                                       operands[3]));
17891       DONE;
17892     }
17895 (define_expand "strset_singleop"
17896   [(parallel [(set (match_operand 1 "memory_operand" "")
17897                    (match_operand 2 "register_operand" ""))
17898               (set (match_operand 0 "register_operand" "")
17899                    (match_operand 3 "" ""))])]
17900   ""
17901   "ix86_current_function_needs_cld = 1;")
17903 (define_insn "*strsetdi_rex_1"
17904   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17905         (match_operand:DI 2 "register_operand" "a"))
17906    (set (match_operand:DI 0 "register_operand" "=D")
17907         (plus:DI (match_dup 1)
17908                  (const_int 8)))]
17909   "TARGET_64BIT"
17910   "stosq"
17911   [(set_attr "type" "str")
17912    (set_attr "memory" "store")
17913    (set_attr "mode" "DI")])
17915 (define_insn "*strsetsi_1"
17916   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17917         (match_operand:SI 2 "register_operand" "a"))
17918    (set (match_operand:SI 0 "register_operand" "=D")
17919         (plus:SI (match_dup 1)
17920                  (const_int 4)))]
17921   "!TARGET_64BIT"
17922   "stos{l|d}"
17923   [(set_attr "type" "str")
17924    (set_attr "memory" "store")
17925    (set_attr "mode" "SI")])
17927 (define_insn "*strsetsi_rex_1"
17928   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17929         (match_operand:SI 2 "register_operand" "a"))
17930    (set (match_operand:DI 0 "register_operand" "=D")
17931         (plus:DI (match_dup 1)
17932                  (const_int 4)))]
17933   "TARGET_64BIT"
17934   "stos{l|d}"
17935   [(set_attr "type" "str")
17936    (set_attr "memory" "store")
17937    (set_attr "mode" "SI")])
17939 (define_insn "*strsethi_1"
17940   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17941         (match_operand:HI 2 "register_operand" "a"))
17942    (set (match_operand:SI 0 "register_operand" "=D")
17943         (plus:SI (match_dup 1)
17944                  (const_int 2)))]
17945   "!TARGET_64BIT"
17946   "stosw"
17947   [(set_attr "type" "str")
17948    (set_attr "memory" "store")
17949    (set_attr "mode" "HI")])
17951 (define_insn "*strsethi_rex_1"
17952   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17953         (match_operand:HI 2 "register_operand" "a"))
17954    (set (match_operand:DI 0 "register_operand" "=D")
17955         (plus:DI (match_dup 1)
17956                  (const_int 2)))]
17957   "TARGET_64BIT"
17958   "stosw"
17959   [(set_attr "type" "str")
17960    (set_attr "memory" "store")
17961    (set_attr "mode" "HI")])
17963 (define_insn "*strsetqi_1"
17964   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17965         (match_operand:QI 2 "register_operand" "a"))
17966    (set (match_operand:SI 0 "register_operand" "=D")
17967         (plus:SI (match_dup 1)
17968                  (const_int 1)))]
17969   "!TARGET_64BIT"
17970   "stosb"
17971   [(set_attr "type" "str")
17972    (set_attr "memory" "store")
17973    (set_attr "mode" "QI")])
17975 (define_insn "*strsetqi_rex_1"
17976   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17977         (match_operand:QI 2 "register_operand" "a"))
17978    (set (match_operand:DI 0 "register_operand" "=D")
17979         (plus:DI (match_dup 1)
17980                  (const_int 1)))]
17981   "TARGET_64BIT"
17982   "stosb"
17983   [(set_attr "type" "str")
17984    (set_attr "memory" "store")
17985    (set_attr "prefix_rex" "0")
17986    (set_attr "mode" "QI")])
17988 (define_expand "rep_stos"
17989   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17990               (set (match_operand 0 "register_operand" "")
17991                    (match_operand 4 "" ""))
17992               (set (match_operand 2 "memory_operand" "") (const_int 0))
17993               (use (match_operand 3 "register_operand" ""))
17994               (use (match_dup 1))])]
17995   ""
17996   "ix86_current_function_needs_cld = 1;")
17998 (define_insn "*rep_stosdi_rex64"
17999   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18000    (set (match_operand:DI 0 "register_operand" "=D")
18001         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18002                             (const_int 3))
18003                  (match_operand:DI 3 "register_operand" "0")))
18004    (set (mem:BLK (match_dup 3))
18005         (const_int 0))
18006    (use (match_operand:DI 2 "register_operand" "a"))
18007    (use (match_dup 4))]
18008   "TARGET_64BIT"
18009   "rep stosq"
18010   [(set_attr "type" "str")
18011    (set_attr "prefix_rep" "1")
18012    (set_attr "memory" "store")
18013    (set_attr "mode" "DI")])
18015 (define_insn "*rep_stossi"
18016   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18017    (set (match_operand:SI 0 "register_operand" "=D")
18018         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18019                             (const_int 2))
18020                  (match_operand:SI 3 "register_operand" "0")))
18021    (set (mem:BLK (match_dup 3))
18022         (const_int 0))
18023    (use (match_operand:SI 2 "register_operand" "a"))
18024    (use (match_dup 4))]
18025   "!TARGET_64BIT"
18026   "rep stos{l|d}"
18027   [(set_attr "type" "str")
18028    (set_attr "prefix_rep" "1")
18029    (set_attr "memory" "store")
18030    (set_attr "mode" "SI")])
18032 (define_insn "*rep_stossi_rex64"
18033   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18034    (set (match_operand:DI 0 "register_operand" "=D")
18035         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18036                             (const_int 2))
18037                  (match_operand:DI 3 "register_operand" "0")))
18038    (set (mem:BLK (match_dup 3))
18039         (const_int 0))
18040    (use (match_operand:SI 2 "register_operand" "a"))
18041    (use (match_dup 4))]
18042   "TARGET_64BIT"
18043   "rep stos{l|d}"
18044   [(set_attr "type" "str")
18045    (set_attr "prefix_rep" "1")
18046    (set_attr "memory" "store")
18047    (set_attr "mode" "SI")])
18049 (define_insn "*rep_stosqi"
18050   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18051    (set (match_operand:SI 0 "register_operand" "=D")
18052         (plus:SI (match_operand:SI 3 "register_operand" "0")
18053                  (match_operand:SI 4 "register_operand" "1")))
18054    (set (mem:BLK (match_dup 3))
18055         (const_int 0))
18056    (use (match_operand:QI 2 "register_operand" "a"))
18057    (use (match_dup 4))]
18058   "!TARGET_64BIT"
18059   "rep stosb"
18060   [(set_attr "type" "str")
18061    (set_attr "prefix_rep" "1")
18062    (set_attr "memory" "store")
18063    (set_attr "mode" "QI")])
18065 (define_insn "*rep_stosqi_rex64"
18066   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18067    (set (match_operand:DI 0 "register_operand" "=D")
18068         (plus:DI (match_operand:DI 3 "register_operand" "0")
18069                  (match_operand:DI 4 "register_operand" "1")))
18070    (set (mem:BLK (match_dup 3))
18071         (const_int 0))
18072    (use (match_operand:QI 2 "register_operand" "a"))
18073    (use (match_dup 4))]
18074   "TARGET_64BIT"
18075   "rep stosb"
18076   [(set_attr "type" "str")
18077    (set_attr "prefix_rep" "1")
18078    (set_attr "memory" "store")
18079    (set_attr "prefix_rex" "0")
18080    (set_attr "mode" "QI")])
18082 (define_expand "cmpstrnsi"
18083   [(set (match_operand:SI 0 "register_operand" "")
18084         (compare:SI (match_operand:BLK 1 "general_operand" "")
18085                     (match_operand:BLK 2 "general_operand" "")))
18086    (use (match_operand 3 "general_operand" ""))
18087    (use (match_operand 4 "immediate_operand" ""))]
18088   ""
18090   rtx addr1, addr2, out, outlow, count, countreg, align;
18092   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
18093     FAIL;
18095   /* Can't use this if the user has appropriated esi or edi.  */
18096   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18097     FAIL;
18099   out = operands[0];
18100   if (!REG_P (out))
18101     out = gen_reg_rtx (SImode);
18103   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18104   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18105   if (addr1 != XEXP (operands[1], 0))
18106     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18107   if (addr2 != XEXP (operands[2], 0))
18108     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18110   count = operands[3];
18111   countreg = ix86_zero_extend_to_Pmode (count);
18113   /* %%% Iff we are testing strict equality, we can use known alignment
18114      to good advantage.  This may be possible with combine, particularly
18115      once cc0 is dead.  */
18116   align = operands[4];
18118   if (CONST_INT_P (count))
18119     {
18120       if (INTVAL (count) == 0)
18121         {
18122           emit_move_insn (operands[0], const0_rtx);
18123           DONE;
18124         }
18125       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18126                                      operands[1], operands[2]));
18127     }
18128   else
18129     {
18130       rtx (*cmp_insn)(rtx, rtx);
18132       if (TARGET_64BIT)
18133         cmp_insn = gen_cmpdi_1;
18134       else
18135         cmp_insn = gen_cmpsi_1;
18136       emit_insn (cmp_insn (countreg, countreg));
18137       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18138                                   operands[1], operands[2]));
18139     }
18141   outlow = gen_lowpart (QImode, out);
18142   emit_insn (gen_cmpintqi (outlow));
18143   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18145   if (operands[0] != out)
18146     emit_move_insn (operands[0], out);
18148   DONE;
18151 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18153 (define_expand "cmpintqi"
18154   [(set (match_dup 1)
18155         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18156    (set (match_dup 2)
18157         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18158    (parallel [(set (match_operand:QI 0 "register_operand" "")
18159                    (minus:QI (match_dup 1)
18160                              (match_dup 2)))
18161               (clobber (reg:CC FLAGS_REG))])]
18162   ""
18163   "operands[1] = gen_reg_rtx (QImode);
18164    operands[2] = gen_reg_rtx (QImode);")
18166 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18167 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18169 (define_expand "cmpstrnqi_nz_1"
18170   [(parallel [(set (reg:CC FLAGS_REG)
18171                    (compare:CC (match_operand 4 "memory_operand" "")
18172                                (match_operand 5 "memory_operand" "")))
18173               (use (match_operand 2 "register_operand" ""))
18174               (use (match_operand:SI 3 "immediate_operand" ""))
18175               (clobber (match_operand 0 "register_operand" ""))
18176               (clobber (match_operand 1 "register_operand" ""))
18177               (clobber (match_dup 2))])]
18178   ""
18179   "ix86_current_function_needs_cld = 1;")
18181 (define_insn "*cmpstrnqi_nz_1"
18182   [(set (reg:CC FLAGS_REG)
18183         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18184                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18185    (use (match_operand:SI 6 "register_operand" "2"))
18186    (use (match_operand:SI 3 "immediate_operand" "i"))
18187    (clobber (match_operand:SI 0 "register_operand" "=S"))
18188    (clobber (match_operand:SI 1 "register_operand" "=D"))
18189    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18190   "!TARGET_64BIT"
18191   "repz cmpsb"
18192   [(set_attr "type" "str")
18193    (set_attr "mode" "QI")
18194    (set_attr "prefix_rep" "1")])
18196 (define_insn "*cmpstrnqi_nz_rex_1"
18197   [(set (reg:CC FLAGS_REG)
18198         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18199                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18200    (use (match_operand:DI 6 "register_operand" "2"))
18201    (use (match_operand:SI 3 "immediate_operand" "i"))
18202    (clobber (match_operand:DI 0 "register_operand" "=S"))
18203    (clobber (match_operand:DI 1 "register_operand" "=D"))
18204    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18205   "TARGET_64BIT"
18206   "repz cmpsb"
18207   [(set_attr "type" "str")
18208    (set_attr "mode" "QI")
18209    (set_attr "prefix_rex" "0")
18210    (set_attr "prefix_rep" "1")])
18212 ;; The same, but the count is not known to not be zero.
18214 (define_expand "cmpstrnqi_1"
18215   [(parallel [(set (reg:CC FLAGS_REG)
18216                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18217                                      (const_int 0))
18218                   (compare:CC (match_operand 4 "memory_operand" "")
18219                               (match_operand 5 "memory_operand" ""))
18220                   (const_int 0)))
18221               (use (match_operand:SI 3 "immediate_operand" ""))
18222               (use (reg:CC FLAGS_REG))
18223               (clobber (match_operand 0 "register_operand" ""))
18224               (clobber (match_operand 1 "register_operand" ""))
18225               (clobber (match_dup 2))])]
18226   ""
18227   "ix86_current_function_needs_cld = 1;")
18229 (define_insn "*cmpstrnqi_1"
18230   [(set (reg:CC FLAGS_REG)
18231         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18232                              (const_int 0))
18233           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18234                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18235           (const_int 0)))
18236    (use (match_operand:SI 3 "immediate_operand" "i"))
18237    (use (reg:CC FLAGS_REG))
18238    (clobber (match_operand:SI 0 "register_operand" "=S"))
18239    (clobber (match_operand:SI 1 "register_operand" "=D"))
18240    (clobber (match_operand:SI 2 "register_operand" "=c"))]
18241   "!TARGET_64BIT"
18242   "repz cmpsb"
18243   [(set_attr "type" "str")
18244    (set_attr "mode" "QI")
18245    (set_attr "prefix_rep" "1")])
18247 (define_insn "*cmpstrnqi_rex_1"
18248   [(set (reg:CC FLAGS_REG)
18249         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18250                              (const_int 0))
18251           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18252                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18253           (const_int 0)))
18254    (use (match_operand:SI 3 "immediate_operand" "i"))
18255    (use (reg:CC FLAGS_REG))
18256    (clobber (match_operand:DI 0 "register_operand" "=S"))
18257    (clobber (match_operand:DI 1 "register_operand" "=D"))
18258    (clobber (match_operand:DI 2 "register_operand" "=c"))]
18259   "TARGET_64BIT"
18260   "repz cmpsb"
18261   [(set_attr "type" "str")
18262    (set_attr "mode" "QI")
18263    (set_attr "prefix_rex" "0")
18264    (set_attr "prefix_rep" "1")])
18266 (define_expand "strlensi"
18267   [(set (match_operand:SI 0 "register_operand" "")
18268         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18269                     (match_operand:QI 2 "immediate_operand" "")
18270                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18271   ""
18273  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18274    DONE;
18275  else
18276    FAIL;
18279 (define_expand "strlendi"
18280   [(set (match_operand:DI 0 "register_operand" "")
18281         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18282                     (match_operand:QI 2 "immediate_operand" "")
18283                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18284   ""
18286  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18287    DONE;
18288  else
18289    FAIL;
18292 (define_expand "strlenqi_1"
18293   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18294               (clobber (match_operand 1 "register_operand" ""))
18295               (clobber (reg:CC FLAGS_REG))])]
18296   ""
18297   "ix86_current_function_needs_cld = 1;")
18299 (define_insn "*strlenqi_1"
18300   [(set (match_operand:SI 0 "register_operand" "=&c")
18301         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18302                     (match_operand:QI 2 "register_operand" "a")
18303                     (match_operand:SI 3 "immediate_operand" "i")
18304                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18305    (clobber (match_operand:SI 1 "register_operand" "=D"))
18306    (clobber (reg:CC FLAGS_REG))]
18307   "!TARGET_64BIT"
18308   "repnz scasb"
18309   [(set_attr "type" "str")
18310    (set_attr "mode" "QI")
18311    (set_attr "prefix_rep" "1")])
18313 (define_insn "*strlenqi_rex_1"
18314   [(set (match_operand:DI 0 "register_operand" "=&c")
18315         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18316                     (match_operand:QI 2 "register_operand" "a")
18317                     (match_operand:DI 3 "immediate_operand" "i")
18318                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18319    (clobber (match_operand:DI 1 "register_operand" "=D"))
18320    (clobber (reg:CC FLAGS_REG))]
18321   "TARGET_64BIT"
18322   "repnz scasb"
18323   [(set_attr "type" "str")
18324    (set_attr "mode" "QI")
18325    (set_attr "prefix_rex" "0")
18326    (set_attr "prefix_rep" "1")])
18328 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
18329 ;; handled in combine, but it is not currently up to the task.
18330 ;; When used for their truth value, the cmpstrn* expanders generate
18331 ;; code like this:
18333 ;;   repz cmpsb
18334 ;;   seta       %al
18335 ;;   setb       %dl
18336 ;;   cmpb       %al, %dl
18337 ;;   jcc        label
18339 ;; The intermediate three instructions are unnecessary.
18341 ;; This one handles cmpstrn*_nz_1...
18342 (define_peephole2
18343   [(parallel[
18344      (set (reg:CC FLAGS_REG)
18345           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18346                       (mem:BLK (match_operand 5 "register_operand" ""))))
18347      (use (match_operand 6 "register_operand" ""))
18348      (use (match_operand:SI 3 "immediate_operand" ""))
18349      (clobber (match_operand 0 "register_operand" ""))
18350      (clobber (match_operand 1 "register_operand" ""))
18351      (clobber (match_operand 2 "register_operand" ""))])
18352    (set (match_operand:QI 7 "register_operand" "")
18353         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18354    (set (match_operand:QI 8 "register_operand" "")
18355         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18356    (set (reg FLAGS_REG)
18357         (compare (match_dup 7) (match_dup 8)))
18358   ]
18359   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18360   [(parallel[
18361      (set (reg:CC FLAGS_REG)
18362           (compare:CC (mem:BLK (match_dup 4))
18363                       (mem:BLK (match_dup 5))))
18364      (use (match_dup 6))
18365      (use (match_dup 3))
18366      (clobber (match_dup 0))
18367      (clobber (match_dup 1))
18368      (clobber (match_dup 2))])]
18369   "")
18371 ;; ...and this one handles cmpstrn*_1.
18372 (define_peephole2
18373   [(parallel[
18374      (set (reg:CC FLAGS_REG)
18375           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18376                                (const_int 0))
18377             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18378                         (mem:BLK (match_operand 5 "register_operand" "")))
18379             (const_int 0)))
18380      (use (match_operand:SI 3 "immediate_operand" ""))
18381      (use (reg:CC FLAGS_REG))
18382      (clobber (match_operand 0 "register_operand" ""))
18383      (clobber (match_operand 1 "register_operand" ""))
18384      (clobber (match_operand 2 "register_operand" ""))])
18385    (set (match_operand:QI 7 "register_operand" "")
18386         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18387    (set (match_operand:QI 8 "register_operand" "")
18388         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18389    (set (reg FLAGS_REG)
18390         (compare (match_dup 7) (match_dup 8)))
18391   ]
18392   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18393   [(parallel[
18394      (set (reg:CC FLAGS_REG)
18395           (if_then_else:CC (ne (match_dup 6)
18396                                (const_int 0))
18397             (compare:CC (mem:BLK (match_dup 4))
18398                         (mem:BLK (match_dup 5)))
18399             (const_int 0)))
18400      (use (match_dup 3))
18401      (use (reg:CC FLAGS_REG))
18402      (clobber (match_dup 0))
18403      (clobber (match_dup 1))
18404      (clobber (match_dup 2))])]
18405   "")
18409 ;; Conditional move instructions.
18411 (define_expand "mov<mode>cc"
18412   [(set (match_operand:SWIM 0 "register_operand" "")
18413         (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
18414                            (match_operand:SWIM 2 "general_operand" "")
18415                            (match_operand:SWIM 3 "general_operand" "")))]
18416   ""
18417   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18419 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18420 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18421 ;; So just document what we're doing explicitly.
18423 (define_expand "x86_mov<mode>cc_0_m1"
18424   [(parallel
18425     [(set (match_operand:SWI48 0 "register_operand" "")
18426           (if_then_else:SWI48
18427             (match_operator:SWI48 2 "ix86_carry_flag_operator"
18428              [(match_operand 1 "flags_reg_operand" "")
18429               (const_int 0)])
18430             (const_int -1)
18431             (const_int 0)))
18432      (clobber (reg:CC FLAGS_REG))])]
18433   ""
18434   "")
18436 (define_insn "*x86_mov<mode>cc_0_m1"
18437   [(set (match_operand:SWI48 0 "register_operand" "=r")
18438         (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18439                              [(reg FLAGS_REG) (const_int 0)])
18440           (const_int -1)
18441           (const_int 0)))
18442    (clobber (reg:CC FLAGS_REG))]
18443   ""
18444   "sbb{<imodesuffix>}\t%0, %0"
18445   ; Since we don't have the proper number of operands for an alu insn,
18446   ; fill in all the blanks.
18447   [(set_attr "type" "alu")
18448    (set_attr "use_carry" "1")
18449    (set_attr "pent_pair" "pu")
18450    (set_attr "memory" "none")
18451    (set_attr "imm_disp" "false")
18452    (set_attr "mode" "<MODE>")
18453    (set_attr "length_immediate" "0")])
18455 (define_insn "*x86_mov<mode>cc_0_m1_se"
18456   [(set (match_operand:SWI48 0 "register_operand" "=r")
18457         (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18458                              [(reg FLAGS_REG) (const_int 0)])
18459                             (const_int 1)
18460                             (const_int 0)))
18461    (clobber (reg:CC FLAGS_REG))]
18462   ""
18463   "sbb{<imodesuffix>}\t%0, %0"
18464   [(set_attr "type" "alu")
18465    (set_attr "use_carry" "1")
18466    (set_attr "pent_pair" "pu")
18467    (set_attr "memory" "none")
18468    (set_attr "imm_disp" "false")
18469    (set_attr "mode" "<MODE>")
18470    (set_attr "length_immediate" "0")])
18472 (define_insn "*x86_mov<mode>cc_0_m1_neg"
18473   [(set (match_operand:SWI48 0 "register_operand" "=r")
18474         (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18475                     [(reg FLAGS_REG) (const_int 0)])))]
18476   ""
18477   "sbb{<imodesuffix>}\t%0, %0"
18478   [(set_attr "type" "alu")
18479    (set_attr "use_carry" "1")
18480    (set_attr "pent_pair" "pu")
18481    (set_attr "memory" "none")
18482    (set_attr "imm_disp" "false")
18483    (set_attr "mode" "<MODE>")
18484    (set_attr "length_immediate" "0")])
18486 (define_insn "*mov<mode>cc_noc"
18487   [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18488         (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18489                                [(reg FLAGS_REG) (const_int 0)])
18490           (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18491           (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18492   "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18493   "@
18494    cmov%O2%C1\t{%2, %0|%0, %2}
18495    cmov%O2%c1\t{%3, %0|%0, %3}"
18496   [(set_attr "type" "icmov")
18497    (set_attr "mode" "<MODE>")])
18499 (define_insn_and_split "*movqicc_noc"
18500   [(set (match_operand:QI 0 "register_operand" "=r,r")
18501         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18502                            [(match_operand 4 "flags_reg_operand" "")
18503                             (const_int 0)])
18504                       (match_operand:QI 2 "register_operand" "r,0")
18505                       (match_operand:QI 3 "register_operand" "0,r")))]
18506   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18507   "#"
18508   "&& reload_completed"
18509   [(set (match_dup 0)
18510         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18511                       (match_dup 2)
18512                       (match_dup 3)))]
18513   "operands[0] = gen_lowpart (SImode, operands[0]);
18514    operands[2] = gen_lowpart (SImode, operands[2]);
18515    operands[3] = gen_lowpart (SImode, operands[3]);"
18516   [(set_attr "type" "icmov")
18517    (set_attr "mode" "SI")])
18519 (define_expand "mov<mode>cc"
18520   [(set (match_operand:X87MODEF 0 "register_operand" "")
18521         (if_then_else:X87MODEF
18522           (match_operand 1 "ix86_fp_comparison_operator" "")
18523           (match_operand:X87MODEF 2 "register_operand" "")
18524           (match_operand:X87MODEF 3 "register_operand" "")))]
18525   "(TARGET_80387 && TARGET_CMOVE)
18526    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18527   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18529 (define_insn "*movsfcc_1_387"
18530   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18531         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18532                                 [(reg FLAGS_REG) (const_int 0)])
18533                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18534                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18535   "TARGET_80387 && TARGET_CMOVE
18536    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18537   "@
18538    fcmov%F1\t{%2, %0|%0, %2}
18539    fcmov%f1\t{%3, %0|%0, %3}
18540    cmov%O2%C1\t{%2, %0|%0, %2}
18541    cmov%O2%c1\t{%3, %0|%0, %3}"
18542   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18543    (set_attr "mode" "SF,SF,SI,SI")])
18545 (define_insn "*movdfcc_1"
18546   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18547         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18548                                 [(reg FLAGS_REG) (const_int 0)])
18549                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18550                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18551   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18552    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18553   "@
18554    fcmov%F1\t{%2, %0|%0, %2}
18555    fcmov%f1\t{%3, %0|%0, %3}
18556    #
18557    #"
18558   [(set_attr "type" "fcmov,fcmov,multi,multi")
18559    (set_attr "mode" "DF")])
18561 (define_insn "*movdfcc_1_rex64"
18562   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18563         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18564                                 [(reg FLAGS_REG) (const_int 0)])
18565                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18566                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18567   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18568    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18569   "@
18570    fcmov%F1\t{%2, %0|%0, %2}
18571    fcmov%f1\t{%3, %0|%0, %3}
18572    cmov%O2%C1\t{%2, %0|%0, %2}
18573    cmov%O2%c1\t{%3, %0|%0, %3}"
18574   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18575    (set_attr "mode" "DF")])
18577 (define_split
18578   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18579         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18580                                 [(match_operand 4 "flags_reg_operand" "")
18581                                  (const_int 0)])
18582                       (match_operand:DF 2 "nonimmediate_operand" "")
18583                       (match_operand:DF 3 "nonimmediate_operand" "")))]
18584   "!TARGET_64BIT && reload_completed"
18585   [(set (match_dup 2)
18586         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18587                       (match_dup 5)
18588                       (match_dup 6)))
18589    (set (match_dup 3)
18590         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18591                       (match_dup 7)
18592                       (match_dup 8)))]
18593   "split_di (&operands[2], 2, &operands[5], &operands[7]);
18594    split_di (&operands[0], 1, &operands[2], &operands[3]);")
18596 (define_insn "*movxfcc_1"
18597   [(set (match_operand:XF 0 "register_operand" "=f,f")
18598         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18599                                 [(reg FLAGS_REG) (const_int 0)])
18600                       (match_operand:XF 2 "register_operand" "f,0")
18601                       (match_operand:XF 3 "register_operand" "0,f")))]
18602   "TARGET_80387 && TARGET_CMOVE"
18603   "@
18604    fcmov%F1\t{%2, %0|%0, %2}
18605    fcmov%f1\t{%3, %0|%0, %3}"
18606   [(set_attr "type" "fcmov")
18607    (set_attr "mode" "XF")])
18609 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18610 ;; the scalar versions to have only XMM registers as operands.
18612 ;; XOP conditional move
18613 (define_insn "*xop_pcmov_<mode>"
18614   [(set (match_operand:MODEF 0 "register_operand" "=x")
18615         (if_then_else:MODEF
18616           (match_operand:MODEF 1 "register_operand" "x")
18617           (match_operand:MODEF 2 "register_operand" "x")
18618           (match_operand:MODEF 3 "register_operand" "x")))]
18619   "TARGET_XOP"
18620   "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18621   [(set_attr "type" "sse4arg")])
18623 ;; These versions of the min/max patterns are intentionally ignorant of
18624 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18625 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18626 ;; are undefined in this condition, we're certain this is correct.
18628 (define_insn "*avx_<code><mode>3"
18629   [(set (match_operand:MODEF 0 "register_operand" "=x")
18630         (smaxmin:MODEF
18631           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
18632           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18633   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18634   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18635   [(set_attr "type" "sseadd")
18636    (set_attr "prefix" "vex")
18637    (set_attr "mode" "<MODE>")])
18639 (define_insn "<code><mode>3"
18640   [(set (match_operand:MODEF 0 "register_operand" "=x")
18641         (smaxmin:MODEF
18642           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
18643           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18644   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18645   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
18646   [(set_attr "type" "sseadd")
18647    (set_attr "mode" "<MODE>")])
18649 ;; These versions of the min/max patterns implement exactly the operations
18650 ;;   min = (op1 < op2 ? op1 : op2)
18651 ;;   max = (!(op1 < op2) ? op1 : op2)
18652 ;; Their operands are not commutative, and thus they may be used in the
18653 ;; presence of -0.0 and NaN.
18655 (define_insn "*avx_ieee_smin<mode>3"
18656   [(set (match_operand:MODEF 0 "register_operand" "=x")
18657         (unspec:MODEF
18658           [(match_operand:MODEF 1 "register_operand" "x")
18659            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18660          UNSPEC_IEEE_MIN))]
18661   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18662   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18663   [(set_attr "type" "sseadd")
18664    (set_attr "prefix" "vex")
18665    (set_attr "mode" "<MODE>")])
18667 (define_insn "*ieee_smin<mode>3"
18668   [(set (match_operand:MODEF 0 "register_operand" "=x")
18669         (unspec:MODEF
18670           [(match_operand:MODEF 1 "register_operand" "0")
18671            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18672          UNSPEC_IEEE_MIN))]
18673   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18674   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
18675   [(set_attr "type" "sseadd")
18676    (set_attr "mode" "<MODE>")])
18678 (define_insn "*avx_ieee_smax<mode>3"
18679   [(set (match_operand:MODEF 0 "register_operand" "=x")
18680         (unspec:MODEF
18681           [(match_operand:MODEF 1 "register_operand" "0")
18682            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18683          UNSPEC_IEEE_MAX))]
18684   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18685   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18686   [(set_attr "type" "sseadd")
18687    (set_attr "prefix" "vex")
18688    (set_attr "mode" "<MODE>")])
18690 (define_insn "*ieee_smax<mode>3"
18691   [(set (match_operand:MODEF 0 "register_operand" "=x")
18692         (unspec:MODEF
18693           [(match_operand:MODEF 1 "register_operand" "0")
18694            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18695          UNSPEC_IEEE_MAX))]
18696   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18697   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
18698   [(set_attr "type" "sseadd")
18699    (set_attr "mode" "<MODE>")])
18701 ;; Make two stack loads independent:
18702 ;;   fld aa              fld aa
18703 ;;   fld %st(0)     ->   fld bb
18704 ;;   fmul bb             fmul %st(1), %st
18706 ;; Actually we only match the last two instructions for simplicity.
18707 (define_peephole2
18708   [(set (match_operand 0 "fp_register_operand" "")
18709         (match_operand 1 "fp_register_operand" ""))
18710    (set (match_dup 0)
18711         (match_operator 2 "binary_fp_operator"
18712            [(match_dup 0)
18713             (match_operand 3 "memory_operand" "")]))]
18714   "REGNO (operands[0]) != REGNO (operands[1])"
18715   [(set (match_dup 0) (match_dup 3))
18716    (set (match_dup 0) (match_dup 4))]
18718   ;; The % modifier is not operational anymore in peephole2's, so we have to
18719   ;; swap the operands manually in the case of addition and multiplication.
18720   "if (COMMUTATIVE_ARITH_P (operands[2]))
18721      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18722                                  operands[0], operands[1]);
18723    else
18724      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18725                                  operands[1], operands[0]);")
18727 ;; Conditional addition patterns
18728 (define_expand "add<mode>cc"
18729   [(match_operand:SWI 0 "register_operand" "")
18730    (match_operand 1 "comparison_operator" "")
18731    (match_operand:SWI 2 "register_operand" "")
18732    (match_operand:SWI 3 "const_int_operand" "")]
18733   ""
18734   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18737 ;; Misc patterns (?)
18739 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18740 ;; Otherwise there will be nothing to keep
18742 ;; [(set (reg ebp) (reg esp))]
18743 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18744 ;;  (clobber (eflags)]
18745 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18747 ;; in proper program order.
18748 (define_insn "pro_epilogue_adjust_stack_1"
18749   [(set (match_operand:SI 0 "register_operand" "=r,r")
18750         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18751                  (match_operand:SI 2 "immediate_operand" "i,i")))
18752    (clobber (reg:CC FLAGS_REG))
18753    (clobber (mem:BLK (scratch)))]
18754   "!TARGET_64BIT"
18756   switch (get_attr_type (insn))
18757     {
18758     case TYPE_IMOV:
18759       return "mov{l}\t{%1, %0|%0, %1}";
18761     case TYPE_ALU:
18762       if (CONST_INT_P (operands[2])
18763           && (INTVAL (operands[2]) == 128
18764               || (INTVAL (operands[2]) < 0
18765                   && INTVAL (operands[2]) != -128)))
18766         {
18767           operands[2] = GEN_INT (-INTVAL (operands[2]));
18768           return "sub{l}\t{%2, %0|%0, %2}";
18769         }
18770       return "add{l}\t{%2, %0|%0, %2}";
18772     case TYPE_LEA:
18773       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18774       return "lea{l}\t{%a2, %0|%0, %a2}";
18776     default:
18777       gcc_unreachable ();
18778     }
18780   [(set (attr "type")
18781         (cond [(and (eq_attr "alternative" "0") 
18782                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18783                  (const_string "alu")
18784                (match_operand:SI 2 "const0_operand" "")
18785                  (const_string "imov")
18786               ]
18787               (const_string "lea")))
18788    (set (attr "length_immediate")
18789         (cond [(eq_attr "type" "imov")
18790                  (const_string "0")
18791                (and (eq_attr "type" "alu")
18792                     (match_operand 2 "const128_operand" ""))
18793                  (const_string "1")
18794               ]
18795               (const_string "*")))
18796    (set_attr "mode" "SI")])
18798 (define_insn "pro_epilogue_adjust_stack_rex64"
18799   [(set (match_operand:DI 0 "register_operand" "=r,r")
18800         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18801                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18802    (clobber (reg:CC FLAGS_REG))
18803    (clobber (mem:BLK (scratch)))]
18804   "TARGET_64BIT"
18806   switch (get_attr_type (insn))
18807     {
18808     case TYPE_IMOV:
18809       return "mov{q}\t{%1, %0|%0, %1}";
18811     case TYPE_ALU:
18812       if (CONST_INT_P (operands[2])
18813           /* Avoid overflows.  */
18814           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18815           && (INTVAL (operands[2]) == 128
18816               || (INTVAL (operands[2]) < 0
18817                   && INTVAL (operands[2]) != -128)))
18818         {
18819           operands[2] = GEN_INT (-INTVAL (operands[2]));
18820           return "sub{q}\t{%2, %0|%0, %2}";
18821         }
18822       return "add{q}\t{%2, %0|%0, %2}";
18824     case TYPE_LEA:
18825       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18826       return "lea{q}\t{%a2, %0|%0, %a2}";
18828     default:
18829       gcc_unreachable ();
18830     }
18832   [(set (attr "type")
18833         (cond [(and (eq_attr "alternative" "0")
18834                     (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18835                  (const_string "alu")
18836                (match_operand:DI 2 "const0_operand" "")
18837                  (const_string "imov")
18838               ]
18839               (const_string "lea")))
18840    (set (attr "length_immediate")
18841         (cond [(eq_attr "type" "imov")
18842                  (const_string "0")
18843                (and (eq_attr "type" "alu")
18844                     (match_operand 2 "const128_operand" ""))
18845                  (const_string "1")
18846               ]
18847               (const_string "*")))
18848    (set_attr "mode" "DI")])
18850 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18851   [(set (match_operand:DI 0 "register_operand" "=r,r")
18852         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18853                  (match_operand:DI 3 "immediate_operand" "i,i")))
18854    (use (match_operand:DI 2 "register_operand" "r,r"))
18855    (clobber (reg:CC FLAGS_REG))
18856    (clobber (mem:BLK (scratch)))]
18857   "TARGET_64BIT"
18859   switch (get_attr_type (insn))
18860     {
18861     case TYPE_ALU:
18862       return "add{q}\t{%2, %0|%0, %2}";
18864     case TYPE_LEA:
18865       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18866       return "lea{q}\t{%a2, %0|%0, %a2}";
18868     default:
18869       gcc_unreachable ();
18870     }
18872   [(set_attr "type" "alu,lea")
18873    (set_attr "mode" "DI")])
18875 (define_insn "allocate_stack_worker_32"
18876   [(set (match_operand:SI 0 "register_operand" "=a")
18877         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
18878                             UNSPECV_STACK_PROBE))
18879    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
18880    (clobber (reg:CC FLAGS_REG))]
18881   "!TARGET_64BIT && TARGET_STACK_PROBE"
18882   "call\t___chkstk"
18883   [(set_attr "type" "multi")
18884    (set_attr "length" "5")])
18886 (define_insn "allocate_stack_worker_64"
18887   [(set (match_operand:DI 0 "register_operand" "=a")
18888         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
18889                             UNSPECV_STACK_PROBE))
18890    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
18891    (clobber (reg:DI R10_REG))
18892    (clobber (reg:DI R11_REG))
18893    (clobber (reg:CC FLAGS_REG))]
18894   "TARGET_64BIT && TARGET_STACK_PROBE"
18895   "call\t___chkstk"
18896   [(set_attr "type" "multi")
18897    (set_attr "length" "5")])
18899 (define_expand "allocate_stack"
18900   [(match_operand 0 "register_operand" "")
18901    (match_operand 1 "general_operand" "")]
18902   "TARGET_STACK_PROBE"
18904   rtx x;
18906 #ifndef CHECK_STACK_LIMIT
18907 #define CHECK_STACK_LIMIT 0
18908 #endif
18910   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18911       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18912     {
18913       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
18914                                stack_pointer_rtx, 0, OPTAB_DIRECT);
18915       if (x != stack_pointer_rtx)
18916         emit_move_insn (stack_pointer_rtx, x);
18917     }
18918   else
18919     {
18920       x = copy_to_mode_reg (Pmode, operands[1]);
18921       if (TARGET_64BIT)
18922         x = gen_allocate_stack_worker_64 (x, x);
18923       else
18924         x = gen_allocate_stack_worker_32 (x, x);
18925       emit_insn (x);
18926     }
18928   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18929   DONE;
18932 ;; Use IOR for stack probes, this is shorter.
18933 (define_expand "probe_stack"
18934   [(match_operand 0 "memory_operand" "")]
18935   ""
18937   if (GET_MODE (operands[0]) == DImode)
18938     emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
18939   else
18940     emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
18941   DONE;
18944 (define_expand "builtin_setjmp_receiver"
18945   [(label_ref (match_operand 0 "" ""))]
18946   "!TARGET_64BIT && flag_pic"
18948 #if TARGET_MACHO
18949   if (TARGET_MACHO)
18950     {
18951       rtx xops[3];
18952       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
18953       rtx label_rtx = gen_label_rtx ();
18954       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18955       xops[0] = xops[1] = picreg;
18956       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18957       ix86_expand_binary_operator (MINUS, SImode, xops);
18958     }
18959   else
18960 #endif
18961     emit_insn (gen_set_got (pic_offset_table_rtx));
18962   DONE;
18965 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18967 (define_split
18968   [(set (match_operand 0 "register_operand" "")
18969         (match_operator 3 "promotable_binary_operator"
18970            [(match_operand 1 "register_operand" "")
18971             (match_operand 2 "aligned_operand" "")]))
18972    (clobber (reg:CC FLAGS_REG))]
18973   "! TARGET_PARTIAL_REG_STALL && reload_completed
18974    && ((GET_MODE (operands[0]) == HImode
18975         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18976             /* ??? next two lines just !satisfies_constraint_K (...) */
18977             || !CONST_INT_P (operands[2])
18978             || satisfies_constraint_K (operands[2])))
18979        || (GET_MODE (operands[0]) == QImode
18980            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18981   [(parallel [(set (match_dup 0)
18982                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18983               (clobber (reg:CC FLAGS_REG))])]
18984   "operands[0] = gen_lowpart (SImode, operands[0]);
18985    operands[1] = gen_lowpart (SImode, operands[1]);
18986    if (GET_CODE (operands[3]) != ASHIFT)
18987      operands[2] = gen_lowpart (SImode, operands[2]);
18988    PUT_MODE (operands[3], SImode);")
18990 ; Promote the QImode tests, as i386 has encoding of the AND
18991 ; instruction with 32-bit sign-extended immediate and thus the
18992 ; instruction size is unchanged, except in the %eax case for
18993 ; which it is increased by one byte, hence the ! optimize_size.
18994 (define_split
18995   [(set (match_operand 0 "flags_reg_operand" "")
18996         (match_operator 2 "compare_operator"
18997           [(and (match_operand 3 "aligned_operand" "")
18998                 (match_operand 4 "const_int_operand" ""))
18999            (const_int 0)]))
19000    (set (match_operand 1 "register_operand" "")
19001         (and (match_dup 3) (match_dup 4)))]
19002   "! TARGET_PARTIAL_REG_STALL && reload_completed
19003    && optimize_insn_for_speed_p ()
19004    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19005        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19006    /* Ensure that the operand will remain sign-extended immediate.  */
19007    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19008   [(parallel [(set (match_dup 0)
19009                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19010                                     (const_int 0)]))
19011               (set (match_dup 1)
19012                    (and:SI (match_dup 3) (match_dup 4)))])]
19014   operands[4]
19015     = gen_int_mode (INTVAL (operands[4])
19016                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19017   operands[1] = gen_lowpart (SImode, operands[1]);
19018   operands[3] = gen_lowpart (SImode, operands[3]);
19021 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19022 ; the TEST instruction with 32-bit sign-extended immediate and thus
19023 ; the instruction size would at least double, which is not what we
19024 ; want even with ! optimize_size.
19025 (define_split
19026   [(set (match_operand 0 "flags_reg_operand" "")
19027         (match_operator 1 "compare_operator"
19028           [(and (match_operand:HI 2 "aligned_operand" "")
19029                 (match_operand:HI 3 "const_int_operand" ""))
19030            (const_int 0)]))]
19031   "! TARGET_PARTIAL_REG_STALL && reload_completed
19032    && ! TARGET_FAST_PREFIX
19033    && optimize_insn_for_speed_p ()
19034    /* Ensure that the operand will remain sign-extended immediate.  */
19035    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19036   [(set (match_dup 0)
19037         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19038                          (const_int 0)]))]
19040   operands[3]
19041     = gen_int_mode (INTVAL (operands[3])
19042                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19043   operands[2] = gen_lowpart (SImode, operands[2]);
19046 (define_split
19047   [(set (match_operand 0 "register_operand" "")
19048         (neg (match_operand 1 "register_operand" "")))
19049    (clobber (reg:CC FLAGS_REG))]
19050   "! TARGET_PARTIAL_REG_STALL && reload_completed
19051    && (GET_MODE (operands[0]) == HImode
19052        || (GET_MODE (operands[0]) == QImode
19053            && (TARGET_PROMOTE_QImode
19054                || optimize_insn_for_size_p ())))"
19055   [(parallel [(set (match_dup 0)
19056                    (neg:SI (match_dup 1)))
19057               (clobber (reg:CC FLAGS_REG))])]
19058   "operands[0] = gen_lowpart (SImode, operands[0]);
19059    operands[1] = gen_lowpart (SImode, operands[1]);")
19061 (define_split
19062   [(set (match_operand 0 "register_operand" "")
19063         (not (match_operand 1 "register_operand" "")))]
19064   "! TARGET_PARTIAL_REG_STALL && reload_completed
19065    && (GET_MODE (operands[0]) == HImode
19066        || (GET_MODE (operands[0]) == QImode
19067            && (TARGET_PROMOTE_QImode
19068                || optimize_insn_for_size_p ())))"
19069   [(set (match_dup 0)
19070         (not:SI (match_dup 1)))]
19071   "operands[0] = gen_lowpart (SImode, operands[0]);
19072    operands[1] = gen_lowpart (SImode, operands[1]);")
19074 (define_split
19075   [(set (match_operand 0 "register_operand" "")
19076         (if_then_else (match_operator 1 "comparison_operator"
19077                                 [(reg FLAGS_REG) (const_int 0)])
19078                       (match_operand 2 "register_operand" "")
19079                       (match_operand 3 "register_operand" "")))]
19080   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19081    && (GET_MODE (operands[0]) == HImode
19082        || (GET_MODE (operands[0]) == QImode
19083            && (TARGET_PROMOTE_QImode
19084                || optimize_insn_for_size_p ())))"
19085   [(set (match_dup 0)
19086         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19087   "operands[0] = gen_lowpart (SImode, operands[0]);
19088    operands[2] = gen_lowpart (SImode, operands[2]);
19089    operands[3] = gen_lowpart (SImode, operands[3]);")
19092 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19093 ;; transform a complex memory operation into two memory to register operations.
19095 ;; Don't push memory operands
19096 (define_peephole2
19097   [(set (match_operand:SI 0 "push_operand" "")
19098         (match_operand:SI 1 "memory_operand" ""))
19099    (match_scratch:SI 2 "r")]
19100   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19101    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19102   [(set (match_dup 2) (match_dup 1))
19103    (set (match_dup 0) (match_dup 2))]
19104   "")
19106 (define_peephole2
19107   [(set (match_operand:DI 0 "push_operand" "")
19108         (match_operand:DI 1 "memory_operand" ""))
19109    (match_scratch:DI 2 "r")]
19110   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19111    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19112   [(set (match_dup 2) (match_dup 1))
19113    (set (match_dup 0) (match_dup 2))]
19114   "")
19116 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19117 ;; SImode pushes.
19118 (define_peephole2
19119   [(set (match_operand:SF 0 "push_operand" "")
19120         (match_operand:SF 1 "memory_operand" ""))
19121    (match_scratch:SF 2 "r")]
19122   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19123    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19124   [(set (match_dup 2) (match_dup 1))
19125    (set (match_dup 0) (match_dup 2))]
19126   "")
19128 (define_peephole2
19129   [(set (match_operand:HI 0 "push_operand" "")
19130         (match_operand:HI 1 "memory_operand" ""))
19131    (match_scratch:HI 2 "r")]
19132   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19133    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19134   [(set (match_dup 2) (match_dup 1))
19135    (set (match_dup 0) (match_dup 2))]
19136   "")
19138 (define_peephole2
19139   [(set (match_operand:QI 0 "push_operand" "")
19140         (match_operand:QI 1 "memory_operand" ""))
19141    (match_scratch:QI 2 "q")]
19142   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19143    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19144   [(set (match_dup 2) (match_dup 1))
19145    (set (match_dup 0) (match_dup 2))]
19146   "")
19148 ;; Don't move an immediate directly to memory when the instruction
19149 ;; gets too big.
19150 (define_peephole2
19151   [(match_scratch:SI 1 "r")
19152    (set (match_operand:SI 0 "memory_operand" "")
19153         (const_int 0))]
19154   "optimize_insn_for_speed_p ()
19155    && ! TARGET_USE_MOV0
19156    && TARGET_SPLIT_LONG_MOVES
19157    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19158    && peep2_regno_dead_p (0, FLAGS_REG)"
19159   [(parallel [(set (match_dup 1) (const_int 0))
19160               (clobber (reg:CC FLAGS_REG))])
19161    (set (match_dup 0) (match_dup 1))]
19162   "")
19164 (define_peephole2
19165   [(match_scratch:HI 1 "r")
19166    (set (match_operand:HI 0 "memory_operand" "")
19167         (const_int 0))]
19168   "optimize_insn_for_speed_p ()
19169    && ! TARGET_USE_MOV0
19170    && TARGET_SPLIT_LONG_MOVES
19171    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19172    && peep2_regno_dead_p (0, FLAGS_REG)"
19173   [(parallel [(set (match_dup 2) (const_int 0))
19174               (clobber (reg:CC FLAGS_REG))])
19175    (set (match_dup 0) (match_dup 1))]
19176   "operands[2] = gen_lowpart (SImode, operands[1]);")
19178 (define_peephole2
19179   [(match_scratch:QI 1 "q")
19180    (set (match_operand:QI 0 "memory_operand" "")
19181         (const_int 0))]
19182   "optimize_insn_for_speed_p ()
19183    && ! TARGET_USE_MOV0
19184    && TARGET_SPLIT_LONG_MOVES
19185    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19186    && peep2_regno_dead_p (0, FLAGS_REG)"
19187   [(parallel [(set (match_dup 2) (const_int 0))
19188               (clobber (reg:CC FLAGS_REG))])
19189    (set (match_dup 0) (match_dup 1))]
19190   "operands[2] = gen_lowpart (SImode, operands[1]);")
19192 (define_peephole2
19193   [(match_scratch:SI 2 "r")
19194    (set (match_operand:SI 0 "memory_operand" "")
19195         (match_operand:SI 1 "immediate_operand" ""))]
19196   "optimize_insn_for_speed_p ()
19197    && TARGET_SPLIT_LONG_MOVES
19198    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19199   [(set (match_dup 2) (match_dup 1))
19200    (set (match_dup 0) (match_dup 2))]
19201   "")
19203 (define_peephole2
19204   [(match_scratch:HI 2 "r")
19205    (set (match_operand:HI 0 "memory_operand" "")
19206         (match_operand:HI 1 "immediate_operand" ""))]
19207   "optimize_insn_for_speed_p ()
19208    && TARGET_SPLIT_LONG_MOVES
19209    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19210   [(set (match_dup 2) (match_dup 1))
19211    (set (match_dup 0) (match_dup 2))]
19212   "")
19214 (define_peephole2
19215   [(match_scratch:QI 2 "q")
19216    (set (match_operand:QI 0 "memory_operand" "")
19217         (match_operand:QI 1 "immediate_operand" ""))]
19218   "optimize_insn_for_speed_p ()
19219    && TARGET_SPLIT_LONG_MOVES
19220    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19221   [(set (match_dup 2) (match_dup 1))
19222    (set (match_dup 0) (match_dup 2))]
19223   "")
19225 ;; Don't compare memory with zero, load and use a test instead.
19226 (define_peephole2
19227   [(set (match_operand 0 "flags_reg_operand" "")
19228         (match_operator 1 "compare_operator"
19229           [(match_operand:SI 2 "memory_operand" "")
19230            (const_int 0)]))
19231    (match_scratch:SI 3 "r")]
19232   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19233   [(set (match_dup 3) (match_dup 2))
19234    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19235   "")
19237 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19238 ;; Don't split NOTs with a displacement operand, because resulting XOR
19239 ;; will not be pairable anyway.
19241 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19242 ;; represented using a modRM byte.  The XOR replacement is long decoded,
19243 ;; so this split helps here as well.
19245 ;; Note: Can't do this as a regular split because we can't get proper
19246 ;; lifetime information then.
19248 (define_peephole2
19249   [(set (match_operand:SI 0 "nonimmediate_operand" "")
19250         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19251   "optimize_insn_for_speed_p ()
19252    && ((TARGET_NOT_UNPAIRABLE
19253         && (!MEM_P (operands[0])
19254             || !memory_displacement_operand (operands[0], SImode)))
19255        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
19256    && peep2_regno_dead_p (0, FLAGS_REG)"
19257   [(parallel [(set (match_dup 0)
19258                    (xor:SI (match_dup 1) (const_int -1)))
19259               (clobber (reg:CC FLAGS_REG))])]
19260   "")
19262 (define_peephole2
19263   [(set (match_operand:HI 0 "nonimmediate_operand" "")
19264         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19265   "optimize_insn_for_speed_p ()
19266    && ((TARGET_NOT_UNPAIRABLE
19267         && (!MEM_P (operands[0])
19268             || !memory_displacement_operand (operands[0], HImode)))
19269        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
19270    && peep2_regno_dead_p (0, FLAGS_REG)"
19271   [(parallel [(set (match_dup 0)
19272                    (xor:HI (match_dup 1) (const_int -1)))
19273               (clobber (reg:CC FLAGS_REG))])]
19274   "")
19276 (define_peephole2
19277   [(set (match_operand:QI 0 "nonimmediate_operand" "")
19278         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19279   "optimize_insn_for_speed_p ()
19280    && ((TARGET_NOT_UNPAIRABLE
19281         && (!MEM_P (operands[0])
19282             || !memory_displacement_operand (operands[0], QImode)))
19283        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
19284    && peep2_regno_dead_p (0, FLAGS_REG)"
19285   [(parallel [(set (match_dup 0)
19286                    (xor:QI (match_dup 1) (const_int -1)))
19287               (clobber (reg:CC FLAGS_REG))])]
19288   "")
19290 ;; Non pairable "test imm, reg" instructions can be translated to
19291 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
19292 ;; byte opcode instead of two, have a short form for byte operands),
19293 ;; so do it for other CPUs as well.  Given that the value was dead,
19294 ;; this should not create any new dependencies.  Pass on the sub-word
19295 ;; versions if we're concerned about partial register stalls.
19297 (define_peephole2
19298   [(set (match_operand 0 "flags_reg_operand" "")
19299         (match_operator 1 "compare_operator"
19300           [(and:SI (match_operand:SI 2 "register_operand" "")
19301                    (match_operand:SI 3 "immediate_operand" ""))
19302            (const_int 0)]))]
19303   "ix86_match_ccmode (insn, CCNOmode)
19304    && (true_regnum (operands[2]) != AX_REG
19305        || satisfies_constraint_K (operands[3]))
19306    && peep2_reg_dead_p (1, operands[2])"
19307   [(parallel
19308      [(set (match_dup 0)
19309            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19310                             (const_int 0)]))
19311       (set (match_dup 2)
19312            (and:SI (match_dup 2) (match_dup 3)))])]
19313   "")
19315 ;; We don't need to handle HImode case, because it will be promoted to SImode
19316 ;; on ! TARGET_PARTIAL_REG_STALL
19318 (define_peephole2
19319   [(set (match_operand 0 "flags_reg_operand" "")
19320         (match_operator 1 "compare_operator"
19321           [(and:QI (match_operand:QI 2 "register_operand" "")
19322                    (match_operand:QI 3 "immediate_operand" ""))
19323            (const_int 0)]))]
19324   "! TARGET_PARTIAL_REG_STALL
19325    && ix86_match_ccmode (insn, CCNOmode)
19326    && true_regnum (operands[2]) != AX_REG
19327    && peep2_reg_dead_p (1, operands[2])"
19328   [(parallel
19329      [(set (match_dup 0)
19330            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19331                             (const_int 0)]))
19332       (set (match_dup 2)
19333            (and:QI (match_dup 2) (match_dup 3)))])]
19334   "")
19336 (define_peephole2
19337   [(set (match_operand 0 "flags_reg_operand" "")
19338         (match_operator 1 "compare_operator"
19339           [(and:SI
19340              (zero_extract:SI
19341                (match_operand 2 "ext_register_operand" "")
19342                (const_int 8)
19343                (const_int 8))
19344              (match_operand 3 "const_int_operand" ""))
19345            (const_int 0)]))]
19346   "! TARGET_PARTIAL_REG_STALL
19347    && ix86_match_ccmode (insn, CCNOmode)
19348    && true_regnum (operands[2]) != AX_REG
19349    && peep2_reg_dead_p (1, operands[2])"
19350   [(parallel [(set (match_dup 0)
19351                    (match_op_dup 1
19352                      [(and:SI
19353                         (zero_extract:SI
19354                           (match_dup 2)
19355                           (const_int 8)
19356                           (const_int 8))
19357                         (match_dup 3))
19358                       (const_int 0)]))
19359               (set (zero_extract:SI (match_dup 2)
19360                                     (const_int 8)
19361                                     (const_int 8))
19362                    (and:SI
19363                      (zero_extract:SI
19364                        (match_dup 2)
19365                        (const_int 8)
19366                        (const_int 8))
19367                      (match_dup 3)))])]
19368   "")
19370 ;; Don't do logical operations with memory inputs.
19371 (define_peephole2
19372   [(match_scratch:SI 2 "r")
19373    (parallel [(set (match_operand:SI 0 "register_operand" "")
19374                    (match_operator:SI 3 "arith_or_logical_operator"
19375                      [(match_dup 0)
19376                       (match_operand:SI 1 "memory_operand" "")]))
19377               (clobber (reg:CC FLAGS_REG))])]
19378   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19379   [(set (match_dup 2) (match_dup 1))
19380    (parallel [(set (match_dup 0)
19381                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19382               (clobber (reg:CC FLAGS_REG))])]
19383   "")
19385 (define_peephole2
19386   [(match_scratch:SI 2 "r")
19387    (parallel [(set (match_operand:SI 0 "register_operand" "")
19388                    (match_operator:SI 3 "arith_or_logical_operator"
19389                      [(match_operand:SI 1 "memory_operand" "")
19390                       (match_dup 0)]))
19391               (clobber (reg:CC FLAGS_REG))])]
19392   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19393   [(set (match_dup 2) (match_dup 1))
19394    (parallel [(set (match_dup 0)
19395                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19396               (clobber (reg:CC FLAGS_REG))])]
19397   "")
19399 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
19400 ;; refers to the destination of the load!
19402 (define_peephole2
19403   [(set (match_operand:SI 0 "register_operand" "")
19404         (match_operand:SI 1 "register_operand" ""))
19405    (parallel [(set (match_dup 0)
19406                    (match_operator:SI 3 "commutative_operator"
19407                      [(match_dup 0)
19408                       (match_operand:SI 2 "memory_operand" "")]))
19409               (clobber (reg:CC FLAGS_REG))])]
19410   "REGNO (operands[0]) != REGNO (operands[1])
19411    && GENERAL_REGNO_P (REGNO (operands[0]))
19412    && GENERAL_REGNO_P (REGNO (operands[1]))"
19413   [(set (match_dup 0) (match_dup 4))
19414    (parallel [(set (match_dup 0)
19415                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19416               (clobber (reg:CC FLAGS_REG))])]
19417   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
19419 (define_peephole2
19420   [(set (match_operand 0 "register_operand" "")
19421         (match_operand 1 "register_operand" ""))
19422    (set (match_dup 0)
19423                    (match_operator 3 "commutative_operator"
19424                      [(match_dup 0)
19425                       (match_operand 2 "memory_operand" "")]))]
19426   "REGNO (operands[0]) != REGNO (operands[1])
19427    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
19428        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
19429   [(set (match_dup 0) (match_dup 2))
19430    (set (match_dup 0)
19431         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
19432   "")
19434 ; Don't do logical operations with memory outputs
19436 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19437 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
19438 ; the same decoder scheduling characteristics as the original.
19440 (define_peephole2
19441   [(match_scratch:SI 2 "r")
19442    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19443                    (match_operator:SI 3 "arith_or_logical_operator"
19444                      [(match_dup 0)
19445                       (match_operand:SI 1 "nonmemory_operand" "")]))
19446               (clobber (reg:CC FLAGS_REG))])]
19447   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19448    /* Do not split stack checking probes.  */
19449    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19450   [(set (match_dup 2) (match_dup 0))
19451    (parallel [(set (match_dup 2)
19452                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19453               (clobber (reg:CC FLAGS_REG))])
19454    (set (match_dup 0) (match_dup 2))]
19455   "")
19457 (define_peephole2
19458   [(match_scratch:SI 2 "r")
19459    (parallel [(set (match_operand:SI 0 "memory_operand" "")
19460                    (match_operator:SI 3 "arith_or_logical_operator"
19461                      [(match_operand:SI 1 "nonmemory_operand" "")
19462                       (match_dup 0)]))
19463               (clobber (reg:CC FLAGS_REG))])]
19464   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19465    /* Do not split stack checking probes.  */
19466    && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19467   [(set (match_dup 2) (match_dup 0))
19468    (parallel [(set (match_dup 2)
19469                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19470               (clobber (reg:CC FLAGS_REG))])
19471    (set (match_dup 0) (match_dup 2))]
19472   "")
19474 ;; Attempt to always use XOR for zeroing registers.
19475 (define_peephole2
19476   [(set (match_operand 0 "register_operand" "")
19477         (match_operand 1 "const0_operand" ""))]
19478   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19479    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19480    && GENERAL_REG_P (operands[0])
19481    && peep2_regno_dead_p (0, FLAGS_REG)"
19482   [(parallel [(set (match_dup 0) (const_int 0))
19483               (clobber (reg:CC FLAGS_REG))])]
19485   operands[0] = gen_lowpart (word_mode, operands[0]);
19488 (define_peephole2
19489   [(set (strict_low_part (match_operand 0 "register_operand" ""))
19490         (const_int 0))]
19491   "(GET_MODE (operands[0]) == QImode
19492     || GET_MODE (operands[0]) == HImode)
19493    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19494    && peep2_regno_dead_p (0, FLAGS_REG)"
19495   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19496               (clobber (reg:CC FLAGS_REG))])])
19498 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19499 (define_peephole2
19500   [(set (match_operand 0 "register_operand" "")
19501         (const_int -1))]
19502   "(GET_MODE (operands[0]) == HImode
19503     || GET_MODE (operands[0]) == SImode
19504     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19505    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
19506    && peep2_regno_dead_p (0, FLAGS_REG)"
19507   [(parallel [(set (match_dup 0) (const_int -1))
19508               (clobber (reg:CC FLAGS_REG))])]
19509   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19510                               operands[0]);")
19512 ;; Attempt to convert simple leas to adds. These can be created by
19513 ;; move expanders.
19514 (define_peephole2
19515   [(set (match_operand:SI 0 "register_operand" "")
19516         (plus:SI (match_dup 0)
19517                  (match_operand:SI 1 "nonmemory_operand" "")))]
19518   "peep2_regno_dead_p (0, FLAGS_REG)"
19519   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19520               (clobber (reg:CC FLAGS_REG))])]
19521   "")
19523 (define_peephole2
19524   [(set (match_operand:SI 0 "register_operand" "")
19525         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19526                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19527   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19528   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19529               (clobber (reg:CC FLAGS_REG))])]
19530   "operands[2] = gen_lowpart (SImode, operands[2]);")
19532 (define_peephole2
19533   [(set (match_operand:DI 0 "register_operand" "")
19534         (plus:DI (match_dup 0)
19535                  (match_operand:DI 1 "x86_64_general_operand" "")))]
19536   "peep2_regno_dead_p (0, FLAGS_REG)"
19537   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19538               (clobber (reg:CC FLAGS_REG))])]
19539   "")
19541 (define_peephole2
19542   [(set (match_operand:SI 0 "register_operand" "")
19543         (mult:SI (match_dup 0)
19544                  (match_operand:SI 1 "const_int_operand" "")))]
19545   "exact_log2 (INTVAL (operands[1])) >= 0
19546    && peep2_regno_dead_p (0, FLAGS_REG)"
19547   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19548               (clobber (reg:CC FLAGS_REG))])]
19549   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19551 (define_peephole2
19552   [(set (match_operand:DI 0 "register_operand" "")
19553         (mult:DI (match_dup 0)
19554                  (match_operand:DI 1 "const_int_operand" "")))]
19555   "exact_log2 (INTVAL (operands[1])) >= 0
19556    && peep2_regno_dead_p (0, FLAGS_REG)"
19557   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19558               (clobber (reg:CC FLAGS_REG))])]
19559   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19561 (define_peephole2
19562   [(set (match_operand:SI 0 "register_operand" "")
19563         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19564                    (match_operand:DI 2 "const_int_operand" "")) 0))]
19565   "exact_log2 (INTVAL (operands[2])) >= 0
19566    && REGNO (operands[0]) == REGNO (operands[1])
19567    && peep2_regno_dead_p (0, FLAGS_REG)"
19568   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19569               (clobber (reg:CC FLAGS_REG))])]
19570   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19572 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
19573 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
19574 ;; many CPUs it is also faster, since special hardware to avoid esp
19575 ;; dependencies is present.
19577 ;; While some of these conversions may be done using splitters, we use peepholes
19578 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19580 ;; Convert prologue esp subtractions to push.
19581 ;; We need register to push.  In order to keep verify_flow_info happy we have
19582 ;; two choices
19583 ;; - use scratch and clobber it in order to avoid dependencies
19584 ;; - use already live register
19585 ;; We can't use the second way right now, since there is no reliable way how to
19586 ;; verify that given register is live.  First choice will also most likely in
19587 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
19588 ;; call clobbered registers are dead.  We may want to use base pointer as an
19589 ;; alternative when no register is available later.
19591 (define_peephole2
19592   [(match_scratch:SI 0 "r")
19593    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19594               (clobber (reg:CC FLAGS_REG))
19595               (clobber (mem:BLK (scratch)))])]
19596   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19597   [(clobber (match_dup 0))
19598    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19599               (clobber (mem:BLK (scratch)))])])
19601 (define_peephole2
19602   [(match_scratch:SI 0 "r")
19603    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19604               (clobber (reg:CC FLAGS_REG))
19605               (clobber (mem:BLK (scratch)))])]
19606   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19607   [(clobber (match_dup 0))
19608    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19609    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19610               (clobber (mem:BLK (scratch)))])])
19612 ;; Convert esp subtractions to push.
19613 (define_peephole2
19614   [(match_scratch:SI 0 "r")
19615    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19616               (clobber (reg:CC FLAGS_REG))])]
19617   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19618   [(clobber (match_dup 0))
19619    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19621 (define_peephole2
19622   [(match_scratch:SI 0 "r")
19623    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19624               (clobber (reg:CC FLAGS_REG))])]
19625   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19626   [(clobber (match_dup 0))
19627    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19628    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19630 ;; Convert epilogue deallocator to pop.
19631 (define_peephole2
19632   [(match_scratch:SI 0 "r")
19633    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19634               (clobber (reg:CC FLAGS_REG))
19635               (clobber (mem:BLK (scratch)))])]
19636   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19637   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19638               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19639               (clobber (mem:BLK (scratch)))])]
19640   "")
19642 ;; Two pops case is tricky, since pop causes dependency on destination register.
19643 ;; We use two registers if available.
19644 (define_peephole2
19645   [(match_scratch:SI 0 "r")
19646    (match_scratch:SI 1 "r")
19647    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19648               (clobber (reg:CC FLAGS_REG))
19649               (clobber (mem:BLK (scratch)))])]
19650   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19651   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19652               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19653               (clobber (mem:BLK (scratch)))])
19654    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19655               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19656   "")
19658 (define_peephole2
19659   [(match_scratch:SI 0 "r")
19660    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19661               (clobber (reg:CC FLAGS_REG))
19662               (clobber (mem:BLK (scratch)))])]
19663   "optimize_insn_for_size_p ()"
19664   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19665               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19666               (clobber (mem:BLK (scratch)))])
19667    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19668               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19669   "")
19671 ;; Convert esp additions to pop.
19672 (define_peephole2
19673   [(match_scratch:SI 0 "r")
19674    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19675               (clobber (reg:CC FLAGS_REG))])]
19676   ""
19677   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19678               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19679   "")
19681 ;; Two pops case is tricky, since pop causes dependency on destination register.
19682 ;; We use two registers if available.
19683 (define_peephole2
19684   [(match_scratch:SI 0 "r")
19685    (match_scratch:SI 1 "r")
19686    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19687               (clobber (reg:CC FLAGS_REG))])]
19688   ""
19689   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19690               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19691    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19692               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19693   "")
19695 (define_peephole2
19696   [(match_scratch:SI 0 "r")
19697    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19698               (clobber (reg:CC FLAGS_REG))])]
19699   "optimize_insn_for_size_p ()"
19700   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19701               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19702    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19703               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19704   "")
19706 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19707 ;; required and register dies.  Similarly for 128 to -128.
19708 (define_peephole2
19709   [(set (match_operand 0 "flags_reg_operand" "")
19710         (match_operator 1 "compare_operator"
19711           [(match_operand 2 "register_operand" "")
19712            (match_operand 3 "const_int_operand" "")]))]
19713   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19714      && incdec_operand (operands[3], GET_MODE (operands[3])))
19715     || (!TARGET_FUSE_CMP_AND_BRANCH
19716         && INTVAL (operands[3]) == 128))
19717    && ix86_match_ccmode (insn, CCGCmode)
19718    && peep2_reg_dead_p (1, operands[2])"
19719   [(parallel [(set (match_dup 0)
19720                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19721               (clobber (match_dup 2))])]
19722   "")
19724 (define_peephole2
19725   [(match_scratch:DI 0 "r")
19726    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19727               (clobber (reg:CC FLAGS_REG))
19728               (clobber (mem:BLK (scratch)))])]
19729   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19730   [(clobber (match_dup 0))
19731    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19732               (clobber (mem:BLK (scratch)))])])
19734 (define_peephole2
19735   [(match_scratch:DI 0 "r")
19736    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19737               (clobber (reg:CC FLAGS_REG))
19738               (clobber (mem:BLK (scratch)))])]
19739   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19740   [(clobber (match_dup 0))
19741    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19742    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19743               (clobber (mem:BLK (scratch)))])])
19745 ;; Convert esp subtractions to push.
19746 (define_peephole2
19747   [(match_scratch:DI 0 "r")
19748    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19749               (clobber (reg:CC FLAGS_REG))])]
19750   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19751   [(clobber (match_dup 0))
19752    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19754 (define_peephole2
19755   [(match_scratch:DI 0 "r")
19756    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19757               (clobber (reg:CC FLAGS_REG))])]
19758   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19759   [(clobber (match_dup 0))
19760    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19761    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19763 ;; Convert epilogue deallocator to pop.
19764 (define_peephole2
19765   [(match_scratch:DI 0 "r")
19766    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19767               (clobber (reg:CC FLAGS_REG))
19768               (clobber (mem:BLK (scratch)))])]
19769   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19770   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19771               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19772               (clobber (mem:BLK (scratch)))])]
19773   "")
19775 ;; Two pops case is tricky, since pop causes dependency on destination register.
19776 ;; We use two registers if available.
19777 (define_peephole2
19778   [(match_scratch:DI 0 "r")
19779    (match_scratch:DI 1 "r")
19780    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19781               (clobber (reg:CC FLAGS_REG))
19782               (clobber (mem:BLK (scratch)))])]
19783   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19784   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19785               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19786               (clobber (mem:BLK (scratch)))])
19787    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19788               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19789   "")
19791 (define_peephole2
19792   [(match_scratch:DI 0 "r")
19793    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19794               (clobber (reg:CC FLAGS_REG))
19795               (clobber (mem:BLK (scratch)))])]
19796   "optimize_insn_for_size_p ()"
19797   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19798               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19799               (clobber (mem:BLK (scratch)))])
19800    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19801               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19802   "")
19804 ;; Convert esp additions to pop.
19805 (define_peephole2
19806   [(match_scratch:DI 0 "r")
19807    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19808               (clobber (reg:CC FLAGS_REG))])]
19809   ""
19810   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19811               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19812   "")
19814 ;; Two pops case is tricky, since pop causes dependency on destination register.
19815 ;; We use two registers if available.
19816 (define_peephole2
19817   [(match_scratch:DI 0 "r")
19818    (match_scratch:DI 1 "r")
19819    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19820               (clobber (reg:CC FLAGS_REG))])]
19821   ""
19822   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19823               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19824    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19825               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19826   "")
19828 (define_peephole2
19829   [(match_scratch:DI 0 "r")
19830    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19831               (clobber (reg:CC FLAGS_REG))])]
19832   "optimize_insn_for_size_p ()"
19833   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19834               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19835    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19836               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19837   "")
19839 ;; Convert imul by three, five and nine into lea
19840 (define_peephole2
19841   [(parallel
19842     [(set (match_operand:SI 0 "register_operand" "")
19843           (mult:SI (match_operand:SI 1 "register_operand" "")
19844                    (match_operand:SI 2 "const_int_operand" "")))
19845      (clobber (reg:CC FLAGS_REG))])]
19846   "INTVAL (operands[2]) == 3
19847    || INTVAL (operands[2]) == 5
19848    || INTVAL (operands[2]) == 9"
19849   [(set (match_dup 0)
19850         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19851                  (match_dup 1)))]
19852   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19854 (define_peephole2
19855   [(parallel
19856     [(set (match_operand:SI 0 "register_operand" "")
19857           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19858                    (match_operand:SI 2 "const_int_operand" "")))
19859      (clobber (reg:CC FLAGS_REG))])]
19860   "optimize_insn_for_speed_p ()
19861    && (INTVAL (operands[2]) == 3
19862        || INTVAL (operands[2]) == 5
19863        || INTVAL (operands[2]) == 9)"
19864   [(set (match_dup 0) (match_dup 1))
19865    (set (match_dup 0)
19866         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19867                  (match_dup 0)))]
19868   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19870 (define_peephole2
19871   [(parallel
19872     [(set (match_operand:DI 0 "register_operand" "")
19873           (mult:DI (match_operand:DI 1 "register_operand" "")
19874                    (match_operand:DI 2 "const_int_operand" "")))
19875      (clobber (reg:CC FLAGS_REG))])]
19876   "TARGET_64BIT
19877    && (INTVAL (operands[2]) == 3
19878        || INTVAL (operands[2]) == 5
19879        || INTVAL (operands[2]) == 9)"
19880   [(set (match_dup 0)
19881         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19882                  (match_dup 1)))]
19883   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19885 (define_peephole2
19886   [(parallel
19887     [(set (match_operand:DI 0 "register_operand" "")
19888           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19889                    (match_operand:DI 2 "const_int_operand" "")))
19890      (clobber (reg:CC FLAGS_REG))])]
19891   "TARGET_64BIT
19892    && optimize_insn_for_speed_p ()
19893    && (INTVAL (operands[2]) == 3
19894        || INTVAL (operands[2]) == 5
19895        || INTVAL (operands[2]) == 9)"
19896   [(set (match_dup 0) (match_dup 1))
19897    (set (match_dup 0)
19898         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19899                  (match_dup 0)))]
19900   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19902 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19903 ;; imul $32bit_imm, reg, reg is direct decoded.
19904 (define_peephole2
19905   [(match_scratch:DI 3 "r")
19906    (parallel [(set (match_operand:DI 0 "register_operand" "")
19907                    (mult:DI (match_operand:DI 1 "memory_operand" "")
19908                             (match_operand:DI 2 "immediate_operand" "")))
19909               (clobber (reg:CC FLAGS_REG))])]
19910   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19911    && !satisfies_constraint_K (operands[2])"
19912   [(set (match_dup 3) (match_dup 1))
19913    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19914               (clobber (reg:CC FLAGS_REG))])]
19917 (define_peephole2
19918   [(match_scratch:SI 3 "r")
19919    (parallel [(set (match_operand:SI 0 "register_operand" "")
19920                    (mult:SI (match_operand:SI 1 "memory_operand" "")
19921                             (match_operand:SI 2 "immediate_operand" "")))
19922               (clobber (reg:CC FLAGS_REG))])]
19923   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19924    && !satisfies_constraint_K (operands[2])"
19925   [(set (match_dup 3) (match_dup 1))
19926    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19927               (clobber (reg:CC FLAGS_REG))])]
19930 (define_peephole2
19931   [(match_scratch:SI 3 "r")
19932    (parallel [(set (match_operand:DI 0 "register_operand" "")
19933                    (zero_extend:DI
19934                      (mult:SI (match_operand:SI 1 "memory_operand" "")
19935                               (match_operand:SI 2 "immediate_operand" ""))))
19936               (clobber (reg:CC FLAGS_REG))])]
19937   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19938    && !satisfies_constraint_K (operands[2])"
19939   [(set (match_dup 3) (match_dup 1))
19940    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19941               (clobber (reg:CC FLAGS_REG))])]
19944 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19945 ;; Convert it into imul reg, reg
19946 ;; It would be better to force assembler to encode instruction using long
19947 ;; immediate, but there is apparently no way to do so.
19948 (define_peephole2
19949   [(parallel [(set (match_operand:DI 0 "register_operand" "")
19950                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19951                             (match_operand:DI 2 "const_int_operand" "")))
19952               (clobber (reg:CC FLAGS_REG))])
19953    (match_scratch:DI 3 "r")]
19954   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19955    && satisfies_constraint_K (operands[2])"
19956   [(set (match_dup 3) (match_dup 2))
19957    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19958               (clobber (reg:CC FLAGS_REG))])]
19960   if (!rtx_equal_p (operands[0], operands[1]))
19961     emit_move_insn (operands[0], operands[1]);
19964 (define_peephole2
19965   [(parallel [(set (match_operand:SI 0 "register_operand" "")
19966                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19967                             (match_operand:SI 2 "const_int_operand" "")))
19968               (clobber (reg:CC FLAGS_REG))])
19969    (match_scratch:SI 3 "r")]
19970   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19971    && satisfies_constraint_K (operands[2])"
19972   [(set (match_dup 3) (match_dup 2))
19973    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19974               (clobber (reg:CC FLAGS_REG))])]
19976   if (!rtx_equal_p (operands[0], operands[1]))
19977     emit_move_insn (operands[0], operands[1]);
19980 (define_peephole2
19981   [(parallel [(set (match_operand:HI 0 "register_operand" "")
19982                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19983                             (match_operand:HI 2 "immediate_operand" "")))
19984               (clobber (reg:CC FLAGS_REG))])
19985    (match_scratch:HI 3 "r")]
19986   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
19987   [(set (match_dup 3) (match_dup 2))
19988    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19989               (clobber (reg:CC FLAGS_REG))])]
19991   if (!rtx_equal_p (operands[0], operands[1]))
19992     emit_move_insn (operands[0], operands[1]);
19995 ;; After splitting up read-modify operations, array accesses with memory
19996 ;; operands might end up in form:
19997 ;;  sall    $2, %eax
19998 ;;  movl    4(%esp), %edx
19999 ;;  addl    %edx, %eax
20000 ;; instead of pre-splitting:
20001 ;;  sall    $2, %eax
20002 ;;  addl    4(%esp), %eax
20003 ;; Turn it into:
20004 ;;  movl    4(%esp), %edx
20005 ;;  leal    (%edx,%eax,4), %eax
20007 (define_peephole2
20008   [(parallel [(set (match_operand 0 "register_operand" "")
20009                    (ashift (match_operand 1 "register_operand" "")
20010                            (match_operand 2 "const_int_operand" "")))
20011                (clobber (reg:CC FLAGS_REG))])
20012    (set (match_operand 3 "register_operand")
20013         (match_operand 4 "x86_64_general_operand" ""))
20014    (parallel [(set (match_operand 5 "register_operand" "")
20015                    (plus (match_operand 6 "register_operand" "")
20016                          (match_operand 7 "register_operand" "")))
20017                    (clobber (reg:CC FLAGS_REG))])]
20018   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20019    /* Validate MODE for lea.  */
20020    && ((!TARGET_PARTIAL_REG_STALL
20021         && (GET_MODE (operands[0]) == QImode
20022             || GET_MODE (operands[0]) == HImode))
20023        || GET_MODE (operands[0]) == SImode
20024        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20025    /* We reorder load and the shift.  */
20026    && !rtx_equal_p (operands[1], operands[3])
20027    && !reg_overlap_mentioned_p (operands[0], operands[4])
20028    /* Last PLUS must consist of operand 0 and 3.  */
20029    && !rtx_equal_p (operands[0], operands[3])
20030    && (rtx_equal_p (operands[3], operands[6])
20031        || rtx_equal_p (operands[3], operands[7]))
20032    && (rtx_equal_p (operands[0], operands[6])
20033        || rtx_equal_p (operands[0], operands[7]))
20034    /* The intermediate operand 0 must die or be same as output.  */
20035    && (rtx_equal_p (operands[0], operands[5])
20036        || peep2_reg_dead_p (3, operands[0]))"
20037   [(set (match_dup 3) (match_dup 4))
20038    (set (match_dup 0) (match_dup 1))]
20040   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20041   int scale = 1 << INTVAL (operands[2]);
20042   rtx index = gen_lowpart (Pmode, operands[1]);
20043   rtx base = gen_lowpart (Pmode, operands[3]);
20044   rtx dest = gen_lowpart (mode, operands[5]);
20046   operands[1] = gen_rtx_PLUS (Pmode, base,
20047                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20048   if (mode != Pmode)
20049     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20050   operands[0] = dest;
20053 ;; Call-value patterns last so that the wildcard operand does not
20054 ;; disrupt insn-recog's switch tables.
20056 (define_insn "*call_value_pop_0"
20057   [(set (match_operand 0 "" "")
20058         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20059               (match_operand:SI 2 "" "")))
20060    (set (reg:SI SP_REG)
20061         (plus:SI (reg:SI SP_REG)
20062                  (match_operand:SI 3 "immediate_operand" "")))]
20063   "!TARGET_64BIT"
20065   if (SIBLING_CALL_P (insn))
20066     return "jmp\t%P1";
20067   else
20068     return "call\t%P1";
20070   [(set_attr "type" "callv")])
20072 (define_insn "*call_value_pop_1"
20073   [(set (match_operand 0 "" "")
20074         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20075               (match_operand:SI 2 "" "")))
20076    (set (reg:SI SP_REG)
20077         (plus:SI (reg:SI SP_REG)
20078                  (match_operand:SI 3 "immediate_operand" "i")))]
20079   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20081   if (constant_call_address_operand (operands[1], Pmode))
20082     return "call\t%P1";
20083   return "call\t%A1";
20085   [(set_attr "type" "callv")])
20087 (define_insn "*sibcall_value_pop_1"
20088   [(set (match_operand 0 "" "")
20089         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20090               (match_operand:SI 2 "" "")))
20091    (set (reg:SI SP_REG)
20092         (plus:SI (reg:SI SP_REG)
20093                  (match_operand:SI 3 "immediate_operand" "i,i")))]
20094   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20095   "@
20096    jmp\t%P1
20097    jmp\t%A1"
20098   [(set_attr "type" "callv")])
20100 (define_insn "*call_value_0"
20101   [(set (match_operand 0 "" "")
20102         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20103               (match_operand:SI 2 "" "")))]
20104   "!TARGET_64BIT"
20106   if (SIBLING_CALL_P (insn))
20107     return "jmp\t%P1";
20108   else
20109     return "call\t%P1";
20111   [(set_attr "type" "callv")])
20113 (define_insn "*call_value_0_rex64"
20114   [(set (match_operand 0 "" "")
20115         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20116               (match_operand:DI 2 "const_int_operand" "")))]
20117   "TARGET_64BIT"
20119   if (SIBLING_CALL_P (insn))
20120     return "jmp\t%P1";
20121   else
20122     return "call\t%P1";
20124   [(set_attr "type" "callv")])
20126 (define_insn "*call_value_0_rex64_ms_sysv"
20127   [(set (match_operand 0 "" "")
20128         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20129               (match_operand:DI 2 "const_int_operand" "")))
20130    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20131    (clobber (reg:TI XMM6_REG))
20132    (clobber (reg:TI XMM7_REG))
20133    (clobber (reg:TI XMM8_REG))
20134    (clobber (reg:TI XMM9_REG))
20135    (clobber (reg:TI XMM10_REG))
20136    (clobber (reg:TI XMM11_REG))
20137    (clobber (reg:TI XMM12_REG))
20138    (clobber (reg:TI XMM13_REG))
20139    (clobber (reg:TI XMM14_REG))
20140    (clobber (reg:TI XMM15_REG))
20141    (clobber (reg:DI SI_REG))
20142    (clobber (reg:DI DI_REG))]
20143   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20145   if (SIBLING_CALL_P (insn))
20146     return "jmp\t%P1";
20147   else
20148     return "call\t%P1";
20150   [(set_attr "type" "callv")])
20152 (define_insn "*call_value_1"
20153   [(set (match_operand 0 "" "")
20154         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20155               (match_operand:SI 2 "" "")))]
20156   "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20158   if (constant_call_address_operand (operands[1], Pmode))
20159     return "call\t%P1";
20160   return "call\t%A1";
20162   [(set_attr "type" "callv")])
20164 (define_insn "*sibcall_value_1"
20165   [(set (match_operand 0 "" "")
20166         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20167               (match_operand:SI 2 "" "")))]
20168   "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20169   "@
20170    jmp\t%P1
20171    jmp\t%A1"
20172   [(set_attr "type" "callv")])
20174 (define_insn "*call_value_1_rex64"
20175   [(set (match_operand 0 "" "")
20176         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20177               (match_operand:DI 2 "" "")))]
20178   "TARGET_64BIT && !SIBLING_CALL_P (insn)
20179    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20181   if (constant_call_address_operand (operands[1], Pmode))
20182     return "call\t%P1";
20183   return "call\t%A1";
20185   [(set_attr "type" "callv")])
20187 (define_insn "*call_value_1_rex64_ms_sysv"
20188   [(set (match_operand 0 "" "")
20189         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20190               (match_operand:DI 2 "" "")))
20191    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20192    (clobber (reg:TI XMM6_REG))
20193    (clobber (reg:TI XMM7_REG))
20194    (clobber (reg:TI XMM8_REG))
20195    (clobber (reg:TI XMM9_REG))
20196    (clobber (reg:TI XMM10_REG))
20197    (clobber (reg:TI XMM11_REG))
20198    (clobber (reg:TI XMM12_REG))
20199    (clobber (reg:TI XMM13_REG))
20200    (clobber (reg:TI XMM14_REG))
20201    (clobber (reg:TI XMM15_REG))
20202    (clobber (reg:DI SI_REG))
20203    (clobber (reg:DI DI_REG))]
20204   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20206   if (constant_call_address_operand (operands[1], Pmode))
20207     return "call\t%P1";
20208   return "call\t%A1";
20210   [(set_attr "type" "callv")])
20212 (define_insn "*call_value_1_rex64_large"
20213   [(set (match_operand 0 "" "")
20214         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20215               (match_operand:DI 2 "" "")))]
20216   "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20217   "call\t%A1"
20218   [(set_attr "type" "callv")])
20220 (define_insn "*sibcall_value_1_rex64"
20221   [(set (match_operand 0 "" "")
20222         (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
20223               (match_operand:DI 2 "" "")))]
20224   "TARGET_64BIT && SIBLING_CALL_P (insn)"
20225   "@
20226    jmp\t%P1
20227    jmp\t%A1"
20228   [(set_attr "type" "callv")])
20230 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20231 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20232 ;; caught for use by garbage collectors and the like.  Using an insn that
20233 ;; maps to SIGILL makes it more likely the program will rightfully die.
20234 ;; Keeping with tradition, "6" is in honor of #UD.
20235 (define_insn "trap"
20236   [(trap_if (const_int 1) (const_int 6))]
20237   ""
20238   { return ASM_SHORT "0x0b0f"; }
20239   [(set_attr "length" "2")])
20241 (define_expand "sse_prologue_save"
20242   [(parallel [(set (match_operand:BLK 0 "" "")
20243                    (unspec:BLK [(reg:DI XMM0_REG)
20244                                 (reg:DI XMM1_REG)
20245                                 (reg:DI XMM2_REG)
20246                                 (reg:DI XMM3_REG)
20247                                 (reg:DI XMM4_REG)
20248                                 (reg:DI XMM5_REG)
20249                                 (reg:DI XMM6_REG)
20250                                 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20251               (use (match_operand:DI 1 "register_operand" ""))
20252               (use (match_operand:DI 2 "immediate_operand" ""))
20253               (use (label_ref:DI (match_operand 3 "" "")))])]
20254   "TARGET_64BIT"
20255   "")
20257 (define_insn "*sse_prologue_save_insn"
20258   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20259                           (match_operand:DI 4 "const_int_operand" "n")))
20260         (unspec:BLK [(reg:DI XMM0_REG)
20261                      (reg:DI XMM1_REG)
20262                      (reg:DI XMM2_REG)
20263                      (reg:DI XMM3_REG)
20264                      (reg:DI XMM4_REG)
20265                      (reg:DI XMM5_REG)
20266                      (reg:DI XMM6_REG)
20267                      (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20268    (use (match_operand:DI 1 "register_operand" "r"))
20269    (use (match_operand:DI 2 "const_int_operand" "i"))
20270    (use (label_ref:DI (match_operand 3 "" "X")))]
20271   "TARGET_64BIT
20272    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
20273    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20275   int i;
20276   operands[0] = gen_rtx_MEM (Pmode,
20277                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20278   /* VEX instruction with a REX prefix will #UD.  */
20279   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
20280     gcc_unreachable ();
20282   output_asm_insn ("jmp\t%A1", operands);
20283   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20284     {
20285       operands[4] = adjust_address (operands[0], DImode, i*16);
20286       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20287       PUT_MODE (operands[4], TImode);
20288       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20289         output_asm_insn ("rex", operands);
20290       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
20291     }
20292   (*targetm.asm_out.internal_label) (asm_out_file, "L",
20293                                      CODE_LABEL_NUMBER (operands[3]));
20294   return "";
20296   [(set_attr "type" "other")
20297    (set_attr "length_immediate" "0")
20298    (set_attr "length_address" "0")
20299    (set (attr "length")
20300      (if_then_else
20301        (eq (symbol_ref "TARGET_AVX") (const_int 0))
20302        (const_string "34")
20303        (const_string "42")))
20304    (set_attr "memory" "store")
20305    (set_attr "modrm" "0")
20306    (set_attr "prefix" "maybe_vex")
20307    (set_attr "mode" "DI")])
20309 (define_expand "prefetch"
20310   [(prefetch (match_operand 0 "address_operand" "")
20311              (match_operand:SI 1 "const_int_operand" "")
20312              (match_operand:SI 2 "const_int_operand" ""))]
20313   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20315   int rw = INTVAL (operands[1]);
20316   int locality = INTVAL (operands[2]);
20318   gcc_assert (rw == 0 || rw == 1);
20319   gcc_assert (locality >= 0 && locality <= 3);
20320   gcc_assert (GET_MODE (operands[0]) == Pmode
20321               || GET_MODE (operands[0]) == VOIDmode);
20323   /* Use 3dNOW prefetch in case we are asking for write prefetch not
20324      supported by SSE counterpart or the SSE prefetch is not available
20325      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
20326      of locality.  */
20327   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20328     operands[2] = GEN_INT (3);
20329   else
20330     operands[1] = const0_rtx;
20333 (define_insn "*prefetch_sse"
20334   [(prefetch (match_operand:SI 0 "address_operand" "p")
20335              (const_int 0)
20336              (match_operand:SI 1 "const_int_operand" ""))]
20337   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20339   static const char * const patterns[4] = {
20340    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20341   };
20343   int locality = INTVAL (operands[1]);
20344   gcc_assert (locality >= 0 && locality <= 3);
20346   return patterns[locality];
20348   [(set_attr "type" "sse")
20349    (set_attr "atom_sse_attr" "prefetch")
20350    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20351    (set_attr "memory" "none")])
20353 (define_insn "*prefetch_sse_rex"
20354   [(prefetch (match_operand:DI 0 "address_operand" "p")
20355              (const_int 0)
20356              (match_operand:SI 1 "const_int_operand" ""))]
20357   "TARGET_PREFETCH_SSE && TARGET_64BIT"
20359   static const char * const patterns[4] = {
20360    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20361   };
20363   int locality = INTVAL (operands[1]);
20364   gcc_assert (locality >= 0 && locality <= 3);
20366   return patterns[locality];
20368   [(set_attr "type" "sse")
20369    (set_attr "atom_sse_attr" "prefetch")
20370    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20371    (set_attr "memory" "none")])
20373 (define_insn "*prefetch_3dnow"
20374   [(prefetch (match_operand:SI 0 "address_operand" "p")
20375              (match_operand:SI 1 "const_int_operand" "n")
20376              (const_int 3))]
20377   "TARGET_3DNOW && !TARGET_64BIT"
20379   if (INTVAL (operands[1]) == 0)
20380     return "prefetch\t%a0";
20381   else
20382     return "prefetchw\t%a0";
20384   [(set_attr "type" "mmx")
20385    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20386    (set_attr "memory" "none")])
20388 (define_insn "*prefetch_3dnow_rex"
20389   [(prefetch (match_operand:DI 0 "address_operand" "p")
20390              (match_operand:SI 1 "const_int_operand" "n")
20391              (const_int 3))]
20392   "TARGET_3DNOW && TARGET_64BIT"
20394   if (INTVAL (operands[1]) == 0)
20395     return "prefetch\t%a0";
20396   else
20397     return "prefetchw\t%a0";
20399   [(set_attr "type" "mmx")
20400    (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20401    (set_attr "memory" "none")])
20403 (define_expand "stack_protect_set"
20404   [(match_operand 0 "memory_operand" "")
20405    (match_operand 1 "memory_operand" "")]
20406   ""
20408 #ifdef TARGET_THREAD_SSP_OFFSET
20409   if (TARGET_64BIT)
20410     emit_insn (gen_stack_tls_protect_set_di (operands[0],
20411                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20412   else
20413     emit_insn (gen_stack_tls_protect_set_si (operands[0],
20414                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20415 #else
20416   if (TARGET_64BIT)
20417     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20418   else
20419     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20420 #endif
20421   DONE;
20424 (define_insn "stack_protect_set_si"
20425   [(set (match_operand:SI 0 "memory_operand" "=m")
20426         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20427    (set (match_scratch:SI 2 "=&r") (const_int 0))
20428    (clobber (reg:CC FLAGS_REG))]
20429   ""
20430   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20431   [(set_attr "type" "multi")])
20433 (define_insn "stack_protect_set_di"
20434   [(set (match_operand:DI 0 "memory_operand" "=m")
20435         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20436    (set (match_scratch:DI 2 "=&r") (const_int 0))
20437    (clobber (reg:CC FLAGS_REG))]
20438   "TARGET_64BIT"
20439   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20440   [(set_attr "type" "multi")])
20442 (define_insn "stack_tls_protect_set_si"
20443   [(set (match_operand:SI 0 "memory_operand" "=m")
20444         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20445    (set (match_scratch:SI 2 "=&r") (const_int 0))
20446    (clobber (reg:CC FLAGS_REG))]
20447   ""
20448   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20449   [(set_attr "type" "multi")])
20451 (define_insn "stack_tls_protect_set_di"
20452   [(set (match_operand:DI 0 "memory_operand" "=m")
20453         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20454    (set (match_scratch:DI 2 "=&r") (const_int 0))
20455    (clobber (reg:CC FLAGS_REG))]
20456   "TARGET_64BIT"
20457   {
20458      /* The kernel uses a different segment register for performance reasons; a
20459         system call would not have to trash the userspace segment register,
20460         which would be expensive */
20461      if (ix86_cmodel != CM_KERNEL)
20462         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20463      else
20464         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20465   }
20466   [(set_attr "type" "multi")])
20468 (define_expand "stack_protect_test"
20469   [(match_operand 0 "memory_operand" "")
20470    (match_operand 1 "memory_operand" "")
20471    (match_operand 2 "" "")]
20472   ""
20474   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20476 #ifdef TARGET_THREAD_SSP_OFFSET
20477   if (TARGET_64BIT)
20478     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20479                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20480   else
20481     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20482                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20483 #else
20484   if (TARGET_64BIT)
20485     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20486   else
20487     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20488 #endif
20490   emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20491                                   flags, const0_rtx, operands[2]));
20492   DONE;
20495 (define_insn "stack_protect_test_si"
20496   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20497         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20498                      (match_operand:SI 2 "memory_operand" "m")]
20499                     UNSPEC_SP_TEST))
20500    (clobber (match_scratch:SI 3 "=&r"))]
20501   ""
20502   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20503   [(set_attr "type" "multi")])
20505 (define_insn "stack_protect_test_di"
20506   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20507         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20508                      (match_operand:DI 2 "memory_operand" "m")]
20509                     UNSPEC_SP_TEST))
20510    (clobber (match_scratch:DI 3 "=&r"))]
20511   "TARGET_64BIT"
20512   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20513   [(set_attr "type" "multi")])
20515 (define_insn "stack_tls_protect_test_si"
20516   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20517         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20518                      (match_operand:SI 2 "const_int_operand" "i")]
20519                     UNSPEC_SP_TLS_TEST))
20520    (clobber (match_scratch:SI 3 "=r"))]
20521   ""
20522   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
20523   [(set_attr "type" "multi")])
20525 (define_insn "stack_tls_protect_test_di"
20526   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20527         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20528                      (match_operand:DI 2 "const_int_operand" "i")]
20529                     UNSPEC_SP_TLS_TEST))
20530    (clobber (match_scratch:DI 3 "=r"))]
20531   "TARGET_64BIT"
20532   {
20533      /* The kernel uses a different segment register for performance reasons; a
20534         system call would not have to trash the userspace segment register,
20535         which would be expensive */
20536      if (ix86_cmodel != CM_KERNEL)
20537         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
20538      else
20539         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
20540   }
20541   [(set_attr "type" "multi")])
20543 (define_insn "sse4_2_crc32<mode>"
20544   [(set (match_operand:SI 0 "register_operand" "=r")
20545         (unspec:SI
20546           [(match_operand:SI 1 "register_operand" "0")
20547            (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20548           UNSPEC_CRC32))]
20549   "TARGET_SSE4_2 || TARGET_CRC32"
20550   "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20551   [(set_attr "type" "sselog1")
20552    (set_attr "prefix_rep" "1")
20553    (set_attr "prefix_extra" "1")
20554    (set (attr "prefix_data16")
20555      (if_then_else (match_operand:HI 2 "" "")
20556        (const_string "1")
20557        (const_string "*")))
20558    (set (attr "prefix_rex")
20559      (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
20560        (const_string "1")
20561        (const_string "*")))
20562    (set_attr "mode" "SI")])
20564 (define_insn "sse4_2_crc32di"
20565   [(set (match_operand:DI 0 "register_operand" "=r")
20566         (unspec:DI
20567           [(match_operand:DI 1 "register_operand" "0")
20568            (match_operand:DI 2 "nonimmediate_operand" "rm")]
20569           UNSPEC_CRC32))]
20570   "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
20571   "crc32{q}\t{%2, %0|%0, %2}"
20572   [(set_attr "type" "sselog1")
20573    (set_attr "prefix_rep" "1")
20574    (set_attr "prefix_extra" "1")
20575    (set_attr "mode" "DI")])
20577 (define_expand "rdpmc"
20578   [(match_operand:DI 0 "register_operand" "")
20579    (match_operand:SI 1 "register_operand" "")]
20580   ""
20582   rtx reg = gen_reg_rtx (DImode);
20583   rtx si;
20585   /* Force operand 1 into ECX.  */
20586   rtx ecx = gen_rtx_REG (SImode, CX_REG);
20587   emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
20588   si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
20589                                 UNSPECV_RDPMC);
20591   if (TARGET_64BIT)
20592     {
20593       rtvec vec = rtvec_alloc (2);
20594       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20595       rtx upper = gen_reg_rtx (DImode);
20596       rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20597                                         gen_rtvec (1, const0_rtx),
20598                                         UNSPECV_RDPMC);
20599       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
20600       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20601       emit_insn (load);
20602       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20603                                    NULL, 1, OPTAB_DIRECT);
20604       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20605                                  OPTAB_DIRECT);
20606     }
20607   else
20608     emit_insn (gen_rtx_SET (VOIDmode, reg, si));
20609   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20610   DONE;
20613 (define_insn "*rdpmc"
20614   [(set (match_operand:DI 0 "register_operand" "=A")
20615         (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20616                             UNSPECV_RDPMC))]
20617   "!TARGET_64BIT"
20618   "rdpmc"
20619   [(set_attr "type" "other")
20620    (set_attr "length" "2")])
20622 (define_insn "*rdpmc_rex64"
20623   [(set (match_operand:DI 0 "register_operand" "=a")
20624         (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20625                             UNSPECV_RDPMC))
20626   (set (match_operand:DI 1 "register_operand" "=d")
20627        (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
20628   "TARGET_64BIT"
20629   "rdpmc"
20630   [(set_attr "type" "other")
20631    (set_attr "length" "2")])
20633 (define_expand "rdtsc"
20634   [(set (match_operand:DI 0 "register_operand" "")
20635         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20636   ""
20638   if (TARGET_64BIT)
20639     {
20640       rtvec vec = rtvec_alloc (2);
20641       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20642       rtx upper = gen_reg_rtx (DImode);
20643       rtx lower = gen_reg_rtx (DImode);
20644       rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
20645                                          gen_rtvec (1, const0_rtx),
20646                                          UNSPECV_RDTSC);
20647       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
20648       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
20649       emit_insn (load);
20650       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20651                                    NULL, 1, OPTAB_DIRECT);
20652       lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
20653                                    OPTAB_DIRECT);
20654       emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
20655       DONE;
20656     }
20659 (define_insn "*rdtsc"
20660   [(set (match_operand:DI 0 "register_operand" "=A")
20661         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20662   "!TARGET_64BIT"
20663   "rdtsc"
20664   [(set_attr "type" "other")
20665    (set_attr "length" "2")])
20667 (define_insn "*rdtsc_rex64"
20668   [(set (match_operand:DI 0 "register_operand" "=a")
20669         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
20670    (set (match_operand:DI 1 "register_operand" "=d")
20671         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20672   "TARGET_64BIT"
20673   "rdtsc"
20674   [(set_attr "type" "other")
20675    (set_attr "length" "2")])
20677 (define_expand "rdtscp"
20678   [(match_operand:DI 0 "register_operand" "")
20679    (match_operand:SI 1 "memory_operand" "")]
20680   ""
20682   rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20683                                     gen_rtvec (1, const0_rtx),
20684                                     UNSPECV_RDTSCP);
20685   rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
20686                                     gen_rtvec (1, const0_rtx),
20687                                     UNSPECV_RDTSCP);
20688   rtx reg = gen_reg_rtx (DImode);
20689   rtx tmp = gen_reg_rtx (SImode);
20691   if (TARGET_64BIT)
20692     {
20693       rtvec vec = rtvec_alloc (3);
20694       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20695       rtx upper = gen_reg_rtx (DImode);
20696       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20697       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20698       RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
20699       emit_insn (load);
20700       upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20701                                    NULL, 1, OPTAB_DIRECT);
20702       reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20703                                  OPTAB_DIRECT);
20704     }
20705   else
20706     {
20707       rtvec vec = rtvec_alloc (2);
20708       rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20709       RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20710       RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
20711       emit_insn (load);
20712     }
20713   emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20714   emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
20715   DONE;
20718 (define_insn "*rdtscp"
20719   [(set (match_operand:DI 0 "register_operand" "=A")
20720         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20721    (set (match_operand:SI 1 "register_operand" "=c")
20722         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20723   "!TARGET_64BIT"
20724   "rdtscp"
20725   [(set_attr "type" "other")
20726    (set_attr "length" "3")])
20728 (define_insn "*rdtscp_rex64"
20729   [(set (match_operand:DI 0 "register_operand" "=a")
20730         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20731    (set (match_operand:DI 1 "register_operand" "=d")
20732         (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20733    (set (match_operand:SI 2 "register_operand" "=c")
20734         (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20735   "TARGET_64BIT"
20736   "rdtscp"
20737   [(set_attr "type" "other")
20738    (set_attr "length" "3")])
20740 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20742 ;; LWP instructions
20744 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20746 (define_expand "lwp_llwpcb"
20747   [(unspec_volatile [(match_operand 0 "register_operand" "r")]
20748                     UNSPECV_LLWP_INTRINSIC)]
20749   "TARGET_LWP"
20750   "")
20752 (define_insn "*lwp_llwpcb<mode>1"
20753   [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20754                     UNSPECV_LLWP_INTRINSIC)]
20755   "TARGET_LWP"
20756   "llwpcb\t%0"
20757   [(set_attr "type" "lwp")
20758    (set_attr "mode" "<MODE>")
20759    (set_attr "length" "5")])
20761 (define_expand "lwp_slwpcb"
20762   [(set (match_operand 0 "register_operand" "=r")
20763         (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20764   "TARGET_LWP"
20765   {
20766     if (TARGET_64BIT)
20767       emit_insn (gen_lwp_slwpcbdi (operands[0]));
20768     else
20769       emit_insn (gen_lwp_slwpcbsi (operands[0]));
20770     DONE;
20771   })
20773 (define_insn "lwp_slwpcb<mode>"
20774   [(set (match_operand:P 0 "register_operand" "=r")
20775         (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20776   "TARGET_LWP"
20777   "slwpcb\t%0"
20778   [(set_attr "type" "lwp")
20779    (set_attr "mode" "<MODE>")
20780    (set_attr "length" "5")])
20782 (define_expand "lwp_lwpval<mode>3"
20783   [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
20784                      (match_operand:SI 2 "nonimmediate_operand" "rm")
20785                      (match_operand:SI 3 "const_int_operand" "i")]
20786                     UNSPECV_LWPVAL_INTRINSIC)]
20787   "TARGET_LWP"
20788   "/* Avoid unused variable warning.  */
20789    (void) operand0;")
20791 (define_insn "*lwp_lwpval<mode>3_1"
20792   [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20793                      (match_operand:SI 1 "nonimmediate_operand" "rm")
20794                      (match_operand:SI 2 "const_int_operand" "i")]
20795                     UNSPECV_LWPVAL_INTRINSIC)]
20796   "TARGET_LWP"
20797   "lwpval\t{%2, %1, %0|%0, %1, %2}"
20798   [(set_attr "type" "lwp")
20799    (set_attr "mode" "<MODE>")
20800    (set (attr "length")
20801         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20803 (define_expand "lwp_lwpins<mode>3"
20804   [(set (reg:CCC FLAGS_REG)
20805         (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
20806                               (match_operand:SI 2 "nonimmediate_operand" "rm")
20807                               (match_operand:SI 3 "const_int_operand" "i")]
20808                              UNSPECV_LWPINS_INTRINSIC))
20809    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
20810         (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20811   "TARGET_LWP"
20812   "")
20814 (define_insn "*lwp_lwpins<mode>3_1"
20815   [(set (reg:CCC FLAGS_REG)
20816         (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20817                               (match_operand:SI 1 "nonimmediate_operand" "rm")
20818                               (match_operand:SI 2 "const_int_operand" "i")]
20819                              UNSPECV_LWPINS_INTRINSIC))]
20820   "TARGET_LWP"
20821   "lwpins\t{%2, %1, %0|%0, %1, %2}"
20822   [(set_attr "type" "lwp")
20823    (set_attr "mode" "<MODE>")
20824    (set (attr "length")
20825         (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20827 (include "mmx.md")
20828 (include "sse.md")
20829 (include "sync.md")