Merged revisions 143552,143554,143557,143560,143562,143564-143567,143570-143573,14357...
[official-gcc.git] / gcc / config / i386 / i386.md
blob761a5e70c680095c722d19221038a3554358c086
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
31 ;;     operands[1].
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;;     %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
47 ;; UNSPEC usage:
49 (define_constants
50   [; Relocation specifiers
51    (UNSPEC_GOT                  0)
52    (UNSPEC_GOTOFF               1)
53    (UNSPEC_GOTPCREL             2)
54    (UNSPEC_GOTTPOFF             3)
55    (UNSPEC_TPOFF                4)
56    (UNSPEC_NTPOFF               5)
57    (UNSPEC_DTPOFF               6)
58    (UNSPEC_GOTNTPOFF            7)
59    (UNSPEC_INDNTPOFF            8)
60    (UNSPEC_PLTOFF               9)
61    (UNSPEC_MACHOPIC_OFFSET      10)
63    ; Prologue support
64    (UNSPEC_STACK_ALLOC          11)
65    (UNSPEC_SET_GOT              12)
66    (UNSPEC_SSE_PROLOGUE_SAVE    13)
67    (UNSPEC_REG_SAVE             14)
68    (UNSPEC_DEF_CFA              15)
69    (UNSPEC_SET_RIP              16)
70    (UNSPEC_SET_GOT_OFFSET       17)
71    (UNSPEC_MEMORY_BLOCKAGE      18)
73    ; TLS support
74    (UNSPEC_TP                   20)
75    (UNSPEC_TLS_GD               21)
76    (UNSPEC_TLS_LD_BASE          22)
77    (UNSPEC_TLSDESC              23)
79    ; Other random patterns
80    (UNSPEC_SCAS                 30)
81    (UNSPEC_FNSTSW               31)
82    (UNSPEC_SAHF                 32)
83    (UNSPEC_FSTCW                33)
84    (UNSPEC_ADD_CARRY            34)
85    (UNSPEC_FLDCW                35)
86    (UNSPEC_REP                  36)
87    (UNSPEC_EH_RETURN            37)
88    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
89    (UNSPEC_TRUNC_NOOP           39)
91    ; For SSE/MMX support:
92    (UNSPEC_FIX_NOTRUNC          40)
93    (UNSPEC_MASKMOV              41)
94    (UNSPEC_MOVMSK               42)
95    (UNSPEC_MOVNT                43)
96    (UNSPEC_MOVU                 44)
97    (UNSPEC_RCP                  45)
98    (UNSPEC_RSQRT                46)
99    (UNSPEC_SFENCE               47)
100    (UNSPEC_PFRCP                49)
101    (UNSPEC_PFRCPIT1             40)
102    (UNSPEC_PFRCPIT2             41)
103    (UNSPEC_PFRSQRT              42)
104    (UNSPEC_PFRSQIT1             43)
105    (UNSPEC_MFENCE               44)
106    (UNSPEC_LFENCE               45)
107    (UNSPEC_PSADBW               46)
108    (UNSPEC_LDDQU                47)
109    (UNSPEC_MS_TO_SYSV_CALL      48)
111    ; Generic math support
112    (UNSPEC_COPYSIGN             50)
113    (UNSPEC_IEEE_MIN             51)     ; not commutative
114    (UNSPEC_IEEE_MAX             52)     ; not commutative
116    ; x87 Floating point
117    (UNSPEC_SIN                  60)
118    (UNSPEC_COS                  61)
119    (UNSPEC_FPATAN               62)
120    (UNSPEC_FYL2X                63)
121    (UNSPEC_FYL2XP1              64)
122    (UNSPEC_FRNDINT              65)
123    (UNSPEC_FIST                 66)
124    (UNSPEC_F2XM1                67)
125    (UNSPEC_TAN                  68)
126    (UNSPEC_FXAM                 69)
128    ; x87 Rounding
129    (UNSPEC_FRNDINT_FLOOR        70)
130    (UNSPEC_FRNDINT_CEIL         71)
131    (UNSPEC_FRNDINT_TRUNC        72)
132    (UNSPEC_FRNDINT_MASK_PM      73)
133    (UNSPEC_FIST_FLOOR           74)
134    (UNSPEC_FIST_CEIL            75)
136    ; x87 Double output FP
137    (UNSPEC_SINCOS_COS           80)
138    (UNSPEC_SINCOS_SIN           81)
139    (UNSPEC_XTRACT_FRACT         84)
140    (UNSPEC_XTRACT_EXP           85)
141    (UNSPEC_FSCALE_FRACT         86)
142    (UNSPEC_FSCALE_EXP           87)
143    (UNSPEC_FPREM_F              88)
144    (UNSPEC_FPREM_U              89)
145    (UNSPEC_FPREM1_F             90)
146    (UNSPEC_FPREM1_U             91)
148    (UNSPEC_C2_FLAG              95)
149    (UNSPEC_FXAM_MEM             96)
151    ; SSP patterns
152    (UNSPEC_SP_SET               100)
153    (UNSPEC_SP_TEST              101)
154    (UNSPEC_SP_TLS_SET           102)
155    (UNSPEC_SP_TLS_TEST          103)
157    ; SSSE3
158    (UNSPEC_PSHUFB               120)
159    (UNSPEC_PSIGN                121)
160    (UNSPEC_PALIGNR              122)
162    ; For SSE4A support
163    (UNSPEC_EXTRQI               130)
164    (UNSPEC_EXTRQ                131)
165    (UNSPEC_INSERTQI             132)
166    (UNSPEC_INSERTQ              133)
168    ; For SSE4.1 support
169    (UNSPEC_BLENDV               134)
170    (UNSPEC_INSERTPS             135)
171    (UNSPEC_DP                   136)
172    (UNSPEC_MOVNTDQA             137)
173    (UNSPEC_MPSADBW              138)
174    (UNSPEC_PHMINPOSUW           139)
175    (UNSPEC_PTEST                140)
176    (UNSPEC_ROUND                141)
178    ; For SSE4.2 support
179    (UNSPEC_CRC32                143)
180    (UNSPEC_PCMPESTR             144)
181    (UNSPEC_PCMPISTR             145)
183    ;; For SSE5
184    (UNSPEC_SSE5_INTRINSIC       150)
185    (UNSPEC_SSE5_UNSIGNED_CMP    151)
186    (UNSPEC_SSE5_TRUEFALSE       152)
187    (UNSPEC_SSE5_PERMUTE         153)
188    (UNSPEC_FRCZ                 154)
189    (UNSPEC_CVTPH2PS             155)
190    (UNSPEC_CVTPS2PH             156)
192    ; For AES support
193    (UNSPEC_AESENC               159)
194    (UNSPEC_AESENCLAST           160)
195    (UNSPEC_AESDEC               161)
196    (UNSPEC_AESDECLAST           162)
197    (UNSPEC_AESIMC               163)
198    (UNSPEC_AESKEYGENASSIST      164)
200    ; For PCLMUL support
201    (UNSPEC_PCLMUL               165)
203    ; For AVX support
204    (UNSPEC_PCMP                 166)
205    (UNSPEC_VPERMIL              167)
206    (UNSPEC_VPERMIL2F128         168)
207    (UNSPEC_MASKLOAD             169)
208    (UNSPEC_MASKSTORE            170)
209    (UNSPEC_CAST                 171)
210    (UNSPEC_VTESTP               172)
211   ])
213 (define_constants
214   [(UNSPECV_BLOCKAGE            0)
215    (UNSPECV_STACK_PROBE         1)
216    (UNSPECV_EMMS                2)
217    (UNSPECV_LDMXCSR             3)
218    (UNSPECV_STMXCSR             4)
219    (UNSPECV_FEMMS               5)
220    (UNSPECV_CLFLUSH             6)
221    (UNSPECV_ALIGN               7)
222    (UNSPECV_MONITOR             8)
223    (UNSPECV_MWAIT               9)
224    (UNSPECV_CMPXCHG             10)
225    (UNSPECV_XCHG                12)
226    (UNSPECV_LOCK                13)
227    (UNSPECV_PROLOGUE_USE        14)
228    (UNSPECV_CLD                 15)
229    (UNSPECV_VZEROALL            16)
230    (UNSPECV_VZEROUPPER          17)
231   ])
233 ;; Constants to represent pcomtrue/pcomfalse variants
234 (define_constants
235   [(PCOM_FALSE                  0)
236    (PCOM_TRUE                   1)
237    (COM_FALSE_S                 2)
238    (COM_FALSE_P                 3)
239    (COM_TRUE_S                  4)
240    (COM_TRUE_P                  5)
241   ])
243 ;; Constants used in the SSE5 pperm instruction
244 (define_constants
245   [(PPERM_SRC                   0x00)   /* copy source */
246    (PPERM_INVERT                0x20)   /* invert source */
247    (PPERM_REVERSE               0x40)   /* bit reverse source */
248    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
249    (PPERM_ZERO                  0x80)   /* all 0's */
250    (PPERM_ONES                  0xa0)   /* all 1's */
251    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
252    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
253    (PPERM_SRC1                  0x00)   /* use first source byte */
254    (PPERM_SRC2                  0x10)   /* use second source byte */
255    ])
257 ;; Registers by name.
258 (define_constants
259   [(AX_REG                       0)
260    (DX_REG                       1)
261    (CX_REG                       2)
262    (BX_REG                       3)
263    (SI_REG                       4)
264    (DI_REG                       5)
265    (BP_REG                       6)
266    (SP_REG                       7)
267    (ST0_REG                      8)
268    (ST1_REG                      9)
269    (ST2_REG                     10)
270    (ST3_REG                     11)
271    (ST4_REG                     12)
272    (ST5_REG                     13)
273    (ST6_REG                     14)
274    (ST7_REG                     15)
275    (FLAGS_REG                   17)
276    (FPSR_REG                    18)
277    (FPCR_REG                    19)
278    (XMM0_REG                    21)
279    (XMM1_REG                    22)
280    (XMM2_REG                    23)
281    (XMM3_REG                    24)
282    (XMM4_REG                    25)
283    (XMM5_REG                    26)
284    (XMM6_REG                    27)
285    (XMM7_REG                    28)
286    (MM0_REG                     29)
287    (MM1_REG                     30)
288    (MM2_REG                     31)
289    (MM3_REG                     32)
290    (MM4_REG                     33)
291    (MM5_REG                     34)
292    (MM6_REG                     35)
293    (MM7_REG                     36)
294    (R8_REG                      37)
295    (R9_REG                      38)
296    (R10_REG                     39)
297    (R11_REG                     40)
298    (R13_REG                     42)
299    (XMM8_REG                    45)
300    (XMM9_REG                    46)
301    (XMM10_REG                   47)
302    (XMM11_REG                   48)
303    (XMM12_REG                   49)
304    (XMM13_REG                   50)
305    (XMM14_REG                   51)
306    (XMM15_REG                   52)
307   ])
309 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
310 ;; from i386.c.
312 ;; In C guard expressions, put expressions which may be compile-time
313 ;; constants first.  This allows for better optimization.  For
314 ;; example, write "TARGET_64BIT && reload_completed", not
315 ;; "reload_completed && TARGET_64BIT".
318 ;; Processor type.
319 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,
320                     generic64,amdfam10"
321   (const (symbol_ref "ix86_schedule")))
323 ;; A basic instruction type.  Refinements due to arguments to be
324 ;; provided in other attributes.
325 (define_attr "type"
326   "other,multi,
327    alu,alu1,negnot,imov,imovx,lea,
328    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
329    icmp,test,ibr,setcc,icmov,
330    push,pop,call,callv,leave,
331    str,bitmanip,
332    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
333    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
334    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
335    ssemuladd,sse4arg,
336    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
337   (const_string "other"))
339 ;; Main data type used by the insn
340 (define_attr "mode"
341   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
342   (const_string "unknown"))
344 ;; The CPU unit operations uses.
345 (define_attr "unit" "integer,i387,sse,mmx,unknown"
346   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
347            (const_string "i387")
348          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
349                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
350                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
351            (const_string "sse")
352          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
353            (const_string "mmx")
354          (eq_attr "type" "other")
355            (const_string "unknown")]
356          (const_string "integer")))
358 ;; The (bounding maximum) length of an instruction immediate.
359 (define_attr "length_immediate" ""
360   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
361                           bitmanip")
362            (const_int 0)
363          (eq_attr "unit" "i387,sse,mmx")
364            (const_int 0)
365          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
366                           imul,icmp,push,pop")
367            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
368          (eq_attr "type" "imov,test")
369            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
370          (eq_attr "type" "call")
371            (if_then_else (match_operand 0 "constant_call_address_operand" "")
372              (const_int 4)
373              (const_int 0))
374          (eq_attr "type" "callv")
375            (if_then_else (match_operand 1 "constant_call_address_operand" "")
376              (const_int 4)
377              (const_int 0))
378          ;; We don't know the size before shorten_branches.  Expect
379          ;; the instruction to fit for better scheduling.
380          (eq_attr "type" "ibr")
381            (const_int 1)
382          ]
383          (symbol_ref "/* Update immediate_length and other attributes! */
384                       gcc_unreachable (),1")))
386 ;; The (bounding maximum) length of an instruction address.
387 (define_attr "length_address" ""
388   (cond [(eq_attr "type" "str,other,multi,fxch")
389            (const_int 0)
390          (and (eq_attr "type" "call")
391               (match_operand 0 "constant_call_address_operand" ""))
392              (const_int 0)
393          (and (eq_attr "type" "callv")
394               (match_operand 1 "constant_call_address_operand" ""))
395              (const_int 0)
396          ]
397          (symbol_ref "ix86_attr_length_address_default (insn)")))
399 ;; Set when length prefix is used.
400 (define_attr "prefix_data16" ""
401   (if_then_else (ior (eq_attr "mode" "HI")
402                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
403     (const_int 1)
404     (const_int 0)))
406 ;; Set when string REP prefix is used.
407 (define_attr "prefix_rep" ""
408   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
409     (const_int 1)
410     (const_int 0)))
412 ;; Set when 0f opcode prefix is used.
413 (define_attr "prefix_0f" ""
414   (if_then_else
415     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
416          (eq_attr "unit" "sse,mmx"))
417     (const_int 1)
418     (const_int 0)))
420 ;; Set when REX opcode prefix is used.
421 (define_attr "prefix_rex" ""
422   (cond [(and (eq_attr "mode" "DI")
423               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
424            (const_int 1)
425          (and (eq_attr "mode" "QI")
426               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
427                   (const_int 0)))
428            (const_int 1)
429          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
430              (const_int 0))
431            (const_int 1)
432         ]
433         (const_int 0)))
435 ;; There are also additional prefixes in SSSE3.
436 (define_attr "prefix_extra" "" (const_int 0))
438 ;; Prefix used: original, VEX or maybe VEX.
439 (define_attr "prefix" "orig,vex,maybe_vex"
440   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
441     (const_string "vex")
442     (const_string "orig")))
444 ;; There is a 8bit immediate for VEX.
445 (define_attr "prefix_vex_imm8" "" (const_int 0))
447 ;; VEX W bit is used.
448 (define_attr "prefix_vex_w" "" (const_int 0))
450 ;; The length of VEX prefix
451 (define_attr "length_vex" ""
452   (if_then_else (eq_attr "prefix_0f" "1")
453     (if_then_else (eq_attr "prefix_vex_w" "1")
454       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
455       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
456     (if_then_else (eq_attr "prefix_vex_w" "1")
457       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
458       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
460 ;; Set when modrm byte is used.
461 (define_attr "modrm" ""
462   (cond [(eq_attr "type" "str,leave")
463            (const_int 0)
464          (eq_attr "unit" "i387")
465            (const_int 0)
466          (and (eq_attr "type" "incdec")
467               (ior (match_operand:SI 1 "register_operand" "")
468                    (match_operand:HI 1 "register_operand" "")))
469            (const_int 0)
470          (and (eq_attr "type" "push")
471               (not (match_operand 1 "memory_operand" "")))
472            (const_int 0)
473          (and (eq_attr "type" "pop")
474               (not (match_operand 0 "memory_operand" "")))
475            (const_int 0)
476          (and (eq_attr "type" "imov")
477               (ior (and (match_operand 0 "register_operand" "")
478                         (match_operand 1 "immediate_operand" ""))
479                    (ior (and (match_operand 0 "ax_reg_operand" "")
480                              (match_operand 1 "memory_displacement_only_operand" ""))
481                         (and (match_operand 0 "memory_displacement_only_operand" "")
482                              (match_operand 1 "ax_reg_operand" "")))))
483            (const_int 0)
484          (and (eq_attr "type" "call")
485               (match_operand 0 "constant_call_address_operand" ""))
486              (const_int 0)
487          (and (eq_attr "type" "callv")
488               (match_operand 1 "constant_call_address_operand" ""))
489              (const_int 0)
490          ]
491          (const_int 1)))
493 ;; The (bounding maximum) length of an instruction in bytes.
494 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
495 ;; Later we may want to split them and compute proper length as for
496 ;; other insns.
497 (define_attr "length" ""
498   (cond [(eq_attr "type" "other,multi,fistp,frndint")
499            (const_int 16)
500          (eq_attr "type" "fcmp")
501            (const_int 4)
502          (eq_attr "unit" "i387")
503            (plus (const_int 2)
504                  (plus (attr "prefix_data16")
505                        (attr "length_address")))
506          (ior (eq_attr "prefix" "vex")
507               (and (eq_attr "prefix" "maybe_vex")
508                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
509            (plus (attr "length_vex")
510                  (plus (attr "prefix_vex_imm8")
511                        (plus (attr "modrm")
512                              (attr "length_address"))))]
513          (plus (plus (attr "modrm")
514                      (plus (attr "prefix_0f")
515                            (plus (attr "prefix_rex")
516                                  (plus (attr "prefix_extra")
517                                        (const_int 1)))))
518                (plus (attr "prefix_rep")
519                      (plus (attr "prefix_data16")
520                            (plus (attr "length_immediate")
521                                  (attr "length_address")))))))
523 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
524 ;; `store' if there is a simple memory reference therein, or `unknown'
525 ;; if the instruction is complex.
527 (define_attr "memory" "none,load,store,both,unknown"
528   (cond [(eq_attr "type" "other,multi,str")
529            (const_string "unknown")
530          (eq_attr "type" "lea,fcmov,fpspc")
531            (const_string "none")
532          (eq_attr "type" "fistp,leave")
533            (const_string "both")
534          (eq_attr "type" "frndint")
535            (const_string "load")
536          (eq_attr "type" "push")
537            (if_then_else (match_operand 1 "memory_operand" "")
538              (const_string "both")
539              (const_string "store"))
540          (eq_attr "type" "pop")
541            (if_then_else (match_operand 0 "memory_operand" "")
542              (const_string "both")
543              (const_string "load"))
544          (eq_attr "type" "setcc")
545            (if_then_else (match_operand 0 "memory_operand" "")
546              (const_string "store")
547              (const_string "none"))
548          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
549            (if_then_else (ior (match_operand 0 "memory_operand" "")
550                               (match_operand 1 "memory_operand" ""))
551              (const_string "load")
552              (const_string "none"))
553          (eq_attr "type" "ibr")
554            (if_then_else (match_operand 0 "memory_operand" "")
555              (const_string "load")
556              (const_string "none"))
557          (eq_attr "type" "call")
558            (if_then_else (match_operand 0 "constant_call_address_operand" "")
559              (const_string "none")
560              (const_string "load"))
561          (eq_attr "type" "callv")
562            (if_then_else (match_operand 1 "constant_call_address_operand" "")
563              (const_string "none")
564              (const_string "load"))
565          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
566               (match_operand 1 "memory_operand" ""))
567            (const_string "both")
568          (and (match_operand 0 "memory_operand" "")
569               (match_operand 1 "memory_operand" ""))
570            (const_string "both")
571          (match_operand 0 "memory_operand" "")
572            (const_string "store")
573          (match_operand 1 "memory_operand" "")
574            (const_string "load")
575          (and (eq_attr "type"
576                  "!alu1,negnot,ishift1,
577                    imov,imovx,icmp,test,bitmanip,
578                    fmov,fcmp,fsgn,
579                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
580                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
581               (match_operand 2 "memory_operand" ""))
582            (const_string "load")
583          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
584               (match_operand 3 "memory_operand" ""))
585            (const_string "load")
586         ]
587         (const_string "none")))
589 ;; Indicates if an instruction has both an immediate and a displacement.
591 (define_attr "imm_disp" "false,true,unknown"
592   (cond [(eq_attr "type" "other,multi")
593            (const_string "unknown")
594          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
595               (and (match_operand 0 "memory_displacement_operand" "")
596                    (match_operand 1 "immediate_operand" "")))
597            (const_string "true")
598          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
599               (and (match_operand 0 "memory_displacement_operand" "")
600                    (match_operand 2 "immediate_operand" "")))
601            (const_string "true")
602         ]
603         (const_string "false")))
605 ;; Indicates if an FP operation has an integer source.
607 (define_attr "fp_int_src" "false,true"
608   (const_string "false"))
610 ;; Defines rounding mode of an FP operation.
612 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
613   (const_string "any"))
615 ;; Describe a user's asm statement.
616 (define_asm_attributes
617   [(set_attr "length" "128")
618    (set_attr "type" "multi")])
620 ;; All integer comparison codes.
621 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
623 ;; All floating-point comparison codes.
624 (define_code_iterator fp_cond [unordered ordered
625                                uneq unge ungt unle unlt ltgt ])
627 (define_code_iterator plusminus [plus minus])
629 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
631 ;; Base name for define_insn
632 (define_code_attr plusminus_insn
633   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
634    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
636 ;; Base name for insn mnemonic.
637 (define_code_attr plusminus_mnemonic
638   [(plus "add") (ss_plus "adds") (us_plus "addus")
639    (minus "sub") (ss_minus "subs") (us_minus "subus")])
641 ;; Mark commutative operators as such in constraints.
642 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
643                         (minus "") (ss_minus "") (us_minus "")])
645 ;; Mapping of signed max and min
646 (define_code_iterator smaxmin [smax smin])
648 ;; Mapping of unsigned max and min
649 (define_code_iterator umaxmin [umax umin])
651 ;; Mapping of signed/unsigned max and min
652 (define_code_iterator maxmin [smax smin umax umin])
654 ;; Base name for integer and FP insn mnemonic
655 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
656                                  (umax "maxu") (umin "minu")])
657 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
659 ;; Mapping of parallel logic operators
660 (define_code_iterator plogic [and ior xor])
662 ;; Base name for insn mnemonic.
663 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
665 ;; Mapping of abs neg operators
666 (define_code_iterator absneg [abs neg])
668 ;; Base name for x87 insn mnemonic.
669 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
671 ;; All single word integer modes.
672 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
674 ;; Single word integer modes without QImode.
675 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
677 ;; Instruction suffix for integer modes.
678 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
680 ;; Register class for integer modes.
681 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
683 ;; Immediate operand constraint for integer modes.
684 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
686 ;; General operand predicate for integer modes.
687 (define_mode_attr general_operand
688         [(QI "general_operand")
689          (HI "general_operand")
690          (SI "general_operand")
691          (DI "x86_64_general_operand")])
693 ;; SSE and x87 SFmode and DFmode floating point modes
694 (define_mode_iterator MODEF [SF DF])
696 ;; All x87 floating point modes
697 (define_mode_iterator X87MODEF [SF DF XF])
699 ;; All integer modes handled by x87 fisttp operator.
700 (define_mode_iterator X87MODEI [HI SI DI])
702 ;; All integer modes handled by integer x87 operators.
703 (define_mode_iterator X87MODEI12 [HI SI])
705 ;; All integer modes handled by SSE cvtts?2si* operators.
706 (define_mode_iterator SSEMODEI24 [SI DI])
708 ;; SSE asm suffix for floating point modes
709 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
711 ;; SSE vector mode corresponding to a scalar mode
712 (define_mode_attr ssevecmode
713   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
715 ;; Instruction suffix for REX 64bit operators.
716 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
718 ;; This mode iterator allows :P to be used for patterns that operate on
719 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
720 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
723 ;; Scheduling descriptions
725 (include "pentium.md")
726 (include "ppro.md")
727 (include "k6.md")
728 (include "athlon.md")
729 (include "geode.md")
732 ;; Operand and operator predicates and constraints
734 (include "predicates.md")
735 (include "constraints.md")
738 ;; Compare instructions.
740 ;; All compare insns have expanders that save the operands away without
741 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
742 ;; after the cmp) will actually emit the cmpM.
744 (define_expand "cmpti"
745   [(set (reg:CC FLAGS_REG)
746         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
747                     (match_operand:TI 1 "x86_64_general_operand" "")))]
748   "TARGET_64BIT"
750   if (MEM_P (operands[0]) && MEM_P (operands[1]))
751     operands[0] = force_reg (TImode, operands[0]);
752   ix86_compare_op0 = operands[0];
753   ix86_compare_op1 = operands[1];
754   DONE;
757 (define_expand "cmpdi"
758   [(set (reg:CC FLAGS_REG)
759         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
760                     (match_operand:DI 1 "x86_64_general_operand" "")))]
761   ""
763   if (MEM_P (operands[0]) && MEM_P (operands[1]))
764     operands[0] = force_reg (DImode, operands[0]);
765   ix86_compare_op0 = operands[0];
766   ix86_compare_op1 = operands[1];
767   DONE;
770 (define_expand "cmpsi"
771   [(set (reg:CC FLAGS_REG)
772         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
773                     (match_operand:SI 1 "general_operand" "")))]
774   ""
776   if (MEM_P (operands[0]) && MEM_P (operands[1]))
777     operands[0] = force_reg (SImode, operands[0]);
778   ix86_compare_op0 = operands[0];
779   ix86_compare_op1 = operands[1];
780   DONE;
783 (define_expand "cmphi"
784   [(set (reg:CC FLAGS_REG)
785         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
786                     (match_operand:HI 1 "general_operand" "")))]
787   ""
789   if (MEM_P (operands[0]) && MEM_P (operands[1]))
790     operands[0] = force_reg (HImode, operands[0]);
791   ix86_compare_op0 = operands[0];
792   ix86_compare_op1 = operands[1];
793   DONE;
796 (define_expand "cmpqi"
797   [(set (reg:CC FLAGS_REG)
798         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
799                     (match_operand:QI 1 "general_operand" "")))]
800   "TARGET_QIMODE_MATH"
802   if (MEM_P (operands[0]) && MEM_P (operands[1]))
803     operands[0] = force_reg (QImode, operands[0]);
804   ix86_compare_op0 = operands[0];
805   ix86_compare_op1 = operands[1];
806   DONE;
809 (define_insn "cmpdi_ccno_1_rex64"
810   [(set (reg FLAGS_REG)
811         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
812                  (match_operand:DI 1 "const0_operand" "")))]
813   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
814   "@
815    test{q}\t%0, %0
816    cmp{q}\t{%1, %0|%0, %1}"
817   [(set_attr "type" "test,icmp")
818    (set_attr "length_immediate" "0,1")
819    (set_attr "mode" "DI")])
821 (define_insn "*cmpdi_minus_1_rex64"
822   [(set (reg FLAGS_REG)
823         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
824                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
825                  (const_int 0)))]
826   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
827   "cmp{q}\t{%1, %0|%0, %1}"
828   [(set_attr "type" "icmp")
829    (set_attr "mode" "DI")])
831 (define_expand "cmpdi_1_rex64"
832   [(set (reg:CC FLAGS_REG)
833         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
834                     (match_operand:DI 1 "general_operand" "")))]
835   "TARGET_64BIT"
836   "")
838 (define_insn "cmpdi_1_insn_rex64"
839   [(set (reg FLAGS_REG)
840         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
841                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
842   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
843   "cmp{q}\t{%1, %0|%0, %1}"
844   [(set_attr "type" "icmp")
845    (set_attr "mode" "DI")])
848 (define_insn "*cmpsi_ccno_1"
849   [(set (reg FLAGS_REG)
850         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
851                  (match_operand:SI 1 "const0_operand" "")))]
852   "ix86_match_ccmode (insn, CCNOmode)"
853   "@
854    test{l}\t%0, %0
855    cmp{l}\t{%1, %0|%0, %1}"
856   [(set_attr "type" "test,icmp")
857    (set_attr "length_immediate" "0,1")
858    (set_attr "mode" "SI")])
860 (define_insn "*cmpsi_minus_1"
861   [(set (reg FLAGS_REG)
862         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
863                            (match_operand:SI 1 "general_operand" "ri,mr"))
864                  (const_int 0)))]
865   "ix86_match_ccmode (insn, CCGOCmode)"
866   "cmp{l}\t{%1, %0|%0, %1}"
867   [(set_attr "type" "icmp")
868    (set_attr "mode" "SI")])
870 (define_expand "cmpsi_1"
871   [(set (reg:CC FLAGS_REG)
872         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
873                     (match_operand:SI 1 "general_operand" "")))]
874   ""
875   "")
877 (define_insn "*cmpsi_1_insn"
878   [(set (reg FLAGS_REG)
879         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
880                  (match_operand:SI 1 "general_operand" "ri,mr")))]
881   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
882     && ix86_match_ccmode (insn, CCmode)"
883   "cmp{l}\t{%1, %0|%0, %1}"
884   [(set_attr "type" "icmp")
885    (set_attr "mode" "SI")])
887 (define_insn "*cmphi_ccno_1"
888   [(set (reg FLAGS_REG)
889         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
890                  (match_operand:HI 1 "const0_operand" "")))]
891   "ix86_match_ccmode (insn, CCNOmode)"
892   "@
893    test{w}\t%0, %0
894    cmp{w}\t{%1, %0|%0, %1}"
895   [(set_attr "type" "test,icmp")
896    (set_attr "length_immediate" "0,1")
897    (set_attr "mode" "HI")])
899 (define_insn "*cmphi_minus_1"
900   [(set (reg FLAGS_REG)
901         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
902                            (match_operand:HI 1 "general_operand" "rn,mr"))
903                  (const_int 0)))]
904   "ix86_match_ccmode (insn, CCGOCmode)"
905   "cmp{w}\t{%1, %0|%0, %1}"
906   [(set_attr "type" "icmp")
907    (set_attr "mode" "HI")])
909 (define_insn "*cmphi_1"
910   [(set (reg FLAGS_REG)
911         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
912                  (match_operand:HI 1 "general_operand" "rn,mr")))]
913   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
914    && ix86_match_ccmode (insn, CCmode)"
915   "cmp{w}\t{%1, %0|%0, %1}"
916   [(set_attr "type" "icmp")
917    (set_attr "mode" "HI")])
919 (define_insn "*cmpqi_ccno_1"
920   [(set (reg FLAGS_REG)
921         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
922                  (match_operand:QI 1 "const0_operand" "")))]
923   "ix86_match_ccmode (insn, CCNOmode)"
924   "@
925    test{b}\t%0, %0
926    cmp{b}\t{$0, %0|%0, 0}"
927   [(set_attr "type" "test,icmp")
928    (set_attr "length_immediate" "0,1")
929    (set_attr "mode" "QI")])
931 (define_insn "*cmpqi_1"
932   [(set (reg FLAGS_REG)
933         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
934                  (match_operand:QI 1 "general_operand" "qn,mq")))]
935   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
936     && ix86_match_ccmode (insn, CCmode)"
937   "cmp{b}\t{%1, %0|%0, %1}"
938   [(set_attr "type" "icmp")
939    (set_attr "mode" "QI")])
941 (define_insn "*cmpqi_minus_1"
942   [(set (reg FLAGS_REG)
943         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
944                            (match_operand:QI 1 "general_operand" "qn,mq"))
945                  (const_int 0)))]
946   "ix86_match_ccmode (insn, CCGOCmode)"
947   "cmp{b}\t{%1, %0|%0, %1}"
948   [(set_attr "type" "icmp")
949    (set_attr "mode" "QI")])
951 (define_insn "*cmpqi_ext_1"
952   [(set (reg FLAGS_REG)
953         (compare
954           (match_operand:QI 0 "general_operand" "Qm")
955           (subreg:QI
956             (zero_extract:SI
957               (match_operand 1 "ext_register_operand" "Q")
958               (const_int 8)
959               (const_int 8)) 0)))]
960   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
961   "cmp{b}\t{%h1, %0|%0, %h1}"
962   [(set_attr "type" "icmp")
963    (set_attr "mode" "QI")])
965 (define_insn "*cmpqi_ext_1_rex64"
966   [(set (reg FLAGS_REG)
967         (compare
968           (match_operand:QI 0 "register_operand" "Q")
969           (subreg:QI
970             (zero_extract:SI
971               (match_operand 1 "ext_register_operand" "Q")
972               (const_int 8)
973               (const_int 8)) 0)))]
974   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
975   "cmp{b}\t{%h1, %0|%0, %h1}"
976   [(set_attr "type" "icmp")
977    (set_attr "mode" "QI")])
979 (define_insn "*cmpqi_ext_2"
980   [(set (reg FLAGS_REG)
981         (compare
982           (subreg:QI
983             (zero_extract:SI
984               (match_operand 0 "ext_register_operand" "Q")
985               (const_int 8)
986               (const_int 8)) 0)
987           (match_operand:QI 1 "const0_operand" "")))]
988   "ix86_match_ccmode (insn, CCNOmode)"
989   "test{b}\t%h0, %h0"
990   [(set_attr "type" "test")
991    (set_attr "length_immediate" "0")
992    (set_attr "mode" "QI")])
994 (define_expand "cmpqi_ext_3"
995   [(set (reg:CC FLAGS_REG)
996         (compare:CC
997           (subreg:QI
998             (zero_extract:SI
999               (match_operand 0 "ext_register_operand" "")
1000               (const_int 8)
1001               (const_int 8)) 0)
1002           (match_operand:QI 1 "general_operand" "")))]
1003   ""
1004   "")
1006 (define_insn "cmpqi_ext_3_insn"
1007   [(set (reg FLAGS_REG)
1008         (compare
1009           (subreg:QI
1010             (zero_extract:SI
1011               (match_operand 0 "ext_register_operand" "Q")
1012               (const_int 8)
1013               (const_int 8)) 0)
1014           (match_operand:QI 1 "general_operand" "Qmn")))]
1015   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1016   "cmp{b}\t{%1, %h0|%h0, %1}"
1017   [(set_attr "type" "icmp")
1018    (set_attr "mode" "QI")])
1020 (define_insn "cmpqi_ext_3_insn_rex64"
1021   [(set (reg FLAGS_REG)
1022         (compare
1023           (subreg:QI
1024             (zero_extract:SI
1025               (match_operand 0 "ext_register_operand" "Q")
1026               (const_int 8)
1027               (const_int 8)) 0)
1028           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1029   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1030   "cmp{b}\t{%1, %h0|%h0, %1}"
1031   [(set_attr "type" "icmp")
1032    (set_attr "mode" "QI")])
1034 (define_insn "*cmpqi_ext_4"
1035   [(set (reg FLAGS_REG)
1036         (compare
1037           (subreg:QI
1038             (zero_extract:SI
1039               (match_operand 0 "ext_register_operand" "Q")
1040               (const_int 8)
1041               (const_int 8)) 0)
1042           (subreg:QI
1043             (zero_extract:SI
1044               (match_operand 1 "ext_register_operand" "Q")
1045               (const_int 8)
1046               (const_int 8)) 0)))]
1047   "ix86_match_ccmode (insn, CCmode)"
1048   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1049   [(set_attr "type" "icmp")
1050    (set_attr "mode" "QI")])
1052 ;; These implement float point compares.
1053 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1054 ;; which would allow mix and match FP modes on the compares.  Which is what
1055 ;; the old patterns did, but with many more of them.
1057 (define_expand "cmpxf"
1058   [(set (reg:CC FLAGS_REG)
1059         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1060                     (match_operand:XF 1 "nonmemory_operand" "")))]
1061   "TARGET_80387"
1063   ix86_compare_op0 = operands[0];
1064   ix86_compare_op1 = operands[1];
1065   DONE;
1068 (define_expand "cmp<mode>"
1069   [(set (reg:CC FLAGS_REG)
1070         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1071                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1072   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1074   ix86_compare_op0 = operands[0];
1075   ix86_compare_op1 = operands[1];
1076   DONE;
1079 ;; FP compares, step 1:
1080 ;; Set the FP condition codes.
1082 ;; CCFPmode     compare with exceptions
1083 ;; CCFPUmode    compare with no exceptions
1085 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1086 ;; used to manage the reg stack popping would not be preserved.
1088 (define_insn "*cmpfp_0"
1089   [(set (match_operand:HI 0 "register_operand" "=a")
1090         (unspec:HI
1091           [(compare:CCFP
1092              (match_operand 1 "register_operand" "f")
1093              (match_operand 2 "const0_operand" ""))]
1094         UNSPEC_FNSTSW))]
1095   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1096    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1097   "* return output_fp_compare (insn, operands, 0, 0);"
1098   [(set_attr "type" "multi")
1099    (set_attr "unit" "i387")
1100    (set (attr "mode")
1101      (cond [(match_operand:SF 1 "" "")
1102               (const_string "SF")
1103             (match_operand:DF 1 "" "")
1104               (const_string "DF")
1105            ]
1106            (const_string "XF")))])
1108 (define_insn_and_split "*cmpfp_0_cc"
1109   [(set (reg:CCFP FLAGS_REG)
1110         (compare:CCFP
1111           (match_operand 1 "register_operand" "f")
1112           (match_operand 2 "const0_operand" "")))
1113    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1114   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1115    && TARGET_SAHF && !TARGET_CMOVE
1116    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1117   "#"
1118   "&& reload_completed"
1119   [(set (match_dup 0)
1120         (unspec:HI
1121           [(compare:CCFP (match_dup 1)(match_dup 2))]
1122         UNSPEC_FNSTSW))
1123    (set (reg:CC FLAGS_REG)
1124         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1125   ""
1126   [(set_attr "type" "multi")
1127    (set_attr "unit" "i387")
1128    (set (attr "mode")
1129      (cond [(match_operand:SF 1 "" "")
1130               (const_string "SF")
1131             (match_operand:DF 1 "" "")
1132               (const_string "DF")
1133            ]
1134            (const_string "XF")))])
1136 (define_insn "*cmpfp_xf"
1137   [(set (match_operand:HI 0 "register_operand" "=a")
1138         (unspec:HI
1139           [(compare:CCFP
1140              (match_operand:XF 1 "register_operand" "f")
1141              (match_operand:XF 2 "register_operand" "f"))]
1142           UNSPEC_FNSTSW))]
1143   "TARGET_80387"
1144   "* return output_fp_compare (insn, operands, 0, 0);"
1145   [(set_attr "type" "multi")
1146    (set_attr "unit" "i387")
1147    (set_attr "mode" "XF")])
1149 (define_insn_and_split "*cmpfp_xf_cc"
1150   [(set (reg:CCFP FLAGS_REG)
1151         (compare:CCFP
1152           (match_operand:XF 1 "register_operand" "f")
1153           (match_operand:XF 2 "register_operand" "f")))
1154    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1155   "TARGET_80387
1156    && TARGET_SAHF && !TARGET_CMOVE"
1157   "#"
1158   "&& reload_completed"
1159   [(set (match_dup 0)
1160         (unspec:HI
1161           [(compare:CCFP (match_dup 1)(match_dup 2))]
1162         UNSPEC_FNSTSW))
1163    (set (reg:CC FLAGS_REG)
1164         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1165   ""
1166   [(set_attr "type" "multi")
1167    (set_attr "unit" "i387")
1168    (set_attr "mode" "XF")])
1170 (define_insn "*cmpfp_<mode>"
1171   [(set (match_operand:HI 0 "register_operand" "=a")
1172         (unspec:HI
1173           [(compare:CCFP
1174              (match_operand:MODEF 1 "register_operand" "f")
1175              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1176           UNSPEC_FNSTSW))]
1177   "TARGET_80387"
1178   "* return output_fp_compare (insn, operands, 0, 0);"
1179   [(set_attr "type" "multi")
1180    (set_attr "unit" "i387")
1181    (set_attr "mode" "<MODE>")])
1183 (define_insn_and_split "*cmpfp_<mode>_cc"
1184   [(set (reg:CCFP FLAGS_REG)
1185         (compare:CCFP
1186           (match_operand:MODEF 1 "register_operand" "f")
1187           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1188    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1189   "TARGET_80387
1190    && TARGET_SAHF && !TARGET_CMOVE"
1191   "#"
1192   "&& reload_completed"
1193   [(set (match_dup 0)
1194         (unspec:HI
1195           [(compare:CCFP (match_dup 1)(match_dup 2))]
1196         UNSPEC_FNSTSW))
1197    (set (reg:CC FLAGS_REG)
1198         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1199   ""
1200   [(set_attr "type" "multi")
1201    (set_attr "unit" "i387")
1202    (set_attr "mode" "<MODE>")])
1204 (define_insn "*cmpfp_u"
1205   [(set (match_operand:HI 0 "register_operand" "=a")
1206         (unspec:HI
1207           [(compare:CCFPU
1208              (match_operand 1 "register_operand" "f")
1209              (match_operand 2 "register_operand" "f"))]
1210           UNSPEC_FNSTSW))]
1211   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1212    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1213   "* return output_fp_compare (insn, operands, 0, 1);"
1214   [(set_attr "type" "multi")
1215    (set_attr "unit" "i387")
1216    (set (attr "mode")
1217      (cond [(match_operand:SF 1 "" "")
1218               (const_string "SF")
1219             (match_operand:DF 1 "" "")
1220               (const_string "DF")
1221            ]
1222            (const_string "XF")))])
1224 (define_insn_and_split "*cmpfp_u_cc"
1225   [(set (reg:CCFPU FLAGS_REG)
1226         (compare:CCFPU
1227           (match_operand 1 "register_operand" "f")
1228           (match_operand 2 "register_operand" "f")))
1229    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1230   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1231    && TARGET_SAHF && !TARGET_CMOVE
1232    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1233   "#"
1234   "&& reload_completed"
1235   [(set (match_dup 0)
1236         (unspec:HI
1237           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1238         UNSPEC_FNSTSW))
1239    (set (reg:CC FLAGS_REG)
1240         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1241   ""
1242   [(set_attr "type" "multi")
1243    (set_attr "unit" "i387")
1244    (set (attr "mode")
1245      (cond [(match_operand:SF 1 "" "")
1246               (const_string "SF")
1247             (match_operand:DF 1 "" "")
1248               (const_string "DF")
1249            ]
1250            (const_string "XF")))])
1252 (define_insn "*cmpfp_<mode>"
1253   [(set (match_operand:HI 0 "register_operand" "=a")
1254         (unspec:HI
1255           [(compare:CCFP
1256              (match_operand 1 "register_operand" "f")
1257              (match_operator 3 "float_operator"
1258                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1259           UNSPEC_FNSTSW))]
1260   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1261    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1262    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1263   "* return output_fp_compare (insn, operands, 0, 0);"
1264   [(set_attr "type" "multi")
1265    (set_attr "unit" "i387")
1266    (set_attr "fp_int_src" "true")
1267    (set_attr "mode" "<MODE>")])
1269 (define_insn_and_split "*cmpfp_<mode>_cc"
1270   [(set (reg:CCFP FLAGS_REG)
1271         (compare:CCFP
1272           (match_operand 1 "register_operand" "f")
1273           (match_operator 3 "float_operator"
1274             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1275    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1276   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1277    && TARGET_SAHF && !TARGET_CMOVE
1278    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1279    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1280   "#"
1281   "&& reload_completed"
1282   [(set (match_dup 0)
1283         (unspec:HI
1284           [(compare:CCFP
1285              (match_dup 1)
1286              (match_op_dup 3 [(match_dup 2)]))]
1287         UNSPEC_FNSTSW))
1288    (set (reg:CC FLAGS_REG)
1289         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1290   ""
1291   [(set_attr "type" "multi")
1292    (set_attr "unit" "i387")
1293    (set_attr "fp_int_src" "true")
1294    (set_attr "mode" "<MODE>")])
1296 ;; FP compares, step 2
1297 ;; Move the fpsw to ax.
1299 (define_insn "x86_fnstsw_1"
1300   [(set (match_operand:HI 0 "register_operand" "=a")
1301         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1302   "TARGET_80387"
1303   "fnstsw\t%0"
1304   [(set_attr "length" "2")
1305    (set_attr "mode" "SI")
1306    (set_attr "unit" "i387")])
1308 ;; FP compares, step 3
1309 ;; Get ax into flags, general case.
1311 (define_insn "x86_sahf_1"
1312   [(set (reg:CC FLAGS_REG)
1313         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1314                    UNSPEC_SAHF))]
1315   "TARGET_SAHF"
1317 #ifdef HAVE_AS_IX86_SAHF
1318   return "sahf";
1319 #else
1320   return ".byte\t0x9e";
1321 #endif
1323   [(set_attr "length" "1")
1324    (set_attr "athlon_decode" "vector")
1325    (set_attr "amdfam10_decode" "direct")
1326    (set_attr "mode" "SI")])
1328 ;; Pentium Pro can do steps 1 through 3 in one go.
1329 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1330 (define_insn "*cmpfp_i_mixed"
1331   [(set (reg:CCFP FLAGS_REG)
1332         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1333                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1334   "TARGET_MIX_SSE_I387
1335    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1336    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1337   "* return output_fp_compare (insn, operands, 1, 0);"
1338   [(set_attr "type" "fcmp,ssecomi")
1339    (set_attr "prefix" "orig,maybe_vex")
1340    (set (attr "mode")
1341      (if_then_else (match_operand:SF 1 "" "")
1342         (const_string "SF")
1343         (const_string "DF")))
1344    (set_attr "athlon_decode" "vector")
1345    (set_attr "amdfam10_decode" "direct")])
1347 (define_insn "*cmpfp_i_sse"
1348   [(set (reg:CCFP FLAGS_REG)
1349         (compare:CCFP (match_operand 0 "register_operand" "x")
1350                       (match_operand 1 "nonimmediate_operand" "xm")))]
1351   "TARGET_SSE_MATH
1352    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1353    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1354   "* return output_fp_compare (insn, operands, 1, 0);"
1355   [(set_attr "type" "ssecomi")
1356    (set_attr "prefix" "maybe_vex")
1357    (set (attr "mode")
1358      (if_then_else (match_operand:SF 1 "" "")
1359         (const_string "SF")
1360         (const_string "DF")))
1361    (set_attr "athlon_decode" "vector")
1362    (set_attr "amdfam10_decode" "direct")])
1364 (define_insn "*cmpfp_i_i387"
1365   [(set (reg:CCFP FLAGS_REG)
1366         (compare:CCFP (match_operand 0 "register_operand" "f")
1367                       (match_operand 1 "register_operand" "f")))]
1368   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1369    && TARGET_CMOVE
1370    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1371    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1372   "* return output_fp_compare (insn, operands, 1, 0);"
1373   [(set_attr "type" "fcmp")
1374    (set (attr "mode")
1375      (cond [(match_operand:SF 1 "" "")
1376               (const_string "SF")
1377             (match_operand:DF 1 "" "")
1378               (const_string "DF")
1379            ]
1380            (const_string "XF")))
1381    (set_attr "athlon_decode" "vector")
1382    (set_attr "amdfam10_decode" "direct")])
1384 (define_insn "*cmpfp_iu_mixed"
1385   [(set (reg:CCFPU FLAGS_REG)
1386         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1387                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1388   "TARGET_MIX_SSE_I387
1389    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1390    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1391   "* return output_fp_compare (insn, operands, 1, 1);"
1392   [(set_attr "type" "fcmp,ssecomi")
1393    (set_attr "prefix" "orig,maybe_vex")
1394    (set (attr "mode")
1395      (if_then_else (match_operand:SF 1 "" "")
1396         (const_string "SF")
1397         (const_string "DF")))
1398    (set_attr "athlon_decode" "vector")
1399    (set_attr "amdfam10_decode" "direct")])
1401 (define_insn "*cmpfp_iu_sse"
1402   [(set (reg:CCFPU FLAGS_REG)
1403         (compare:CCFPU (match_operand 0 "register_operand" "x")
1404                        (match_operand 1 "nonimmediate_operand" "xm")))]
1405   "TARGET_SSE_MATH
1406    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1407    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1408   "* return output_fp_compare (insn, operands, 1, 1);"
1409   [(set_attr "type" "ssecomi")
1410    (set_attr "prefix" "maybe_vex")
1411    (set (attr "mode")
1412      (if_then_else (match_operand:SF 1 "" "")
1413         (const_string "SF")
1414         (const_string "DF")))
1415    (set_attr "athlon_decode" "vector")
1416    (set_attr "amdfam10_decode" "direct")])
1418 (define_insn "*cmpfp_iu_387"
1419   [(set (reg:CCFPU FLAGS_REG)
1420         (compare:CCFPU (match_operand 0 "register_operand" "f")
1421                        (match_operand 1 "register_operand" "f")))]
1422   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1423    && TARGET_CMOVE
1424    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1425    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1426   "* return output_fp_compare (insn, operands, 1, 1);"
1427   [(set_attr "type" "fcmp")
1428    (set (attr "mode")
1429      (cond [(match_operand:SF 1 "" "")
1430               (const_string "SF")
1431             (match_operand:DF 1 "" "")
1432               (const_string "DF")
1433            ]
1434            (const_string "XF")))
1435    (set_attr "athlon_decode" "vector")
1436    (set_attr "amdfam10_decode" "direct")])
1438 ;; Move instructions.
1440 ;; General case of fullword move.
1442 (define_expand "movsi"
1443   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1444         (match_operand:SI 1 "general_operand" ""))]
1445   ""
1446   "ix86_expand_move (SImode, operands); DONE;")
1448 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1449 ;; general_operand.
1451 ;; %%% We don't use a post-inc memory reference because x86 is not a
1452 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1453 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1454 ;; targets without our curiosities, and it is just as easy to represent
1455 ;; this differently.
1457 (define_insn "*pushsi2"
1458   [(set (match_operand:SI 0 "push_operand" "=<")
1459         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1460   "!TARGET_64BIT"
1461   "push{l}\t%1"
1462   [(set_attr "type" "push")
1463    (set_attr "mode" "SI")])
1465 ;; For 64BIT abi we always round up to 8 bytes.
1466 (define_insn "*pushsi2_rex64"
1467   [(set (match_operand:SI 0 "push_operand" "=X")
1468         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1469   "TARGET_64BIT"
1470   "push{q}\t%q1"
1471   [(set_attr "type" "push")
1472    (set_attr "mode" "SI")])
1474 (define_insn "*pushsi2_prologue"
1475   [(set (match_operand:SI 0 "push_operand" "=<")
1476         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1477    (clobber (mem:BLK (scratch)))]
1478   "!TARGET_64BIT"
1479   "push{l}\t%1"
1480   [(set_attr "type" "push")
1481    (set_attr "mode" "SI")])
1483 (define_insn "*popsi1_epilogue"
1484   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1485         (mem:SI (reg:SI SP_REG)))
1486    (set (reg:SI SP_REG)
1487         (plus:SI (reg:SI SP_REG) (const_int 4)))
1488    (clobber (mem:BLK (scratch)))]
1489   "!TARGET_64BIT"
1490   "pop{l}\t%0"
1491   [(set_attr "type" "pop")
1492    (set_attr "mode" "SI")])
1494 (define_insn "popsi1"
1495   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1496         (mem:SI (reg:SI SP_REG)))
1497    (set (reg:SI SP_REG)
1498         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1499   "!TARGET_64BIT"
1500   "pop{l}\t%0"
1501   [(set_attr "type" "pop")
1502    (set_attr "mode" "SI")])
1504 (define_insn "*movsi_xor"
1505   [(set (match_operand:SI 0 "register_operand" "=r")
1506         (match_operand:SI 1 "const0_operand" ""))
1507    (clobber (reg:CC FLAGS_REG))]
1508   "reload_completed"
1509   "xor{l}\t%0, %0"
1510   [(set_attr "type" "alu1")
1511    (set_attr "mode" "SI")
1512    (set_attr "length_immediate" "0")])
1514 (define_insn "*movsi_or"
1515   [(set (match_operand:SI 0 "register_operand" "=r")
1516         (match_operand:SI 1 "immediate_operand" "i"))
1517    (clobber (reg:CC FLAGS_REG))]
1518   "reload_completed
1519    && operands[1] == constm1_rtx"
1521   operands[1] = constm1_rtx;
1522   return "or{l}\t{%1, %0|%0, %1}";
1524   [(set_attr "type" "alu1")
1525    (set_attr "mode" "SI")
1526    (set_attr "length_immediate" "1")])
1528 (define_insn "*movsi_1"
1529   [(set (match_operand:SI 0 "nonimmediate_operand"
1530                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1531         (match_operand:SI 1 "general_operand"
1532                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1533   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1535   switch (get_attr_type (insn))
1536     {
1537     case TYPE_SSELOG1:
1538       if (get_attr_mode (insn) == MODE_TI)
1539         return "%vpxor\t%0, %d0";
1540       return "%vxorps\t%0, %d0";
1542     case TYPE_SSEMOV:
1543       switch (get_attr_mode (insn))
1544         {
1545         case MODE_TI:
1546           return "%vmovdqa\t{%1, %0|%0, %1}";
1547         case MODE_V4SF:
1548           return "%vmovaps\t{%1, %0|%0, %1}";
1549         case MODE_SI:
1550           return "%vmovd\t{%1, %0|%0, %1}";
1551         case MODE_SF:
1552           return "%vmovss\t{%1, %0|%0, %1}";
1553         default:
1554           gcc_unreachable ();
1555         }
1557     case TYPE_MMX:
1558       return "pxor\t%0, %0";
1560     case TYPE_MMXMOV:
1561       if (get_attr_mode (insn) == MODE_DI)
1562         return "movq\t{%1, %0|%0, %1}";
1563       return "movd\t{%1, %0|%0, %1}";
1565     case TYPE_LEA:
1566       return "lea{l}\t{%1, %0|%0, %1}";
1568     default:
1569       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1570       return "mov{l}\t{%1, %0|%0, %1}";
1571     }
1573   [(set (attr "type")
1574      (cond [(eq_attr "alternative" "2")
1575               (const_string "mmx")
1576             (eq_attr "alternative" "3,4,5")
1577               (const_string "mmxmov")
1578             (eq_attr "alternative" "6")
1579               (const_string "sselog1")
1580             (eq_attr "alternative" "7,8,9,10,11")
1581               (const_string "ssemov")
1582             (match_operand:DI 1 "pic_32bit_operand" "")
1583               (const_string "lea")
1584            ]
1585            (const_string "imov")))
1586    (set (attr "prefix")
1587      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1588        (const_string "orig")
1589        (const_string "maybe_vex")))
1590    (set (attr "mode")
1591      (cond [(eq_attr "alternative" "2,3")
1592               (const_string "DI")
1593             (eq_attr "alternative" "6,7")
1594               (if_then_else
1595                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1596                 (const_string "V4SF")
1597                 (const_string "TI"))
1598             (and (eq_attr "alternative" "8,9,10,11")
1599                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1600               (const_string "SF")
1601            ]
1602            (const_string "SI")))])
1604 ;; Stores and loads of ax to arbitrary constant address.
1605 ;; We fake an second form of instruction to force reload to load address
1606 ;; into register when rax is not available
1607 (define_insn "*movabssi_1_rex64"
1608   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1609         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1610   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1611   "@
1612    movabs{l}\t{%1, %P0|%P0, %1}
1613    mov{l}\t{%1, %a0|%a0, %1}"
1614   [(set_attr "type" "imov")
1615    (set_attr "modrm" "0,*")
1616    (set_attr "length_address" "8,0")
1617    (set_attr "length_immediate" "0,*")
1618    (set_attr "memory" "store")
1619    (set_attr "mode" "SI")])
1621 (define_insn "*movabssi_2_rex64"
1622   [(set (match_operand:SI 0 "register_operand" "=a,r")
1623         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1624   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1625   "@
1626    movabs{l}\t{%P1, %0|%0, %P1}
1627    mov{l}\t{%a1, %0|%0, %a1}"
1628   [(set_attr "type" "imov")
1629    (set_attr "modrm" "0,*")
1630    (set_attr "length_address" "8,0")
1631    (set_attr "length_immediate" "0")
1632    (set_attr "memory" "load")
1633    (set_attr "mode" "SI")])
1635 (define_insn "*swapsi"
1636   [(set (match_operand:SI 0 "register_operand" "+r")
1637         (match_operand:SI 1 "register_operand" "+r"))
1638    (set (match_dup 1)
1639         (match_dup 0))]
1640   ""
1641   "xchg{l}\t%1, %0"
1642   [(set_attr "type" "imov")
1643    (set_attr "mode" "SI")
1644    (set_attr "pent_pair" "np")
1645    (set_attr "athlon_decode" "vector")
1646    (set_attr "amdfam10_decode" "double")])
1648 (define_expand "movhi"
1649   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1650         (match_operand:HI 1 "general_operand" ""))]
1651   ""
1652   "ix86_expand_move (HImode, operands); DONE;")
1654 (define_insn "*pushhi2"
1655   [(set (match_operand:HI 0 "push_operand" "=X")
1656         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1657   "!TARGET_64BIT"
1658   "push{l}\t%k1"
1659   [(set_attr "type" "push")
1660    (set_attr "mode" "SI")])
1662 ;; For 64BIT abi we always round up to 8 bytes.
1663 (define_insn "*pushhi2_rex64"
1664   [(set (match_operand:HI 0 "push_operand" "=X")
1665         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1666   "TARGET_64BIT"
1667   "push{q}\t%q1"
1668   [(set_attr "type" "push")
1669    (set_attr "mode" "DI")])
1671 (define_insn "*movhi_1"
1672   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1673         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1674   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1676   switch (get_attr_type (insn))
1677     {
1678     case TYPE_IMOVX:
1679       /* movzwl is faster than movw on p2 due to partial word stalls,
1680          though not as fast as an aligned movl.  */
1681       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1682     default:
1683       if (get_attr_mode (insn) == MODE_SI)
1684         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1685       else
1686         return "mov{w}\t{%1, %0|%0, %1}";
1687     }
1689   [(set (attr "type")
1690      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1691               (const_string "imov")
1692             (and (eq_attr "alternative" "0")
1693                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1694                           (const_int 0))
1695                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1696                           (const_int 0))))
1697               (const_string "imov")
1698             (and (eq_attr "alternative" "1,2")
1699                  (match_operand:HI 1 "aligned_operand" ""))
1700               (const_string "imov")
1701             (and (ne (symbol_ref "TARGET_MOVX")
1702                      (const_int 0))
1703                  (eq_attr "alternative" "0,2"))
1704               (const_string "imovx")
1705            ]
1706            (const_string "imov")))
1707     (set (attr "mode")
1708       (cond [(eq_attr "type" "imovx")
1709                (const_string "SI")
1710              (and (eq_attr "alternative" "1,2")
1711                   (match_operand:HI 1 "aligned_operand" ""))
1712                (const_string "SI")
1713              (and (eq_attr "alternative" "0")
1714                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1715                            (const_int 0))
1716                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1717                            (const_int 0))))
1718                (const_string "SI")
1719             ]
1720             (const_string "HI")))])
1722 ;; Stores and loads of ax to arbitrary constant address.
1723 ;; We fake an second form of instruction to force reload to load address
1724 ;; into register when rax is not available
1725 (define_insn "*movabshi_1_rex64"
1726   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1727         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1728   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1729   "@
1730    movabs{w}\t{%1, %P0|%P0, %1}
1731    mov{w}\t{%1, %a0|%a0, %1}"
1732   [(set_attr "type" "imov")
1733    (set_attr "modrm" "0,*")
1734    (set_attr "length_address" "8,0")
1735    (set_attr "length_immediate" "0,*")
1736    (set_attr "memory" "store")
1737    (set_attr "mode" "HI")])
1739 (define_insn "*movabshi_2_rex64"
1740   [(set (match_operand:HI 0 "register_operand" "=a,r")
1741         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1742   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1743   "@
1744    movabs{w}\t{%P1, %0|%0, %P1}
1745    mov{w}\t{%a1, %0|%0, %a1}"
1746   [(set_attr "type" "imov")
1747    (set_attr "modrm" "0,*")
1748    (set_attr "length_address" "8,0")
1749    (set_attr "length_immediate" "0")
1750    (set_attr "memory" "load")
1751    (set_attr "mode" "HI")])
1753 (define_insn "*swaphi_1"
1754   [(set (match_operand:HI 0 "register_operand" "+r")
1755         (match_operand:HI 1 "register_operand" "+r"))
1756    (set (match_dup 1)
1757         (match_dup 0))]
1758   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1759   "xchg{l}\t%k1, %k0"
1760   [(set_attr "type" "imov")
1761    (set_attr "mode" "SI")
1762    (set_attr "pent_pair" "np")
1763    (set_attr "athlon_decode" "vector")
1764    (set_attr "amdfam10_decode" "double")])
1766 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1767 (define_insn "*swaphi_2"
1768   [(set (match_operand:HI 0 "register_operand" "+r")
1769         (match_operand:HI 1 "register_operand" "+r"))
1770    (set (match_dup 1)
1771         (match_dup 0))]
1772   "TARGET_PARTIAL_REG_STALL"
1773   "xchg{w}\t%1, %0"
1774   [(set_attr "type" "imov")
1775    (set_attr "mode" "HI")
1776    (set_attr "pent_pair" "np")
1777    (set_attr "athlon_decode" "vector")])
1779 (define_expand "movstricthi"
1780   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1781         (match_operand:HI 1 "general_operand" ""))]
1782   ""
1784   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1785     FAIL;
1786   /* Don't generate memory->memory moves, go through a register */
1787   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1788     operands[1] = force_reg (HImode, operands[1]);
1791 (define_insn "*movstricthi_1"
1792   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1793         (match_operand:HI 1 "general_operand" "rn,m"))]
1794   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1795    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1796   "mov{w}\t{%1, %0|%0, %1}"
1797   [(set_attr "type" "imov")
1798    (set_attr "mode" "HI")])
1800 (define_insn "*movstricthi_xor"
1801   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1802         (match_operand:HI 1 "const0_operand" ""))
1803    (clobber (reg:CC FLAGS_REG))]
1804   "reload_completed"
1805   "xor{w}\t%0, %0"
1806   [(set_attr "type" "alu1")
1807    (set_attr "mode" "HI")
1808    (set_attr "length_immediate" "0")])
1810 (define_expand "movqi"
1811   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1812         (match_operand:QI 1 "general_operand" ""))]
1813   ""
1814   "ix86_expand_move (QImode, operands); DONE;")
1816 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1817 ;; "push a byte".  But actually we use pushl, which has the effect
1818 ;; of rounding the amount pushed up to a word.
1820 (define_insn "*pushqi2"
1821   [(set (match_operand:QI 0 "push_operand" "=X")
1822         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1823   "!TARGET_64BIT"
1824   "push{l}\t%k1"
1825   [(set_attr "type" "push")
1826    (set_attr "mode" "SI")])
1828 ;; For 64BIT abi we always round up to 8 bytes.
1829 (define_insn "*pushqi2_rex64"
1830   [(set (match_operand:QI 0 "push_operand" "=X")
1831         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1832   "TARGET_64BIT"
1833   "push{q}\t%q1"
1834   [(set_attr "type" "push")
1835    (set_attr "mode" "DI")])
1837 ;; Situation is quite tricky about when to choose full sized (SImode) move
1838 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1839 ;; partial register dependency machines (such as AMD Athlon), where QImode
1840 ;; moves issue extra dependency and for partial register stalls machines
1841 ;; that don't use QImode patterns (and QImode move cause stall on the next
1842 ;; instruction).
1844 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1845 ;; register stall machines with, where we use QImode instructions, since
1846 ;; partial register stall can be caused there.  Then we use movzx.
1847 (define_insn "*movqi_1"
1848   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1849         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1850   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1852   switch (get_attr_type (insn))
1853     {
1854     case TYPE_IMOVX:
1855       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1856       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1857     default:
1858       if (get_attr_mode (insn) == MODE_SI)
1859         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1860       else
1861         return "mov{b}\t{%1, %0|%0, %1}";
1862     }
1864   [(set (attr "type")
1865      (cond [(and (eq_attr "alternative" "5")
1866                  (not (match_operand:QI 1 "aligned_operand" "")))
1867               (const_string "imovx")
1868             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1869               (const_string "imov")
1870             (and (eq_attr "alternative" "3")
1871                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1872                           (const_int 0))
1873                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1874                           (const_int 0))))
1875               (const_string "imov")
1876             (eq_attr "alternative" "3,5")
1877               (const_string "imovx")
1878             (and (ne (symbol_ref "TARGET_MOVX")
1879                      (const_int 0))
1880                  (eq_attr "alternative" "2"))
1881               (const_string "imovx")
1882            ]
1883            (const_string "imov")))
1884    (set (attr "mode")
1885       (cond [(eq_attr "alternative" "3,4,5")
1886                (const_string "SI")
1887              (eq_attr "alternative" "6")
1888                (const_string "QI")
1889              (eq_attr "type" "imovx")
1890                (const_string "SI")
1891              (and (eq_attr "type" "imov")
1892                   (and (eq_attr "alternative" "0,1")
1893                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1894                                 (const_int 0))
1895                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1896                                      (const_int 0))
1897                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1898                                      (const_int 0))))))
1899                (const_string "SI")
1900              ;; Avoid partial register stalls when not using QImode arithmetic
1901              (and (eq_attr "type" "imov")
1902                   (and (eq_attr "alternative" "0,1")
1903                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1904                                 (const_int 0))
1905                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1906                                 (const_int 0)))))
1907                (const_string "SI")
1908            ]
1909            (const_string "QI")))])
1911 (define_insn "*swapqi_1"
1912   [(set (match_operand:QI 0 "register_operand" "+r")
1913         (match_operand:QI 1 "register_operand" "+r"))
1914    (set (match_dup 1)
1915         (match_dup 0))]
1916   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1917   "xchg{l}\t%k1, %k0"
1918   [(set_attr "type" "imov")
1919    (set_attr "mode" "SI")
1920    (set_attr "pent_pair" "np")
1921    (set_attr "athlon_decode" "vector")
1922    (set_attr "amdfam10_decode" "vector")])
1924 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1925 (define_insn "*swapqi_2"
1926   [(set (match_operand:QI 0 "register_operand" "+q")
1927         (match_operand:QI 1 "register_operand" "+q"))
1928    (set (match_dup 1)
1929         (match_dup 0))]
1930   "TARGET_PARTIAL_REG_STALL"
1931   "xchg{b}\t%1, %0"
1932   [(set_attr "type" "imov")
1933    (set_attr "mode" "QI")
1934    (set_attr "pent_pair" "np")
1935    (set_attr "athlon_decode" "vector")])
1937 (define_expand "movstrictqi"
1938   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1939         (match_operand:QI 1 "general_operand" ""))]
1940   ""
1942   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1943     FAIL;
1944   /* Don't generate memory->memory moves, go through a register.  */
1945   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1946     operands[1] = force_reg (QImode, operands[1]);
1949 (define_insn "*movstrictqi_1"
1950   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1951         (match_operand:QI 1 "general_operand" "*qn,m"))]
1952   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1953    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1954   "mov{b}\t{%1, %0|%0, %1}"
1955   [(set_attr "type" "imov")
1956    (set_attr "mode" "QI")])
1958 (define_insn "*movstrictqi_xor"
1959   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1960         (match_operand:QI 1 "const0_operand" ""))
1961    (clobber (reg:CC FLAGS_REG))]
1962   "reload_completed"
1963   "xor{b}\t%0, %0"
1964   [(set_attr "type" "alu1")
1965    (set_attr "mode" "QI")
1966    (set_attr "length_immediate" "0")])
1968 (define_insn "*movsi_extv_1"
1969   [(set (match_operand:SI 0 "register_operand" "=R")
1970         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1971                          (const_int 8)
1972                          (const_int 8)))]
1973   ""
1974   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1975   [(set_attr "type" "imovx")
1976    (set_attr "mode" "SI")])
1978 (define_insn "*movhi_extv_1"
1979   [(set (match_operand:HI 0 "register_operand" "=R")
1980         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1981                          (const_int 8)
1982                          (const_int 8)))]
1983   ""
1984   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1985   [(set_attr "type" "imovx")
1986    (set_attr "mode" "SI")])
1988 (define_insn "*movqi_extv_1"
1989   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1990         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1991                          (const_int 8)
1992                          (const_int 8)))]
1993   "!TARGET_64BIT"
1995   switch (get_attr_type (insn))
1996     {
1997     case TYPE_IMOVX:
1998       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1999     default:
2000       return "mov{b}\t{%h1, %0|%0, %h1}";
2001     }
2003   [(set (attr "type")
2004      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2005                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2006                              (ne (symbol_ref "TARGET_MOVX")
2007                                  (const_int 0))))
2008         (const_string "imovx")
2009         (const_string "imov")))
2010    (set (attr "mode")
2011      (if_then_else (eq_attr "type" "imovx")
2012         (const_string "SI")
2013         (const_string "QI")))])
2015 (define_insn "*movqi_extv_1_rex64"
2016   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2017         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2018                          (const_int 8)
2019                          (const_int 8)))]
2020   "TARGET_64BIT"
2022   switch (get_attr_type (insn))
2023     {
2024     case TYPE_IMOVX:
2025       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2026     default:
2027       return "mov{b}\t{%h1, %0|%0, %h1}";
2028     }
2030   [(set (attr "type")
2031      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2032                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2033                              (ne (symbol_ref "TARGET_MOVX")
2034                                  (const_int 0))))
2035         (const_string "imovx")
2036         (const_string "imov")))
2037    (set (attr "mode")
2038      (if_then_else (eq_attr "type" "imovx")
2039         (const_string "SI")
2040         (const_string "QI")))])
2042 ;; Stores and loads of ax to arbitrary constant address.
2043 ;; We fake an second form of instruction to force reload to load address
2044 ;; into register when rax is not available
2045 (define_insn "*movabsqi_1_rex64"
2046   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2047         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2048   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2049   "@
2050    movabs{b}\t{%1, %P0|%P0, %1}
2051    mov{b}\t{%1, %a0|%a0, %1}"
2052   [(set_attr "type" "imov")
2053    (set_attr "modrm" "0,*")
2054    (set_attr "length_address" "8,0")
2055    (set_attr "length_immediate" "0,*")
2056    (set_attr "memory" "store")
2057    (set_attr "mode" "QI")])
2059 (define_insn "*movabsqi_2_rex64"
2060   [(set (match_operand:QI 0 "register_operand" "=a,r")
2061         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2062   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2063   "@
2064    movabs{b}\t{%P1, %0|%0, %P1}
2065    mov{b}\t{%a1, %0|%0, %a1}"
2066   [(set_attr "type" "imov")
2067    (set_attr "modrm" "0,*")
2068    (set_attr "length_address" "8,0")
2069    (set_attr "length_immediate" "0")
2070    (set_attr "memory" "load")
2071    (set_attr "mode" "QI")])
2073 (define_insn "*movdi_extzv_1"
2074   [(set (match_operand:DI 0 "register_operand" "=R")
2075         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2076                          (const_int 8)
2077                          (const_int 8)))]
2078   "TARGET_64BIT"
2079   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2080   [(set_attr "type" "imovx")
2081    (set_attr "mode" "DI")])
2083 (define_insn "*movsi_extzv_1"
2084   [(set (match_operand:SI 0 "register_operand" "=R")
2085         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2086                          (const_int 8)
2087                          (const_int 8)))]
2088   ""
2089   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2090   [(set_attr "type" "imovx")
2091    (set_attr "mode" "SI")])
2093 (define_insn "*movqi_extzv_2"
2094   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2095         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2096                                     (const_int 8)
2097                                     (const_int 8)) 0))]
2098   "!TARGET_64BIT"
2100   switch (get_attr_type (insn))
2101     {
2102     case TYPE_IMOVX:
2103       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2104     default:
2105       return "mov{b}\t{%h1, %0|%0, %h1}";
2106     }
2108   [(set (attr "type")
2109      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2110                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2111                              (ne (symbol_ref "TARGET_MOVX")
2112                                  (const_int 0))))
2113         (const_string "imovx")
2114         (const_string "imov")))
2115    (set (attr "mode")
2116      (if_then_else (eq_attr "type" "imovx")
2117         (const_string "SI")
2118         (const_string "QI")))])
2120 (define_insn "*movqi_extzv_2_rex64"
2121   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2122         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2123                                     (const_int 8)
2124                                     (const_int 8)) 0))]
2125   "TARGET_64BIT"
2127   switch (get_attr_type (insn))
2128     {
2129     case TYPE_IMOVX:
2130       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2131     default:
2132       return "mov{b}\t{%h1, %0|%0, %h1}";
2133     }
2135   [(set (attr "type")
2136      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2137                         (ne (symbol_ref "TARGET_MOVX")
2138                             (const_int 0)))
2139         (const_string "imovx")
2140         (const_string "imov")))
2141    (set (attr "mode")
2142      (if_then_else (eq_attr "type" "imovx")
2143         (const_string "SI")
2144         (const_string "QI")))])
2146 (define_insn "movsi_insv_1"
2147   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2148                          (const_int 8)
2149                          (const_int 8))
2150         (match_operand:SI 1 "general_operand" "Qmn"))]
2151   "!TARGET_64BIT"
2152   "mov{b}\t{%b1, %h0|%h0, %b1}"
2153   [(set_attr "type" "imov")
2154    (set_attr "mode" "QI")])
2156 (define_insn "*movsi_insv_1_rex64"
2157   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2158                          (const_int 8)
2159                          (const_int 8))
2160         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2161   "TARGET_64BIT"
2162   "mov{b}\t{%b1, %h0|%h0, %b1}"
2163   [(set_attr "type" "imov")
2164    (set_attr "mode" "QI")])
2166 (define_insn "movdi_insv_1_rex64"
2167   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2168                          (const_int 8)
2169                          (const_int 8))
2170         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2171   "TARGET_64BIT"
2172   "mov{b}\t{%b1, %h0|%h0, %b1}"
2173   [(set_attr "type" "imov")
2174    (set_attr "mode" "QI")])
2176 (define_insn "*movqi_insv_2"
2177   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2178                          (const_int 8)
2179                          (const_int 8))
2180         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2181                      (const_int 8)))]
2182   ""
2183   "mov{b}\t{%h1, %h0|%h0, %h1}"
2184   [(set_attr "type" "imov")
2185    (set_attr "mode" "QI")])
2187 (define_expand "movdi"
2188   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2189         (match_operand:DI 1 "general_operand" ""))]
2190   ""
2191   "ix86_expand_move (DImode, operands); DONE;")
2193 (define_insn "*pushdi"
2194   [(set (match_operand:DI 0 "push_operand" "=<")
2195         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2196   "!TARGET_64BIT"
2197   "#")
2199 (define_insn "*pushdi2_rex64"
2200   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2201         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2202   "TARGET_64BIT"
2203   "@
2204    push{q}\t%1
2205    #"
2206   [(set_attr "type" "push,multi")
2207    (set_attr "mode" "DI")])
2209 ;; Convert impossible pushes of immediate to existing instructions.
2210 ;; First try to get scratch register and go through it.  In case this
2211 ;; fails, push sign extended lower part first and then overwrite
2212 ;; upper part by 32bit move.
2213 (define_peephole2
2214   [(match_scratch:DI 2 "r")
2215    (set (match_operand:DI 0 "push_operand" "")
2216         (match_operand:DI 1 "immediate_operand" ""))]
2217   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2218    && !x86_64_immediate_operand (operands[1], DImode)"
2219   [(set (match_dup 2) (match_dup 1))
2220    (set (match_dup 0) (match_dup 2))]
2221   "")
2223 ;; We need to define this as both peepholer and splitter for case
2224 ;; peephole2 pass is not run.
2225 ;; "&& 1" is needed to keep it from matching the previous pattern.
2226 (define_peephole2
2227   [(set (match_operand:DI 0 "push_operand" "")
2228         (match_operand:DI 1 "immediate_operand" ""))]
2229   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2230    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2231   [(set (match_dup 0) (match_dup 1))
2232    (set (match_dup 2) (match_dup 3))]
2233   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2234    operands[1] = gen_lowpart (DImode, operands[2]);
2235    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2236                                                     GEN_INT (4)));
2237   ")
2239 (define_split
2240   [(set (match_operand:DI 0 "push_operand" "")
2241         (match_operand:DI 1 "immediate_operand" ""))]
2242   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2243                     ? epilogue_completed : reload_completed)
2244    && !symbolic_operand (operands[1], DImode)
2245    && !x86_64_immediate_operand (operands[1], DImode)"
2246   [(set (match_dup 0) (match_dup 1))
2247    (set (match_dup 2) (match_dup 3))]
2248   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2249    operands[1] = gen_lowpart (DImode, operands[2]);
2250    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2251                                                     GEN_INT (4)));
2252   ")
2254 (define_insn "*pushdi2_prologue_rex64"
2255   [(set (match_operand:DI 0 "push_operand" "=<")
2256         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2257    (clobber (mem:BLK (scratch)))]
2258   "TARGET_64BIT"
2259   "push{q}\t%1"
2260   [(set_attr "type" "push")
2261    (set_attr "mode" "DI")])
2263 (define_insn "*popdi1_epilogue_rex64"
2264   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2265         (mem:DI (reg:DI SP_REG)))
2266    (set (reg:DI SP_REG)
2267         (plus:DI (reg:DI SP_REG) (const_int 8)))
2268    (clobber (mem:BLK (scratch)))]
2269   "TARGET_64BIT"
2270   "pop{q}\t%0"
2271   [(set_attr "type" "pop")
2272    (set_attr "mode" "DI")])
2274 (define_insn "popdi1"
2275   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2276         (mem:DI (reg:DI SP_REG)))
2277    (set (reg:DI SP_REG)
2278         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2279   "TARGET_64BIT"
2280   "pop{q}\t%0"
2281   [(set_attr "type" "pop")
2282    (set_attr "mode" "DI")])
2284 (define_insn "*movdi_xor_rex64"
2285   [(set (match_operand:DI 0 "register_operand" "=r")
2286         (match_operand:DI 1 "const0_operand" ""))
2287    (clobber (reg:CC FLAGS_REG))]
2288   "TARGET_64BIT
2289    && reload_completed"
2290   "xor{l}\t%k0, %k0";
2291   [(set_attr "type" "alu1")
2292    (set_attr "mode" "SI")
2293    (set_attr "length_immediate" "0")])
2295 (define_insn "*movdi_or_rex64"
2296   [(set (match_operand:DI 0 "register_operand" "=r")
2297         (match_operand:DI 1 "const_int_operand" "i"))
2298    (clobber (reg:CC FLAGS_REG))]
2299   "TARGET_64BIT
2300    && reload_completed
2301    && operands[1] == constm1_rtx"
2303   operands[1] = constm1_rtx;
2304   return "or{q}\t{%1, %0|%0, %1}";
2306   [(set_attr "type" "alu1")
2307    (set_attr "mode" "DI")
2308    (set_attr "length_immediate" "1")])
2310 (define_insn "*movdi_2"
2311   [(set (match_operand:DI 0 "nonimmediate_operand"
2312                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2313         (match_operand:DI 1 "general_operand"
2314                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2315   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2316   "@
2317    #
2318    #
2319    pxor\t%0, %0
2320    movq\t{%1, %0|%0, %1}
2321    movq\t{%1, %0|%0, %1}
2322    %vpxor\t%0, %d0
2323    %vmovq\t{%1, %0|%0, %1}
2324    %vmovdqa\t{%1, %0|%0, %1}
2325    %vmovq\t{%1, %0|%0, %1}
2326    xorps\t%0, %0
2327    movlps\t{%1, %0|%0, %1}
2328    movaps\t{%1, %0|%0, %1}
2329    movlps\t{%1, %0|%0, %1}"
2330   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2331    (set (attr "prefix")
2332      (if_then_else (eq_attr "alternative" "5,6,7,8")
2333        (const_string "vex")
2334        (const_string "orig")))
2335    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2337 (define_split
2338   [(set (match_operand:DI 0 "push_operand" "")
2339         (match_operand:DI 1 "general_operand" ""))]
2340   "!TARGET_64BIT && reload_completed
2341    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2342   [(const_int 0)]
2343   "ix86_split_long_move (operands); DONE;")
2345 ;; %%% This multiword shite has got to go.
2346 (define_split
2347   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2348         (match_operand:DI 1 "general_operand" ""))]
2349   "!TARGET_64BIT && reload_completed
2350    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2351    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2352   [(const_int 0)]
2353   "ix86_split_long_move (operands); DONE;")
2355 (define_insn "*movdi_1_rex64"
2356   [(set (match_operand:DI 0 "nonimmediate_operand"
2357           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2358         (match_operand:DI 1 "general_operand"
2359           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2360   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2362   switch (get_attr_type (insn))
2363     {
2364     case TYPE_SSECVT:
2365       if (SSE_REG_P (operands[0]))
2366         return "movq2dq\t{%1, %0|%0, %1}";
2367       else
2368         return "movdq2q\t{%1, %0|%0, %1}";
2370     case TYPE_SSEMOV:
2371       if (TARGET_AVX)
2372         {
2373           if (get_attr_mode (insn) == MODE_TI)
2374             return "vmovdqa\t{%1, %0|%0, %1}";
2375           else
2376             return "vmovq\t{%1, %0|%0, %1}";
2377         }
2379       if (get_attr_mode (insn) == MODE_TI)
2380         return "movdqa\t{%1, %0|%0, %1}";
2381       /* FALLTHRU */
2383     case TYPE_MMXMOV:
2384       /* Moves from and into integer register is done using movd
2385          opcode with REX prefix.  */
2386       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2387         return "movd\t{%1, %0|%0, %1}";
2388       return "movq\t{%1, %0|%0, %1}";
2390     case TYPE_SSELOG1:
2391       return "%vpxor\t%0, %d0";
2393     case TYPE_MMX:
2394       return "pxor\t%0, %0";
2396     case TYPE_MULTI:
2397       return "#";
2399     case TYPE_LEA:
2400       return "lea{q}\t{%a1, %0|%0, %a1}";
2402     default:
2403       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2404       if (get_attr_mode (insn) == MODE_SI)
2405         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2406       else if (which_alternative == 2)
2407         return "movabs{q}\t{%1, %0|%0, %1}";
2408       else
2409         return "mov{q}\t{%1, %0|%0, %1}";
2410     }
2412   [(set (attr "type")
2413      (cond [(eq_attr "alternative" "5")
2414               (const_string "mmx")
2415             (eq_attr "alternative" "6,7,8,9,10")
2416               (const_string "mmxmov")
2417             (eq_attr "alternative" "11")
2418               (const_string "sselog1")
2419             (eq_attr "alternative" "12,13,14,15,16")
2420               (const_string "ssemov")
2421             (eq_attr "alternative" "17,18")
2422               (const_string "ssecvt")
2423             (eq_attr "alternative" "4")
2424               (const_string "multi")
2425             (match_operand:DI 1 "pic_32bit_operand" "")
2426               (const_string "lea")
2427            ]
2428            (const_string "imov")))
2429    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2430    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2431    (set (attr "prefix")
2432      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2433        (const_string "maybe_vex")
2434        (const_string "orig")))
2435    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2437 ;; Stores and loads of ax to arbitrary constant address.
2438 ;; We fake an second form of instruction to force reload to load address
2439 ;; into register when rax is not available
2440 (define_insn "*movabsdi_1_rex64"
2441   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2442         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2443   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2444   "@
2445    movabs{q}\t{%1, %P0|%P0, %1}
2446    mov{q}\t{%1, %a0|%a0, %1}"
2447   [(set_attr "type" "imov")
2448    (set_attr "modrm" "0,*")
2449    (set_attr "length_address" "8,0")
2450    (set_attr "length_immediate" "0,*")
2451    (set_attr "memory" "store")
2452    (set_attr "mode" "DI")])
2454 (define_insn "*movabsdi_2_rex64"
2455   [(set (match_operand:DI 0 "register_operand" "=a,r")
2456         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2457   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2458   "@
2459    movabs{q}\t{%P1, %0|%0, %P1}
2460    mov{q}\t{%a1, %0|%0, %a1}"
2461   [(set_attr "type" "imov")
2462    (set_attr "modrm" "0,*")
2463    (set_attr "length_address" "8,0")
2464    (set_attr "length_immediate" "0")
2465    (set_attr "memory" "load")
2466    (set_attr "mode" "DI")])
2468 ;; Convert impossible stores of immediate to existing instructions.
2469 ;; First try to get scratch register and go through it.  In case this
2470 ;; fails, move by 32bit parts.
2471 (define_peephole2
2472   [(match_scratch:DI 2 "r")
2473    (set (match_operand:DI 0 "memory_operand" "")
2474         (match_operand:DI 1 "immediate_operand" ""))]
2475   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2476    && !x86_64_immediate_operand (operands[1], DImode)"
2477   [(set (match_dup 2) (match_dup 1))
2478    (set (match_dup 0) (match_dup 2))]
2479   "")
2481 ;; We need to define this as both peepholer and splitter for case
2482 ;; peephole2 pass is not run.
2483 ;; "&& 1" is needed to keep it from matching the previous pattern.
2484 (define_peephole2
2485   [(set (match_operand:DI 0 "memory_operand" "")
2486         (match_operand:DI 1 "immediate_operand" ""))]
2487   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2488    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2489   [(set (match_dup 2) (match_dup 3))
2490    (set (match_dup 4) (match_dup 5))]
2491   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2493 (define_split
2494   [(set (match_operand:DI 0 "memory_operand" "")
2495         (match_operand:DI 1 "immediate_operand" ""))]
2496   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2497                     ? epilogue_completed : reload_completed)
2498    && !symbolic_operand (operands[1], DImode)
2499    && !x86_64_immediate_operand (operands[1], DImode)"
2500   [(set (match_dup 2) (match_dup 3))
2501    (set (match_dup 4) (match_dup 5))]
2502   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2504 (define_insn "*swapdi_rex64"
2505   [(set (match_operand:DI 0 "register_operand" "+r")
2506         (match_operand:DI 1 "register_operand" "+r"))
2507    (set (match_dup 1)
2508         (match_dup 0))]
2509   "TARGET_64BIT"
2510   "xchg{q}\t%1, %0"
2511   [(set_attr "type" "imov")
2512    (set_attr "mode" "DI")
2513    (set_attr "pent_pair" "np")
2514    (set_attr "athlon_decode" "vector")
2515    (set_attr "amdfam10_decode" "double")])
2517 (define_expand "movoi"
2518   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2519         (match_operand:OI 1 "general_operand" ""))]
2520   "TARGET_AVX"
2521   "ix86_expand_move (OImode, operands); DONE;")
2523 (define_insn "*movoi_internal"
2524   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2525         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2526   "TARGET_AVX
2527    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2529   switch (which_alternative)
2530     {
2531     case 0:
2532       return "vxorps\t%0, %0, %0";
2533     case 1:
2534     case 2:
2535       if (misaligned_operand (operands[0], OImode)
2536           || misaligned_operand (operands[1], OImode))
2537         return "vmovdqu\t{%1, %0|%0, %1}";
2538       else
2539         return "vmovdqa\t{%1, %0|%0, %1}";
2540     default:
2541       gcc_unreachable ();
2542     }
2544   [(set_attr "type" "sselog1,ssemov,ssemov")
2545    (set_attr "prefix" "vex")
2546    (set_attr "mode" "OI")])
2548 (define_expand "movti"
2549   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2550         (match_operand:TI 1 "nonimmediate_operand" ""))]
2551   "TARGET_SSE || TARGET_64BIT"
2553   if (TARGET_64BIT)
2554     ix86_expand_move (TImode, operands);
2555   else if (push_operand (operands[0], TImode))
2556     ix86_expand_push (TImode, operands[1]);
2557   else
2558     ix86_expand_vector_move (TImode, operands);
2559   DONE;
2562 (define_insn "*movti_internal"
2563   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2564         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2565   "TARGET_SSE && !TARGET_64BIT
2566    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2568   switch (which_alternative)
2569     {
2570     case 0:
2571       if (get_attr_mode (insn) == MODE_V4SF)
2572         return "%vxorps\t%0, %d0";
2573       else
2574         return "%vpxor\t%0, %d0";
2575     case 1:
2576     case 2:
2577       /* TDmode values are passed as TImode on the stack.  Moving them
2578          to stack may result in unaligned memory access.  */
2579       if (misaligned_operand (operands[0], TImode)
2580           || misaligned_operand (operands[1], TImode))
2581         {
2582           if (get_attr_mode (insn) == MODE_V4SF)
2583             return "%vmovups\t{%1, %0|%0, %1}";
2584          else
2585            return "%vmovdqu\t{%1, %0|%0, %1}";
2586         }
2587       else
2588         {
2589           if (get_attr_mode (insn) == MODE_V4SF)
2590             return "%vmovaps\t{%1, %0|%0, %1}";
2591          else
2592            return "%vmovdqa\t{%1, %0|%0, %1}";
2593         }
2594     default:
2595       gcc_unreachable ();
2596     }
2598   [(set_attr "type" "sselog1,ssemov,ssemov")
2599    (set_attr "prefix" "maybe_vex")
2600    (set (attr "mode")
2601         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2602                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2603                  (const_string "V4SF")
2604                (and (eq_attr "alternative" "2")
2605                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2606                         (const_int 0)))
2607                  (const_string "V4SF")]
2608               (const_string "TI")))])
2610 (define_insn "*movti_rex64"
2611   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2612         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2613   "TARGET_64BIT
2614    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2616   switch (which_alternative)
2617     {
2618     case 0:
2619     case 1:
2620       return "#";
2621     case 2:
2622       if (get_attr_mode (insn) == MODE_V4SF)
2623         return "%vxorps\t%0, %d0";
2624       else
2625         return "%vpxor\t%0, %d0";
2626     case 3:
2627     case 4:
2628       /* TDmode values are passed as TImode on the stack.  Moving them
2629          to stack may result in unaligned memory access.  */
2630       if (misaligned_operand (operands[0], TImode)
2631           || misaligned_operand (operands[1], TImode))
2632         {
2633           if (get_attr_mode (insn) == MODE_V4SF)
2634             return "%vmovups\t{%1, %0|%0, %1}";
2635          else
2636            return "%vmovdqu\t{%1, %0|%0, %1}";
2637         }
2638       else
2639         {
2640           if (get_attr_mode (insn) == MODE_V4SF)
2641             return "%vmovaps\t{%1, %0|%0, %1}";
2642          else
2643            return "%vmovdqa\t{%1, %0|%0, %1}";
2644         }
2645     default:
2646       gcc_unreachable ();
2647     }
2649   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2650    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2651    (set (attr "mode")
2652         (cond [(eq_attr "alternative" "2,3")
2653                  (if_then_else
2654                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2655                        (const_int 0))
2656                    (const_string "V4SF")
2657                    (const_string "TI"))
2658                (eq_attr "alternative" "4")
2659                  (if_then_else
2660                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2661                             (const_int 0))
2662                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2663                             (const_int 0)))
2664                    (const_string "V4SF")
2665                    (const_string "TI"))]
2666                (const_string "DI")))])
2668 (define_split
2669   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2670         (match_operand:TI 1 "general_operand" ""))]
2671   "reload_completed && !SSE_REG_P (operands[0])
2672    && !SSE_REG_P (operands[1])"
2673   [(const_int 0)]
2674   "ix86_split_long_move (operands); DONE;")
2676 ;; This expands to what emit_move_complex would generate if we didn't
2677 ;; have a movti pattern.  Having this avoids problems with reload on
2678 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2679 ;; to have around all the time.
2680 (define_expand "movcdi"
2681   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2682         (match_operand:CDI 1 "general_operand" ""))]
2683   ""
2685   if (push_operand (operands[0], CDImode))
2686     emit_move_complex_push (CDImode, operands[0], operands[1]);
2687   else
2688     emit_move_complex_parts (operands[0], operands[1]);
2689   DONE;
2692 (define_expand "movsf"
2693   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2694         (match_operand:SF 1 "general_operand" ""))]
2695   ""
2696   "ix86_expand_move (SFmode, operands); DONE;")
2698 (define_insn "*pushsf"
2699   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2700         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2701   "!TARGET_64BIT"
2703   /* Anything else should be already split before reg-stack.  */
2704   gcc_assert (which_alternative == 1);
2705   return "push{l}\t%1";
2707   [(set_attr "type" "multi,push,multi")
2708    (set_attr "unit" "i387,*,*")
2709    (set_attr "mode" "SF,SI,SF")])
2711 (define_insn "*pushsf_rex64"
2712   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2713         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2714   "TARGET_64BIT"
2716   /* Anything else should be already split before reg-stack.  */
2717   gcc_assert (which_alternative == 1);
2718   return "push{q}\t%q1";
2720   [(set_attr "type" "multi,push,multi")
2721    (set_attr "unit" "i387,*,*")
2722    (set_attr "mode" "SF,DI,SF")])
2724 (define_split
2725   [(set (match_operand:SF 0 "push_operand" "")
2726         (match_operand:SF 1 "memory_operand" ""))]
2727   "reload_completed
2728    && MEM_P (operands[1])
2729    && (operands[2] = find_constant_src (insn))"
2730   [(set (match_dup 0)
2731         (match_dup 2))])
2734 ;; %%% Kill this when call knows how to work this out.
2735 (define_split
2736   [(set (match_operand:SF 0 "push_operand" "")
2737         (match_operand:SF 1 "any_fp_register_operand" ""))]
2738   "!TARGET_64BIT"
2739   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2740    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2742 (define_split
2743   [(set (match_operand:SF 0 "push_operand" "")
2744         (match_operand:SF 1 "any_fp_register_operand" ""))]
2745   "TARGET_64BIT"
2746   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2747    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2749 (define_insn "*movsf_1"
2750   [(set (match_operand:SF 0 "nonimmediate_operand"
2751           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2752         (match_operand:SF 1 "general_operand"
2753           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2754   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2755    && (reload_in_progress || reload_completed
2756        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2757        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2758            && standard_80387_constant_p (operands[1]))
2759        || GET_CODE (operands[1]) != CONST_DOUBLE
2760        || memory_operand (operands[0], SFmode))"
2762   switch (which_alternative)
2763     {
2764     case 0:
2765     case 1:
2766       return output_387_reg_move (insn, operands);
2768     case 2:
2769       return standard_80387_constant_opcode (operands[1]);
2771     case 3:
2772     case 4:
2773       return "mov{l}\t{%1, %0|%0, %1}";
2774     case 5:
2775       if (get_attr_mode (insn) == MODE_TI)
2776         return "%vpxor\t%0, %d0";
2777       else
2778         return "%vxorps\t%0, %d0";
2779     case 6:
2780       if (get_attr_mode (insn) == MODE_V4SF)
2781         return "%vmovaps\t{%1, %0|%0, %1}";
2782       else
2783         return "%vmovss\t{%1, %d0|%d0, %1}";
2784     case 7:
2785       if (TARGET_AVX)
2786         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2787                                    : "vmovss\t{%1, %0|%0, %1}";
2788       else
2789         return "movss\t{%1, %0|%0, %1}";
2790     case 8:
2791       return "%vmovss\t{%1, %0|%0, %1}";
2793     case 9: case 10: case 14: case 15:
2794       return "movd\t{%1, %0|%0, %1}";
2795     case 12: case 13:
2796       return "%vmovd\t{%1, %0|%0, %1}";
2798     case 11:
2799       return "movq\t{%1, %0|%0, %1}";
2801     default:
2802       gcc_unreachable ();
2803     }
2805   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2806    (set (attr "prefix")
2807      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2808        (const_string "maybe_vex")
2809        (const_string "orig")))
2810    (set (attr "mode")
2811         (cond [(eq_attr "alternative" "3,4,9,10")
2812                  (const_string "SI")
2813                (eq_attr "alternative" "5")
2814                  (if_then_else
2815                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2816                                  (const_int 0))
2817                              (ne (symbol_ref "TARGET_SSE2")
2818                                  (const_int 0)))
2819                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2820                             (const_int 0)))
2821                    (const_string "TI")
2822                    (const_string "V4SF"))
2823                /* For architectures resolving dependencies on
2824                   whole SSE registers use APS move to break dependency
2825                   chains, otherwise use short move to avoid extra work.
2827                   Do the same for architectures resolving dependencies on
2828                   the parts.  While in DF mode it is better to always handle
2829                   just register parts, the SF mode is different due to lack
2830                   of instructions to load just part of the register.  It is
2831                   better to maintain the whole registers in single format
2832                   to avoid problems on using packed logical operations.  */
2833                (eq_attr "alternative" "6")
2834                  (if_then_else
2835                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2836                             (const_int 0))
2837                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2838                             (const_int 0)))
2839                    (const_string "V4SF")
2840                    (const_string "SF"))
2841                (eq_attr "alternative" "11")
2842                  (const_string "DI")]
2843                (const_string "SF")))])
2845 (define_insn "*swapsf"
2846   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2847         (match_operand:SF 1 "fp_register_operand" "+f"))
2848    (set (match_dup 1)
2849         (match_dup 0))]
2850   "reload_completed || TARGET_80387"
2852   if (STACK_TOP_P (operands[0]))
2853     return "fxch\t%1";
2854   else
2855     return "fxch\t%0";
2857   [(set_attr "type" "fxch")
2858    (set_attr "mode" "SF")])
2860 (define_expand "movdf"
2861   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2862         (match_operand:DF 1 "general_operand" ""))]
2863   ""
2864   "ix86_expand_move (DFmode, operands); DONE;")
2866 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2867 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2868 ;; On the average, pushdf using integers can be still shorter.  Allow this
2869 ;; pattern for optimize_size too.
2871 (define_insn "*pushdf_nointeger"
2872   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2873         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2874   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2876   /* This insn should be already split before reg-stack.  */
2877   gcc_unreachable ();
2879   [(set_attr "type" "multi")
2880    (set_attr "unit" "i387,*,*,*")
2881    (set_attr "mode" "DF,SI,SI,DF")])
2883 (define_insn "*pushdf_integer"
2884   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2885         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2886   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2888   /* This insn should be already split before reg-stack.  */
2889   gcc_unreachable ();
2891   [(set_attr "type" "multi")
2892    (set_attr "unit" "i387,*,*")
2893    (set_attr "mode" "DF,SI,DF")])
2895 ;; %%% Kill this when call knows how to work this out.
2896 (define_split
2897   [(set (match_operand:DF 0 "push_operand" "")
2898         (match_operand:DF 1 "any_fp_register_operand" ""))]
2899   "reload_completed"
2900   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2901    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2902   "")
2904 (define_split
2905   [(set (match_operand:DF 0 "push_operand" "")
2906         (match_operand:DF 1 "general_operand" ""))]
2907   "reload_completed"
2908   [(const_int 0)]
2909   "ix86_split_long_move (operands); DONE;")
2911 ;; Moving is usually shorter when only FP registers are used. This separate
2912 ;; movdf pattern avoids the use of integer registers for FP operations
2913 ;; when optimizing for size.
2915 (define_insn "*movdf_nointeger"
2916   [(set (match_operand:DF 0 "nonimmediate_operand"
2917                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2918         (match_operand:DF 1 "general_operand"
2919                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2920   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2921    && ((optimize_function_for_size_p (cfun)
2922        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2923    && (reload_in_progress || reload_completed
2924        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2925        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2926            && optimize_function_for_size_p (cfun)
2927            && !memory_operand (operands[0], DFmode)
2928            && standard_80387_constant_p (operands[1]))
2929        || GET_CODE (operands[1]) != CONST_DOUBLE
2930        || ((optimize_function_for_size_p (cfun)
2931             || !TARGET_MEMORY_MISMATCH_STALL
2932             || reload_in_progress || reload_completed)
2933            && memory_operand (operands[0], DFmode)))"
2935   switch (which_alternative)
2936     {
2937     case 0:
2938     case 1:
2939       return output_387_reg_move (insn, operands);
2941     case 2:
2942       return standard_80387_constant_opcode (operands[1]);
2944     case 3:
2945     case 4:
2946       return "#";
2947     case 5:
2948       switch (get_attr_mode (insn))
2949         {
2950         case MODE_V4SF:
2951           return "%vxorps\t%0, %d0";
2952         case MODE_V2DF:
2953           return "%vxorpd\t%0, %d0";
2954         case MODE_TI:
2955           return "%vpxor\t%0, %d0";
2956         default:
2957           gcc_unreachable ();
2958         }
2959     case 6:
2960     case 7:
2961     case 8:
2962       switch (get_attr_mode (insn))
2963         {
2964         case MODE_V4SF:
2965           return "%vmovaps\t{%1, %0|%0, %1}";
2966         case MODE_V2DF:
2967           return "%vmovapd\t{%1, %0|%0, %1}";
2968         case MODE_TI:
2969           return "%vmovdqa\t{%1, %0|%0, %1}";
2970         case MODE_DI:
2971           return "%vmovq\t{%1, %0|%0, %1}";
2972         case MODE_DF:
2973           if (TARGET_AVX)
2974             {
2975               if (REG_P (operands[0]) && REG_P (operands[1]))
2976                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2977               else
2978                 return "vmovsd\t{%1, %0|%0, %1}";
2979             }
2980           else
2981             return "movsd\t{%1, %0|%0, %1}";
2982         case MODE_V1DF:
2983           if (TARGET_AVX)
2984             {
2985               if (REG_P (operands[0]))
2986                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
2987               else
2988                 return "vmovlpd\t{%1, %0|%0, %1}";
2989             }
2990           else
2991             return "movlpd\t{%1, %0|%0, %1}";
2992         case MODE_V2SF:
2993           if (TARGET_AVX)
2994             {
2995               if (REG_P (operands[0]))
2996                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
2997               else
2998                 return "vmovlps\t{%1, %0|%0, %1}";
2999             }
3000           else
3001             return "movlps\t{%1, %0|%0, %1}";
3002         default:
3003           gcc_unreachable ();
3004         }
3006     default:
3007       gcc_unreachable ();
3008     }
3010   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3011    (set (attr "prefix")
3012      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3013        (const_string "orig")
3014        (const_string "maybe_vex")))
3015    (set (attr "mode")
3016         (cond [(eq_attr "alternative" "0,1,2")
3017                  (const_string "DF")
3018                (eq_attr "alternative" "3,4")
3019                  (const_string "SI")
3021                /* For SSE1, we have many fewer alternatives.  */
3022                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3023                  (cond [(eq_attr "alternative" "5,6")
3024                           (const_string "V4SF")
3025                        ]
3026                    (const_string "V2SF"))
3028                /* xorps is one byte shorter.  */
3029                (eq_attr "alternative" "5")
3030                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3031                             (const_int 0))
3032                           (const_string "V4SF")
3033                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3034                             (const_int 0))
3035                           (const_string "TI")
3036                        ]
3037                        (const_string "V2DF"))
3039                /* For architectures resolving dependencies on
3040                   whole SSE registers use APD move to break dependency
3041                   chains, otherwise use short move to avoid extra work.
3043                   movaps encodes one byte shorter.  */
3044                (eq_attr "alternative" "6")
3045                  (cond
3046                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3047                         (const_int 0))
3048                       (const_string "V4SF")
3049                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3050                         (const_int 0))
3051                       (const_string "V2DF")
3052                    ]
3053                    (const_string "DF"))
3054                /* For architectures resolving dependencies on register
3055                   parts we may avoid extra work to zero out upper part
3056                   of register.  */
3057                (eq_attr "alternative" "7")
3058                  (if_then_else
3059                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3060                        (const_int 0))
3061                    (const_string "V1DF")
3062                    (const_string "DF"))
3063               ]
3064               (const_string "DF")))])
3066 (define_insn "*movdf_integer_rex64"
3067   [(set (match_operand:DF 0 "nonimmediate_operand"
3068                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3069         (match_operand:DF 1 "general_operand"
3070                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3071   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3072    && (reload_in_progress || reload_completed
3073        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3074        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3075            && optimize_function_for_size_p (cfun)
3076            && standard_80387_constant_p (operands[1]))
3077        || GET_CODE (operands[1]) != CONST_DOUBLE
3078        || memory_operand (operands[0], DFmode))"
3080   switch (which_alternative)
3081     {
3082     case 0:
3083     case 1:
3084       return output_387_reg_move (insn, operands);
3086     case 2:
3087       return standard_80387_constant_opcode (operands[1]);
3089     case 3:
3090     case 4:
3091       return "#";
3093     case 5:
3094       switch (get_attr_mode (insn))
3095         {
3096         case MODE_V4SF:
3097           return "%vxorps\t%0, %d0";
3098         case MODE_V2DF:
3099           return "%vxorpd\t%0, %d0";
3100         case MODE_TI:
3101           return "%vpxor\t%0, %d0";
3102         default:
3103           gcc_unreachable ();
3104         }
3105     case 6:
3106     case 7:
3107     case 8:
3108       switch (get_attr_mode (insn))
3109         {
3110         case MODE_V4SF:
3111           return "%vmovaps\t{%1, %0|%0, %1}";
3112         case MODE_V2DF:
3113           return "%vmovapd\t{%1, %0|%0, %1}";
3114         case MODE_TI:
3115           return "%vmovdqa\t{%1, %0|%0, %1}";
3116         case MODE_DI:
3117           return "%vmovq\t{%1, %0|%0, %1}";
3118         case MODE_DF:
3119           if (TARGET_AVX)
3120             {
3121               if (REG_P (operands[0]) && REG_P (operands[1]))
3122                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3123               else
3124                 return "vmovsd\t{%1, %0|%0, %1}";
3125             }
3126           else
3127             return "movsd\t{%1, %0|%0, %1}";
3128         case MODE_V1DF:
3129           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3130         case MODE_V2SF:
3131           return "%vmovlps\t{%1, %d0|%d0, %1}";
3132         default:
3133           gcc_unreachable ();
3134         }
3136     case 9:
3137     case 10:
3138     return "%vmovd\t{%1, %0|%0, %1}";
3140     default:
3141       gcc_unreachable();
3142     }
3144   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3145    (set (attr "prefix")
3146      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3147        (const_string "orig")
3148        (const_string "maybe_vex")))
3149    (set (attr "mode")
3150         (cond [(eq_attr "alternative" "0,1,2")
3151                  (const_string "DF")
3152                (eq_attr "alternative" "3,4,9,10")
3153                  (const_string "DI")
3155                /* For SSE1, we have many fewer alternatives.  */
3156                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3157                  (cond [(eq_attr "alternative" "5,6")
3158                           (const_string "V4SF")
3159                        ]
3160                    (const_string "V2SF"))
3162                /* xorps is one byte shorter.  */
3163                (eq_attr "alternative" "5")
3164                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3165                             (const_int 0))
3166                           (const_string "V4SF")
3167                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3168                             (const_int 0))
3169                           (const_string "TI")
3170                        ]
3171                        (const_string "V2DF"))
3173                /* For architectures resolving dependencies on
3174                   whole SSE registers use APD move to break dependency
3175                   chains, otherwise use short move to avoid extra work.
3177                   movaps encodes one byte shorter.  */
3178                (eq_attr "alternative" "6")
3179                  (cond
3180                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3181                         (const_int 0))
3182                       (const_string "V4SF")
3183                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3184                         (const_int 0))
3185                       (const_string "V2DF")
3186                    ]
3187                    (const_string "DF"))
3188                /* For architectures resolving dependencies on register
3189                   parts we may avoid extra work to zero out upper part
3190                   of register.  */
3191                (eq_attr "alternative" "7")
3192                  (if_then_else
3193                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3194                        (const_int 0))
3195                    (const_string "V1DF")
3196                    (const_string "DF"))
3197               ]
3198               (const_string "DF")))])
3200 (define_insn "*movdf_integer"
3201   [(set (match_operand:DF 0 "nonimmediate_operand"
3202                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3203         (match_operand:DF 1 "general_operand"
3204                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3205   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3206    && optimize_function_for_speed_p (cfun)
3207    && TARGET_INTEGER_DFMODE_MOVES
3208    && (reload_in_progress || reload_completed
3209        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3210        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3211            && optimize_function_for_size_p (cfun)
3212            && standard_80387_constant_p (operands[1]))
3213        || GET_CODE (operands[1]) != CONST_DOUBLE
3214        || memory_operand (operands[0], DFmode))"
3216   switch (which_alternative)
3217     {
3218     case 0:
3219     case 1:
3220       return output_387_reg_move (insn, operands);
3222     case 2:
3223       return standard_80387_constant_opcode (operands[1]);
3225     case 3:
3226     case 4:
3227       return "#";
3229     case 5:
3230       switch (get_attr_mode (insn))
3231         {
3232         case MODE_V4SF:
3233           return "xorps\t%0, %0";
3234         case MODE_V2DF:
3235           return "xorpd\t%0, %0";
3236         case MODE_TI:
3237           return "pxor\t%0, %0";
3238         default:
3239           gcc_unreachable ();
3240         }
3241     case 6:
3242     case 7:
3243     case 8:
3244       switch (get_attr_mode (insn))
3245         {
3246         case MODE_V4SF:
3247           return "movaps\t{%1, %0|%0, %1}";
3248         case MODE_V2DF:
3249           return "movapd\t{%1, %0|%0, %1}";
3250         case MODE_TI:
3251           return "movdqa\t{%1, %0|%0, %1}";
3252         case MODE_DI:
3253           return "movq\t{%1, %0|%0, %1}";
3254         case MODE_DF:
3255           return "movsd\t{%1, %0|%0, %1}";
3256         case MODE_V1DF:
3257           return "movlpd\t{%1, %0|%0, %1}";
3258         case MODE_V2SF:
3259           return "movlps\t{%1, %0|%0, %1}";
3260         default:
3261           gcc_unreachable ();
3262         }
3264     default:
3265       gcc_unreachable();
3266     }
3268   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3269    (set (attr "mode")
3270         (cond [(eq_attr "alternative" "0,1,2")
3271                  (const_string "DF")
3272                (eq_attr "alternative" "3,4")
3273                  (const_string "SI")
3275                /* For SSE1, we have many fewer alternatives.  */
3276                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3277                  (cond [(eq_attr "alternative" "5,6")
3278                           (const_string "V4SF")
3279                        ]
3280                    (const_string "V2SF"))
3282                /* xorps is one byte shorter.  */
3283                (eq_attr "alternative" "5")
3284                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3285                             (const_int 0))
3286                           (const_string "V4SF")
3287                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3288                             (const_int 0))
3289                           (const_string "TI")
3290                        ]
3291                        (const_string "V2DF"))
3293                /* For architectures resolving dependencies on
3294                   whole SSE registers use APD move to break dependency
3295                   chains, otherwise use short move to avoid extra work.
3297                   movaps encodes one byte shorter.  */
3298                (eq_attr "alternative" "6")
3299                  (cond
3300                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3301                         (const_int 0))
3302                       (const_string "V4SF")
3303                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3304                         (const_int 0))
3305                       (const_string "V2DF")
3306                    ]
3307                    (const_string "DF"))
3308                /* For architectures resolving dependencies on register
3309                   parts we may avoid extra work to zero out upper part
3310                   of register.  */
3311                (eq_attr "alternative" "7")
3312                  (if_then_else
3313                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3314                        (const_int 0))
3315                    (const_string "V1DF")
3316                    (const_string "DF"))
3317               ]
3318               (const_string "DF")))])
3320 (define_split
3321   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3322         (match_operand:DF 1 "general_operand" ""))]
3323   "reload_completed
3324    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3325    && ! (ANY_FP_REG_P (operands[0]) ||
3326          (GET_CODE (operands[0]) == SUBREG
3327           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3328    && ! (ANY_FP_REG_P (operands[1]) ||
3329          (GET_CODE (operands[1]) == SUBREG
3330           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3331   [(const_int 0)]
3332   "ix86_split_long_move (operands); DONE;")
3334 (define_insn "*swapdf"
3335   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3336         (match_operand:DF 1 "fp_register_operand" "+f"))
3337    (set (match_dup 1)
3338         (match_dup 0))]
3339   "reload_completed || TARGET_80387"
3341   if (STACK_TOP_P (operands[0]))
3342     return "fxch\t%1";
3343   else
3344     return "fxch\t%0";
3346   [(set_attr "type" "fxch")
3347    (set_attr "mode" "DF")])
3349 (define_expand "movxf"
3350   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3351         (match_operand:XF 1 "general_operand" ""))]
3352   ""
3353   "ix86_expand_move (XFmode, operands); DONE;")
3355 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3356 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3357 ;; Pushing using integer instructions is longer except for constants
3358 ;; and direct memory references.
3359 ;; (assuming that any given constant is pushed only once, but this ought to be
3360 ;;  handled elsewhere).
3362 (define_insn "*pushxf_nointeger"
3363   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3364         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3365   "optimize_function_for_size_p (cfun)"
3367   /* This insn should be already split before reg-stack.  */
3368   gcc_unreachable ();
3370   [(set_attr "type" "multi")
3371    (set_attr "unit" "i387,*,*")
3372    (set_attr "mode" "XF,SI,SI")])
3374 (define_insn "*pushxf_integer"
3375   [(set (match_operand:XF 0 "push_operand" "=<,<")
3376         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3377   "optimize_function_for_speed_p (cfun)"
3379   /* This insn should be already split before reg-stack.  */
3380   gcc_unreachable ();
3382   [(set_attr "type" "multi")
3383    (set_attr "unit" "i387,*")
3384    (set_attr "mode" "XF,SI")])
3386 (define_split
3387   [(set (match_operand 0 "push_operand" "")
3388         (match_operand 1 "general_operand" ""))]
3389   "reload_completed
3390    && (GET_MODE (operands[0]) == XFmode
3391        || GET_MODE (operands[0]) == DFmode)
3392    && !ANY_FP_REG_P (operands[1])"
3393   [(const_int 0)]
3394   "ix86_split_long_move (operands); DONE;")
3396 (define_split
3397   [(set (match_operand:XF 0 "push_operand" "")
3398         (match_operand:XF 1 "any_fp_register_operand" ""))]
3399   ""
3400   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3401    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3402   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3404 ;; Do not use integer registers when optimizing for size
3405 (define_insn "*movxf_nointeger"
3406   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3407         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3408   "optimize_function_for_size_p (cfun)
3409    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3410    && (reload_in_progress || reload_completed
3411        || standard_80387_constant_p (operands[1])
3412        || GET_CODE (operands[1]) != CONST_DOUBLE
3413        || memory_operand (operands[0], XFmode))"
3415   switch (which_alternative)
3416     {
3417     case 0:
3418     case 1:
3419       return output_387_reg_move (insn, operands);
3421     case 2:
3422       return standard_80387_constant_opcode (operands[1]);
3424     case 3: case 4:
3425       return "#";
3426     default:
3427       gcc_unreachable ();
3428     }
3430   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3431    (set_attr "mode" "XF,XF,XF,SI,SI")])
3433 (define_insn "*movxf_integer"
3434   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3435         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3436   "optimize_function_for_speed_p (cfun)
3437    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3438    && (reload_in_progress || reload_completed
3439        || GET_CODE (operands[1]) != CONST_DOUBLE
3440        || memory_operand (operands[0], XFmode))"
3442   switch (which_alternative)
3443     {
3444     case 0:
3445     case 1:
3446       return output_387_reg_move (insn, operands);
3448     case 2:
3449       return standard_80387_constant_opcode (operands[1]);
3451     case 3: case 4:
3452       return "#";
3454     default:
3455       gcc_unreachable ();
3456     }
3458   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3459    (set_attr "mode" "XF,XF,XF,SI,SI")])
3461 (define_expand "movtf"
3462   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3463         (match_operand:TF 1 "nonimmediate_operand" ""))]
3464   "TARGET_SSE2"
3466   ix86_expand_move (TFmode, operands);
3467   DONE;
3470 (define_insn "*movtf_internal"
3471   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3472         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3473   "TARGET_SSE2
3474    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3476   switch (which_alternative)
3477     {
3478     case 0:
3479     case 1:
3480       if (get_attr_mode (insn) == MODE_V4SF)
3481         return "%vmovaps\t{%1, %0|%0, %1}";
3482       else
3483         return "%vmovdqa\t{%1, %0|%0, %1}";
3484     case 2:
3485       if (get_attr_mode (insn) == MODE_V4SF)
3486         return "%vxorps\t%0, %d0";
3487       else
3488         return "%vpxor\t%0, %d0";
3489     case 3:
3490     case 4:
3491         return "#";
3492     default:
3493       gcc_unreachable ();
3494     }
3496   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3497    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3498    (set (attr "mode")
3499         (cond [(eq_attr "alternative" "0,2")
3500                  (if_then_else
3501                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3502                        (const_int 0))
3503                    (const_string "V4SF")
3504                    (const_string "TI"))
3505                (eq_attr "alternative" "1")
3506                  (if_then_else
3507                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3508                             (const_int 0))
3509                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3510                             (const_int 0)))
3511                    (const_string "V4SF")
3512                    (const_string "TI"))]
3513                (const_string "DI")))])
3515 (define_insn "*pushtf_sse"
3516   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3517         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3518   "TARGET_SSE2"
3520   /* This insn should be already split before reg-stack.  */
3521   gcc_unreachable ();
3523   [(set_attr "type" "multi")
3524    (set_attr "unit" "sse,*,*")
3525    (set_attr "mode" "TF,SI,SI")])
3527 (define_split
3528   [(set (match_operand:TF 0 "push_operand" "")
3529         (match_operand:TF 1 "general_operand" ""))]
3530   "TARGET_SSE2 && reload_completed
3531    && !SSE_REG_P (operands[1])"
3532   [(const_int 0)]
3533   "ix86_split_long_move (operands); DONE;")
3535 (define_split
3536   [(set (match_operand:TF 0 "push_operand" "")
3537         (match_operand:TF 1 "any_fp_register_operand" ""))]
3538   "TARGET_SSE2"
3539   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3540    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3541   "")
3543 (define_split
3544   [(set (match_operand 0 "nonimmediate_operand" "")
3545         (match_operand 1 "general_operand" ""))]
3546   "reload_completed
3547    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3548    && GET_MODE (operands[0]) == XFmode
3549    && ! (ANY_FP_REG_P (operands[0]) ||
3550          (GET_CODE (operands[0]) == SUBREG
3551           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3552    && ! (ANY_FP_REG_P (operands[1]) ||
3553          (GET_CODE (operands[1]) == SUBREG
3554           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3555   [(const_int 0)]
3556   "ix86_split_long_move (operands); DONE;")
3558 (define_split
3559   [(set (match_operand 0 "register_operand" "")
3560         (match_operand 1 "memory_operand" ""))]
3561   "reload_completed
3562    && MEM_P (operands[1])
3563    && (GET_MODE (operands[0]) == TFmode
3564        || GET_MODE (operands[0]) == XFmode
3565        || GET_MODE (operands[0]) == SFmode
3566        || GET_MODE (operands[0]) == DFmode)
3567    && (operands[2] = find_constant_src (insn))"
3568   [(set (match_dup 0) (match_dup 2))]
3570   rtx c = operands[2];
3571   rtx r = operands[0];
3573   if (GET_CODE (r) == SUBREG)
3574     r = SUBREG_REG (r);
3576   if (SSE_REG_P (r))
3577     {
3578       if (!standard_sse_constant_p (c))
3579         FAIL;
3580     }
3581   else if (FP_REG_P (r))
3582     {
3583       if (!standard_80387_constant_p (c))
3584         FAIL;
3585     }
3586   else if (MMX_REG_P (r))
3587     FAIL;
3590 (define_split
3591   [(set (match_operand 0 "register_operand" "")
3592         (float_extend (match_operand 1 "memory_operand" "")))]
3593   "reload_completed
3594    && MEM_P (operands[1])
3595    && (GET_MODE (operands[0]) == TFmode
3596        || GET_MODE (operands[0]) == XFmode
3597        || GET_MODE (operands[0]) == SFmode
3598        || GET_MODE (operands[0]) == DFmode)
3599    && (operands[2] = find_constant_src (insn))"
3600   [(set (match_dup 0) (match_dup 2))]
3602   rtx c = operands[2];
3603   rtx r = operands[0];
3605   if (GET_CODE (r) == SUBREG)
3606     r = SUBREG_REG (r);
3608   if (SSE_REG_P (r))
3609     {
3610       if (!standard_sse_constant_p (c))
3611         FAIL;
3612     }
3613   else if (FP_REG_P (r))
3614     {
3615       if (!standard_80387_constant_p (c))
3616         FAIL;
3617     }
3618   else if (MMX_REG_P (r))
3619     FAIL;
3622 (define_insn "swapxf"
3623   [(set (match_operand:XF 0 "register_operand" "+f")
3624         (match_operand:XF 1 "register_operand" "+f"))
3625    (set (match_dup 1)
3626         (match_dup 0))]
3627   "TARGET_80387"
3629   if (STACK_TOP_P (operands[0]))
3630     return "fxch\t%1";
3631   else
3632     return "fxch\t%0";
3634   [(set_attr "type" "fxch")
3635    (set_attr "mode" "XF")])
3637 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3638 (define_split
3639   [(set (match_operand:X87MODEF 0 "register_operand" "")
3640         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3641   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3642    && (standard_80387_constant_p (operands[1]) == 8
3643        || standard_80387_constant_p (operands[1]) == 9)"
3644   [(set (match_dup 0)(match_dup 1))
3645    (set (match_dup 0)
3646         (neg:X87MODEF (match_dup 0)))]
3648   REAL_VALUE_TYPE r;
3650   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3651   if (real_isnegzero (&r))
3652     operands[1] = CONST0_RTX (<MODE>mode);
3653   else
3654     operands[1] = CONST1_RTX (<MODE>mode);
3657 (define_split
3658   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3659         (match_operand:TF 1 "general_operand" ""))]
3660   "reload_completed
3661    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3662   [(const_int 0)]
3663   "ix86_split_long_move (operands); DONE;")
3665 ;; Zero extension instructions
3667 (define_expand "zero_extendhisi2"
3668   [(set (match_operand:SI 0 "register_operand" "")
3669      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3670   ""
3672   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3673     {
3674       operands[1] = force_reg (HImode, operands[1]);
3675       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3676       DONE;
3677     }
3680 (define_insn "zero_extendhisi2_and"
3681   [(set (match_operand:SI 0 "register_operand" "=r")
3682      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3683    (clobber (reg:CC FLAGS_REG))]
3684   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3685   "#"
3686   [(set_attr "type" "alu1")
3687    (set_attr "mode" "SI")])
3689 (define_split
3690   [(set (match_operand:SI 0 "register_operand" "")
3691         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3692    (clobber (reg:CC FLAGS_REG))]
3693   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3694    && optimize_function_for_speed_p (cfun)"
3695   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3696               (clobber (reg:CC FLAGS_REG))])]
3697   "")
3699 (define_insn "*zero_extendhisi2_movzwl"
3700   [(set (match_operand:SI 0 "register_operand" "=r")
3701      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3702   "!TARGET_ZERO_EXTEND_WITH_AND
3703    || optimize_function_for_size_p (cfun)"
3704   "movz{wl|x}\t{%1, %0|%0, %1}"
3705   [(set_attr "type" "imovx")
3706    (set_attr "mode" "SI")])
3708 (define_expand "zero_extendqihi2"
3709   [(parallel
3710     [(set (match_operand:HI 0 "register_operand" "")
3711        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3712      (clobber (reg:CC FLAGS_REG))])]
3713   ""
3714   "")
3716 (define_insn "*zero_extendqihi2_and"
3717   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3718      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3719    (clobber (reg:CC FLAGS_REG))]
3720   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3721   "#"
3722   [(set_attr "type" "alu1")
3723    (set_attr "mode" "HI")])
3725 (define_insn "*zero_extendqihi2_movzbw_and"
3726   [(set (match_operand:HI 0 "register_operand" "=r,r")
3727      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3728    (clobber (reg:CC FLAGS_REG))]
3729   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3730   "#"
3731   [(set_attr "type" "imovx,alu1")
3732    (set_attr "mode" "HI")])
3734 ; zero extend to SImode here to avoid partial register stalls
3735 (define_insn "*zero_extendqihi2_movzbl"
3736   [(set (match_operand:HI 0 "register_operand" "=r")
3737      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3738   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3739    && reload_completed"
3740   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3741   [(set_attr "type" "imovx")
3742    (set_attr "mode" "SI")])
3744 ;; For the movzbw case strip only the clobber
3745 (define_split
3746   [(set (match_operand:HI 0 "register_operand" "")
3747         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3748    (clobber (reg:CC FLAGS_REG))]
3749   "reload_completed
3750    && (!TARGET_ZERO_EXTEND_WITH_AND
3751        || optimize_function_for_size_p (cfun))
3752    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3753   [(set (match_operand:HI 0 "register_operand" "")
3754         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3756 ;; When source and destination does not overlap, clear destination
3757 ;; first and then do the movb
3758 (define_split
3759   [(set (match_operand:HI 0 "register_operand" "")
3760         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3761    (clobber (reg:CC FLAGS_REG))]
3762   "reload_completed
3763    && ANY_QI_REG_P (operands[0])
3764    && (TARGET_ZERO_EXTEND_WITH_AND
3765        && optimize_function_for_speed_p (cfun))
3766    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3767   [(set (match_dup 0) (const_int 0))
3768    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3769   "operands[2] = gen_lowpart (QImode, operands[0]);")
3771 ;; Rest is handled by single and.
3772 (define_split
3773   [(set (match_operand:HI 0 "register_operand" "")
3774         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3775    (clobber (reg:CC FLAGS_REG))]
3776   "reload_completed
3777    && true_regnum (operands[0]) == true_regnum (operands[1])"
3778   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3779               (clobber (reg:CC FLAGS_REG))])]
3780   "")
3782 (define_expand "zero_extendqisi2"
3783   [(parallel
3784     [(set (match_operand:SI 0 "register_operand" "")
3785        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3786      (clobber (reg:CC FLAGS_REG))])]
3787   ""
3788   "")
3790 (define_insn "*zero_extendqisi2_and"
3791   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3792      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3793    (clobber (reg:CC FLAGS_REG))]
3794   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3795   "#"
3796   [(set_attr "type" "alu1")
3797    (set_attr "mode" "SI")])
3799 (define_insn "*zero_extendqisi2_movzbw_and"
3800   [(set (match_operand:SI 0 "register_operand" "=r,r")
3801      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3802    (clobber (reg:CC FLAGS_REG))]
3803   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3804   "#"
3805   [(set_attr "type" "imovx,alu1")
3806    (set_attr "mode" "SI")])
3808 (define_insn "*zero_extendqisi2_movzbw"
3809   [(set (match_operand:SI 0 "register_operand" "=r")
3810      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3811   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3812    && reload_completed"
3813   "movz{bl|x}\t{%1, %0|%0, %1}"
3814   [(set_attr "type" "imovx")
3815    (set_attr "mode" "SI")])
3817 ;; For the movzbl case strip only the clobber
3818 (define_split
3819   [(set (match_operand:SI 0 "register_operand" "")
3820         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3821    (clobber (reg:CC FLAGS_REG))]
3822   "reload_completed
3823    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3824    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3825   [(set (match_dup 0)
3826         (zero_extend:SI (match_dup 1)))])
3828 ;; When source and destination does not overlap, clear destination
3829 ;; first and then do the movb
3830 (define_split
3831   [(set (match_operand:SI 0 "register_operand" "")
3832         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3833    (clobber (reg:CC FLAGS_REG))]
3834   "reload_completed
3835    && ANY_QI_REG_P (operands[0])
3836    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3837    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3838    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3839   [(set (match_dup 0) (const_int 0))
3840    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3841   "operands[2] = gen_lowpart (QImode, operands[0]);")
3843 ;; Rest is handled by single and.
3844 (define_split
3845   [(set (match_operand:SI 0 "register_operand" "")
3846         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3847    (clobber (reg:CC FLAGS_REG))]
3848   "reload_completed
3849    && true_regnum (operands[0]) == true_regnum (operands[1])"
3850   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3851               (clobber (reg:CC FLAGS_REG))])]
3852   "")
3854 ;; %%% Kill me once multi-word ops are sane.
3855 (define_expand "zero_extendsidi2"
3856   [(set (match_operand:DI 0 "register_operand" "")
3857      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3858   ""
3860   if (!TARGET_64BIT)
3861     {
3862       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3863       DONE;
3864     }
3867 (define_insn "zero_extendsidi2_32"
3868   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3869         (zero_extend:DI
3870          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3871    (clobber (reg:CC FLAGS_REG))]
3872   "!TARGET_64BIT"
3873   "@
3874    #
3875    #
3876    #
3877    movd\t{%1, %0|%0, %1}
3878    movd\t{%1, %0|%0, %1}
3879    %vmovd\t{%1, %0|%0, %1}
3880    %vmovd\t{%1, %0|%0, %1}"
3881   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3882    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3883    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3885 (define_insn "zero_extendsidi2_rex64"
3886   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3887      (zero_extend:DI
3888        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3889   "TARGET_64BIT"
3890   "@
3891    mov\t{%k1, %k0|%k0, %k1}
3892    #
3893    movd\t{%1, %0|%0, %1}
3894    movd\t{%1, %0|%0, %1}
3895    %vmovd\t{%1, %0|%0, %1}
3896    %vmovd\t{%1, %0|%0, %1}"
3897   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3898    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3899    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3901 (define_split
3902   [(set (match_operand:DI 0 "memory_operand" "")
3903      (zero_extend:DI (match_dup 0)))]
3904   "TARGET_64BIT"
3905   [(set (match_dup 4) (const_int 0))]
3906   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3908 (define_split
3909   [(set (match_operand:DI 0 "register_operand" "")
3910         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3911    (clobber (reg:CC FLAGS_REG))]
3912   "!TARGET_64BIT && reload_completed
3913    && true_regnum (operands[0]) == true_regnum (operands[1])"
3914   [(set (match_dup 4) (const_int 0))]
3915   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3917 (define_split
3918   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3919         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3920    (clobber (reg:CC FLAGS_REG))]
3921   "!TARGET_64BIT && reload_completed
3922    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3923   [(set (match_dup 3) (match_dup 1))
3924    (set (match_dup 4) (const_int 0))]
3925   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3927 (define_insn "zero_extendhidi2"
3928   [(set (match_operand:DI 0 "register_operand" "=r")
3929      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3930   "TARGET_64BIT"
3931   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3932   [(set_attr "type" "imovx")
3933    (set_attr "mode" "DI")])
3935 (define_insn "zero_extendqidi2"
3936   [(set (match_operand:DI 0 "register_operand" "=r")
3937      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3938   "TARGET_64BIT"
3939   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3940   [(set_attr "type" "imovx")
3941    (set_attr "mode" "DI")])
3943 ;; Sign extension instructions
3945 (define_expand "extendsidi2"
3946   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3947                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3948               (clobber (reg:CC FLAGS_REG))
3949               (clobber (match_scratch:SI 2 ""))])]
3950   ""
3952   if (TARGET_64BIT)
3953     {
3954       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3955       DONE;
3956     }
3959 (define_insn "*extendsidi2_1"
3960   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3961         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3962    (clobber (reg:CC FLAGS_REG))
3963    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3964   "!TARGET_64BIT"
3965   "#")
3967 (define_insn "extendsidi2_rex64"
3968   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3969         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3970   "TARGET_64BIT"
3971   "@
3972    {cltq|cdqe}
3973    movs{lq|x}\t{%1,%0|%0, %1}"
3974   [(set_attr "type" "imovx")
3975    (set_attr "mode" "DI")
3976    (set_attr "prefix_0f" "0")
3977    (set_attr "modrm" "0,1")])
3979 (define_insn "extendhidi2"
3980   [(set (match_operand:DI 0 "register_operand" "=r")
3981         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3982   "TARGET_64BIT"
3983   "movs{wq|x}\t{%1,%0|%0, %1}"
3984   [(set_attr "type" "imovx")
3985    (set_attr "mode" "DI")])
3987 (define_insn "extendqidi2"
3988   [(set (match_operand:DI 0 "register_operand" "=r")
3989         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3990   "TARGET_64BIT"
3991   "movs{bq|x}\t{%1,%0|%0, %1}"
3992    [(set_attr "type" "imovx")
3993     (set_attr "mode" "DI")])
3995 ;; Extend to memory case when source register does die.
3996 (define_split
3997   [(set (match_operand:DI 0 "memory_operand" "")
3998         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3999    (clobber (reg:CC FLAGS_REG))
4000    (clobber (match_operand:SI 2 "register_operand" ""))]
4001   "(reload_completed
4002     && dead_or_set_p (insn, operands[1])
4003     && !reg_mentioned_p (operands[1], operands[0]))"
4004   [(set (match_dup 3) (match_dup 1))
4005    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4006               (clobber (reg:CC FLAGS_REG))])
4007    (set (match_dup 4) (match_dup 1))]
4008   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4010 ;; Extend to memory case when source register does not die.
4011 (define_split
4012   [(set (match_operand:DI 0 "memory_operand" "")
4013         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4014    (clobber (reg:CC FLAGS_REG))
4015    (clobber (match_operand:SI 2 "register_operand" ""))]
4016   "reload_completed"
4017   [(const_int 0)]
4019   split_di (&operands[0], 1, &operands[3], &operands[4]);
4021   emit_move_insn (operands[3], operands[1]);
4023   /* Generate a cltd if possible and doing so it profitable.  */
4024   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4025       && true_regnum (operands[1]) == AX_REG
4026       && true_regnum (operands[2]) == DX_REG)
4027     {
4028       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4029     }
4030   else
4031     {
4032       emit_move_insn (operands[2], operands[1]);
4033       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4034     }
4035   emit_move_insn (operands[4], operands[2]);
4036   DONE;
4039 ;; Extend to register case.  Optimize case where source and destination
4040 ;; registers match and cases where we can use cltd.
4041 (define_split
4042   [(set (match_operand:DI 0 "register_operand" "")
4043         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4044    (clobber (reg:CC FLAGS_REG))
4045    (clobber (match_scratch:SI 2 ""))]
4046   "reload_completed"
4047   [(const_int 0)]
4049   split_di (&operands[0], 1, &operands[3], &operands[4]);
4051   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4052     emit_move_insn (operands[3], operands[1]);
4054   /* Generate a cltd if possible and doing so it profitable.  */
4055   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4056       && true_regnum (operands[3]) == AX_REG)
4057     {
4058       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4059       DONE;
4060     }
4062   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4063     emit_move_insn (operands[4], operands[1]);
4065   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4066   DONE;
4069 (define_insn "extendhisi2"
4070   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4071         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4072   ""
4074   switch (get_attr_prefix_0f (insn))
4075     {
4076     case 0:
4077       return "{cwtl|cwde}";
4078     default:
4079       return "movs{wl|x}\t{%1,%0|%0, %1}";
4080     }
4082   [(set_attr "type" "imovx")
4083    (set_attr "mode" "SI")
4084    (set (attr "prefix_0f")
4085      ;; movsx is short decodable while cwtl is vector decoded.
4086      (if_then_else (and (eq_attr "cpu" "!k6")
4087                         (eq_attr "alternative" "0"))
4088         (const_string "0")
4089         (const_string "1")))
4090    (set (attr "modrm")
4091      (if_then_else (eq_attr "prefix_0f" "0")
4092         (const_string "0")
4093         (const_string "1")))])
4095 (define_insn "*extendhisi2_zext"
4096   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4097         (zero_extend:DI
4098           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4099   "TARGET_64BIT"
4101   switch (get_attr_prefix_0f (insn))
4102     {
4103     case 0:
4104       return "{cwtl|cwde}";
4105     default:
4106       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4107     }
4109   [(set_attr "type" "imovx")
4110    (set_attr "mode" "SI")
4111    (set (attr "prefix_0f")
4112      ;; movsx is short decodable while cwtl is vector decoded.
4113      (if_then_else (and (eq_attr "cpu" "!k6")
4114                         (eq_attr "alternative" "0"))
4115         (const_string "0")
4116         (const_string "1")))
4117    (set (attr "modrm")
4118      (if_then_else (eq_attr "prefix_0f" "0")
4119         (const_string "0")
4120         (const_string "1")))])
4122 (define_insn "extendqihi2"
4123   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4124         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4125   ""
4127   switch (get_attr_prefix_0f (insn))
4128     {
4129     case 0:
4130       return "{cbtw|cbw}";
4131     default:
4132       return "movs{bw|x}\t{%1,%0|%0, %1}";
4133     }
4135   [(set_attr "type" "imovx")
4136    (set_attr "mode" "HI")
4137    (set (attr "prefix_0f")
4138      ;; movsx is short decodable while cwtl is vector decoded.
4139      (if_then_else (and (eq_attr "cpu" "!k6")
4140                         (eq_attr "alternative" "0"))
4141         (const_string "0")
4142         (const_string "1")))
4143    (set (attr "modrm")
4144      (if_then_else (eq_attr "prefix_0f" "0")
4145         (const_string "0")
4146         (const_string "1")))])
4148 (define_insn "extendqisi2"
4149   [(set (match_operand:SI 0 "register_operand" "=r")
4150         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4151   ""
4152   "movs{bl|x}\t{%1,%0|%0, %1}"
4153    [(set_attr "type" "imovx")
4154     (set_attr "mode" "SI")])
4156 (define_insn "*extendqisi2_zext"
4157   [(set (match_operand:DI 0 "register_operand" "=r")
4158         (zero_extend:DI
4159           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4160   "TARGET_64BIT"
4161   "movs{bl|x}\t{%1,%k0|%k0, %1}"
4162    [(set_attr "type" "imovx")
4163     (set_attr "mode" "SI")])
4165 ;; Conversions between float and double.
4167 ;; These are all no-ops in the model used for the 80387.  So just
4168 ;; emit moves.
4170 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4171 (define_insn "*dummy_extendsfdf2"
4172   [(set (match_operand:DF 0 "push_operand" "=<")
4173         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4174   "0"
4175   "#")
4177 (define_split
4178   [(set (match_operand:DF 0 "push_operand" "")
4179         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4180   ""
4181   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4182    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4184 (define_insn "*dummy_extendsfxf2"
4185   [(set (match_operand:XF 0 "push_operand" "=<")
4186         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4187   "0"
4188   "#")
4190 (define_split
4191   [(set (match_operand:XF 0 "push_operand" "")
4192         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4193   ""
4194   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4195    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4196   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4198 (define_split
4199   [(set (match_operand:XF 0 "push_operand" "")
4200         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4201   ""
4202   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4203    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4204   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4206 (define_expand "extendsfdf2"
4207   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4208         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4209   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4211   /* ??? Needed for compress_float_constant since all fp constants
4212      are LEGITIMATE_CONSTANT_P.  */
4213   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4214     {
4215       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4216           && standard_80387_constant_p (operands[1]) > 0)
4217         {
4218           operands[1] = simplify_const_unary_operation
4219             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4220           emit_move_insn_1 (operands[0], operands[1]);
4221           DONE;
4222         }
4223       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4224     }
4227 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4228    cvtss2sd:
4229       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4230       cvtps2pd xmm2,xmm1
4231    We do the conversion post reload to avoid producing of 128bit spills
4232    that might lead to ICE on 32bit target.  The sequence unlikely combine
4233    anyway.  */
4234 (define_split
4235   [(set (match_operand:DF 0 "register_operand" "")
4236         (float_extend:DF
4237           (match_operand:SF 1 "nonimmediate_operand" "")))]
4238   "TARGET_USE_VECTOR_FP_CONVERTS
4239    && optimize_insn_for_speed_p ()
4240    && reload_completed && SSE_REG_P (operands[0])"
4241    [(set (match_dup 2)
4242          (float_extend:V2DF
4243            (vec_select:V2SF
4244              (match_dup 3)
4245              (parallel [(const_int 0) (const_int 1)]))))]
4247   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4248   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4249   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4250      Try to avoid move when unpacking can be done in source.  */
4251   if (REG_P (operands[1]))
4252     {
4253       /* If it is unsafe to overwrite upper half of source, we need
4254          to move to destination and unpack there.  */
4255       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4256            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4257           && true_regnum (operands[0]) != true_regnum (operands[1]))
4258         {
4259           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4260           emit_move_insn (tmp, operands[1]);
4261         }
4262       else
4263         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4264       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4265     }
4266   else
4267     emit_insn (gen_vec_setv4sf_0 (operands[3],
4268                                   CONST0_RTX (V4SFmode), operands[1]));
4271 (define_insn "*extendsfdf2_mixed"
4272   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4273         (float_extend:DF
4274           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4275   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4277   switch (which_alternative)
4278     {
4279     case 0:
4280     case 1:
4281       return output_387_reg_move (insn, operands);
4283     case 2:
4284       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4286     default:
4287       gcc_unreachable ();
4288     }
4290   [(set_attr "type" "fmov,fmov,ssecvt")
4291    (set_attr "prefix" "orig,orig,maybe_vex")
4292    (set_attr "mode" "SF,XF,DF")])
4294 (define_insn "*extendsfdf2_sse"
4295   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4296         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4297   "TARGET_SSE2 && TARGET_SSE_MATH"
4298   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4299   [(set_attr "type" "ssecvt")
4300    (set_attr "prefix" "maybe_vex")
4301    (set_attr "mode" "DF")])
4303 (define_insn "*extendsfdf2_i387"
4304   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4305         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4306   "TARGET_80387"
4307   "* return output_387_reg_move (insn, operands);"
4308   [(set_attr "type" "fmov")
4309    (set_attr "mode" "SF,XF")])
4311 (define_expand "extend<mode>xf2"
4312   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4313         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4314   "TARGET_80387"
4316   /* ??? Needed for compress_float_constant since all fp constants
4317      are LEGITIMATE_CONSTANT_P.  */
4318   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4319     {
4320       if (standard_80387_constant_p (operands[1]) > 0)
4321         {
4322           operands[1] = simplify_const_unary_operation
4323             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4324           emit_move_insn_1 (operands[0], operands[1]);
4325           DONE;
4326         }
4327       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4328     }
4331 (define_insn "*extend<mode>xf2_i387"
4332   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4333         (float_extend:XF
4334           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4335   "TARGET_80387"
4336   "* return output_387_reg_move (insn, operands);"
4337   [(set_attr "type" "fmov")
4338    (set_attr "mode" "<MODE>,XF")])
4340 ;; %%% This seems bad bad news.
4341 ;; This cannot output into an f-reg because there is no way to be sure
4342 ;; of truncating in that case.  Otherwise this is just like a simple move
4343 ;; insn.  So we pretend we can output to a reg in order to get better
4344 ;; register preferencing, but we really use a stack slot.
4346 ;; Conversion from DFmode to SFmode.
4348 (define_expand "truncdfsf2"
4349   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4350         (float_truncate:SF
4351           (match_operand:DF 1 "nonimmediate_operand" "")))]
4352   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4354   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4355     ;
4356   else if (flag_unsafe_math_optimizations)
4357     ;
4358   else
4359     {
4360       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4361       rtx temp = assign_386_stack_local (SFmode, slot);
4362       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4363       DONE;
4364     }
4367 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4368    cvtsd2ss:
4369       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4370       cvtpd2ps xmm2,xmm1
4371    We do the conversion post reload to avoid producing of 128bit spills
4372    that might lead to ICE on 32bit target.  The sequence unlikely combine
4373    anyway.  */
4374 (define_split
4375   [(set (match_operand:SF 0 "register_operand" "")
4376         (float_truncate:SF
4377           (match_operand:DF 1 "nonimmediate_operand" "")))]
4378   "TARGET_USE_VECTOR_FP_CONVERTS
4379    && optimize_insn_for_speed_p ()
4380    && reload_completed && SSE_REG_P (operands[0])"
4381    [(set (match_dup 2)
4382          (vec_concat:V4SF
4383            (float_truncate:V2SF
4384              (match_dup 4))
4385            (match_dup 3)))]
4387   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4388   operands[3] = CONST0_RTX (V2SFmode);
4389   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4390   /* Use movsd for loading from memory, unpcklpd for registers.
4391      Try to avoid move when unpacking can be done in source, or SSE3
4392      movddup is available.  */
4393   if (REG_P (operands[1]))
4394     {
4395       if (!TARGET_SSE3
4396           && true_regnum (operands[0]) != true_regnum (operands[1])
4397           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4398               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4399         {
4400           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4401           emit_move_insn (tmp, operands[1]);
4402           operands[1] = tmp;
4403         }
4404       else if (!TARGET_SSE3)
4405         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4406       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4407     }
4408   else
4409     emit_insn (gen_sse2_loadlpd (operands[4],
4410                                  CONST0_RTX (V2DFmode), operands[1]));
4413 (define_expand "truncdfsf2_with_temp"
4414   [(parallel [(set (match_operand:SF 0 "" "")
4415                    (float_truncate:SF (match_operand:DF 1 "" "")))
4416               (clobber (match_operand:SF 2 "" ""))])]
4417   "")
4419 (define_insn "*truncdfsf_fast_mixed"
4420   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4421         (float_truncate:SF
4422           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4423   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4425   switch (which_alternative)
4426     {
4427     case 0:
4428       return output_387_reg_move (insn, operands);
4429     case 1:
4430       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4431     default:
4432       gcc_unreachable ();
4433     }
4435   [(set_attr "type" "fmov,ssecvt")
4436    (set_attr "prefix" "orig,maybe_vex")
4437    (set_attr "mode" "SF")])
4439 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4440 ;; because nothing we do here is unsafe.
4441 (define_insn "*truncdfsf_fast_sse"
4442   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4443         (float_truncate:SF
4444           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4445   "TARGET_SSE2 && TARGET_SSE_MATH"
4446   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4447   [(set_attr "type" "ssecvt")
4448    (set_attr "prefix" "maybe_vex")
4449    (set_attr "mode" "SF")])
4451 (define_insn "*truncdfsf_fast_i387"
4452   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4453         (float_truncate:SF
4454           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4455   "TARGET_80387 && flag_unsafe_math_optimizations"
4456   "* return output_387_reg_move (insn, operands);"
4457   [(set_attr "type" "fmov")
4458    (set_attr "mode" "SF")])
4460 (define_insn "*truncdfsf_mixed"
4461   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4462         (float_truncate:SF
4463           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4464    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4465   "TARGET_MIX_SSE_I387"
4467   switch (which_alternative)
4468     {
4469     case 0:
4470       return output_387_reg_move (insn, operands);
4472     case 1:
4473       return "#";
4474     case 2:
4475       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4476     default:
4477       gcc_unreachable ();
4478     }
4480   [(set_attr "type" "fmov,multi,ssecvt")
4481    (set_attr "unit" "*,i387,*")
4482    (set_attr "prefix" "orig,orig,maybe_vex")
4483    (set_attr "mode" "SF")])
4485 (define_insn "*truncdfsf_i387"
4486   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4487         (float_truncate:SF
4488           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4489    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4490   "TARGET_80387"
4492   switch (which_alternative)
4493     {
4494     case 0:
4495       return output_387_reg_move (insn, operands);
4497     case 1:
4498       return "#";
4499     default:
4500       gcc_unreachable ();
4501     }
4503   [(set_attr "type" "fmov,multi")
4504    (set_attr "unit" "*,i387")
4505    (set_attr "mode" "SF")])
4507 (define_insn "*truncdfsf2_i387_1"
4508   [(set (match_operand:SF 0 "memory_operand" "=m")
4509         (float_truncate:SF
4510           (match_operand:DF 1 "register_operand" "f")))]
4511   "TARGET_80387
4512    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4513    && !TARGET_MIX_SSE_I387"
4514   "* return output_387_reg_move (insn, operands);"
4515   [(set_attr "type" "fmov")
4516    (set_attr "mode" "SF")])
4518 (define_split
4519   [(set (match_operand:SF 0 "register_operand" "")
4520         (float_truncate:SF
4521          (match_operand:DF 1 "fp_register_operand" "")))
4522    (clobber (match_operand 2 "" ""))]
4523   "reload_completed"
4524   [(set (match_dup 2) (match_dup 1))
4525    (set (match_dup 0) (match_dup 2))]
4527   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4530 ;; Conversion from XFmode to {SF,DF}mode
4532 (define_expand "truncxf<mode>2"
4533   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4534                    (float_truncate:MODEF
4535                      (match_operand:XF 1 "register_operand" "")))
4536               (clobber (match_dup 2))])]
4537   "TARGET_80387"
4539   if (flag_unsafe_math_optimizations)
4540     {
4541       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4542       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4543       if (reg != operands[0])
4544         emit_move_insn (operands[0], reg);
4545       DONE;
4546     }
4547   else
4548     {
4549       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4550       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4551     }
4554 (define_insn "*truncxfsf2_mixed"
4555   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4556         (float_truncate:SF
4557           (match_operand:XF 1 "register_operand" "f,f")))
4558    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4559   "TARGET_80387"
4561   gcc_assert (!which_alternative);
4562   return output_387_reg_move (insn, operands);
4564   [(set_attr "type" "fmov,multi")
4565    (set_attr "unit" "*,i387")
4566    (set_attr "mode" "SF")])
4568 (define_insn "*truncxfdf2_mixed"
4569   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4570         (float_truncate:DF
4571           (match_operand:XF 1 "register_operand" "f,f")))
4572    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4573   "TARGET_80387"
4575   gcc_assert (!which_alternative);
4576   return output_387_reg_move (insn, operands);
4578   [(set_attr "type" "fmov,multi")
4579    (set_attr "unit" "*,i387")
4580    (set_attr "mode" "DF")])
4582 (define_insn "truncxf<mode>2_i387_noop"
4583   [(set (match_operand:MODEF 0 "register_operand" "=f")
4584         (float_truncate:MODEF
4585           (match_operand:XF 1 "register_operand" "f")))]
4586   "TARGET_80387 && flag_unsafe_math_optimizations"
4587   "* return output_387_reg_move (insn, operands);"
4588   [(set_attr "type" "fmov")
4589    (set_attr "mode" "<MODE>")])
4591 (define_insn "*truncxf<mode>2_i387"
4592   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4593         (float_truncate:MODEF
4594           (match_operand:XF 1 "register_operand" "f")))]
4595   "TARGET_80387"
4596   "* return output_387_reg_move (insn, operands);"
4597   [(set_attr "type" "fmov")
4598    (set_attr "mode" "<MODE>")])
4600 (define_split
4601   [(set (match_operand:MODEF 0 "register_operand" "")
4602         (float_truncate:MODEF
4603           (match_operand:XF 1 "register_operand" "")))
4604    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4605   "TARGET_80387 && reload_completed"
4606   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4607    (set (match_dup 0) (match_dup 2))]
4608   "")
4610 (define_split
4611   [(set (match_operand:MODEF 0 "memory_operand" "")
4612         (float_truncate:MODEF
4613           (match_operand:XF 1 "register_operand" "")))
4614    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4615   "TARGET_80387"
4616   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4617   "")
4619 ;; Signed conversion to DImode.
4621 (define_expand "fix_truncxfdi2"
4622   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4623                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4624               (clobber (reg:CC FLAGS_REG))])]
4625   "TARGET_80387"
4627   if (TARGET_FISTTP)
4628    {
4629      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4630      DONE;
4631    }
4634 (define_expand "fix_trunc<mode>di2"
4635   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4636                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4637               (clobber (reg:CC FLAGS_REG))])]
4638   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4640   if (TARGET_FISTTP
4641       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4642    {
4643      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4644      DONE;
4645    }
4646   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4647    {
4648      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4649      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4650      if (out != operands[0])
4651         emit_move_insn (operands[0], out);
4652      DONE;
4653    }
4656 ;; Signed conversion to SImode.
4658 (define_expand "fix_truncxfsi2"
4659   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4660                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4661               (clobber (reg:CC FLAGS_REG))])]
4662   "TARGET_80387"
4664   if (TARGET_FISTTP)
4665    {
4666      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4667      DONE;
4668    }
4671 (define_expand "fix_trunc<mode>si2"
4672   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4673                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4674               (clobber (reg:CC FLAGS_REG))])]
4675   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4677   if (TARGET_FISTTP
4678       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4679    {
4680      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4681      DONE;
4682    }
4683   if (SSE_FLOAT_MODE_P (<MODE>mode))
4684    {
4685      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4686      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4687      if (out != operands[0])
4688         emit_move_insn (operands[0], out);
4689      DONE;
4690    }
4693 ;; Signed conversion to HImode.
4695 (define_expand "fix_trunc<mode>hi2"
4696   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4697                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4698               (clobber (reg:CC FLAGS_REG))])]
4699   "TARGET_80387
4700    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4702   if (TARGET_FISTTP)
4703    {
4704      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4705      DONE;
4706    }
4709 ;; Unsigned conversion to SImode.
4711 (define_expand "fixuns_trunc<mode>si2"
4712   [(parallel
4713     [(set (match_operand:SI 0 "register_operand" "")
4714           (unsigned_fix:SI
4715             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4716      (use (match_dup 2))
4717      (clobber (match_scratch:<ssevecmode> 3 ""))
4718      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4719   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4721   enum machine_mode mode = <MODE>mode;
4722   enum machine_mode vecmode = <ssevecmode>mode;
4723   REAL_VALUE_TYPE TWO31r;
4724   rtx two31;
4726   if (optimize_insn_for_size_p ())
4727     FAIL;
4729   real_ldexp (&TWO31r, &dconst1, 31);
4730   two31 = const_double_from_real_value (TWO31r, mode);
4731   two31 = ix86_build_const_vector (mode, true, two31);
4732   operands[2] = force_reg (vecmode, two31);
4735 (define_insn_and_split "*fixuns_trunc<mode>_1"
4736   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4737         (unsigned_fix:SI
4738           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4739    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4740    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4741    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4742   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4743    && optimize_function_for_speed_p (cfun)"
4744   "#"
4745   "&& reload_completed"
4746   [(const_int 0)]
4748   ix86_split_convert_uns_si_sse (operands);
4749   DONE;
4752 ;; Unsigned conversion to HImode.
4753 ;; Without these patterns, we'll try the unsigned SI conversion which
4754 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4756 (define_expand "fixuns_trunc<mode>hi2"
4757   [(set (match_dup 2)
4758         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4759    (set (match_operand:HI 0 "nonimmediate_operand" "")
4760         (subreg:HI (match_dup 2) 0))]
4761   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4762   "operands[2] = gen_reg_rtx (SImode);")
4764 ;; When SSE is available, it is always faster to use it!
4765 (define_insn "fix_trunc<mode>di_sse"
4766   [(set (match_operand:DI 0 "register_operand" "=r,r")
4767         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4768   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4769    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4770   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4771   [(set_attr "type" "sseicvt")
4772    (set_attr "prefix" "maybe_vex")
4773    (set_attr "mode" "<MODE>")
4774    (set_attr "athlon_decode" "double,vector")
4775    (set_attr "amdfam10_decode" "double,double")])
4777 (define_insn "fix_trunc<mode>si_sse"
4778   [(set (match_operand:SI 0 "register_operand" "=r,r")
4779         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4780   "SSE_FLOAT_MODE_P (<MODE>mode)
4781    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4782   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4783   [(set_attr "type" "sseicvt")
4784    (set_attr "prefix" "maybe_vex")
4785    (set_attr "mode" "<MODE>")
4786    (set_attr "athlon_decode" "double,vector")
4787    (set_attr "amdfam10_decode" "double,double")])
4789 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4790 (define_peephole2
4791   [(set (match_operand:MODEF 0 "register_operand" "")
4792         (match_operand:MODEF 1 "memory_operand" ""))
4793    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4794         (fix:SSEMODEI24 (match_dup 0)))]
4795   "TARGET_SHORTEN_X87_SSE
4796    && peep2_reg_dead_p (2, operands[0])"
4797   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4798   "")
4800 ;; Avoid vector decoded forms of the instruction.
4801 (define_peephole2
4802   [(match_scratch:DF 2 "Y2")
4803    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4804         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4805   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4806   [(set (match_dup 2) (match_dup 1))
4807    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4808   "")
4810 (define_peephole2
4811   [(match_scratch:SF 2 "x")
4812    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4813         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4814   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4815   [(set (match_dup 2) (match_dup 1))
4816    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4817   "")
4819 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4820   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4821         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4822   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4823    && TARGET_FISTTP
4824    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4825          && (TARGET_64BIT || <MODE>mode != DImode))
4826         && TARGET_SSE_MATH)
4827    && !(reload_completed || reload_in_progress)"
4828   "#"
4829   "&& 1"
4830   [(const_int 0)]
4832   if (memory_operand (operands[0], VOIDmode))
4833     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4834   else
4835     {
4836       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4837       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4838                                                             operands[1],
4839                                                             operands[2]));
4840     }
4841   DONE;
4843   [(set_attr "type" "fisttp")
4844    (set_attr "mode" "<MODE>")])
4846 (define_insn "fix_trunc<mode>_i387_fisttp"
4847   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4848         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4849    (clobber (match_scratch:XF 2 "=&1f"))]
4850   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4851    && TARGET_FISTTP
4852    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4853          && (TARGET_64BIT || <MODE>mode != DImode))
4854         && TARGET_SSE_MATH)"
4855   "* return output_fix_trunc (insn, operands, 1);"
4856   [(set_attr "type" "fisttp")
4857    (set_attr "mode" "<MODE>")])
4859 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4860   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4861         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4862    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4863    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4864   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4865    && TARGET_FISTTP
4866    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4867         && (TARGET_64BIT || <MODE>mode != DImode))
4868         && TARGET_SSE_MATH)"
4869   "#"
4870   [(set_attr "type" "fisttp")
4871    (set_attr "mode" "<MODE>")])
4873 (define_split
4874   [(set (match_operand:X87MODEI 0 "register_operand" "")
4875         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4876    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4877    (clobber (match_scratch 3 ""))]
4878   "reload_completed"
4879   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4880               (clobber (match_dup 3))])
4881    (set (match_dup 0) (match_dup 2))]
4882   "")
4884 (define_split
4885   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4886         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4887    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4888    (clobber (match_scratch 3 ""))]
4889   "reload_completed"
4890   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4891               (clobber (match_dup 3))])]
4892   "")
4894 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4895 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4896 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4897 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4898 ;; function in i386.c.
4899 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4900   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4901         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4902    (clobber (reg:CC FLAGS_REG))]
4903   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4904    && !TARGET_FISTTP
4905    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4906          && (TARGET_64BIT || <MODE>mode != DImode))
4907    && !(reload_completed || reload_in_progress)"
4908   "#"
4909   "&& 1"
4910   [(const_int 0)]
4912   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4914   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4915   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4916   if (memory_operand (operands[0], VOIDmode))
4917     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4918                                          operands[2], operands[3]));
4919   else
4920     {
4921       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4922       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4923                                                      operands[2], operands[3],
4924                                                      operands[4]));
4925     }
4926   DONE;
4928   [(set_attr "type" "fistp")
4929    (set_attr "i387_cw" "trunc")
4930    (set_attr "mode" "<MODE>")])
4932 (define_insn "fix_truncdi_i387"
4933   [(set (match_operand:DI 0 "memory_operand" "=m")
4934         (fix:DI (match_operand 1 "register_operand" "f")))
4935    (use (match_operand:HI 2 "memory_operand" "m"))
4936    (use (match_operand:HI 3 "memory_operand" "m"))
4937    (clobber (match_scratch:XF 4 "=&1f"))]
4938   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4939    && !TARGET_FISTTP
4940    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4941   "* return output_fix_trunc (insn, operands, 0);"
4942   [(set_attr "type" "fistp")
4943    (set_attr "i387_cw" "trunc")
4944    (set_attr "mode" "DI")])
4946 (define_insn "fix_truncdi_i387_with_temp"
4947   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4948         (fix:DI (match_operand 1 "register_operand" "f,f")))
4949    (use (match_operand:HI 2 "memory_operand" "m,m"))
4950    (use (match_operand:HI 3 "memory_operand" "m,m"))
4951    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4952    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4953   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4954    && !TARGET_FISTTP
4955    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4956   "#"
4957   [(set_attr "type" "fistp")
4958    (set_attr "i387_cw" "trunc")
4959    (set_attr "mode" "DI")])
4961 (define_split
4962   [(set (match_operand:DI 0 "register_operand" "")
4963         (fix:DI (match_operand 1 "register_operand" "")))
4964    (use (match_operand:HI 2 "memory_operand" ""))
4965    (use (match_operand:HI 3 "memory_operand" ""))
4966    (clobber (match_operand:DI 4 "memory_operand" ""))
4967    (clobber (match_scratch 5 ""))]
4968   "reload_completed"
4969   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4970               (use (match_dup 2))
4971               (use (match_dup 3))
4972               (clobber (match_dup 5))])
4973    (set (match_dup 0) (match_dup 4))]
4974   "")
4976 (define_split
4977   [(set (match_operand:DI 0 "memory_operand" "")
4978         (fix:DI (match_operand 1 "register_operand" "")))
4979    (use (match_operand:HI 2 "memory_operand" ""))
4980    (use (match_operand:HI 3 "memory_operand" ""))
4981    (clobber (match_operand:DI 4 "memory_operand" ""))
4982    (clobber (match_scratch 5 ""))]
4983   "reload_completed"
4984   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4985               (use (match_dup 2))
4986               (use (match_dup 3))
4987               (clobber (match_dup 5))])]
4988   "")
4990 (define_insn "fix_trunc<mode>_i387"
4991   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4992         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4993    (use (match_operand:HI 2 "memory_operand" "m"))
4994    (use (match_operand:HI 3 "memory_operand" "m"))]
4995   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4996    && !TARGET_FISTTP
4997    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4998   "* return output_fix_trunc (insn, operands, 0);"
4999   [(set_attr "type" "fistp")
5000    (set_attr "i387_cw" "trunc")
5001    (set_attr "mode" "<MODE>")])
5003 (define_insn "fix_trunc<mode>_i387_with_temp"
5004   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5005         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5006    (use (match_operand:HI 2 "memory_operand" "m,m"))
5007    (use (match_operand:HI 3 "memory_operand" "m,m"))
5008    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5009   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5010    && !TARGET_FISTTP
5011    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5012   "#"
5013   [(set_attr "type" "fistp")
5014    (set_attr "i387_cw" "trunc")
5015    (set_attr "mode" "<MODE>")])
5017 (define_split
5018   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5019         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5020    (use (match_operand:HI 2 "memory_operand" ""))
5021    (use (match_operand:HI 3 "memory_operand" ""))
5022    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5023   "reload_completed"
5024   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5025               (use (match_dup 2))
5026               (use (match_dup 3))])
5027    (set (match_dup 0) (match_dup 4))]
5028   "")
5030 (define_split
5031   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5032         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5033    (use (match_operand:HI 2 "memory_operand" ""))
5034    (use (match_operand:HI 3 "memory_operand" ""))
5035    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5036   "reload_completed"
5037   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5038               (use (match_dup 2))
5039               (use (match_dup 3))])]
5040   "")
5042 (define_insn "x86_fnstcw_1"
5043   [(set (match_operand:HI 0 "memory_operand" "=m")
5044         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5045   "TARGET_80387"
5046   "fnstcw\t%0"
5047   [(set_attr "length" "2")
5048    (set_attr "mode" "HI")
5049    (set_attr "unit" "i387")])
5051 (define_insn "x86_fldcw_1"
5052   [(set (reg:HI FPCR_REG)
5053         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5054   "TARGET_80387"
5055   "fldcw\t%0"
5056   [(set_attr "length" "2")
5057    (set_attr "mode" "HI")
5058    (set_attr "unit" "i387")
5059    (set_attr "athlon_decode" "vector")
5060    (set_attr "amdfam10_decode" "vector")])
5062 ;; Conversion between fixed point and floating point.
5064 ;; Even though we only accept memory inputs, the backend _really_
5065 ;; wants to be able to do this between registers.
5067 (define_expand "floathi<mode>2"
5068   [(set (match_operand:X87MODEF 0 "register_operand" "")
5069         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5070   "TARGET_80387
5071    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5072        || TARGET_MIX_SSE_I387)"
5073   "")
5075 ;; Pre-reload splitter to add memory clobber to the pattern.
5076 (define_insn_and_split "*floathi<mode>2_1"
5077   [(set (match_operand:X87MODEF 0 "register_operand" "")
5078         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5079   "TARGET_80387
5080    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5081        || TARGET_MIX_SSE_I387)
5082    && !(reload_completed || reload_in_progress)"
5083   "#"
5084   "&& 1"
5085   [(parallel [(set (match_dup 0)
5086               (float:X87MODEF (match_dup 1)))
5087    (clobber (match_dup 2))])]
5088   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5090 (define_insn "*floathi<mode>2_i387_with_temp"
5091   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5092         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5093   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5094   "TARGET_80387
5095    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5096        || TARGET_MIX_SSE_I387)"
5097   "#"
5098   [(set_attr "type" "fmov,multi")
5099    (set_attr "mode" "<MODE>")
5100    (set_attr "unit" "*,i387")
5101    (set_attr "fp_int_src" "true")])
5103 (define_insn "*floathi<mode>2_i387"
5104   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5105         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5106   "TARGET_80387
5107    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5108        || TARGET_MIX_SSE_I387)"
5109   "fild%z1\t%1"
5110   [(set_attr "type" "fmov")
5111    (set_attr "mode" "<MODE>")
5112    (set_attr "fp_int_src" "true")])
5114 (define_split
5115   [(set (match_operand:X87MODEF 0 "register_operand" "")
5116         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5117    (clobber (match_operand:HI 2 "memory_operand" ""))]
5118   "TARGET_80387
5119    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5120        || TARGET_MIX_SSE_I387)
5121    && reload_completed"
5122   [(set (match_dup 2) (match_dup 1))
5123    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5124   "")
5126 (define_split
5127   [(set (match_operand:X87MODEF 0 "register_operand" "")
5128         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5129    (clobber (match_operand:HI 2 "memory_operand" ""))]
5130    "TARGET_80387
5131     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5132         || TARGET_MIX_SSE_I387)
5133     && reload_completed"
5134   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5135   "")
5137 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5138   [(set (match_operand:X87MODEF 0 "register_operand" "")
5139         (float:X87MODEF
5140           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5141   "TARGET_80387
5142    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5143        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5144   "")
5146 ;; Pre-reload splitter to add memory clobber to the pattern.
5147 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5148   [(set (match_operand:X87MODEF 0 "register_operand" "")
5149         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5150   "((TARGET_80387
5151      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5152            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5153          || TARGET_MIX_SSE_I387))
5154     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5155         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5156         && ((<SSEMODEI24:MODE>mode == SImode
5157              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5158              && optimize_function_for_speed_p (cfun)
5159              && flag_trapping_math)
5160             || !(TARGET_INTER_UNIT_CONVERSIONS
5161                  || optimize_function_for_size_p (cfun)))))
5162    && !(reload_completed || reload_in_progress)"
5163   "#"
5164   "&& 1"
5165   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5166               (clobber (match_dup 2))])]
5168   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5170   /* Avoid store forwarding (partial memory) stall penalty
5171      by passing DImode value through XMM registers.  */
5172   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5173       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5174       && optimize_function_for_speed_p (cfun))
5175     {
5176       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5177                                                             operands[1],
5178                                                             operands[2]));
5179       DONE;
5180     }
5183 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5184   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5185         (float:MODEF
5186           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5187    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5188   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5189    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5190   "#"
5191   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5192    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5193    (set_attr "unit" "*,i387,*,*,*")
5194    (set_attr "athlon_decode" "*,*,double,direct,double")
5195    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5196    (set_attr "fp_int_src" "true")])
5198 (define_insn "*floatsi<mode>2_vector_mixed"
5199   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5200         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5201   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5202    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5203   "@
5204    fild%z1\t%1
5205    #"
5206   [(set_attr "type" "fmov,sseicvt")
5207    (set_attr "mode" "<MODE>,<ssevecmode>")
5208    (set_attr "unit" "i387,*")
5209    (set_attr "athlon_decode" "*,direct")
5210    (set_attr "amdfam10_decode" "*,double")
5211    (set_attr "fp_int_src" "true")])
5213 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5214   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5215         (float:MODEF
5216           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5217   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5218   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5219    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5220   "#"
5221   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5222    (set_attr "mode" "<MODEF:MODE>")
5223    (set_attr "unit" "*,i387,*,*")
5224    (set_attr "athlon_decode" "*,*,double,direct")
5225    (set_attr "amdfam10_decode" "*,*,vector,double")
5226    (set_attr "fp_int_src" "true")])
5228 (define_split
5229   [(set (match_operand:MODEF 0 "register_operand" "")
5230         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5231    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5232   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5233    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5234    && TARGET_INTER_UNIT_CONVERSIONS
5235    && reload_completed
5236    && (SSE_REG_P (operands[0])
5237        || (GET_CODE (operands[0]) == SUBREG
5238            && SSE_REG_P (operands[0])))"
5239   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5240   "")
5242 (define_split
5243   [(set (match_operand:MODEF 0 "register_operand" "")
5244         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5245    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5246   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5247    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5248    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5249    && reload_completed
5250    && (SSE_REG_P (operands[0])
5251        || (GET_CODE (operands[0]) == SUBREG
5252            && SSE_REG_P (operands[0])))"
5253   [(set (match_dup 2) (match_dup 1))
5254    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5255   "")
5257 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5258   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5259         (float:MODEF
5260           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5261   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5262    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5263    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5264   "@
5265    fild%z1\t%1
5266    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5267    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5268   [(set_attr "type" "fmov,sseicvt,sseicvt")
5269    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5270    (set_attr "mode" "<MODEF:MODE>")
5271    (set_attr "unit" "i387,*,*")
5272    (set_attr "athlon_decode" "*,double,direct")
5273    (set_attr "amdfam10_decode" "*,vector,double")
5274    (set_attr "fp_int_src" "true")])
5276 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5277   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5278         (float:MODEF
5279           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5280   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5281    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5282    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5283   "@
5284    fild%z1\t%1
5285    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5286   [(set_attr "type" "fmov,sseicvt")
5287    (set_attr "prefix" "orig,maybe_vex")
5288    (set_attr "mode" "<MODEF:MODE>")
5289    (set_attr "athlon_decode" "*,direct")
5290    (set_attr "amdfam10_decode" "*,double")
5291    (set_attr "fp_int_src" "true")])
5293 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5294   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5295         (float:MODEF
5296           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5297    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5298   "TARGET_SSE2 && TARGET_SSE_MATH
5299    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5300   "#"
5301   [(set_attr "type" "sseicvt")
5302    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5303    (set_attr "athlon_decode" "double,direct,double")
5304    (set_attr "amdfam10_decode" "vector,double,double")
5305    (set_attr "fp_int_src" "true")])
5307 (define_insn "*floatsi<mode>2_vector_sse"
5308   [(set (match_operand:MODEF 0 "register_operand" "=x")
5309         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5310   "TARGET_SSE2 && TARGET_SSE_MATH
5311    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5312   "#"
5313   [(set_attr "type" "sseicvt")
5314    (set_attr "mode" "<MODE>")
5315    (set_attr "athlon_decode" "direct")
5316    (set_attr "amdfam10_decode" "double")
5317    (set_attr "fp_int_src" "true")])
5319 (define_split
5320   [(set (match_operand:MODEF 0 "register_operand" "")
5321         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5322    (clobber (match_operand:SI 2 "memory_operand" ""))]
5323   "TARGET_SSE2 && TARGET_SSE_MATH
5324    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5325    && reload_completed
5326    && (SSE_REG_P (operands[0])
5327        || (GET_CODE (operands[0]) == SUBREG
5328            && SSE_REG_P (operands[0])))"
5329   [(const_int 0)]
5331   rtx op1 = operands[1];
5333   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5334                                      <MODE>mode, 0);
5335   if (GET_CODE (op1) == SUBREG)
5336     op1 = SUBREG_REG (op1);
5338   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5339     {
5340       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5341       emit_insn (gen_sse2_loadld (operands[4],
5342                                   CONST0_RTX (V4SImode), operands[1]));
5343     }
5344   /* We can ignore possible trapping value in the
5345      high part of SSE register for non-trapping math. */
5346   else if (SSE_REG_P (op1) && !flag_trapping_math)
5347     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5348   else
5349     {
5350       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5351       emit_move_insn (operands[2], operands[1]);
5352       emit_insn (gen_sse2_loadld (operands[4],
5353                                   CONST0_RTX (V4SImode), operands[2]));
5354     }
5355   emit_insn
5356     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5357   DONE;
5360 (define_split
5361   [(set (match_operand:MODEF 0 "register_operand" "")
5362         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5363    (clobber (match_operand:SI 2 "memory_operand" ""))]
5364   "TARGET_SSE2 && TARGET_SSE_MATH
5365    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5366    && reload_completed
5367    && (SSE_REG_P (operands[0])
5368        || (GET_CODE (operands[0]) == SUBREG
5369            && SSE_REG_P (operands[0])))"
5370   [(const_int 0)]
5372   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5373                                      <MODE>mode, 0);
5374   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5376   emit_insn (gen_sse2_loadld (operands[4],
5377                               CONST0_RTX (V4SImode), operands[1]));
5378   emit_insn
5379     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5380   DONE;
5383 (define_split
5384   [(set (match_operand:MODEF 0 "register_operand" "")
5385         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5386   "TARGET_SSE2 && TARGET_SSE_MATH
5387    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5388    && reload_completed
5389    && (SSE_REG_P (operands[0])
5390        || (GET_CODE (operands[0]) == SUBREG
5391            && SSE_REG_P (operands[0])))"
5392   [(const_int 0)]
5394   rtx op1 = operands[1];
5396   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5397                                      <MODE>mode, 0);
5398   if (GET_CODE (op1) == SUBREG)
5399     op1 = SUBREG_REG (op1);
5401   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5402     {
5403       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5404       emit_insn (gen_sse2_loadld (operands[4],
5405                                   CONST0_RTX (V4SImode), operands[1]));
5406     }
5407   /* We can ignore possible trapping value in the
5408      high part of SSE register for non-trapping math. */
5409   else if (SSE_REG_P (op1) && !flag_trapping_math)
5410     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5411   else
5412     gcc_unreachable ();
5413   emit_insn
5414     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5415   DONE;
5418 (define_split
5419   [(set (match_operand:MODEF 0 "register_operand" "")
5420         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5421   "TARGET_SSE2 && TARGET_SSE_MATH
5422    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5423    && reload_completed
5424    && (SSE_REG_P (operands[0])
5425        || (GET_CODE (operands[0]) == SUBREG
5426            && SSE_REG_P (operands[0])))"
5427   [(const_int 0)]
5429   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5430                                      <MODE>mode, 0);
5431   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5433   emit_insn (gen_sse2_loadld (operands[4],
5434                               CONST0_RTX (V4SImode), operands[1]));
5435   emit_insn
5436     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5437   DONE;
5440 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5441   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5442         (float:MODEF
5443           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5444   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5445   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5446    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5447   "#"
5448   [(set_attr "type" "sseicvt")
5449    (set_attr "mode" "<MODEF:MODE>")
5450    (set_attr "athlon_decode" "double,direct")
5451    (set_attr "amdfam10_decode" "vector,double")
5452    (set_attr "fp_int_src" "true")])
5454 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5455   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5456         (float:MODEF
5457           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5458   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5459    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5460    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5461   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5462   [(set_attr "type" "sseicvt")
5463    (set_attr "prefix" "maybe_vex")
5464    (set_attr "mode" "<MODEF:MODE>")
5465    (set_attr "athlon_decode" "double,direct")
5466    (set_attr "amdfam10_decode" "vector,double")
5467    (set_attr "fp_int_src" "true")])
5469 (define_split
5470   [(set (match_operand:MODEF 0 "register_operand" "")
5471         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5472    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5473   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5474    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5475    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5476    && reload_completed
5477    && (SSE_REG_P (operands[0])
5478        || (GET_CODE (operands[0]) == SUBREG
5479            && SSE_REG_P (operands[0])))"
5480   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5481   "")
5483 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5484   [(set (match_operand:MODEF 0 "register_operand" "=x")
5485         (float:MODEF
5486           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5487   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5488    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5489    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5490   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5491   [(set_attr "type" "sseicvt")
5492    (set_attr "prefix" "maybe_vex")
5493    (set_attr "mode" "<MODEF:MODE>")
5494    (set_attr "athlon_decode" "direct")
5495    (set_attr "amdfam10_decode" "double")
5496    (set_attr "fp_int_src" "true")])
5498 (define_split
5499   [(set (match_operand:MODEF 0 "register_operand" "")
5500         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5501    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5502   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5503    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5504    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5505    && reload_completed
5506    && (SSE_REG_P (operands[0])
5507        || (GET_CODE (operands[0]) == SUBREG
5508            && SSE_REG_P (operands[0])))"
5509   [(set (match_dup 2) (match_dup 1))
5510    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5511   "")
5513 (define_split
5514   [(set (match_operand:MODEF 0 "register_operand" "")
5515         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5516    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5517   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5518    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5519    && reload_completed
5520    && (SSE_REG_P (operands[0])
5521        || (GET_CODE (operands[0]) == SUBREG
5522            && SSE_REG_P (operands[0])))"
5523   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5524   "")
5526 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5527   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5528         (float:X87MODEF
5529           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5530   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5531   "TARGET_80387"
5532   "@
5533    fild%z1\t%1
5534    #"
5535   [(set_attr "type" "fmov,multi")
5536    (set_attr "mode" "<X87MODEF:MODE>")
5537    (set_attr "unit" "*,i387")
5538    (set_attr "fp_int_src" "true")])
5540 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5541   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5542         (float:X87MODEF
5543           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5544   "TARGET_80387"
5545   "fild%z1\t%1"
5546   [(set_attr "type" "fmov")
5547    (set_attr "mode" "<X87MODEF:MODE>")
5548    (set_attr "fp_int_src" "true")])
5550 (define_split
5551   [(set (match_operand:X87MODEF 0 "register_operand" "")
5552         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5553    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5554   "TARGET_80387
5555    && reload_completed
5556    && FP_REG_P (operands[0])"
5557   [(set (match_dup 2) (match_dup 1))
5558    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5559   "")
5561 (define_split
5562   [(set (match_operand:X87MODEF 0 "register_operand" "")
5563         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5564    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5565   "TARGET_80387
5566    && reload_completed
5567    && FP_REG_P (operands[0])"
5568   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5569   "")
5571 ;; Avoid store forwarding (partial memory) stall penalty
5572 ;; by passing DImode value through XMM registers.  */
5574 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5575   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5576         (float:X87MODEF
5577           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5578    (clobber (match_scratch:V4SI 3 "=X,x"))
5579    (clobber (match_scratch:V4SI 4 "=X,x"))
5580    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5581   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5582    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5583   "#"
5584   [(set_attr "type" "multi")
5585    (set_attr "mode" "<X87MODEF:MODE>")
5586    (set_attr "unit" "i387")
5587    (set_attr "fp_int_src" "true")])
5589 (define_split
5590   [(set (match_operand:X87MODEF 0 "register_operand" "")
5591         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5592    (clobber (match_scratch:V4SI 3 ""))
5593    (clobber (match_scratch:V4SI 4 ""))
5594    (clobber (match_operand:DI 2 "memory_operand" ""))]
5595   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5596    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5597    && reload_completed
5598    && FP_REG_P (operands[0])"
5599   [(set (match_dup 2) (match_dup 3))
5600    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5602   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5603      Assemble the 64-bit DImode value in an xmm register.  */
5604   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5605                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5606   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5607                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5608   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5610   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5613 (define_split
5614   [(set (match_operand:X87MODEF 0 "register_operand" "")
5615         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5616    (clobber (match_scratch:V4SI 3 ""))
5617    (clobber (match_scratch:V4SI 4 ""))
5618    (clobber (match_operand:DI 2 "memory_operand" ""))]
5619   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5620    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5621    && reload_completed
5622    && FP_REG_P (operands[0])"
5623   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5624   "")
5626 ;; Avoid store forwarding (partial memory) stall penalty by extending
5627 ;; SImode value to DImode through XMM register instead of pushing two
5628 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5629 ;; targets benefit from this optimization. Also note that fild
5630 ;; loads from memory only.
5632 (define_insn "*floatunssi<mode>2_1"
5633   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5634         (unsigned_float:X87MODEF
5635           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5636    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5637    (clobber (match_scratch:SI 3 "=X,x"))]
5638   "!TARGET_64BIT
5639    && TARGET_80387 && TARGET_SSE"
5640   "#"
5641   [(set_attr "type" "multi")
5642    (set_attr "mode" "<MODE>")])
5644 (define_split
5645   [(set (match_operand:X87MODEF 0 "register_operand" "")
5646         (unsigned_float:X87MODEF
5647           (match_operand:SI 1 "register_operand" "")))
5648    (clobber (match_operand:DI 2 "memory_operand" ""))
5649    (clobber (match_scratch:SI 3 ""))]
5650   "!TARGET_64BIT
5651    && TARGET_80387 && TARGET_SSE
5652    && reload_completed"
5653   [(set (match_dup 2) (match_dup 1))
5654    (set (match_dup 0)
5655         (float:X87MODEF (match_dup 2)))]
5656   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5658 (define_split
5659   [(set (match_operand:X87MODEF 0 "register_operand" "")
5660         (unsigned_float:X87MODEF
5661           (match_operand:SI 1 "memory_operand" "")))
5662    (clobber (match_operand:DI 2 "memory_operand" ""))
5663    (clobber (match_scratch:SI 3 ""))]
5664   "!TARGET_64BIT
5665    && TARGET_80387 && TARGET_SSE
5666    && reload_completed"
5667   [(set (match_dup 2) (match_dup 3))
5668    (set (match_dup 0)
5669         (float:X87MODEF (match_dup 2)))]
5671   emit_move_insn (operands[3], operands[1]);
5672   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5675 (define_expand "floatunssi<mode>2"
5676   [(parallel
5677      [(set (match_operand:X87MODEF 0 "register_operand" "")
5678            (unsigned_float:X87MODEF
5679              (match_operand:SI 1 "nonimmediate_operand" "")))
5680       (clobber (match_dup 2))
5681       (clobber (match_scratch:SI 3 ""))])]
5682   "!TARGET_64BIT
5683    && ((TARGET_80387 && TARGET_SSE)
5684        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5686   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5687     {
5688       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5689       DONE;
5690     }
5691   else
5692     {
5693       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5694       operands[2] = assign_386_stack_local (DImode, slot);
5695     }
5698 (define_expand "floatunsdisf2"
5699   [(use (match_operand:SF 0 "register_operand" ""))
5700    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5701   "TARGET_64BIT && TARGET_SSE_MATH"
5702   "x86_emit_floatuns (operands); DONE;")
5704 (define_expand "floatunsdidf2"
5705   [(use (match_operand:DF 0 "register_operand" ""))
5706    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5707   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5708    && TARGET_SSE2 && TARGET_SSE_MATH"
5710   if (TARGET_64BIT)
5711     x86_emit_floatuns (operands);
5712   else
5713     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5714   DONE;
5717 ;; Add instructions
5719 ;; %%% splits for addditi3
5721 (define_expand "addti3"
5722   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5723         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5724                  (match_operand:TI 2 "x86_64_general_operand" "")))]
5725   "TARGET_64BIT"
5726   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5728 (define_insn "*addti3_1"
5729   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5730         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5731                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5732    (clobber (reg:CC FLAGS_REG))]
5733   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5734   "#")
5736 (define_split
5737   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5738         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5739                  (match_operand:TI 2 "x86_64_general_operand" "")))
5740    (clobber (reg:CC FLAGS_REG))]
5741   "TARGET_64BIT && reload_completed"
5742   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5743                                           UNSPEC_ADD_CARRY))
5744               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5745    (parallel [(set (match_dup 3)
5746                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5747                                      (match_dup 4))
5748                             (match_dup 5)))
5749               (clobber (reg:CC FLAGS_REG))])]
5750   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5752 ;; %%% splits for addsidi3
5753 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5754 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5755 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5757 (define_expand "adddi3"
5758   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5759         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5760                  (match_operand:DI 2 "x86_64_general_operand" "")))]
5761   ""
5762   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5764 (define_insn "*adddi3_1"
5765   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5766         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5767                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5768    (clobber (reg:CC FLAGS_REG))]
5769   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5770   "#")
5772 (define_split
5773   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5774         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5775                  (match_operand:DI 2 "general_operand" "")))
5776    (clobber (reg:CC FLAGS_REG))]
5777   "!TARGET_64BIT && reload_completed"
5778   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5779                                           UNSPEC_ADD_CARRY))
5780               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5781    (parallel [(set (match_dup 3)
5782                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5783                                      (match_dup 4))
5784                             (match_dup 5)))
5785               (clobber (reg:CC FLAGS_REG))])]
5786   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5788 (define_insn "adddi3_carry_rex64"
5789   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5790           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5791                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5792                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5793    (clobber (reg:CC FLAGS_REG))]
5794   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5795   "adc{q}\t{%2, %0|%0, %2}"
5796   [(set_attr "type" "alu")
5797    (set_attr "pent_pair" "pu")
5798    (set_attr "mode" "DI")])
5800 (define_insn "*adddi3_cc_rex64"
5801   [(set (reg:CC FLAGS_REG)
5802         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5803                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5804                    UNSPEC_ADD_CARRY))
5805    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5806         (plus:DI (match_dup 1) (match_dup 2)))]
5807   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5808   "add{q}\t{%2, %0|%0, %2}"
5809   [(set_attr "type" "alu")
5810    (set_attr "mode" "DI")])
5812 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5813   [(set (reg:CCC FLAGS_REG)
5814         (compare:CCC
5815             (plusminus:SWI
5816                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5817                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5818             (match_dup 1)))
5819    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5820         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5821   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5822   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5823   [(set_attr "type" "alu")
5824    (set_attr "mode" "<MODE>")])
5826 (define_insn "*add<mode>3_cconly_overflow"
5827   [(set (reg:CCC FLAGS_REG)
5828         (compare:CCC
5829                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5830                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5831                 (match_dup 1)))
5832    (clobber (match_scratch:SWI 0 "=<r>"))]
5833   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5834   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5835   [(set_attr "type" "alu")
5836    (set_attr "mode" "<MODE>")])
5838 (define_insn "*sub<mode>3_cconly_overflow"
5839   [(set (reg:CCC FLAGS_REG)
5840         (compare:CCC
5841              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5842                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5843              (match_dup 0)))]
5844   ""
5845   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5846   [(set_attr "type" "icmp")
5847    (set_attr "mode" "<MODE>")])
5849 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5850   [(set (reg:CCC FLAGS_REG)
5851         (compare:CCC
5852             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5853                           (match_operand:SI 2 "general_operand" "g"))
5854             (match_dup 1)))
5855    (set (match_operand:DI 0 "register_operand" "=r")
5856         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5857   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5858   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5859   [(set_attr "type" "alu")
5860    (set_attr "mode" "SI")])
5862 (define_insn "addqi3_carry"
5863   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5864           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5865                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5866                    (match_operand:QI 2 "general_operand" "qn,qm")))
5867    (clobber (reg:CC FLAGS_REG))]
5868   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5869   "adc{b}\t{%2, %0|%0, %2}"
5870   [(set_attr "type" "alu")
5871    (set_attr "pent_pair" "pu")
5872    (set_attr "mode" "QI")])
5874 (define_insn "addhi3_carry"
5875   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5876           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5877                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5878                    (match_operand:HI 2 "general_operand" "rn,rm")))
5879    (clobber (reg:CC FLAGS_REG))]
5880   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5881   "adc{w}\t{%2, %0|%0, %2}"
5882   [(set_attr "type" "alu")
5883    (set_attr "pent_pair" "pu")
5884    (set_attr "mode" "HI")])
5886 (define_insn "addsi3_carry"
5887   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5888           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5889                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5890                    (match_operand:SI 2 "general_operand" "ri,rm")))
5891    (clobber (reg:CC FLAGS_REG))]
5892   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5893   "adc{l}\t{%2, %0|%0, %2}"
5894   [(set_attr "type" "alu")
5895    (set_attr "pent_pair" "pu")
5896    (set_attr "mode" "SI")])
5898 (define_insn "*addsi3_carry_zext"
5899   [(set (match_operand:DI 0 "register_operand" "=r")
5900           (zero_extend:DI
5901             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5902                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5903                      (match_operand:SI 2 "general_operand" "g"))))
5904    (clobber (reg:CC FLAGS_REG))]
5905   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5906   "adc{l}\t{%2, %k0|%k0, %2}"
5907   [(set_attr "type" "alu")
5908    (set_attr "pent_pair" "pu")
5909    (set_attr "mode" "SI")])
5911 (define_insn "*addsi3_cc"
5912   [(set (reg:CC FLAGS_REG)
5913         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5914                     (match_operand:SI 2 "general_operand" "ri,rm")]
5915                    UNSPEC_ADD_CARRY))
5916    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5917         (plus:SI (match_dup 1) (match_dup 2)))]
5918   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5919   "add{l}\t{%2, %0|%0, %2}"
5920   [(set_attr "type" "alu")
5921    (set_attr "mode" "SI")])
5923 (define_insn "addqi3_cc"
5924   [(set (reg:CC FLAGS_REG)
5925         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5926                     (match_operand:QI 2 "general_operand" "qn,qm")]
5927                    UNSPEC_ADD_CARRY))
5928    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5929         (plus:QI (match_dup 1) (match_dup 2)))]
5930   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5931   "add{b}\t{%2, %0|%0, %2}"
5932   [(set_attr "type" "alu")
5933    (set_attr "mode" "QI")])
5935 (define_expand "addsi3"
5936   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5937         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5938                  (match_operand:SI 2 "general_operand" "")))]
5939   ""
5940   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5942 (define_insn "*lea_1"
5943   [(set (match_operand:SI 0 "register_operand" "=r")
5944         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5945   "!TARGET_64BIT"
5946   "lea{l}\t{%a1, %0|%0, %a1}"
5947   [(set_attr "type" "lea")
5948    (set_attr "mode" "SI")])
5950 (define_insn "*lea_1_rex64"
5951   [(set (match_operand:SI 0 "register_operand" "=r")
5952         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5953   "TARGET_64BIT"
5954   "lea{l}\t{%a1, %0|%0, %a1}"
5955   [(set_attr "type" "lea")
5956    (set_attr "mode" "SI")])
5958 (define_insn "*lea_1_zext"
5959   [(set (match_operand:DI 0 "register_operand" "=r")
5960         (zero_extend:DI
5961          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5962   "TARGET_64BIT"
5963   "lea{l}\t{%a1, %k0|%k0, %a1}"
5964   [(set_attr "type" "lea")
5965    (set_attr "mode" "SI")])
5967 (define_insn "*lea_2_rex64"
5968   [(set (match_operand:DI 0 "register_operand" "=r")
5969         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5970   "TARGET_64BIT"
5971   "lea{q}\t{%a1, %0|%0, %a1}"
5972   [(set_attr "type" "lea")
5973    (set_attr "mode" "DI")])
5975 ;; The lea patterns for non-Pmodes needs to be matched by several
5976 ;; insns converted to real lea by splitters.
5978 (define_insn_and_split "*lea_general_1"
5979   [(set (match_operand 0 "register_operand" "=r")
5980         (plus (plus (match_operand 1 "index_register_operand" "l")
5981                     (match_operand 2 "register_operand" "r"))
5982               (match_operand 3 "immediate_operand" "i")))]
5983   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5984     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5985    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5986    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5987    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5988    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5989        || GET_MODE (operands[3]) == VOIDmode)"
5990   "#"
5991   "&& reload_completed"
5992   [(const_int 0)]
5994   rtx pat;
5995   operands[0] = gen_lowpart (SImode, operands[0]);
5996   operands[1] = gen_lowpart (Pmode, operands[1]);
5997   operands[2] = gen_lowpart (Pmode, operands[2]);
5998   operands[3] = gen_lowpart (Pmode, operands[3]);
5999   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6000                       operands[3]);
6001   if (Pmode != SImode)
6002     pat = gen_rtx_SUBREG (SImode, pat, 0);
6003   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6004   DONE;
6006   [(set_attr "type" "lea")
6007    (set_attr "mode" "SI")])
6009 (define_insn_and_split "*lea_general_1_zext"
6010   [(set (match_operand:DI 0 "register_operand" "=r")
6011         (zero_extend:DI
6012           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
6013                             (match_operand:SI 2 "register_operand" "r"))
6014                    (match_operand:SI 3 "immediate_operand" "i"))))]
6015   "TARGET_64BIT"
6016   "#"
6017   "&& reload_completed"
6018   [(set (match_dup 0)
6019         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6020                                                      (match_dup 2))
6021                                             (match_dup 3)) 0)))]
6023   operands[1] = gen_lowpart (Pmode, operands[1]);
6024   operands[2] = gen_lowpart (Pmode, operands[2]);
6025   operands[3] = gen_lowpart (Pmode, operands[3]);
6027   [(set_attr "type" "lea")
6028    (set_attr "mode" "SI")])
6030 (define_insn_and_split "*lea_general_2"
6031   [(set (match_operand 0 "register_operand" "=r")
6032         (plus (mult (match_operand 1 "index_register_operand" "l")
6033                     (match_operand 2 "const248_operand" "i"))
6034               (match_operand 3 "nonmemory_operand" "ri")))]
6035   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6036     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6037    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6038    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6039    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6040        || GET_MODE (operands[3]) == VOIDmode)"
6041   "#"
6042   "&& reload_completed"
6043   [(const_int 0)]
6045   rtx pat;
6046   operands[0] = gen_lowpart (SImode, operands[0]);
6047   operands[1] = gen_lowpart (Pmode, operands[1]);
6048   operands[3] = gen_lowpart (Pmode, operands[3]);
6049   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6050                       operands[3]);
6051   if (Pmode != SImode)
6052     pat = gen_rtx_SUBREG (SImode, pat, 0);
6053   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6054   DONE;
6056   [(set_attr "type" "lea")
6057    (set_attr "mode" "SI")])
6059 (define_insn_and_split "*lea_general_2_zext"
6060   [(set (match_operand:DI 0 "register_operand" "=r")
6061         (zero_extend:DI
6062           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6063                             (match_operand:SI 2 "const248_operand" "n"))
6064                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6065   "TARGET_64BIT"
6066   "#"
6067   "&& reload_completed"
6068   [(set (match_dup 0)
6069         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6070                                                      (match_dup 2))
6071                                             (match_dup 3)) 0)))]
6073   operands[1] = gen_lowpart (Pmode, operands[1]);
6074   operands[3] = gen_lowpart (Pmode, operands[3]);
6076   [(set_attr "type" "lea")
6077    (set_attr "mode" "SI")])
6079 (define_insn_and_split "*lea_general_3"
6080   [(set (match_operand 0 "register_operand" "=r")
6081         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6082                           (match_operand 2 "const248_operand" "i"))
6083                     (match_operand 3 "register_operand" "r"))
6084               (match_operand 4 "immediate_operand" "i")))]
6085   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6086     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6087    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6088    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6089    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6090   "#"
6091   "&& reload_completed"
6092   [(const_int 0)]
6094   rtx pat;
6095   operands[0] = gen_lowpart (SImode, operands[0]);
6096   operands[1] = gen_lowpart (Pmode, operands[1]);
6097   operands[3] = gen_lowpart (Pmode, operands[3]);
6098   operands[4] = gen_lowpart (Pmode, operands[4]);
6099   pat = gen_rtx_PLUS (Pmode,
6100                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6101                                                          operands[2]),
6102                                     operands[3]),
6103                       operands[4]);
6104   if (Pmode != SImode)
6105     pat = gen_rtx_SUBREG (SImode, pat, 0);
6106   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6107   DONE;
6109   [(set_attr "type" "lea")
6110    (set_attr "mode" "SI")])
6112 (define_insn_and_split "*lea_general_3_zext"
6113   [(set (match_operand:DI 0 "register_operand" "=r")
6114         (zero_extend:DI
6115           (plus:SI (plus:SI (mult:SI
6116                               (match_operand:SI 1 "index_register_operand" "l")
6117                               (match_operand:SI 2 "const248_operand" "n"))
6118                             (match_operand:SI 3 "register_operand" "r"))
6119                    (match_operand:SI 4 "immediate_operand" "i"))))]
6120   "TARGET_64BIT"
6121   "#"
6122   "&& reload_completed"
6123   [(set (match_dup 0)
6124         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6125                                                               (match_dup 2))
6126                                                      (match_dup 3))
6127                                             (match_dup 4)) 0)))]
6129   operands[1] = gen_lowpart (Pmode, operands[1]);
6130   operands[3] = gen_lowpart (Pmode, operands[3]);
6131   operands[4] = gen_lowpart (Pmode, operands[4]);
6133   [(set_attr "type" "lea")
6134    (set_attr "mode" "SI")])
6136 (define_insn "*adddi_1_rex64"
6137   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
6138         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
6139                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
6140    (clobber (reg:CC FLAGS_REG))]
6141   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6143   switch (get_attr_type (insn))
6144     {
6145     case TYPE_LEA:
6146       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6147       return "lea{q}\t{%a2, %0|%0, %a2}";
6149     case TYPE_INCDEC:
6150       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6151       if (operands[2] == const1_rtx)
6152         return "inc{q}\t%0";
6153       else
6154         {
6155           gcc_assert (operands[2] == constm1_rtx);
6156           return "dec{q}\t%0";
6157         }
6159     default:
6160       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6162       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6163          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6164       if (CONST_INT_P (operands[2])
6165           /* Avoid overflows.  */
6166           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6167           && (INTVAL (operands[2]) == 128
6168               || (INTVAL (operands[2]) < 0
6169                   && INTVAL (operands[2]) != -128)))
6170         {
6171           operands[2] = GEN_INT (-INTVAL (operands[2]));
6172           return "sub{q}\t{%2, %0|%0, %2}";
6173         }
6174       return "add{q}\t{%2, %0|%0, %2}";
6175     }
6177   [(set (attr "type")
6178      (cond [(eq_attr "alternative" "2")
6179               (const_string "lea")
6180             ; Current assemblers are broken and do not allow @GOTOFF in
6181             ; ought but a memory context.
6182             (match_operand:DI 2 "pic_symbolic_operand" "")
6183               (const_string "lea")
6184             (match_operand:DI 2 "incdec_operand" "")
6185               (const_string "incdec")
6186            ]
6187            (const_string "alu")))
6188    (set_attr "mode" "DI")])
6190 ;; Convert lea to the lea pattern to avoid flags dependency.
6191 (define_split
6192   [(set (match_operand:DI 0 "register_operand" "")
6193         (plus:DI (match_operand:DI 1 "register_operand" "")
6194                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6195    (clobber (reg:CC FLAGS_REG))]
6196   "TARGET_64BIT && reload_completed
6197    && true_regnum (operands[0]) != true_regnum (operands[1])"
6198   [(set (match_dup 0)
6199         (plus:DI (match_dup 1)
6200                  (match_dup 2)))]
6201   "")
6203 (define_insn "*adddi_2_rex64"
6204   [(set (reg FLAGS_REG)
6205         (compare
6206           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6207                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6208           (const_int 0)))
6209    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6210         (plus:DI (match_dup 1) (match_dup 2)))]
6211   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6212    && ix86_binary_operator_ok (PLUS, DImode, operands)
6213    /* Current assemblers are broken and do not allow @GOTOFF in
6214       ought but a memory context.  */
6215    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6217   switch (get_attr_type (insn))
6218     {
6219     case TYPE_INCDEC:
6220       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6221       if (operands[2] == const1_rtx)
6222         return "inc{q}\t%0";
6223       else
6224         {
6225           gcc_assert (operands[2] == constm1_rtx);
6226           return "dec{q}\t%0";
6227         }
6229     default:
6230       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6231       /* ???? We ought to handle there the 32bit case too
6232          - do we need new constraint?  */
6233       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6234          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6235       if (CONST_INT_P (operands[2])
6236           /* Avoid overflows.  */
6237           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6238           && (INTVAL (operands[2]) == 128
6239               || (INTVAL (operands[2]) < 0
6240                   && INTVAL (operands[2]) != -128)))
6241         {
6242           operands[2] = GEN_INT (-INTVAL (operands[2]));
6243           return "sub{q}\t{%2, %0|%0, %2}";
6244         }
6245       return "add{q}\t{%2, %0|%0, %2}";
6246     }
6248   [(set (attr "type")
6249      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6250         (const_string "incdec")
6251         (const_string "alu")))
6252    (set_attr "mode" "DI")])
6254 (define_insn "*adddi_3_rex64"
6255   [(set (reg FLAGS_REG)
6256         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6257                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6258    (clobber (match_scratch:DI 0 "=r"))]
6259   "TARGET_64BIT
6260    && ix86_match_ccmode (insn, CCZmode)
6261    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6262    /* Current assemblers are broken and do not allow @GOTOFF in
6263       ought but a memory context.  */
6264    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6266   switch (get_attr_type (insn))
6267     {
6268     case TYPE_INCDEC:
6269       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6270       if (operands[2] == const1_rtx)
6271         return "inc{q}\t%0";
6272       else
6273         {
6274           gcc_assert (operands[2] == constm1_rtx);
6275           return "dec{q}\t%0";
6276         }
6278     default:
6279       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6280       /* ???? We ought to handle there the 32bit case too
6281          - do we need new constraint?  */
6282       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6283          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6284       if (CONST_INT_P (operands[2])
6285           /* Avoid overflows.  */
6286           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
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           return "sub{q}\t{%2, %0|%0, %2}";
6293         }
6294       return "add{q}\t{%2, %0|%0, %2}";
6295     }
6297   [(set (attr "type")
6298      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6299         (const_string "incdec")
6300         (const_string "alu")))
6301    (set_attr "mode" "DI")])
6303 ; For comparisons against 1, -1 and 128, we may generate better code
6304 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6305 ; is matched then.  We can't accept general immediate, because for
6306 ; case of overflows,  the result is messed up.
6307 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6308 ; when negated.
6309 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6310 ; only for comparisons not depending on it.
6311 (define_insn "*adddi_4_rex64"
6312   [(set (reg FLAGS_REG)
6313         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6314                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6315    (clobber (match_scratch:DI 0 "=rm"))]
6316   "TARGET_64BIT
6317    &&  ix86_match_ccmode (insn, CCGCmode)"
6319   switch (get_attr_type (insn))
6320     {
6321     case TYPE_INCDEC:
6322       if (operands[2] == constm1_rtx)
6323         return "inc{q}\t%0";
6324       else
6325         {
6326           gcc_assert (operands[2] == const1_rtx);
6327           return "dec{q}\t%0";
6328         }
6330     default:
6331       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6332       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6333          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6334       if ((INTVAL (operands[2]) == -128
6335            || (INTVAL (operands[2]) > 0
6336                && INTVAL (operands[2]) != 128))
6337           /* Avoid overflows.  */
6338           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6339         return "sub{q}\t{%2, %0|%0, %2}";
6340       operands[2] = GEN_INT (-INTVAL (operands[2]));
6341       return "add{q}\t{%2, %0|%0, %2}";
6342     }
6344   [(set (attr "type")
6345      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6346         (const_string "incdec")
6347         (const_string "alu")))
6348    (set_attr "mode" "DI")])
6350 (define_insn "*adddi_5_rex64"
6351   [(set (reg FLAGS_REG)
6352         (compare
6353           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6354                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6355           (const_int 0)))
6356    (clobber (match_scratch:DI 0 "=r"))]
6357   "TARGET_64BIT
6358    && ix86_match_ccmode (insn, CCGOCmode)
6359    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6360    /* Current assemblers are broken and do not allow @GOTOFF in
6361       ought but a memory context.  */
6362    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6364   switch (get_attr_type (insn))
6365     {
6366     case TYPE_INCDEC:
6367       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6368       if (operands[2] == const1_rtx)
6369         return "inc{q}\t%0";
6370       else
6371         {
6372           gcc_assert (operands[2] == constm1_rtx);
6373           return "dec{q}\t%0";
6374         }
6376     default:
6377       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6378       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6379          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6380       if (CONST_INT_P (operands[2])
6381           /* Avoid overflows.  */
6382           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6383           && (INTVAL (operands[2]) == 128
6384               || (INTVAL (operands[2]) < 0
6385                   && INTVAL (operands[2]) != -128)))
6386         {
6387           operands[2] = GEN_INT (-INTVAL (operands[2]));
6388           return "sub{q}\t{%2, %0|%0, %2}";
6389         }
6390       return "add{q}\t{%2, %0|%0, %2}";
6391     }
6393   [(set (attr "type")
6394      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6395         (const_string "incdec")
6396         (const_string "alu")))
6397    (set_attr "mode" "DI")])
6400 (define_insn "*addsi_1"
6401   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6402         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6403                  (match_operand:SI 2 "general_operand" "g,ri,li")))
6404    (clobber (reg:CC FLAGS_REG))]
6405   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6407   switch (get_attr_type (insn))
6408     {
6409     case TYPE_LEA:
6410       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6411       return "lea{l}\t{%a2, %0|%0, %a2}";
6413     case TYPE_INCDEC:
6414       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6415       if (operands[2] == const1_rtx)
6416         return "inc{l}\t%0";
6417       else
6418         {
6419           gcc_assert (operands[2] == constm1_rtx);
6420           return "dec{l}\t%0";
6421         }
6423     default:
6424       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6426       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6427          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6428       if (CONST_INT_P (operands[2])
6429           && (INTVAL (operands[2]) == 128
6430               || (INTVAL (operands[2]) < 0
6431                   && INTVAL (operands[2]) != -128)))
6432         {
6433           operands[2] = GEN_INT (-INTVAL (operands[2]));
6434           return "sub{l}\t{%2, %0|%0, %2}";
6435         }
6436       return "add{l}\t{%2, %0|%0, %2}";
6437     }
6439   [(set (attr "type")
6440      (cond [(eq_attr "alternative" "2")
6441               (const_string "lea")
6442             ; Current assemblers are broken and do not allow @GOTOFF in
6443             ; ought but a memory context.
6444             (match_operand:SI 2 "pic_symbolic_operand" "")
6445               (const_string "lea")
6446             (match_operand:SI 2 "incdec_operand" "")
6447               (const_string "incdec")
6448            ]
6449            (const_string "alu")))
6450    (set_attr "mode" "SI")])
6452 ;; Convert lea to the lea pattern to avoid flags dependency.
6453 (define_split
6454   [(set (match_operand 0 "register_operand" "")
6455         (plus (match_operand 1 "register_operand" "")
6456               (match_operand 2 "nonmemory_operand" "")))
6457    (clobber (reg:CC FLAGS_REG))]
6458   "reload_completed
6459    && true_regnum (operands[0]) != true_regnum (operands[1])"
6460   [(const_int 0)]
6462   rtx pat;
6463   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6464      may confuse gen_lowpart.  */
6465   if (GET_MODE (operands[0]) != Pmode)
6466     {
6467       operands[1] = gen_lowpart (Pmode, operands[1]);
6468       operands[2] = gen_lowpart (Pmode, operands[2]);
6469     }
6470   operands[0] = gen_lowpart (SImode, operands[0]);
6471   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6472   if (Pmode != SImode)
6473     pat = gen_rtx_SUBREG (SImode, pat, 0);
6474   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6475   DONE;
6478 ;; It may seem that nonimmediate operand is proper one for operand 1.
6479 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6480 ;; we take care in ix86_binary_operator_ok to not allow two memory
6481 ;; operands so proper swapping will be done in reload.  This allow
6482 ;; patterns constructed from addsi_1 to match.
6483 (define_insn "addsi_1_zext"
6484   [(set (match_operand:DI 0 "register_operand" "=r,r")
6485         (zero_extend:DI
6486           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6487                    (match_operand:SI 2 "general_operand" "g,li"))))
6488    (clobber (reg:CC FLAGS_REG))]
6489   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6491   switch (get_attr_type (insn))
6492     {
6493     case TYPE_LEA:
6494       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6495       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6497     case TYPE_INCDEC:
6498       if (operands[2] == const1_rtx)
6499         return "inc{l}\t%k0";
6500       else
6501         {
6502           gcc_assert (operands[2] == constm1_rtx);
6503           return "dec{l}\t%k0";
6504         }
6506     default:
6507       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6508          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6509       if (CONST_INT_P (operands[2])
6510           && (INTVAL (operands[2]) == 128
6511               || (INTVAL (operands[2]) < 0
6512                   && INTVAL (operands[2]) != -128)))
6513         {
6514           operands[2] = GEN_INT (-INTVAL (operands[2]));
6515           return "sub{l}\t{%2, %k0|%k0, %2}";
6516         }
6517       return "add{l}\t{%2, %k0|%k0, %2}";
6518     }
6520   [(set (attr "type")
6521      (cond [(eq_attr "alternative" "1")
6522               (const_string "lea")
6523             ; Current assemblers are broken and do not allow @GOTOFF in
6524             ; ought but a memory context.
6525             (match_operand:SI 2 "pic_symbolic_operand" "")
6526               (const_string "lea")
6527             (match_operand:SI 2 "incdec_operand" "")
6528               (const_string "incdec")
6529            ]
6530            (const_string "alu")))
6531    (set_attr "mode" "SI")])
6533 ;; Convert lea to the lea pattern to avoid flags dependency.
6534 (define_split
6535   [(set (match_operand:DI 0 "register_operand" "")
6536         (zero_extend:DI
6537           (plus:SI (match_operand:SI 1 "register_operand" "")
6538                    (match_operand:SI 2 "nonmemory_operand" ""))))
6539    (clobber (reg:CC FLAGS_REG))]
6540   "TARGET_64BIT && reload_completed
6541    && true_regnum (operands[0]) != true_regnum (operands[1])"
6542   [(set (match_dup 0)
6543         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6545   operands[1] = gen_lowpart (Pmode, operands[1]);
6546   operands[2] = gen_lowpart (Pmode, operands[2]);
6549 (define_insn "*addsi_2"
6550   [(set (reg FLAGS_REG)
6551         (compare
6552           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6553                    (match_operand:SI 2 "general_operand" "g,ri"))
6554           (const_int 0)))
6555    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6556         (plus:SI (match_dup 1) (match_dup 2)))]
6557   "ix86_match_ccmode (insn, CCGOCmode)
6558    && ix86_binary_operator_ok (PLUS, SImode, operands)
6559    /* Current assemblers are broken and do not allow @GOTOFF in
6560       ought but a memory context.  */
6561    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6563   switch (get_attr_type (insn))
6564     {
6565     case TYPE_INCDEC:
6566       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6567       if (operands[2] == const1_rtx)
6568         return "inc{l}\t%0";
6569       else
6570         {
6571           gcc_assert (operands[2] == constm1_rtx);
6572           return "dec{l}\t%0";
6573         }
6575     default:
6576       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6577       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6578          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6579       if (CONST_INT_P (operands[2])
6580           && (INTVAL (operands[2]) == 128
6581               || (INTVAL (operands[2]) < 0
6582                   && INTVAL (operands[2]) != -128)))
6583         {
6584           operands[2] = GEN_INT (-INTVAL (operands[2]));
6585           return "sub{l}\t{%2, %0|%0, %2}";
6586         }
6587       return "add{l}\t{%2, %0|%0, %2}";
6588     }
6590   [(set (attr "type")
6591      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6592         (const_string "incdec")
6593         (const_string "alu")))
6594    (set_attr "mode" "SI")])
6596 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6597 (define_insn "*addsi_2_zext"
6598   [(set (reg FLAGS_REG)
6599         (compare
6600           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6601                    (match_operand:SI 2 "general_operand" "g"))
6602           (const_int 0)))
6603    (set (match_operand:DI 0 "register_operand" "=r")
6604         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6605   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6606    && ix86_binary_operator_ok (PLUS, SImode, operands)
6607    /* Current assemblers are broken and do not allow @GOTOFF in
6608       ought but a memory context.  */
6609    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6611   switch (get_attr_type (insn))
6612     {
6613     case TYPE_INCDEC:
6614       if (operands[2] == const1_rtx)
6615         return "inc{l}\t%k0";
6616       else
6617         {
6618           gcc_assert (operands[2] == constm1_rtx);
6619           return "dec{l}\t%k0";
6620         }
6622     default:
6623       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6624          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6625       if (CONST_INT_P (operands[2])
6626           && (INTVAL (operands[2]) == 128
6627               || (INTVAL (operands[2]) < 0
6628                   && INTVAL (operands[2]) != -128)))
6629         {
6630           operands[2] = GEN_INT (-INTVAL (operands[2]));
6631           return "sub{l}\t{%2, %k0|%k0, %2}";
6632         }
6633       return "add{l}\t{%2, %k0|%k0, %2}";
6634     }
6636   [(set (attr "type")
6637      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6638         (const_string "incdec")
6639         (const_string "alu")))
6640    (set_attr "mode" "SI")])
6642 (define_insn "*addsi_3"
6643   [(set (reg FLAGS_REG)
6644         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6645                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6646    (clobber (match_scratch:SI 0 "=r"))]
6647   "ix86_match_ccmode (insn, CCZmode)
6648    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6649    /* Current assemblers are broken and do not allow @GOTOFF in
6650       ought but a memory context.  */
6651    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6653   switch (get_attr_type (insn))
6654     {
6655     case TYPE_INCDEC:
6656       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6657       if (operands[2] == const1_rtx)
6658         return "inc{l}\t%0";
6659       else
6660         {
6661           gcc_assert (operands[2] == constm1_rtx);
6662           return "dec{l}\t%0";
6663         }
6665     default:
6666       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6667       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6668          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6669       if (CONST_INT_P (operands[2])
6670           && (INTVAL (operands[2]) == 128
6671               || (INTVAL (operands[2]) < 0
6672                   && INTVAL (operands[2]) != -128)))
6673         {
6674           operands[2] = GEN_INT (-INTVAL (operands[2]));
6675           return "sub{l}\t{%2, %0|%0, %2}";
6676         }
6677       return "add{l}\t{%2, %0|%0, %2}";
6678     }
6680   [(set (attr "type")
6681      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6682         (const_string "incdec")
6683         (const_string "alu")))
6684    (set_attr "mode" "SI")])
6686 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6687 (define_insn "*addsi_3_zext"
6688   [(set (reg FLAGS_REG)
6689         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6690                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6691    (set (match_operand:DI 0 "register_operand" "=r")
6692         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6693   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6694    && ix86_binary_operator_ok (PLUS, SImode, operands)
6695    /* Current assemblers are broken and do not allow @GOTOFF in
6696       ought but a memory context.  */
6697    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6699   switch (get_attr_type (insn))
6700     {
6701     case TYPE_INCDEC:
6702       if (operands[2] == const1_rtx)
6703         return "inc{l}\t%k0";
6704       else
6705         {
6706           gcc_assert (operands[2] == constm1_rtx);
6707           return "dec{l}\t%k0";
6708         }
6710     default:
6711       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6712          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6713       if (CONST_INT_P (operands[2])
6714           && (INTVAL (operands[2]) == 128
6715               || (INTVAL (operands[2]) < 0
6716                   && INTVAL (operands[2]) != -128)))
6717         {
6718           operands[2] = GEN_INT (-INTVAL (operands[2]));
6719           return "sub{l}\t{%2, %k0|%k0, %2}";
6720         }
6721       return "add{l}\t{%2, %k0|%k0, %2}";
6722     }
6724   [(set (attr "type")
6725      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6726         (const_string "incdec")
6727         (const_string "alu")))
6728    (set_attr "mode" "SI")])
6730 ; For comparisons against 1, -1 and 128, we may generate better code
6731 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6732 ; is matched then.  We can't accept general immediate, because for
6733 ; case of overflows,  the result is messed up.
6734 ; This pattern also don't hold of 0x80000000, since the value overflows
6735 ; when negated.
6736 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6737 ; only for comparisons not depending on it.
6738 (define_insn "*addsi_4"
6739   [(set (reg FLAGS_REG)
6740         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6741                  (match_operand:SI 2 "const_int_operand" "n")))
6742    (clobber (match_scratch:SI 0 "=rm"))]
6743   "ix86_match_ccmode (insn, CCGCmode)
6744    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6746   switch (get_attr_type (insn))
6747     {
6748     case TYPE_INCDEC:
6749       if (operands[2] == constm1_rtx)
6750         return "inc{l}\t%0";
6751       else
6752         {
6753           gcc_assert (operands[2] == const1_rtx);
6754           return "dec{l}\t%0";
6755         }
6757     default:
6758       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6759       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6760          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6761       if ((INTVAL (operands[2]) == -128
6762            || (INTVAL (operands[2]) > 0
6763                && INTVAL (operands[2]) != 128)))
6764         return "sub{l}\t{%2, %0|%0, %2}";
6765       operands[2] = GEN_INT (-INTVAL (operands[2]));
6766       return "add{l}\t{%2, %0|%0, %2}";
6767     }
6769   [(set (attr "type")
6770      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6771         (const_string "incdec")
6772         (const_string "alu")))
6773    (set_attr "mode" "SI")])
6775 (define_insn "*addsi_5"
6776   [(set (reg FLAGS_REG)
6777         (compare
6778           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6779                    (match_operand:SI 2 "general_operand" "g"))
6780           (const_int 0)))
6781    (clobber (match_scratch:SI 0 "=r"))]
6782   "ix86_match_ccmode (insn, CCGOCmode)
6783    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6784    /* Current assemblers are broken and do not allow @GOTOFF in
6785       ought but a memory context.  */
6786    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6788   switch (get_attr_type (insn))
6789     {
6790     case TYPE_INCDEC:
6791       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6792       if (operands[2] == const1_rtx)
6793         return "inc{l}\t%0";
6794       else
6795         {
6796           gcc_assert (operands[2] == constm1_rtx);
6797           return "dec{l}\t%0";
6798         }
6800     default:
6801       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6802       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6803          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6804       if (CONST_INT_P (operands[2])
6805           && (INTVAL (operands[2]) == 128
6806               || (INTVAL (operands[2]) < 0
6807                   && INTVAL (operands[2]) != -128)))
6808         {
6809           operands[2] = GEN_INT (-INTVAL (operands[2]));
6810           return "sub{l}\t{%2, %0|%0, %2}";
6811         }
6812       return "add{l}\t{%2, %0|%0, %2}";
6813     }
6815   [(set (attr "type")
6816      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6817         (const_string "incdec")
6818         (const_string "alu")))
6819    (set_attr "mode" "SI")])
6821 (define_expand "addhi3"
6822   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6823         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6824                  (match_operand:HI 2 "general_operand" "")))]
6825   "TARGET_HIMODE_MATH"
6826   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6828 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6829 ;; type optimizations enabled by define-splits.  This is not important
6830 ;; for PII, and in fact harmful because of partial register stalls.
6832 (define_insn "*addhi_1_lea"
6833   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6834         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6835                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6836    (clobber (reg:CC FLAGS_REG))]
6837   "!TARGET_PARTIAL_REG_STALL
6838    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6840   switch (get_attr_type (insn))
6841     {
6842     case TYPE_LEA:
6843       return "#";
6844     case TYPE_INCDEC:
6845       if (operands[2] == const1_rtx)
6846         return "inc{w}\t%0";
6847       else
6848         {
6849           gcc_assert (operands[2] == constm1_rtx);
6850           return "dec{w}\t%0";
6851         }
6853     default:
6854       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6855          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6856       if (CONST_INT_P (operands[2])
6857           && (INTVAL (operands[2]) == 128
6858               || (INTVAL (operands[2]) < 0
6859                   && INTVAL (operands[2]) != -128)))
6860         {
6861           operands[2] = GEN_INT (-INTVAL (operands[2]));
6862           return "sub{w}\t{%2, %0|%0, %2}";
6863         }
6864       return "add{w}\t{%2, %0|%0, %2}";
6865     }
6867   [(set (attr "type")
6868      (if_then_else (eq_attr "alternative" "2")
6869         (const_string "lea")
6870         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6871            (const_string "incdec")
6872            (const_string "alu"))))
6873    (set_attr "mode" "HI,HI,SI")])
6875 (define_insn "*addhi_1"
6876   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6877         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6878                  (match_operand:HI 2 "general_operand" "rn,rm")))
6879    (clobber (reg:CC FLAGS_REG))]
6880   "TARGET_PARTIAL_REG_STALL
6881    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6883   switch (get_attr_type (insn))
6884     {
6885     case TYPE_INCDEC:
6886       if (operands[2] == const1_rtx)
6887         return "inc{w}\t%0";
6888       else
6889         {
6890           gcc_assert (operands[2] == constm1_rtx);
6891           return "dec{w}\t%0";
6892         }
6894     default:
6895       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6896          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6897       if (CONST_INT_P (operands[2])
6898           && (INTVAL (operands[2]) == 128
6899               || (INTVAL (operands[2]) < 0
6900                   && INTVAL (operands[2]) != -128)))
6901         {
6902           operands[2] = GEN_INT (-INTVAL (operands[2]));
6903           return "sub{w}\t{%2, %0|%0, %2}";
6904         }
6905       return "add{w}\t{%2, %0|%0, %2}";
6906     }
6908   [(set (attr "type")
6909      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6910         (const_string "incdec")
6911         (const_string "alu")))
6912    (set_attr "mode" "HI")])
6914 (define_insn "*addhi_2"
6915   [(set (reg FLAGS_REG)
6916         (compare
6917           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6918                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6919           (const_int 0)))
6920    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6921         (plus:HI (match_dup 1) (match_dup 2)))]
6922   "ix86_match_ccmode (insn, CCGOCmode)
6923    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6925   switch (get_attr_type (insn))
6926     {
6927     case TYPE_INCDEC:
6928       if (operands[2] == const1_rtx)
6929         return "inc{w}\t%0";
6930       else
6931         {
6932           gcc_assert (operands[2] == constm1_rtx);
6933           return "dec{w}\t%0";
6934         }
6936     default:
6937       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6938          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6939       if (CONST_INT_P (operands[2])
6940           && (INTVAL (operands[2]) == 128
6941               || (INTVAL (operands[2]) < 0
6942                   && INTVAL (operands[2]) != -128)))
6943         {
6944           operands[2] = GEN_INT (-INTVAL (operands[2]));
6945           return "sub{w}\t{%2, %0|%0, %2}";
6946         }
6947       return "add{w}\t{%2, %0|%0, %2}";
6948     }
6950   [(set (attr "type")
6951      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6952         (const_string "incdec")
6953         (const_string "alu")))
6954    (set_attr "mode" "HI")])
6956 (define_insn "*addhi_3"
6957   [(set (reg FLAGS_REG)
6958         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6959                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6960    (clobber (match_scratch:HI 0 "=r"))]
6961   "ix86_match_ccmode (insn, CCZmode)
6962    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6964   switch (get_attr_type (insn))
6965     {
6966     case TYPE_INCDEC:
6967       if (operands[2] == const1_rtx)
6968         return "inc{w}\t%0";
6969       else
6970         {
6971           gcc_assert (operands[2] == constm1_rtx);
6972           return "dec{w}\t%0";
6973         }
6975     default:
6976       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6977          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6978       if (CONST_INT_P (operands[2])
6979           && (INTVAL (operands[2]) == 128
6980               || (INTVAL (operands[2]) < 0
6981                   && INTVAL (operands[2]) != -128)))
6982         {
6983           operands[2] = GEN_INT (-INTVAL (operands[2]));
6984           return "sub{w}\t{%2, %0|%0, %2}";
6985         }
6986       return "add{w}\t{%2, %0|%0, %2}";
6987     }
6989   [(set (attr "type")
6990      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6991         (const_string "incdec")
6992         (const_string "alu")))
6993    (set_attr "mode" "HI")])
6995 ; See comments above addsi_4 for details.
6996 (define_insn "*addhi_4"
6997   [(set (reg FLAGS_REG)
6998         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6999                  (match_operand:HI 2 "const_int_operand" "n")))
7000    (clobber (match_scratch:HI 0 "=rm"))]
7001   "ix86_match_ccmode (insn, CCGCmode)
7002    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7004   switch (get_attr_type (insn))
7005     {
7006     case TYPE_INCDEC:
7007       if (operands[2] == constm1_rtx)
7008         return "inc{w}\t%0";
7009       else
7010         {
7011           gcc_assert (operands[2] == const1_rtx);
7012           return "dec{w}\t%0";
7013         }
7015     default:
7016       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7017       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7018          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7019       if ((INTVAL (operands[2]) == -128
7020            || (INTVAL (operands[2]) > 0
7021                && INTVAL (operands[2]) != 128)))
7022         return "sub{w}\t{%2, %0|%0, %2}";
7023       operands[2] = GEN_INT (-INTVAL (operands[2]));
7024       return "add{w}\t{%2, %0|%0, %2}";
7025     }
7027   [(set (attr "type")
7028      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7029         (const_string "incdec")
7030         (const_string "alu")))
7031    (set_attr "mode" "SI")])
7034 (define_insn "*addhi_5"
7035   [(set (reg FLAGS_REG)
7036         (compare
7037           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7038                    (match_operand:HI 2 "general_operand" "rmn"))
7039           (const_int 0)))
7040    (clobber (match_scratch:HI 0 "=r"))]
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{w}\t%0";
7049       else
7050         {
7051           gcc_assert (operands[2] == constm1_rtx);
7052           return "dec{w}\t%0";
7053         }
7055     default:
7056       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7057          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7058       if (CONST_INT_P (operands[2])
7059           && (INTVAL (operands[2]) == 128
7060               || (INTVAL (operands[2]) < 0
7061                   && INTVAL (operands[2]) != -128)))
7062         {
7063           operands[2] = GEN_INT (-INTVAL (operands[2]));
7064           return "sub{w}\t{%2, %0|%0, %2}";
7065         }
7066       return "add{w}\t{%2, %0|%0, %2}";
7067     }
7069   [(set (attr "type")
7070      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7071         (const_string "incdec")
7072         (const_string "alu")))
7073    (set_attr "mode" "HI")])
7075 (define_expand "addqi3"
7076   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7077         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7078                  (match_operand:QI 2 "general_operand" "")))]
7079   "TARGET_QIMODE_MATH"
7080   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7082 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7083 (define_insn "*addqi_1_lea"
7084   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7085         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7086                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7087    (clobber (reg:CC FLAGS_REG))]
7088   "!TARGET_PARTIAL_REG_STALL
7089    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7091   int widen = (which_alternative == 2);
7092   switch (get_attr_type (insn))
7093     {
7094     case TYPE_LEA:
7095       return "#";
7096     case TYPE_INCDEC:
7097       if (operands[2] == const1_rtx)
7098         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7099       else
7100         {
7101           gcc_assert (operands[2] == constm1_rtx);
7102           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7103         }
7105     default:
7106       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7107          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7108       if (CONST_INT_P (operands[2])
7109           && (INTVAL (operands[2]) == 128
7110               || (INTVAL (operands[2]) < 0
7111                   && INTVAL (operands[2]) != -128)))
7112         {
7113           operands[2] = GEN_INT (-INTVAL (operands[2]));
7114           if (widen)
7115             return "sub{l}\t{%2, %k0|%k0, %2}";
7116           else
7117             return "sub{b}\t{%2, %0|%0, %2}";
7118         }
7119       if (widen)
7120         return "add{l}\t{%k2, %k0|%k0, %k2}";
7121       else
7122         return "add{b}\t{%2, %0|%0, %2}";
7123     }
7125   [(set (attr "type")
7126      (if_then_else (eq_attr "alternative" "3")
7127         (const_string "lea")
7128         (if_then_else (match_operand:QI 2 "incdec_operand" "")
7129            (const_string "incdec")
7130            (const_string "alu"))))
7131    (set_attr "mode" "QI,QI,SI,SI")])
7133 (define_insn "*addqi_1"
7134   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7135         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7136                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7137    (clobber (reg:CC FLAGS_REG))]
7138   "TARGET_PARTIAL_REG_STALL
7139    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7141   int widen = (which_alternative == 2);
7142   switch (get_attr_type (insn))
7143     {
7144     case TYPE_INCDEC:
7145       if (operands[2] == const1_rtx)
7146         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7147       else
7148         {
7149           gcc_assert (operands[2] == constm1_rtx);
7150           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7151         }
7153     default:
7154       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7155          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7156       if (CONST_INT_P (operands[2])
7157           && (INTVAL (operands[2]) == 128
7158               || (INTVAL (operands[2]) < 0
7159                   && INTVAL (operands[2]) != -128)))
7160         {
7161           operands[2] = GEN_INT (-INTVAL (operands[2]));
7162           if (widen)
7163             return "sub{l}\t{%2, %k0|%k0, %2}";
7164           else
7165             return "sub{b}\t{%2, %0|%0, %2}";
7166         }
7167       if (widen)
7168         return "add{l}\t{%k2, %k0|%k0, %k2}";
7169       else
7170         return "add{b}\t{%2, %0|%0, %2}";
7171     }
7173   [(set (attr "type")
7174      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7175         (const_string "incdec")
7176         (const_string "alu")))
7177    (set_attr "mode" "QI,QI,SI")])
7179 (define_insn "*addqi_1_slp"
7180   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7181         (plus:QI (match_dup 0)
7182                  (match_operand:QI 1 "general_operand" "qn,qnm")))
7183    (clobber (reg:CC FLAGS_REG))]
7184   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7185    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7187   switch (get_attr_type (insn))
7188     {
7189     case TYPE_INCDEC:
7190       if (operands[1] == const1_rtx)
7191         return "inc{b}\t%0";
7192       else
7193         {
7194           gcc_assert (operands[1] == constm1_rtx);
7195           return "dec{b}\t%0";
7196         }
7198     default:
7199       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
7200       if (CONST_INT_P (operands[1])
7201           && INTVAL (operands[1]) < 0)
7202         {
7203           operands[1] = GEN_INT (-INTVAL (operands[1]));
7204           return "sub{b}\t{%1, %0|%0, %1}";
7205         }
7206       return "add{b}\t{%1, %0|%0, %1}";
7207     }
7209   [(set (attr "type")
7210      (if_then_else (match_operand:QI 1 "incdec_operand" "")
7211         (const_string "incdec")
7212         (const_string "alu1")))
7213    (set (attr "memory")
7214      (if_then_else (match_operand 1 "memory_operand" "")
7215         (const_string "load")
7216         (const_string "none")))
7217    (set_attr "mode" "QI")])
7219 (define_insn "*addqi_2"
7220   [(set (reg FLAGS_REG)
7221         (compare
7222           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7223                    (match_operand:QI 2 "general_operand" "qmn,qn"))
7224           (const_int 0)))
7225    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7226         (plus:QI (match_dup 1) (match_dup 2)))]
7227   "ix86_match_ccmode (insn, CCGOCmode)
7228    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7230   switch (get_attr_type (insn))
7231     {
7232     case TYPE_INCDEC:
7233       if (operands[2] == const1_rtx)
7234         return "inc{b}\t%0";
7235       else
7236         {
7237           gcc_assert (operands[2] == constm1_rtx
7238                       || (CONST_INT_P (operands[2])
7239                           && INTVAL (operands[2]) == 255));
7240           return "dec{b}\t%0";
7241         }
7243     default:
7244       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7245       if (CONST_INT_P (operands[2])
7246           && INTVAL (operands[2]) < 0)
7247         {
7248           operands[2] = GEN_INT (-INTVAL (operands[2]));
7249           return "sub{b}\t{%2, %0|%0, %2}";
7250         }
7251       return "add{b}\t{%2, %0|%0, %2}";
7252     }
7254   [(set (attr "type")
7255      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7256         (const_string "incdec")
7257         (const_string "alu")))
7258    (set_attr "mode" "QI")])
7260 (define_insn "*addqi_3"
7261   [(set (reg FLAGS_REG)
7262         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7263                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7264    (clobber (match_scratch:QI 0 "=q"))]
7265   "ix86_match_ccmode (insn, CCZmode)
7266    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7268   switch (get_attr_type (insn))
7269     {
7270     case TYPE_INCDEC:
7271       if (operands[2] == const1_rtx)
7272         return "inc{b}\t%0";
7273       else
7274         {
7275           gcc_assert (operands[2] == constm1_rtx
7276                       || (CONST_INT_P (operands[2])
7277                           && INTVAL (operands[2]) == 255));
7278           return "dec{b}\t%0";
7279         }
7281     default:
7282       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7283       if (CONST_INT_P (operands[2])
7284           && INTVAL (operands[2]) < 0)
7285         {
7286           operands[2] = GEN_INT (-INTVAL (operands[2]));
7287           return "sub{b}\t{%2, %0|%0, %2}";
7288         }
7289       return "add{b}\t{%2, %0|%0, %2}";
7290     }
7292   [(set (attr "type")
7293      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7294         (const_string "incdec")
7295         (const_string "alu")))
7296    (set_attr "mode" "QI")])
7298 ; See comments above addsi_4 for details.
7299 (define_insn "*addqi_4"
7300   [(set (reg FLAGS_REG)
7301         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7302                  (match_operand:QI 2 "const_int_operand" "n")))
7303    (clobber (match_scratch:QI 0 "=qm"))]
7304   "ix86_match_ccmode (insn, CCGCmode)
7305    && (INTVAL (operands[2]) & 0xff) != 0x80"
7307   switch (get_attr_type (insn))
7308     {
7309     case TYPE_INCDEC:
7310       if (operands[2] == constm1_rtx
7311           || (CONST_INT_P (operands[2])
7312               && INTVAL (operands[2]) == 255))
7313         return "inc{b}\t%0";
7314       else
7315         {
7316           gcc_assert (operands[2] == const1_rtx);
7317           return "dec{b}\t%0";
7318         }
7320     default:
7321       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7322       if (INTVAL (operands[2]) < 0)
7323         {
7324           operands[2] = GEN_INT (-INTVAL (operands[2]));
7325           return "add{b}\t{%2, %0|%0, %2}";
7326         }
7327       return "sub{b}\t{%2, %0|%0, %2}";
7328     }
7330   [(set (attr "type")
7331      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7332         (const_string "incdec")
7333         (const_string "alu")))
7334    (set_attr "mode" "QI")])
7337 (define_insn "*addqi_5"
7338   [(set (reg FLAGS_REG)
7339         (compare
7340           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7341                    (match_operand:QI 2 "general_operand" "qmn"))
7342           (const_int 0)))
7343    (clobber (match_scratch:QI 0 "=q"))]
7344   "ix86_match_ccmode (insn, CCGOCmode)
7345    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7347   switch (get_attr_type (insn))
7348     {
7349     case TYPE_INCDEC:
7350       if (operands[2] == const1_rtx)
7351         return "inc{b}\t%0";
7352       else
7353         {
7354           gcc_assert (operands[2] == constm1_rtx
7355                       || (CONST_INT_P (operands[2])
7356                           && INTVAL (operands[2]) == 255));
7357           return "dec{b}\t%0";
7358         }
7360     default:
7361       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7362       if (CONST_INT_P (operands[2])
7363           && INTVAL (operands[2]) < 0)
7364         {
7365           operands[2] = GEN_INT (-INTVAL (operands[2]));
7366           return "sub{b}\t{%2, %0|%0, %2}";
7367         }
7368       return "add{b}\t{%2, %0|%0, %2}";
7369     }
7371   [(set (attr "type")
7372      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7373         (const_string "incdec")
7374         (const_string "alu")))
7375    (set_attr "mode" "QI")])
7378 (define_insn "addqi_ext_1"
7379   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7380                          (const_int 8)
7381                          (const_int 8))
7382         (plus:SI
7383           (zero_extract:SI
7384             (match_operand 1 "ext_register_operand" "0")
7385             (const_int 8)
7386             (const_int 8))
7387           (match_operand:QI 2 "general_operand" "Qmn")))
7388    (clobber (reg:CC FLAGS_REG))]
7389   "!TARGET_64BIT"
7391   switch (get_attr_type (insn))
7392     {
7393     case TYPE_INCDEC:
7394       if (operands[2] == const1_rtx)
7395         return "inc{b}\t%h0";
7396       else
7397         {
7398           gcc_assert (operands[2] == constm1_rtx
7399                       || (CONST_INT_P (operands[2])
7400                           && INTVAL (operands[2]) == 255));
7401           return "dec{b}\t%h0";
7402         }
7404     default:
7405       return "add{b}\t{%2, %h0|%h0, %2}";
7406     }
7408   [(set (attr "type")
7409      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7410         (const_string "incdec")
7411         (const_string "alu")))
7412    (set_attr "mode" "QI")])
7414 (define_insn "*addqi_ext_1_rex64"
7415   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7416                          (const_int 8)
7417                          (const_int 8))
7418         (plus:SI
7419           (zero_extract:SI
7420             (match_operand 1 "ext_register_operand" "0")
7421             (const_int 8)
7422             (const_int 8))
7423           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7424    (clobber (reg:CC FLAGS_REG))]
7425   "TARGET_64BIT"
7427   switch (get_attr_type (insn))
7428     {
7429     case TYPE_INCDEC:
7430       if (operands[2] == const1_rtx)
7431         return "inc{b}\t%h0";
7432       else
7433         {
7434           gcc_assert (operands[2] == constm1_rtx
7435                       || (CONST_INT_P (operands[2])
7436                           && INTVAL (operands[2]) == 255));
7437           return "dec{b}\t%h0";
7438         }
7440     default:
7441       return "add{b}\t{%2, %h0|%h0, %2}";
7442     }
7444   [(set (attr "type")
7445      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7446         (const_string "incdec")
7447         (const_string "alu")))
7448    (set_attr "mode" "QI")])
7450 (define_insn "*addqi_ext_2"
7451   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7452                          (const_int 8)
7453                          (const_int 8))
7454         (plus:SI
7455           (zero_extract:SI
7456             (match_operand 1 "ext_register_operand" "%0")
7457             (const_int 8)
7458             (const_int 8))
7459           (zero_extract:SI
7460             (match_operand 2 "ext_register_operand" "Q")
7461             (const_int 8)
7462             (const_int 8))))
7463    (clobber (reg:CC FLAGS_REG))]
7464   ""
7465   "add{b}\t{%h2, %h0|%h0, %h2}"
7466   [(set_attr "type" "alu")
7467    (set_attr "mode" "QI")])
7469 ;; The patterns that match these are at the end of this file.
7471 (define_expand "addxf3"
7472   [(set (match_operand:XF 0 "register_operand" "")
7473         (plus:XF (match_operand:XF 1 "register_operand" "")
7474                  (match_operand:XF 2 "register_operand" "")))]
7475   "TARGET_80387"
7476   "")
7478 (define_expand "add<mode>3"
7479   [(set (match_operand:MODEF 0 "register_operand" "")
7480         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7481                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7482   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7483   "")
7485 ;; Subtract instructions
7487 ;; %%% splits for subditi3
7489 (define_expand "subti3"
7490   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7491         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7492                   (match_operand:TI 2 "x86_64_general_operand" "")))]
7493   "TARGET_64BIT"
7494   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7496 (define_insn "*subti3_1"
7497   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7498         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7499                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7500    (clobber (reg:CC FLAGS_REG))]
7501   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7502   "#")
7504 (define_split
7505   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7506         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7507                   (match_operand:TI 2 "x86_64_general_operand" "")))
7508    (clobber (reg:CC FLAGS_REG))]
7509   "TARGET_64BIT && reload_completed"
7510   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7511               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7512    (parallel [(set (match_dup 3)
7513                    (minus:DI (match_dup 4)
7514                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7515                                       (match_dup 5))))
7516               (clobber (reg:CC FLAGS_REG))])]
7517   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7519 ;; %%% splits for subsidi3
7521 (define_expand "subdi3"
7522   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7523         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7524                   (match_operand:DI 2 "x86_64_general_operand" "")))]
7525   ""
7526   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7528 (define_insn "*subdi3_1"
7529   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7530         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7531                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7532    (clobber (reg:CC FLAGS_REG))]
7533   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7534   "#")
7536 (define_split
7537   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7538         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7539                   (match_operand:DI 2 "general_operand" "")))
7540    (clobber (reg:CC FLAGS_REG))]
7541   "!TARGET_64BIT && reload_completed"
7542   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7543               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7544    (parallel [(set (match_dup 3)
7545                    (minus:SI (match_dup 4)
7546                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7547                                       (match_dup 5))))
7548               (clobber (reg:CC FLAGS_REG))])]
7549   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7551 (define_insn "subdi3_carry_rex64"
7552   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7553           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7554             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7555                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7556    (clobber (reg:CC FLAGS_REG))]
7557   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7558   "sbb{q}\t{%2, %0|%0, %2}"
7559   [(set_attr "type" "alu")
7560    (set_attr "pent_pair" "pu")
7561    (set_attr "mode" "DI")])
7563 (define_insn "*subdi_1_rex64"
7564   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7565         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7566                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7567    (clobber (reg:CC FLAGS_REG))]
7568   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7569   "sub{q}\t{%2, %0|%0, %2}"
7570   [(set_attr "type" "alu")
7571    (set_attr "mode" "DI")])
7573 (define_insn "*subdi_2_rex64"
7574   [(set (reg FLAGS_REG)
7575         (compare
7576           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7577                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7578           (const_int 0)))
7579    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7580         (minus:DI (match_dup 1) (match_dup 2)))]
7581   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7582    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7583   "sub{q}\t{%2, %0|%0, %2}"
7584   [(set_attr "type" "alu")
7585    (set_attr "mode" "DI")])
7587 (define_insn "*subdi_3_rex63"
7588   [(set (reg FLAGS_REG)
7589         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7590                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7591    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7592         (minus:DI (match_dup 1) (match_dup 2)))]
7593   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7594    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7595   "sub{q}\t{%2, %0|%0, %2}"
7596   [(set_attr "type" "alu")
7597    (set_attr "mode" "DI")])
7599 (define_insn "subqi3_carry"
7600   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7601           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7602             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7603                (match_operand:QI 2 "general_operand" "qn,qm"))))
7604    (clobber (reg:CC FLAGS_REG))]
7605   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7606   "sbb{b}\t{%2, %0|%0, %2}"
7607   [(set_attr "type" "alu")
7608    (set_attr "pent_pair" "pu")
7609    (set_attr "mode" "QI")])
7611 (define_insn "subhi3_carry"
7612   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7613           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7614             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7615                (match_operand:HI 2 "general_operand" "rn,rm"))))
7616    (clobber (reg:CC FLAGS_REG))]
7617   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7618   "sbb{w}\t{%2, %0|%0, %2}"
7619   [(set_attr "type" "alu")
7620    (set_attr "pent_pair" "pu")
7621    (set_attr "mode" "HI")])
7623 (define_insn "subsi3_carry"
7624   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7625           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7626             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7627                (match_operand:SI 2 "general_operand" "ri,rm"))))
7628    (clobber (reg:CC FLAGS_REG))]
7629   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7630   "sbb{l}\t{%2, %0|%0, %2}"
7631   [(set_attr "type" "alu")
7632    (set_attr "pent_pair" "pu")
7633    (set_attr "mode" "SI")])
7635 (define_insn "subsi3_carry_zext"
7636   [(set (match_operand:DI 0 "register_operand" "=r")
7637           (zero_extend:DI
7638             (minus:SI (match_operand:SI 1 "register_operand" "0")
7639               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7640                  (match_operand:SI 2 "general_operand" "g")))))
7641    (clobber (reg:CC FLAGS_REG))]
7642   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7643   "sbb{l}\t{%2, %k0|%k0, %2}"
7644   [(set_attr "type" "alu")
7645    (set_attr "pent_pair" "pu")
7646    (set_attr "mode" "SI")])
7648 (define_expand "subsi3"
7649   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7650         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7651                   (match_operand:SI 2 "general_operand" "")))]
7652   ""
7653   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7655 (define_insn "*subsi_1"
7656   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7657         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7658                   (match_operand:SI 2 "general_operand" "ri,rm")))
7659    (clobber (reg:CC FLAGS_REG))]
7660   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7661   "sub{l}\t{%2, %0|%0, %2}"
7662   [(set_attr "type" "alu")
7663    (set_attr "mode" "SI")])
7665 (define_insn "*subsi_1_zext"
7666   [(set (match_operand:DI 0 "register_operand" "=r")
7667         (zero_extend:DI
7668           (minus:SI (match_operand:SI 1 "register_operand" "0")
7669                     (match_operand:SI 2 "general_operand" "g"))))
7670    (clobber (reg:CC FLAGS_REG))]
7671   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7672   "sub{l}\t{%2, %k0|%k0, %2}"
7673   [(set_attr "type" "alu")
7674    (set_attr "mode" "SI")])
7676 (define_insn "*subsi_2"
7677   [(set (reg FLAGS_REG)
7678         (compare
7679           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7680                     (match_operand:SI 2 "general_operand" "ri,rm"))
7681           (const_int 0)))
7682    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7683         (minus:SI (match_dup 1) (match_dup 2)))]
7684   "ix86_match_ccmode (insn, CCGOCmode)
7685    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7686   "sub{l}\t{%2, %0|%0, %2}"
7687   [(set_attr "type" "alu")
7688    (set_attr "mode" "SI")])
7690 (define_insn "*subsi_2_zext"
7691   [(set (reg FLAGS_REG)
7692         (compare
7693           (minus:SI (match_operand:SI 1 "register_operand" "0")
7694                     (match_operand:SI 2 "general_operand" "g"))
7695           (const_int 0)))
7696    (set (match_operand:DI 0 "register_operand" "=r")
7697         (zero_extend:DI
7698           (minus:SI (match_dup 1)
7699                     (match_dup 2))))]
7700   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7701    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7702   "sub{l}\t{%2, %k0|%k0, %2}"
7703   [(set_attr "type" "alu")
7704    (set_attr "mode" "SI")])
7706 (define_insn "*subsi_3"
7707   [(set (reg FLAGS_REG)
7708         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7709                  (match_operand:SI 2 "general_operand" "ri,rm")))
7710    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7711         (minus:SI (match_dup 1) (match_dup 2)))]
7712   "ix86_match_ccmode (insn, CCmode)
7713    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7714   "sub{l}\t{%2, %0|%0, %2}"
7715   [(set_attr "type" "alu")
7716    (set_attr "mode" "SI")])
7718 (define_insn "*subsi_3_zext"
7719   [(set (reg FLAGS_REG)
7720         (compare (match_operand:SI 1 "register_operand" "0")
7721                  (match_operand:SI 2 "general_operand" "g")))
7722    (set (match_operand:DI 0 "register_operand" "=r")
7723         (zero_extend:DI
7724           (minus:SI (match_dup 1)
7725                     (match_dup 2))))]
7726   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7727    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7728   "sub{l}\t{%2, %1|%1, %2}"
7729   [(set_attr "type" "alu")
7730    (set_attr "mode" "DI")])
7732 (define_expand "subhi3"
7733   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7734         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7735                   (match_operand:HI 2 "general_operand" "")))]
7736   "TARGET_HIMODE_MATH"
7737   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7739 (define_insn "*subhi_1"
7740   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7741         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7742                   (match_operand:HI 2 "general_operand" "rn,rm")))
7743    (clobber (reg:CC FLAGS_REG))]
7744   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7745   "sub{w}\t{%2, %0|%0, %2}"
7746   [(set_attr "type" "alu")
7747    (set_attr "mode" "HI")])
7749 (define_insn "*subhi_2"
7750   [(set (reg FLAGS_REG)
7751         (compare
7752           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7753                     (match_operand:HI 2 "general_operand" "rn,rm"))
7754           (const_int 0)))
7755    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7756         (minus:HI (match_dup 1) (match_dup 2)))]
7757   "ix86_match_ccmode (insn, CCGOCmode)
7758    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7759   "sub{w}\t{%2, %0|%0, %2}"
7760   [(set_attr "type" "alu")
7761    (set_attr "mode" "HI")])
7763 (define_insn "*subhi_3"
7764   [(set (reg FLAGS_REG)
7765         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7766                  (match_operand:HI 2 "general_operand" "rn,rm")))
7767    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7768         (minus:HI (match_dup 1) (match_dup 2)))]
7769   "ix86_match_ccmode (insn, CCmode)
7770    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7771   "sub{w}\t{%2, %0|%0, %2}"
7772   [(set_attr "type" "alu")
7773    (set_attr "mode" "HI")])
7775 (define_expand "subqi3"
7776   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7777         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7778                   (match_operand:QI 2 "general_operand" "")))]
7779   "TARGET_QIMODE_MATH"
7780   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7782 (define_insn "*subqi_1"
7783   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7784         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7785                   (match_operand:QI 2 "general_operand" "qn,qm")))
7786    (clobber (reg:CC FLAGS_REG))]
7787   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7788   "sub{b}\t{%2, %0|%0, %2}"
7789   [(set_attr "type" "alu")
7790    (set_attr "mode" "QI")])
7792 (define_insn "*subqi_1_slp"
7793   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7794         (minus:QI (match_dup 0)
7795                   (match_operand:QI 1 "general_operand" "qn,qm")))
7796    (clobber (reg:CC FLAGS_REG))]
7797   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7798    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7799   "sub{b}\t{%1, %0|%0, %1}"
7800   [(set_attr "type" "alu1")
7801    (set_attr "mode" "QI")])
7803 (define_insn "*subqi_2"
7804   [(set (reg FLAGS_REG)
7805         (compare
7806           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7807                     (match_operand:QI 2 "general_operand" "qn,qm"))
7808           (const_int 0)))
7809    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7810         (minus:QI (match_dup 1) (match_dup 2)))]
7811   "ix86_match_ccmode (insn, CCGOCmode)
7812    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7813   "sub{b}\t{%2, %0|%0, %2}"
7814   [(set_attr "type" "alu")
7815    (set_attr "mode" "QI")])
7817 (define_insn "*subqi_3"
7818   [(set (reg FLAGS_REG)
7819         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7820                  (match_operand:QI 2 "general_operand" "qn,qm")))
7821    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7822         (minus:QI (match_dup 1) (match_dup 2)))]
7823   "ix86_match_ccmode (insn, CCmode)
7824    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7825   "sub{b}\t{%2, %0|%0, %2}"
7826   [(set_attr "type" "alu")
7827    (set_attr "mode" "QI")])
7829 ;; The patterns that match these are at the end of this file.
7831 (define_expand "subxf3"
7832   [(set (match_operand:XF 0 "register_operand" "")
7833         (minus:XF (match_operand:XF 1 "register_operand" "")
7834                   (match_operand:XF 2 "register_operand" "")))]
7835   "TARGET_80387"
7836   "")
7838 (define_expand "sub<mode>3"
7839   [(set (match_operand:MODEF 0 "register_operand" "")
7840         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7841                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7842   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7843   "")
7845 ;; Multiply instructions
7847 (define_expand "muldi3"
7848   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7849                    (mult:DI (match_operand:DI 1 "register_operand" "")
7850                             (match_operand:DI 2 "x86_64_general_operand" "")))
7851               (clobber (reg:CC FLAGS_REG))])]
7852   "TARGET_64BIT"
7853   "")
7855 ;; On AMDFAM10
7856 ;; IMUL reg64, reg64, imm8      Direct
7857 ;; IMUL reg64, mem64, imm8      VectorPath
7858 ;; IMUL reg64, reg64, imm32     Direct
7859 ;; IMUL reg64, mem64, imm32     VectorPath
7860 ;; IMUL reg64, reg64            Direct
7861 ;; IMUL reg64, mem64            Direct
7863 (define_insn "*muldi3_1_rex64"
7864   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7865         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7866                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7867    (clobber (reg:CC FLAGS_REG))]
7868   "TARGET_64BIT
7869    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7870   "@
7871    imul{q}\t{%2, %1, %0|%0, %1, %2}
7872    imul{q}\t{%2, %1, %0|%0, %1, %2}
7873    imul{q}\t{%2, %0|%0, %2}"
7874   [(set_attr "type" "imul")
7875    (set_attr "prefix_0f" "0,0,1")
7876    (set (attr "athlon_decode")
7877         (cond [(eq_attr "cpu" "athlon")
7878                   (const_string "vector")
7879                (eq_attr "alternative" "1")
7880                   (const_string "vector")
7881                (and (eq_attr "alternative" "2")
7882                     (match_operand 1 "memory_operand" ""))
7883                   (const_string "vector")]
7884               (const_string "direct")))
7885    (set (attr "amdfam10_decode")
7886         (cond [(and (eq_attr "alternative" "0,1")
7887                     (match_operand 1 "memory_operand" ""))
7888                   (const_string "vector")]
7889               (const_string "direct")))
7890    (set_attr "mode" "DI")])
7892 (define_expand "mulsi3"
7893   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7894                    (mult:SI (match_operand:SI 1 "register_operand" "")
7895                             (match_operand:SI 2 "general_operand" "")))
7896               (clobber (reg:CC FLAGS_REG))])]
7897   ""
7898   "")
7900 ;; On AMDFAM10
7901 ;; IMUL reg32, reg32, imm8      Direct
7902 ;; IMUL reg32, mem32, imm8      VectorPath
7903 ;; IMUL reg32, reg32, imm32     Direct
7904 ;; IMUL reg32, mem32, imm32     VectorPath
7905 ;; IMUL reg32, reg32            Direct
7906 ;; IMUL reg32, mem32            Direct
7908 (define_insn "*mulsi3_1"
7909   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7910         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7911                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7912    (clobber (reg:CC FLAGS_REG))]
7913   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7914   "@
7915    imul{l}\t{%2, %1, %0|%0, %1, %2}
7916    imul{l}\t{%2, %1, %0|%0, %1, %2}
7917    imul{l}\t{%2, %0|%0, %2}"
7918   [(set_attr "type" "imul")
7919    (set_attr "prefix_0f" "0,0,1")
7920    (set (attr "athlon_decode")
7921         (cond [(eq_attr "cpu" "athlon")
7922                   (const_string "vector")
7923                (eq_attr "alternative" "1")
7924                   (const_string "vector")
7925                (and (eq_attr "alternative" "2")
7926                     (match_operand 1 "memory_operand" ""))
7927                   (const_string "vector")]
7928               (const_string "direct")))
7929    (set (attr "amdfam10_decode")
7930         (cond [(and (eq_attr "alternative" "0,1")
7931                     (match_operand 1 "memory_operand" ""))
7932                   (const_string "vector")]
7933               (const_string "direct")))
7934    (set_attr "mode" "SI")])
7936 (define_insn "*mulsi3_1_zext"
7937   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7938         (zero_extend:DI
7939           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7940                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7941    (clobber (reg:CC FLAGS_REG))]
7942   "TARGET_64BIT
7943    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7944   "@
7945    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7946    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7947    imul{l}\t{%2, %k0|%k0, %2}"
7948   [(set_attr "type" "imul")
7949    (set_attr "prefix_0f" "0,0,1")
7950    (set (attr "athlon_decode")
7951         (cond [(eq_attr "cpu" "athlon")
7952                   (const_string "vector")
7953                (eq_attr "alternative" "1")
7954                   (const_string "vector")
7955                (and (eq_attr "alternative" "2")
7956                     (match_operand 1 "memory_operand" ""))
7957                   (const_string "vector")]
7958               (const_string "direct")))
7959    (set (attr "amdfam10_decode")
7960         (cond [(and (eq_attr "alternative" "0,1")
7961                     (match_operand 1 "memory_operand" ""))
7962                   (const_string "vector")]
7963               (const_string "direct")))
7964    (set_attr "mode" "SI")])
7966 (define_expand "mulhi3"
7967   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7968                    (mult:HI (match_operand:HI 1 "register_operand" "")
7969                             (match_operand:HI 2 "general_operand" "")))
7970               (clobber (reg:CC FLAGS_REG))])]
7971   "TARGET_HIMODE_MATH"
7972   "")
7974 ;; On AMDFAM10
7975 ;; IMUL reg16, reg16, imm8      VectorPath
7976 ;; IMUL reg16, mem16, imm8      VectorPath
7977 ;; IMUL reg16, reg16, imm16     VectorPath
7978 ;; IMUL reg16, mem16, imm16     VectorPath
7979 ;; IMUL reg16, reg16            Direct
7980 ;; IMUL reg16, mem16            Direct
7981 (define_insn "*mulhi3_1"
7982   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7983         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7984                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7985    (clobber (reg:CC FLAGS_REG))]
7986   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7987   "@
7988    imul{w}\t{%2, %1, %0|%0, %1, %2}
7989    imul{w}\t{%2, %1, %0|%0, %1, %2}
7990    imul{w}\t{%2, %0|%0, %2}"
7991   [(set_attr "type" "imul")
7992    (set_attr "prefix_0f" "0,0,1")
7993    (set (attr "athlon_decode")
7994         (cond [(eq_attr "cpu" "athlon")
7995                   (const_string "vector")
7996                (eq_attr "alternative" "1,2")
7997                   (const_string "vector")]
7998               (const_string "direct")))
7999    (set (attr "amdfam10_decode")
8000         (cond [(eq_attr "alternative" "0,1")
8001                   (const_string "vector")]
8002               (const_string "direct")))
8003    (set_attr "mode" "HI")])
8005 (define_expand "mulqi3"
8006   [(parallel [(set (match_operand:QI 0 "register_operand" "")
8007                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8008                             (match_operand:QI 2 "register_operand" "")))
8009               (clobber (reg:CC FLAGS_REG))])]
8010   "TARGET_QIMODE_MATH"
8011   "")
8013 ;;On AMDFAM10
8014 ;; MUL reg8     Direct
8015 ;; MUL mem8     Direct
8017 (define_insn "*mulqi3_1"
8018   [(set (match_operand:QI 0 "register_operand" "=a")
8019         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8020                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8021    (clobber (reg:CC FLAGS_REG))]
8022   "TARGET_QIMODE_MATH
8023    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8024   "mul{b}\t%2"
8025   [(set_attr "type" "imul")
8026    (set_attr "length_immediate" "0")
8027    (set (attr "athlon_decode")
8028      (if_then_else (eq_attr "cpu" "athlon")
8029         (const_string "vector")
8030         (const_string "direct")))
8031    (set_attr "amdfam10_decode" "direct")
8032    (set_attr "mode" "QI")])
8034 (define_expand "umulqihi3"
8035   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8036                    (mult:HI (zero_extend:HI
8037                               (match_operand:QI 1 "nonimmediate_operand" ""))
8038                             (zero_extend:HI
8039                               (match_operand:QI 2 "register_operand" ""))))
8040               (clobber (reg:CC FLAGS_REG))])]
8041   "TARGET_QIMODE_MATH"
8042   "")
8044 (define_insn "*umulqihi3_1"
8045   [(set (match_operand:HI 0 "register_operand" "=a")
8046         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8047                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8048    (clobber (reg:CC FLAGS_REG))]
8049   "TARGET_QIMODE_MATH
8050    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8051   "mul{b}\t%2"
8052   [(set_attr "type" "imul")
8053    (set_attr "length_immediate" "0")
8054    (set (attr "athlon_decode")
8055      (if_then_else (eq_attr "cpu" "athlon")
8056         (const_string "vector")
8057         (const_string "direct")))
8058    (set_attr "amdfam10_decode" "direct")
8059    (set_attr "mode" "QI")])
8061 (define_expand "mulqihi3"
8062   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8063                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8064                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8065               (clobber (reg:CC FLAGS_REG))])]
8066   "TARGET_QIMODE_MATH"
8067   "")
8069 (define_insn "*mulqihi3_insn"
8070   [(set (match_operand:HI 0 "register_operand" "=a")
8071         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8072                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8073    (clobber (reg:CC FLAGS_REG))]
8074   "TARGET_QIMODE_MATH
8075    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8076   "imul{b}\t%2"
8077   [(set_attr "type" "imul")
8078    (set_attr "length_immediate" "0")
8079    (set (attr "athlon_decode")
8080      (if_then_else (eq_attr "cpu" "athlon")
8081         (const_string "vector")
8082         (const_string "direct")))
8083    (set_attr "amdfam10_decode" "direct")
8084    (set_attr "mode" "QI")])
8086 (define_expand "umulditi3"
8087   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8088                    (mult:TI (zero_extend:TI
8089                               (match_operand:DI 1 "nonimmediate_operand" ""))
8090                             (zero_extend:TI
8091                               (match_operand:DI 2 "register_operand" ""))))
8092               (clobber (reg:CC FLAGS_REG))])]
8093   "TARGET_64BIT"
8094   "")
8096 (define_insn "*umulditi3_insn"
8097   [(set (match_operand:TI 0 "register_operand" "=A")
8098         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8099                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8100    (clobber (reg:CC FLAGS_REG))]
8101   "TARGET_64BIT
8102    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8103   "mul{q}\t%2"
8104   [(set_attr "type" "imul")
8105    (set_attr "length_immediate" "0")
8106    (set (attr "athlon_decode")
8107      (if_then_else (eq_attr "cpu" "athlon")
8108         (const_string "vector")
8109         (const_string "double")))
8110    (set_attr "amdfam10_decode" "double")
8111    (set_attr "mode" "DI")])
8113 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8114 (define_expand "umulsidi3"
8115   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8116                    (mult:DI (zero_extend:DI
8117                               (match_operand:SI 1 "nonimmediate_operand" ""))
8118                             (zero_extend:DI
8119                               (match_operand:SI 2 "register_operand" ""))))
8120               (clobber (reg:CC FLAGS_REG))])]
8121   "!TARGET_64BIT"
8122   "")
8124 (define_insn "*umulsidi3_insn"
8125   [(set (match_operand:DI 0 "register_operand" "=A")
8126         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8127                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8128    (clobber (reg:CC FLAGS_REG))]
8129   "!TARGET_64BIT
8130    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8131   "mul{l}\t%2"
8132   [(set_attr "type" "imul")
8133    (set_attr "length_immediate" "0")
8134    (set (attr "athlon_decode")
8135      (if_then_else (eq_attr "cpu" "athlon")
8136         (const_string "vector")
8137         (const_string "double")))
8138    (set_attr "amdfam10_decode" "double")
8139    (set_attr "mode" "SI")])
8141 (define_expand "mulditi3"
8142   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8143                    (mult:TI (sign_extend:TI
8144                               (match_operand:DI 1 "nonimmediate_operand" ""))
8145                             (sign_extend:TI
8146                               (match_operand:DI 2 "register_operand" ""))))
8147               (clobber (reg:CC FLAGS_REG))])]
8148   "TARGET_64BIT"
8149   "")
8151 (define_insn "*mulditi3_insn"
8152   [(set (match_operand:TI 0 "register_operand" "=A")
8153         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8154                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8155    (clobber (reg:CC FLAGS_REG))]
8156   "TARGET_64BIT
8157    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8158   "imul{q}\t%2"
8159   [(set_attr "type" "imul")
8160    (set_attr "length_immediate" "0")
8161    (set (attr "athlon_decode")
8162      (if_then_else (eq_attr "cpu" "athlon")
8163         (const_string "vector")
8164         (const_string "double")))
8165    (set_attr "amdfam10_decode" "double")
8166    (set_attr "mode" "DI")])
8168 (define_expand "mulsidi3"
8169   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8170                    (mult:DI (sign_extend:DI
8171                               (match_operand:SI 1 "nonimmediate_operand" ""))
8172                             (sign_extend:DI
8173                               (match_operand:SI 2 "register_operand" ""))))
8174               (clobber (reg:CC FLAGS_REG))])]
8175   "!TARGET_64BIT"
8176   "")
8178 (define_insn "*mulsidi3_insn"
8179   [(set (match_operand:DI 0 "register_operand" "=A")
8180         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8181                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8182    (clobber (reg:CC FLAGS_REG))]
8183   "!TARGET_64BIT
8184    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8185   "imul{l}\t%2"
8186   [(set_attr "type" "imul")
8187    (set_attr "length_immediate" "0")
8188    (set (attr "athlon_decode")
8189      (if_then_else (eq_attr "cpu" "athlon")
8190         (const_string "vector")
8191         (const_string "double")))
8192    (set_attr "amdfam10_decode" "double")
8193    (set_attr "mode" "SI")])
8195 (define_expand "umuldi3_highpart"
8196   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8197                    (truncate:DI
8198                      (lshiftrt:TI
8199                        (mult:TI (zero_extend:TI
8200                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8201                                 (zero_extend:TI
8202                                   (match_operand:DI 2 "register_operand" "")))
8203                        (const_int 64))))
8204               (clobber (match_scratch:DI 3 ""))
8205               (clobber (reg:CC FLAGS_REG))])]
8206   "TARGET_64BIT"
8207   "")
8209 (define_insn "*umuldi3_highpart_rex64"
8210   [(set (match_operand:DI 0 "register_operand" "=d")
8211         (truncate:DI
8212           (lshiftrt:TI
8213             (mult:TI (zero_extend:TI
8214                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8215                      (zero_extend:TI
8216                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8217             (const_int 64))))
8218    (clobber (match_scratch:DI 3 "=1"))
8219    (clobber (reg:CC FLAGS_REG))]
8220   "TARGET_64BIT
8221    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8222   "mul{q}\t%2"
8223   [(set_attr "type" "imul")
8224    (set_attr "length_immediate" "0")
8225    (set (attr "athlon_decode")
8226      (if_then_else (eq_attr "cpu" "athlon")
8227         (const_string "vector")
8228         (const_string "double")))
8229    (set_attr "amdfam10_decode" "double")
8230    (set_attr "mode" "DI")])
8232 (define_expand "umulsi3_highpart"
8233   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8234                    (truncate:SI
8235                      (lshiftrt:DI
8236                        (mult:DI (zero_extend:DI
8237                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8238                                 (zero_extend:DI
8239                                   (match_operand:SI 2 "register_operand" "")))
8240                        (const_int 32))))
8241               (clobber (match_scratch:SI 3 ""))
8242               (clobber (reg:CC FLAGS_REG))])]
8243   ""
8244   "")
8246 (define_insn "*umulsi3_highpart_insn"
8247   [(set (match_operand:SI 0 "register_operand" "=d")
8248         (truncate:SI
8249           (lshiftrt:DI
8250             (mult:DI (zero_extend:DI
8251                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8252                      (zero_extend:DI
8253                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8254             (const_int 32))))
8255    (clobber (match_scratch:SI 3 "=1"))
8256    (clobber (reg:CC FLAGS_REG))]
8257   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8258   "mul{l}\t%2"
8259   [(set_attr "type" "imul")
8260    (set_attr "length_immediate" "0")
8261    (set (attr "athlon_decode")
8262      (if_then_else (eq_attr "cpu" "athlon")
8263         (const_string "vector")
8264         (const_string "double")))
8265    (set_attr "amdfam10_decode" "double")
8266    (set_attr "mode" "SI")])
8268 (define_insn "*umulsi3_highpart_zext"
8269   [(set (match_operand:DI 0 "register_operand" "=d")
8270         (zero_extend:DI (truncate:SI
8271           (lshiftrt:DI
8272             (mult:DI (zero_extend:DI
8273                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8274                      (zero_extend:DI
8275                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8276             (const_int 32)))))
8277    (clobber (match_scratch:SI 3 "=1"))
8278    (clobber (reg:CC FLAGS_REG))]
8279   "TARGET_64BIT
8280    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8281   "mul{l}\t%2"
8282   [(set_attr "type" "imul")
8283    (set_attr "length_immediate" "0")
8284    (set (attr "athlon_decode")
8285      (if_then_else (eq_attr "cpu" "athlon")
8286         (const_string "vector")
8287         (const_string "double")))
8288    (set_attr "amdfam10_decode" "double")
8289    (set_attr "mode" "SI")])
8291 (define_expand "smuldi3_highpart"
8292   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8293                    (truncate:DI
8294                      (lshiftrt:TI
8295                        (mult:TI (sign_extend:TI
8296                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8297                                 (sign_extend:TI
8298                                   (match_operand:DI 2 "register_operand" "")))
8299                        (const_int 64))))
8300               (clobber (match_scratch:DI 3 ""))
8301               (clobber (reg:CC FLAGS_REG))])]
8302   "TARGET_64BIT"
8303   "")
8305 (define_insn "*smuldi3_highpart_rex64"
8306   [(set (match_operand:DI 0 "register_operand" "=d")
8307         (truncate:DI
8308           (lshiftrt:TI
8309             (mult:TI (sign_extend:TI
8310                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8311                      (sign_extend:TI
8312                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8313             (const_int 64))))
8314    (clobber (match_scratch:DI 3 "=1"))
8315    (clobber (reg:CC FLAGS_REG))]
8316   "TARGET_64BIT
8317    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8318   "imul{q}\t%2"
8319   [(set_attr "type" "imul")
8320    (set (attr "athlon_decode")
8321      (if_then_else (eq_attr "cpu" "athlon")
8322         (const_string "vector")
8323         (const_string "double")))
8324    (set_attr "amdfam10_decode" "double")
8325    (set_attr "mode" "DI")])
8327 (define_expand "smulsi3_highpart"
8328   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8329                    (truncate:SI
8330                      (lshiftrt:DI
8331                        (mult:DI (sign_extend:DI
8332                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8333                                 (sign_extend:DI
8334                                   (match_operand:SI 2 "register_operand" "")))
8335                        (const_int 32))))
8336               (clobber (match_scratch:SI 3 ""))
8337               (clobber (reg:CC FLAGS_REG))])]
8338   ""
8339   "")
8341 (define_insn "*smulsi3_highpart_insn"
8342   [(set (match_operand:SI 0 "register_operand" "=d")
8343         (truncate:SI
8344           (lshiftrt:DI
8345             (mult:DI (sign_extend:DI
8346                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8347                      (sign_extend:DI
8348                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8349             (const_int 32))))
8350    (clobber (match_scratch:SI 3 "=1"))
8351    (clobber (reg:CC FLAGS_REG))]
8352   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8353   "imul{l}\t%2"
8354   [(set_attr "type" "imul")
8355    (set (attr "athlon_decode")
8356      (if_then_else (eq_attr "cpu" "athlon")
8357         (const_string "vector")
8358         (const_string "double")))
8359    (set_attr "amdfam10_decode" "double")
8360    (set_attr "mode" "SI")])
8362 (define_insn "*smulsi3_highpart_zext"
8363   [(set (match_operand:DI 0 "register_operand" "=d")
8364         (zero_extend:DI (truncate:SI
8365           (lshiftrt:DI
8366             (mult:DI (sign_extend:DI
8367                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8368                      (sign_extend:DI
8369                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8370             (const_int 32)))))
8371    (clobber (match_scratch:SI 3 "=1"))
8372    (clobber (reg:CC FLAGS_REG))]
8373   "TARGET_64BIT
8374    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8375   "imul{l}\t%2"
8376   [(set_attr "type" "imul")
8377    (set (attr "athlon_decode")
8378      (if_then_else (eq_attr "cpu" "athlon")
8379         (const_string "vector")
8380         (const_string "double")))
8381    (set_attr "amdfam10_decode" "double")
8382    (set_attr "mode" "SI")])
8384 ;; The patterns that match these are at the end of this file.
8386 (define_expand "mulxf3"
8387   [(set (match_operand:XF 0 "register_operand" "")
8388         (mult:XF (match_operand:XF 1 "register_operand" "")
8389                  (match_operand:XF 2 "register_operand" "")))]
8390   "TARGET_80387"
8391   "")
8393 (define_expand "mul<mode>3"
8394   [(set (match_operand:MODEF 0 "register_operand" "")
8395         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8396                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8397   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8398   "")
8400 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8403 ;; Divide instructions
8405 (define_insn "divqi3"
8406   [(set (match_operand:QI 0 "register_operand" "=a")
8407         (div:QI (match_operand:HI 1 "register_operand" "0")
8408                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8409    (clobber (reg:CC FLAGS_REG))]
8410   "TARGET_QIMODE_MATH"
8411   "idiv{b}\t%2"
8412   [(set_attr "type" "idiv")
8413    (set_attr "mode" "QI")])
8415 (define_insn "udivqi3"
8416   [(set (match_operand:QI 0 "register_operand" "=a")
8417         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8418                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8419    (clobber (reg:CC FLAGS_REG))]
8420   "TARGET_QIMODE_MATH"
8421   "div{b}\t%2"
8422   [(set_attr "type" "idiv")
8423    (set_attr "mode" "QI")])
8425 ;; The patterns that match these are at the end of this file.
8427 (define_expand "divxf3"
8428   [(set (match_operand:XF 0 "register_operand" "")
8429         (div:XF (match_operand:XF 1 "register_operand" "")
8430                 (match_operand:XF 2 "register_operand" "")))]
8431   "TARGET_80387"
8432   "")
8434 (define_expand "divdf3"
8435   [(set (match_operand:DF 0 "register_operand" "")
8436         (div:DF (match_operand:DF 1 "register_operand" "")
8437                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8438    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8439    "")
8441 (define_expand "divsf3"
8442   [(set (match_operand:SF 0 "register_operand" "")
8443         (div:SF (match_operand:SF 1 "register_operand" "")
8444                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8445   "TARGET_80387 || TARGET_SSE_MATH"
8447   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8448       && flag_finite_math_only && !flag_trapping_math
8449       && flag_unsafe_math_optimizations)
8450     {
8451       ix86_emit_swdivsf (operands[0], operands[1],
8452                          operands[2], SFmode);
8453       DONE;
8454     }
8457 ;; Remainder instructions.
8459 (define_expand "divmoddi4"
8460   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8461                    (div:DI (match_operand:DI 1 "register_operand" "")
8462                            (match_operand:DI 2 "nonimmediate_operand" "")))
8463               (set (match_operand:DI 3 "register_operand" "")
8464                    (mod:DI (match_dup 1) (match_dup 2)))
8465               (clobber (reg:CC FLAGS_REG))])]
8466   "TARGET_64BIT"
8467   "")
8469 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8470 ;; Penalize eax case slightly because it results in worse scheduling
8471 ;; of code.
8472 (define_insn "*divmoddi4_nocltd_rex64"
8473   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8474         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8475                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8476    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8477         (mod:DI (match_dup 2) (match_dup 3)))
8478    (clobber (reg:CC FLAGS_REG))]
8479   "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8480   "#"
8481   [(set_attr "type" "multi")])
8483 (define_insn "*divmoddi4_cltd_rex64"
8484   [(set (match_operand:DI 0 "register_operand" "=a")
8485         (div:DI (match_operand:DI 2 "register_operand" "a")
8486                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8487    (set (match_operand:DI 1 "register_operand" "=&d")
8488         (mod:DI (match_dup 2) (match_dup 3)))
8489    (clobber (reg:CC FLAGS_REG))]
8490   "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8491   "#"
8492   [(set_attr "type" "multi")])
8494 (define_insn "*divmoddi_noext_rex64"
8495   [(set (match_operand:DI 0 "register_operand" "=a")
8496         (div:DI (match_operand:DI 1 "register_operand" "0")
8497                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8498    (set (match_operand:DI 3 "register_operand" "=d")
8499         (mod:DI (match_dup 1) (match_dup 2)))
8500    (use (match_operand:DI 4 "register_operand" "3"))
8501    (clobber (reg:CC FLAGS_REG))]
8502   "TARGET_64BIT"
8503   "idiv{q}\t%2"
8504   [(set_attr "type" "idiv")
8505    (set_attr "mode" "DI")])
8507 (define_split
8508   [(set (match_operand:DI 0 "register_operand" "")
8509         (div:DI (match_operand:DI 1 "register_operand" "")
8510                 (match_operand:DI 2 "nonimmediate_operand" "")))
8511    (set (match_operand:DI 3 "register_operand" "")
8512         (mod:DI (match_dup 1) (match_dup 2)))
8513    (clobber (reg:CC FLAGS_REG))]
8514   "TARGET_64BIT && reload_completed"
8515   [(parallel [(set (match_dup 3)
8516                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8517               (clobber (reg:CC FLAGS_REG))])
8518    (parallel [(set (match_dup 0)
8519                    (div:DI (reg:DI 0) (match_dup 2)))
8520               (set (match_dup 3)
8521                    (mod:DI (reg:DI 0) (match_dup 2)))
8522               (use (match_dup 3))
8523               (clobber (reg:CC FLAGS_REG))])]
8525   /* Avoid use of cltd in favor of a mov+shift.  */
8526   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8527     {
8528       if (true_regnum (operands[1]))
8529         emit_move_insn (operands[0], operands[1]);
8530       else
8531         emit_move_insn (operands[3], operands[1]);
8532       operands[4] = operands[3];
8533     }
8534   else
8535     {
8536       gcc_assert (!true_regnum (operands[1]));
8537       operands[4] = operands[1];
8538     }
8542 (define_expand "divmodsi4"
8543   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8544                    (div:SI (match_operand:SI 1 "register_operand" "")
8545                            (match_operand:SI 2 "nonimmediate_operand" "")))
8546               (set (match_operand:SI 3 "register_operand" "")
8547                    (mod:SI (match_dup 1) (match_dup 2)))
8548               (clobber (reg:CC FLAGS_REG))])]
8549   ""
8550   "")
8552 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8553 ;; Penalize eax case slightly because it results in worse scheduling
8554 ;; of code.
8555 (define_insn "*divmodsi4_nocltd"
8556   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8557         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8558                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8559    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8560         (mod:SI (match_dup 2) (match_dup 3)))
8561    (clobber (reg:CC FLAGS_REG))]
8562   "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8563   "#"
8564   [(set_attr "type" "multi")])
8566 (define_insn "*divmodsi4_cltd"
8567   [(set (match_operand:SI 0 "register_operand" "=a")
8568         (div:SI (match_operand:SI 2 "register_operand" "a")
8569                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8570    (set (match_operand:SI 1 "register_operand" "=&d")
8571         (mod:SI (match_dup 2) (match_dup 3)))
8572    (clobber (reg:CC FLAGS_REG))]
8573   "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8574   "#"
8575   [(set_attr "type" "multi")])
8577 (define_insn "*divmodsi_noext"
8578   [(set (match_operand:SI 0 "register_operand" "=a")
8579         (div:SI (match_operand:SI 1 "register_operand" "0")
8580                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8581    (set (match_operand:SI 3 "register_operand" "=d")
8582         (mod:SI (match_dup 1) (match_dup 2)))
8583    (use (match_operand:SI 4 "register_operand" "3"))
8584    (clobber (reg:CC FLAGS_REG))]
8585   ""
8586   "idiv{l}\t%2"
8587   [(set_attr "type" "idiv")
8588    (set_attr "mode" "SI")])
8590 (define_split
8591   [(set (match_operand:SI 0 "register_operand" "")
8592         (div:SI (match_operand:SI 1 "register_operand" "")
8593                 (match_operand:SI 2 "nonimmediate_operand" "")))
8594    (set (match_operand:SI 3 "register_operand" "")
8595         (mod:SI (match_dup 1) (match_dup 2)))
8596    (clobber (reg:CC FLAGS_REG))]
8597   "reload_completed"
8598   [(parallel [(set (match_dup 3)
8599                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8600               (clobber (reg:CC FLAGS_REG))])
8601    (parallel [(set (match_dup 0)
8602                    (div:SI (reg:SI 0) (match_dup 2)))
8603               (set (match_dup 3)
8604                    (mod:SI (reg:SI 0) (match_dup 2)))
8605               (use (match_dup 3))
8606               (clobber (reg:CC FLAGS_REG))])]
8608   /* Avoid use of cltd in favor of a mov+shift.  */
8609   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8610     {
8611       if (true_regnum (operands[1]))
8612         emit_move_insn (operands[0], operands[1]);
8613       else
8614         emit_move_insn (operands[3], operands[1]);
8615       operands[4] = operands[3];
8616     }
8617   else
8618     {
8619       gcc_assert (!true_regnum (operands[1]));
8620       operands[4] = operands[1];
8621     }
8623 ;; %%% Split me.
8624 (define_insn "divmodhi4"
8625   [(set (match_operand:HI 0 "register_operand" "=a")
8626         (div:HI (match_operand:HI 1 "register_operand" "0")
8627                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8628    (set (match_operand:HI 3 "register_operand" "=&d")
8629         (mod:HI (match_dup 1) (match_dup 2)))
8630    (clobber (reg:CC FLAGS_REG))]
8631   "TARGET_HIMODE_MATH"
8632   "cwtd\;idiv{w}\t%2"
8633   [(set_attr "type" "multi")
8634    (set_attr "length_immediate" "0")
8635    (set_attr "mode" "SI")])
8637 (define_insn "udivmoddi4"
8638   [(set (match_operand:DI 0 "register_operand" "=a")
8639         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8640                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8641    (set (match_operand:DI 3 "register_operand" "=&d")
8642         (umod:DI (match_dup 1) (match_dup 2)))
8643    (clobber (reg:CC FLAGS_REG))]
8644   "TARGET_64BIT"
8645   "xor{q}\t%3, %3\;div{q}\t%2"
8646   [(set_attr "type" "multi")
8647    (set_attr "length_immediate" "0")
8648    (set_attr "mode" "DI")])
8650 (define_insn "*udivmoddi4_noext"
8651   [(set (match_operand:DI 0 "register_operand" "=a")
8652         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8653                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8654    (set (match_operand:DI 3 "register_operand" "=d")
8655         (umod:DI (match_dup 1) (match_dup 2)))
8656    (use (match_dup 3))
8657    (clobber (reg:CC FLAGS_REG))]
8658   "TARGET_64BIT"
8659   "div{q}\t%2"
8660   [(set_attr "type" "idiv")
8661    (set_attr "mode" "DI")])
8663 (define_split
8664   [(set (match_operand:DI 0 "register_operand" "")
8665         (udiv:DI (match_operand:DI 1 "register_operand" "")
8666                  (match_operand:DI 2 "nonimmediate_operand" "")))
8667    (set (match_operand:DI 3 "register_operand" "")
8668         (umod:DI (match_dup 1) (match_dup 2)))
8669    (clobber (reg:CC FLAGS_REG))]
8670   "TARGET_64BIT && reload_completed"
8671   [(set (match_dup 3) (const_int 0))
8672    (parallel [(set (match_dup 0)
8673                    (udiv:DI (match_dup 1) (match_dup 2)))
8674               (set (match_dup 3)
8675                    (umod:DI (match_dup 1) (match_dup 2)))
8676               (use (match_dup 3))
8677               (clobber (reg:CC FLAGS_REG))])]
8678   "")
8680 (define_insn "udivmodsi4"
8681   [(set (match_operand:SI 0 "register_operand" "=a")
8682         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8683                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8684    (set (match_operand:SI 3 "register_operand" "=&d")
8685         (umod:SI (match_dup 1) (match_dup 2)))
8686    (clobber (reg:CC FLAGS_REG))]
8687   ""
8688   "xor{l}\t%3, %3\;div{l}\t%2"
8689   [(set_attr "type" "multi")
8690    (set_attr "length_immediate" "0")
8691    (set_attr "mode" "SI")])
8693 (define_insn "*udivmodsi4_noext"
8694   [(set (match_operand:SI 0 "register_operand" "=a")
8695         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8696                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8697    (set (match_operand:SI 3 "register_operand" "=d")
8698         (umod:SI (match_dup 1) (match_dup 2)))
8699    (use (match_dup 3))
8700    (clobber (reg:CC FLAGS_REG))]
8701   ""
8702   "div{l}\t%2"
8703   [(set_attr "type" "idiv")
8704    (set_attr "mode" "SI")])
8706 (define_split
8707   [(set (match_operand:SI 0 "register_operand" "")
8708         (udiv:SI (match_operand:SI 1 "register_operand" "")
8709                  (match_operand:SI 2 "nonimmediate_operand" "")))
8710    (set (match_operand:SI 3 "register_operand" "")
8711         (umod:SI (match_dup 1) (match_dup 2)))
8712    (clobber (reg:CC FLAGS_REG))]
8713   "reload_completed"
8714   [(set (match_dup 3) (const_int 0))
8715    (parallel [(set (match_dup 0)
8716                    (udiv:SI (match_dup 1) (match_dup 2)))
8717               (set (match_dup 3)
8718                    (umod:SI (match_dup 1) (match_dup 2)))
8719               (use (match_dup 3))
8720               (clobber (reg:CC FLAGS_REG))])]
8721   "")
8723 (define_expand "udivmodhi4"
8724   [(set (match_dup 4) (const_int 0))
8725    (parallel [(set (match_operand:HI 0 "register_operand" "")
8726                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8727                             (match_operand:HI 2 "nonimmediate_operand" "")))
8728               (set (match_operand:HI 3 "register_operand" "")
8729                    (umod:HI (match_dup 1) (match_dup 2)))
8730               (use (match_dup 4))
8731               (clobber (reg:CC FLAGS_REG))])]
8732   "TARGET_HIMODE_MATH"
8733   "operands[4] = gen_reg_rtx (HImode);")
8735 (define_insn "*udivmodhi_noext"
8736   [(set (match_operand:HI 0 "register_operand" "=a")
8737         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8738                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8739    (set (match_operand:HI 3 "register_operand" "=d")
8740         (umod:HI (match_dup 1) (match_dup 2)))
8741    (use (match_operand:HI 4 "register_operand" "3"))
8742    (clobber (reg:CC FLAGS_REG))]
8743   ""
8744   "div{w}\t%2"
8745   [(set_attr "type" "idiv")
8746    (set_attr "mode" "HI")])
8748 ;; We cannot use div/idiv for double division, because it causes
8749 ;; "division by zero" on the overflow and that's not what we expect
8750 ;; from truncate.  Because true (non truncating) double division is
8751 ;; never generated, we can't create this insn anyway.
8753 ;(define_insn ""
8754 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8755 ;       (truncate:SI
8756 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8757 ;                  (zero_extend:DI
8758 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8759 ;   (set (match_operand:SI 3 "register_operand" "=d")
8760 ;       (truncate:SI
8761 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8762 ;   (clobber (reg:CC FLAGS_REG))]
8763 ;  ""
8764 ;  "div{l}\t{%2, %0|%0, %2}"
8765 ;  [(set_attr "type" "idiv")])
8767 ;;- Logical AND instructions
8769 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8770 ;; Note that this excludes ah.
8772 (define_insn "*testdi_1_rex64"
8773   [(set (reg FLAGS_REG)
8774         (compare
8775           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8776                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8777           (const_int 0)))]
8778   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8779    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8780   "@
8781    test{l}\t{%k1, %k0|%k0, %k1}
8782    test{l}\t{%k1, %k0|%k0, %k1}
8783    test{q}\t{%1, %0|%0, %1}
8784    test{q}\t{%1, %0|%0, %1}
8785    test{q}\t{%1, %0|%0, %1}"
8786   [(set_attr "type" "test")
8787    (set_attr "modrm" "0,1,0,1,1")
8788    (set_attr "mode" "SI,SI,DI,DI,DI")
8789    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8791 (define_insn "testsi_1"
8792   [(set (reg FLAGS_REG)
8793         (compare
8794           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8795                   (match_operand:SI 1 "general_operand" "i,i,ri"))
8796           (const_int 0)))]
8797   "ix86_match_ccmode (insn, CCNOmode)
8798    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8799   "test{l}\t{%1, %0|%0, %1}"
8800   [(set_attr "type" "test")
8801    (set_attr "modrm" "0,1,1")
8802    (set_attr "mode" "SI")
8803    (set_attr "pent_pair" "uv,np,uv")])
8805 (define_expand "testsi_ccno_1"
8806   [(set (reg:CCNO FLAGS_REG)
8807         (compare:CCNO
8808           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8809                   (match_operand:SI 1 "nonmemory_operand" ""))
8810           (const_int 0)))]
8811   ""
8812   "")
8814 (define_insn "*testhi_1"
8815   [(set (reg FLAGS_REG)
8816         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8817                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8818                  (const_int 0)))]
8819   "ix86_match_ccmode (insn, CCNOmode)
8820    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8821   "test{w}\t{%1, %0|%0, %1}"
8822   [(set_attr "type" "test")
8823    (set_attr "modrm" "0,1,1")
8824    (set_attr "mode" "HI")
8825    (set_attr "pent_pair" "uv,np,uv")])
8827 (define_expand "testqi_ccz_1"
8828   [(set (reg:CCZ FLAGS_REG)
8829         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8830                              (match_operand:QI 1 "nonmemory_operand" ""))
8831                  (const_int 0)))]
8832   ""
8833   "")
8835 (define_insn "*testqi_1_maybe_si"
8836   [(set (reg FLAGS_REG)
8837         (compare
8838           (and:QI
8839             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8840             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8841           (const_int 0)))]
8842    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8843     && ix86_match_ccmode (insn,
8844                          CONST_INT_P (operands[1])
8845                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8847   if (which_alternative == 3)
8848     {
8849       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8850         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8851       return "test{l}\t{%1, %k0|%k0, %1}";
8852     }
8853   return "test{b}\t{%1, %0|%0, %1}";
8855   [(set_attr "type" "test")
8856    (set_attr "modrm" "0,1,1,1")
8857    (set_attr "mode" "QI,QI,QI,SI")
8858    (set_attr "pent_pair" "uv,np,uv,np")])
8860 (define_insn "*testqi_1"
8861   [(set (reg FLAGS_REG)
8862         (compare
8863           (and:QI
8864             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8865             (match_operand:QI 1 "general_operand" "n,n,qn"))
8866           (const_int 0)))]
8867   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8868    && ix86_match_ccmode (insn, CCNOmode)"
8869   "test{b}\t{%1, %0|%0, %1}"
8870   [(set_attr "type" "test")
8871    (set_attr "modrm" "0,1,1")
8872    (set_attr "mode" "QI")
8873    (set_attr "pent_pair" "uv,np,uv")])
8875 (define_expand "testqi_ext_ccno_0"
8876   [(set (reg:CCNO FLAGS_REG)
8877         (compare:CCNO
8878           (and:SI
8879             (zero_extract:SI
8880               (match_operand 0 "ext_register_operand" "")
8881               (const_int 8)
8882               (const_int 8))
8883             (match_operand 1 "const_int_operand" ""))
8884           (const_int 0)))]
8885   ""
8886   "")
8888 (define_insn "*testqi_ext_0"
8889   [(set (reg FLAGS_REG)
8890         (compare
8891           (and:SI
8892             (zero_extract:SI
8893               (match_operand 0 "ext_register_operand" "Q")
8894               (const_int 8)
8895               (const_int 8))
8896             (match_operand 1 "const_int_operand" "n"))
8897           (const_int 0)))]
8898   "ix86_match_ccmode (insn, CCNOmode)"
8899   "test{b}\t{%1, %h0|%h0, %1}"
8900   [(set_attr "type" "test")
8901    (set_attr "mode" "QI")
8902    (set_attr "length_immediate" "1")
8903    (set_attr "pent_pair" "np")])
8905 (define_insn "*testqi_ext_1"
8906   [(set (reg FLAGS_REG)
8907         (compare
8908           (and:SI
8909             (zero_extract:SI
8910               (match_operand 0 "ext_register_operand" "Q")
8911               (const_int 8)
8912               (const_int 8))
8913             (zero_extend:SI
8914               (match_operand:QI 1 "general_operand" "Qm")))
8915           (const_int 0)))]
8916   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8917    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8918   "test{b}\t{%1, %h0|%h0, %1}"
8919   [(set_attr "type" "test")
8920    (set_attr "mode" "QI")])
8922 (define_insn "*testqi_ext_1_rex64"
8923   [(set (reg FLAGS_REG)
8924         (compare
8925           (and:SI
8926             (zero_extract:SI
8927               (match_operand 0 "ext_register_operand" "Q")
8928               (const_int 8)
8929               (const_int 8))
8930             (zero_extend:SI
8931               (match_operand:QI 1 "register_operand" "Q")))
8932           (const_int 0)))]
8933   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8934   "test{b}\t{%1, %h0|%h0, %1}"
8935   [(set_attr "type" "test")
8936    (set_attr "mode" "QI")])
8938 (define_insn "*testqi_ext_2"
8939   [(set (reg FLAGS_REG)
8940         (compare
8941           (and:SI
8942             (zero_extract:SI
8943               (match_operand 0 "ext_register_operand" "Q")
8944               (const_int 8)
8945               (const_int 8))
8946             (zero_extract:SI
8947               (match_operand 1 "ext_register_operand" "Q")
8948               (const_int 8)
8949               (const_int 8)))
8950           (const_int 0)))]
8951   "ix86_match_ccmode (insn, CCNOmode)"
8952   "test{b}\t{%h1, %h0|%h0, %h1}"
8953   [(set_attr "type" "test")
8954    (set_attr "mode" "QI")])
8956 ;; Combine likes to form bit extractions for some tests.  Humor it.
8957 (define_insn "*testqi_ext_3"
8958   [(set (reg FLAGS_REG)
8959         (compare (zero_extract:SI
8960                    (match_operand 0 "nonimmediate_operand" "rm")
8961                    (match_operand:SI 1 "const_int_operand" "")
8962                    (match_operand:SI 2 "const_int_operand" ""))
8963                  (const_int 0)))]
8964   "ix86_match_ccmode (insn, CCNOmode)
8965    && INTVAL (operands[1]) > 0
8966    && INTVAL (operands[2]) >= 0
8967    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8968    && (GET_MODE (operands[0]) == SImode
8969        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8970        || GET_MODE (operands[0]) == HImode
8971        || GET_MODE (operands[0]) == QImode)"
8972   "#")
8974 (define_insn "*testqi_ext_3_rex64"
8975   [(set (reg FLAGS_REG)
8976         (compare (zero_extract:DI
8977                    (match_operand 0 "nonimmediate_operand" "rm")
8978                    (match_operand:DI 1 "const_int_operand" "")
8979                    (match_operand:DI 2 "const_int_operand" ""))
8980                  (const_int 0)))]
8981   "TARGET_64BIT
8982    && ix86_match_ccmode (insn, CCNOmode)
8983    && INTVAL (operands[1]) > 0
8984    && INTVAL (operands[2]) >= 0
8985    /* Ensure that resulting mask is zero or sign extended operand.  */
8986    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8987        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8988            && INTVAL (operands[1]) > 32))
8989    && (GET_MODE (operands[0]) == SImode
8990        || GET_MODE (operands[0]) == DImode
8991        || GET_MODE (operands[0]) == HImode
8992        || GET_MODE (operands[0]) == QImode)"
8993   "#")
8995 (define_split
8996   [(set (match_operand 0 "flags_reg_operand" "")
8997         (match_operator 1 "compare_operator"
8998           [(zero_extract
8999              (match_operand 2 "nonimmediate_operand" "")
9000              (match_operand 3 "const_int_operand" "")
9001              (match_operand 4 "const_int_operand" ""))
9002            (const_int 0)]))]
9003   "ix86_match_ccmode (insn, CCNOmode)"
9004   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
9006   rtx val = operands[2];
9007   HOST_WIDE_INT len = INTVAL (operands[3]);
9008   HOST_WIDE_INT pos = INTVAL (operands[4]);
9009   HOST_WIDE_INT mask;
9010   enum machine_mode mode, submode;
9012   mode = GET_MODE (val);
9013   if (MEM_P (val))
9014     {
9015       /* ??? Combine likes to put non-volatile mem extractions in QImode
9016          no matter the size of the test.  So find a mode that works.  */
9017       if (! MEM_VOLATILE_P (val))
9018         {
9019           mode = smallest_mode_for_size (pos + len, MODE_INT);
9020           val = adjust_address (val, mode, 0);
9021         }
9022     }
9023   else if (GET_CODE (val) == SUBREG
9024            && (submode = GET_MODE (SUBREG_REG (val)),
9025                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9026            && pos + len <= GET_MODE_BITSIZE (submode))
9027     {
9028       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
9029       mode = submode;
9030       val = SUBREG_REG (val);
9031     }
9032   else if (mode == HImode && pos + len <= 8)
9033     {
9034       /* Small HImode tests can be converted to QImode.  */
9035       mode = QImode;
9036       val = gen_lowpart (QImode, val);
9037     }
9039   if (len == HOST_BITS_PER_WIDE_INT)
9040     mask = -1;
9041   else
9042     mask = ((HOST_WIDE_INT)1 << len) - 1;
9043   mask <<= pos;
9045   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9048 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9049 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9050 ;; this is relatively important trick.
9051 ;; Do the conversion only post-reload to avoid limiting of the register class
9052 ;; to QI regs.
9053 (define_split
9054   [(set (match_operand 0 "flags_reg_operand" "")
9055         (match_operator 1 "compare_operator"
9056           [(and (match_operand 2 "register_operand" "")
9057                 (match_operand 3 "const_int_operand" ""))
9058            (const_int 0)]))]
9059    "reload_completed
9060     && QI_REG_P (operands[2])
9061     && GET_MODE (operands[2]) != QImode
9062     && ((ix86_match_ccmode (insn, CCZmode)
9063          && !(INTVAL (operands[3]) & ~(255 << 8)))
9064         || (ix86_match_ccmode (insn, CCNOmode)
9065             && !(INTVAL (operands[3]) & ~(127 << 8))))"
9066   [(set (match_dup 0)
9067         (match_op_dup 1
9068           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9069                    (match_dup 3))
9070            (const_int 0)]))]
9071   "operands[2] = gen_lowpart (SImode, operands[2]);
9072    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9074 (define_split
9075   [(set (match_operand 0 "flags_reg_operand" "")
9076         (match_operator 1 "compare_operator"
9077           [(and (match_operand 2 "nonimmediate_operand" "")
9078                 (match_operand 3 "const_int_operand" ""))
9079            (const_int 0)]))]
9080    "reload_completed
9081     && GET_MODE (operands[2]) != QImode
9082     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9083     && ((ix86_match_ccmode (insn, CCZmode)
9084          && !(INTVAL (operands[3]) & ~255))
9085         || (ix86_match_ccmode (insn, CCNOmode)
9086             && !(INTVAL (operands[3]) & ~127)))"
9087   [(set (match_dup 0)
9088         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9089                          (const_int 0)]))]
9090   "operands[2] = gen_lowpart (QImode, operands[2]);
9091    operands[3] = gen_lowpart (QImode, operands[3]);")
9094 ;; %%% This used to optimize known byte-wide and operations to memory,
9095 ;; and sometimes to QImode registers.  If this is considered useful,
9096 ;; it should be done with splitters.
9098 (define_expand "anddi3"
9099   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9100         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9101                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9102   "TARGET_64BIT"
9103   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9105 (define_insn "*anddi_1_rex64"
9106   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9107         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9108                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9109    (clobber (reg:CC FLAGS_REG))]
9110   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9112   switch (get_attr_type (insn))
9113     {
9114     case TYPE_IMOVX:
9115       {
9116         enum machine_mode mode;
9118         gcc_assert (CONST_INT_P (operands[2]));
9119         if (INTVAL (operands[2]) == 0xff)
9120           mode = QImode;
9121         else
9122           {
9123             gcc_assert (INTVAL (operands[2]) == 0xffff);
9124             mode = HImode;
9125           }
9127         operands[1] = gen_lowpart (mode, operands[1]);
9128         if (mode == QImode)
9129           return "movz{bq|x}\t{%1,%0|%0, %1}";
9130         else
9131           return "movz{wq|x}\t{%1,%0|%0, %1}";
9132       }
9134     default:
9135       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9136       if (get_attr_mode (insn) == MODE_SI)
9137         return "and{l}\t{%k2, %k0|%k0, %k2}";
9138       else
9139         return "and{q}\t{%2, %0|%0, %2}";
9140     }
9142   [(set_attr "type" "alu,alu,alu,imovx")
9143    (set_attr "length_immediate" "*,*,*,0")
9144    (set_attr "mode" "SI,DI,DI,DI")])
9146 (define_insn "*anddi_2"
9147   [(set (reg FLAGS_REG)
9148         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9149                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9150                  (const_int 0)))
9151    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9152         (and:DI (match_dup 1) (match_dup 2)))]
9153   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9154    && ix86_binary_operator_ok (AND, DImode, operands)"
9155   "@
9156    and{l}\t{%k2, %k0|%k0, %k2}
9157    and{q}\t{%2, %0|%0, %2}
9158    and{q}\t{%2, %0|%0, %2}"
9159   [(set_attr "type" "alu")
9160    (set_attr "mode" "SI,DI,DI")])
9162 (define_expand "andsi3"
9163   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9164         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9165                 (match_operand:SI 2 "general_operand" "")))]
9166   ""
9167   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9169 (define_insn "*andsi_1"
9170   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9171         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9172                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9173    (clobber (reg:CC FLAGS_REG))]
9174   "ix86_binary_operator_ok (AND, SImode, operands)"
9176   switch (get_attr_type (insn))
9177     {
9178     case TYPE_IMOVX:
9179       {
9180         enum machine_mode mode;
9182         gcc_assert (CONST_INT_P (operands[2]));
9183         if (INTVAL (operands[2]) == 0xff)
9184           mode = QImode;
9185         else
9186           {
9187             gcc_assert (INTVAL (operands[2]) == 0xffff);
9188             mode = HImode;
9189           }
9191         operands[1] = gen_lowpart (mode, operands[1]);
9192         if (mode == QImode)
9193           return "movz{bl|x}\t{%1,%0|%0, %1}";
9194         else
9195           return "movz{wl|x}\t{%1,%0|%0, %1}";
9196       }
9198     default:
9199       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9200       return "and{l}\t{%2, %0|%0, %2}";
9201     }
9203   [(set_attr "type" "alu,alu,imovx")
9204    (set_attr "length_immediate" "*,*,0")
9205    (set_attr "mode" "SI")])
9207 (define_split
9208   [(set (match_operand 0 "register_operand" "")
9209         (and (match_dup 0)
9210              (const_int -65536)))
9211    (clobber (reg:CC FLAGS_REG))]
9212   "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9213   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9214   "operands[1] = gen_lowpart (HImode, operands[0]);")
9216 (define_split
9217   [(set (match_operand 0 "ext_register_operand" "")
9218         (and (match_dup 0)
9219              (const_int -256)))
9220    (clobber (reg:CC FLAGS_REG))]
9221   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9222   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9223   "operands[1] = gen_lowpart (QImode, operands[0]);")
9225 (define_split
9226   [(set (match_operand 0 "ext_register_operand" "")
9227         (and (match_dup 0)
9228              (const_int -65281)))
9229    (clobber (reg:CC FLAGS_REG))]
9230   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9231   [(parallel [(set (zero_extract:SI (match_dup 0)
9232                                     (const_int 8)
9233                                     (const_int 8))
9234                    (xor:SI
9235                      (zero_extract:SI (match_dup 0)
9236                                       (const_int 8)
9237                                       (const_int 8))
9238                      (zero_extract:SI (match_dup 0)
9239                                       (const_int 8)
9240                                       (const_int 8))))
9241               (clobber (reg:CC FLAGS_REG))])]
9242   "operands[0] = gen_lowpart (SImode, operands[0]);")
9244 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9245 (define_insn "*andsi_1_zext"
9246   [(set (match_operand:DI 0 "register_operand" "=r")
9247         (zero_extend:DI
9248           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9249                   (match_operand:SI 2 "general_operand" "g"))))
9250    (clobber (reg:CC FLAGS_REG))]
9251   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9252   "and{l}\t{%2, %k0|%k0, %2}"
9253   [(set_attr "type" "alu")
9254    (set_attr "mode" "SI")])
9256 (define_insn "*andsi_2"
9257   [(set (reg FLAGS_REG)
9258         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9259                          (match_operand:SI 2 "general_operand" "g,ri"))
9260                  (const_int 0)))
9261    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9262         (and:SI (match_dup 1) (match_dup 2)))]
9263   "ix86_match_ccmode (insn, CCNOmode)
9264    && ix86_binary_operator_ok (AND, SImode, operands)"
9265   "and{l}\t{%2, %0|%0, %2}"
9266   [(set_attr "type" "alu")
9267    (set_attr "mode" "SI")])
9269 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9270 (define_insn "*andsi_2_zext"
9271   [(set (reg FLAGS_REG)
9272         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9273                          (match_operand:SI 2 "general_operand" "g"))
9274                  (const_int 0)))
9275    (set (match_operand:DI 0 "register_operand" "=r")
9276         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9277   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9278    && ix86_binary_operator_ok (AND, SImode, operands)"
9279   "and{l}\t{%2, %k0|%k0, %2}"
9280   [(set_attr "type" "alu")
9281    (set_attr "mode" "SI")])
9283 (define_expand "andhi3"
9284   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9285         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9286                 (match_operand:HI 2 "general_operand" "")))]
9287   "TARGET_HIMODE_MATH"
9288   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9290 (define_insn "*andhi_1"
9291   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9292         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9293                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9294    (clobber (reg:CC FLAGS_REG))]
9295   "ix86_binary_operator_ok (AND, HImode, operands)"
9297   switch (get_attr_type (insn))
9298     {
9299     case TYPE_IMOVX:
9300       gcc_assert (CONST_INT_P (operands[2]));
9301       gcc_assert (INTVAL (operands[2]) == 0xff);
9302       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9304     default:
9305       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9307       return "and{w}\t{%2, %0|%0, %2}";
9308     }
9310   [(set_attr "type" "alu,alu,imovx")
9311    (set_attr "length_immediate" "*,*,0")
9312    (set_attr "mode" "HI,HI,SI")])
9314 (define_insn "*andhi_2"
9315   [(set (reg FLAGS_REG)
9316         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9317                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9318                  (const_int 0)))
9319    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9320         (and:HI (match_dup 1) (match_dup 2)))]
9321   "ix86_match_ccmode (insn, CCNOmode)
9322    && ix86_binary_operator_ok (AND, HImode, operands)"
9323   "and{w}\t{%2, %0|%0, %2}"
9324   [(set_attr "type" "alu")
9325    (set_attr "mode" "HI")])
9327 (define_expand "andqi3"
9328   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9329         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9330                 (match_operand:QI 2 "general_operand" "")))]
9331   "TARGET_QIMODE_MATH"
9332   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9334 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9335 (define_insn "*andqi_1"
9336   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9337         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9338                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9339    (clobber (reg:CC FLAGS_REG))]
9340   "ix86_binary_operator_ok (AND, QImode, operands)"
9341   "@
9342    and{b}\t{%2, %0|%0, %2}
9343    and{b}\t{%2, %0|%0, %2}
9344    and{l}\t{%k2, %k0|%k0, %k2}"
9345   [(set_attr "type" "alu")
9346    (set_attr "mode" "QI,QI,SI")])
9348 (define_insn "*andqi_1_slp"
9349   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9350         (and:QI (match_dup 0)
9351                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9352    (clobber (reg:CC FLAGS_REG))]
9353   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9354    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9355   "and{b}\t{%1, %0|%0, %1}"
9356   [(set_attr "type" "alu1")
9357    (set_attr "mode" "QI")])
9359 (define_insn "*andqi_2_maybe_si"
9360   [(set (reg FLAGS_REG)
9361         (compare (and:QI
9362                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9363                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9364                  (const_int 0)))
9365    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9366         (and:QI (match_dup 1) (match_dup 2)))]
9367   "ix86_binary_operator_ok (AND, QImode, operands)
9368    && ix86_match_ccmode (insn,
9369                          CONST_INT_P (operands[2])
9370                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9372   if (which_alternative == 2)
9373     {
9374       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9375         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9376       return "and{l}\t{%2, %k0|%k0, %2}";
9377     }
9378   return "and{b}\t{%2, %0|%0, %2}";
9380   [(set_attr "type" "alu")
9381    (set_attr "mode" "QI,QI,SI")])
9383 (define_insn "*andqi_2"
9384   [(set (reg FLAGS_REG)
9385         (compare (and:QI
9386                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9387                    (match_operand:QI 2 "general_operand" "qmn,qn"))
9388                  (const_int 0)))
9389    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9390         (and:QI (match_dup 1) (match_dup 2)))]
9391   "ix86_match_ccmode (insn, CCNOmode)
9392    && ix86_binary_operator_ok (AND, QImode, operands)"
9393   "and{b}\t{%2, %0|%0, %2}"
9394   [(set_attr "type" "alu")
9395    (set_attr "mode" "QI")])
9397 (define_insn "*andqi_2_slp"
9398   [(set (reg FLAGS_REG)
9399         (compare (and:QI
9400                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9401                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9402                  (const_int 0)))
9403    (set (strict_low_part (match_dup 0))
9404         (and:QI (match_dup 0) (match_dup 1)))]
9405   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9406    && ix86_match_ccmode (insn, CCNOmode)
9407    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9408   "and{b}\t{%1, %0|%0, %1}"
9409   [(set_attr "type" "alu1")
9410    (set_attr "mode" "QI")])
9412 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9413 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9414 ;; for a QImode operand, which of course failed.
9416 (define_insn "andqi_ext_0"
9417   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9418                          (const_int 8)
9419                          (const_int 8))
9420         (and:SI
9421           (zero_extract:SI
9422             (match_operand 1 "ext_register_operand" "0")
9423             (const_int 8)
9424             (const_int 8))
9425           (match_operand 2 "const_int_operand" "n")))
9426    (clobber (reg:CC FLAGS_REG))]
9427   ""
9428   "and{b}\t{%2, %h0|%h0, %2}"
9429   [(set_attr "type" "alu")
9430    (set_attr "length_immediate" "1")
9431    (set_attr "mode" "QI")])
9433 ;; Generated by peephole translating test to and.  This shows up
9434 ;; often in fp comparisons.
9436 (define_insn "*andqi_ext_0_cc"
9437   [(set (reg FLAGS_REG)
9438         (compare
9439           (and:SI
9440             (zero_extract:SI
9441               (match_operand 1 "ext_register_operand" "0")
9442               (const_int 8)
9443               (const_int 8))
9444             (match_operand 2 "const_int_operand" "n"))
9445           (const_int 0)))
9446    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9447                          (const_int 8)
9448                          (const_int 8))
9449         (and:SI
9450           (zero_extract:SI
9451             (match_dup 1)
9452             (const_int 8)
9453             (const_int 8))
9454           (match_dup 2)))]
9455   "ix86_match_ccmode (insn, CCNOmode)"
9456   "and{b}\t{%2, %h0|%h0, %2}"
9457   [(set_attr "type" "alu")
9458    (set_attr "length_immediate" "1")
9459    (set_attr "mode" "QI")])
9461 (define_insn "*andqi_ext_1"
9462   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9463                          (const_int 8)
9464                          (const_int 8))
9465         (and:SI
9466           (zero_extract:SI
9467             (match_operand 1 "ext_register_operand" "0")
9468             (const_int 8)
9469             (const_int 8))
9470           (zero_extend:SI
9471             (match_operand:QI 2 "general_operand" "Qm"))))
9472    (clobber (reg:CC FLAGS_REG))]
9473   "!TARGET_64BIT"
9474   "and{b}\t{%2, %h0|%h0, %2}"
9475   [(set_attr "type" "alu")
9476    (set_attr "length_immediate" "0")
9477    (set_attr "mode" "QI")])
9479 (define_insn "*andqi_ext_1_rex64"
9480   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9481                          (const_int 8)
9482                          (const_int 8))
9483         (and:SI
9484           (zero_extract:SI
9485             (match_operand 1 "ext_register_operand" "0")
9486             (const_int 8)
9487             (const_int 8))
9488           (zero_extend:SI
9489             (match_operand 2 "ext_register_operand" "Q"))))
9490    (clobber (reg:CC FLAGS_REG))]
9491   "TARGET_64BIT"
9492   "and{b}\t{%2, %h0|%h0, %2}"
9493   [(set_attr "type" "alu")
9494    (set_attr "length_immediate" "0")
9495    (set_attr "mode" "QI")])
9497 (define_insn "*andqi_ext_2"
9498   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9499                          (const_int 8)
9500                          (const_int 8))
9501         (and:SI
9502           (zero_extract:SI
9503             (match_operand 1 "ext_register_operand" "%0")
9504             (const_int 8)
9505             (const_int 8))
9506           (zero_extract:SI
9507             (match_operand 2 "ext_register_operand" "Q")
9508             (const_int 8)
9509             (const_int 8))))
9510    (clobber (reg:CC FLAGS_REG))]
9511   ""
9512   "and{b}\t{%h2, %h0|%h0, %h2}"
9513   [(set_attr "type" "alu")
9514    (set_attr "length_immediate" "0")
9515    (set_attr "mode" "QI")])
9517 ;; Convert wide AND instructions with immediate operand to shorter QImode
9518 ;; equivalents when possible.
9519 ;; Don't do the splitting with memory operands, since it introduces risk
9520 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9521 ;; for size, but that can (should?) be handled by generic code instead.
9522 (define_split
9523   [(set (match_operand 0 "register_operand" "")
9524         (and (match_operand 1 "register_operand" "")
9525              (match_operand 2 "const_int_operand" "")))
9526    (clobber (reg:CC FLAGS_REG))]
9527    "reload_completed
9528     && QI_REG_P (operands[0])
9529     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9530     && !(~INTVAL (operands[2]) & ~(255 << 8))
9531     && GET_MODE (operands[0]) != QImode"
9532   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9533                    (and:SI (zero_extract:SI (match_dup 1)
9534                                             (const_int 8) (const_int 8))
9535                            (match_dup 2)))
9536               (clobber (reg:CC FLAGS_REG))])]
9537   "operands[0] = gen_lowpart (SImode, operands[0]);
9538    operands[1] = gen_lowpart (SImode, operands[1]);
9539    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9541 ;; Since AND can be encoded with sign extended immediate, this is only
9542 ;; profitable when 7th bit is not set.
9543 (define_split
9544   [(set (match_operand 0 "register_operand" "")
9545         (and (match_operand 1 "general_operand" "")
9546              (match_operand 2 "const_int_operand" "")))
9547    (clobber (reg:CC FLAGS_REG))]
9548    "reload_completed
9549     && ANY_QI_REG_P (operands[0])
9550     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9551     && !(~INTVAL (operands[2]) & ~255)
9552     && !(INTVAL (operands[2]) & 128)
9553     && GET_MODE (operands[0]) != QImode"
9554   [(parallel [(set (strict_low_part (match_dup 0))
9555                    (and:QI (match_dup 1)
9556                            (match_dup 2)))
9557               (clobber (reg:CC FLAGS_REG))])]
9558   "operands[0] = gen_lowpart (QImode, operands[0]);
9559    operands[1] = gen_lowpart (QImode, operands[1]);
9560    operands[2] = gen_lowpart (QImode, operands[2]);")
9562 ;; Logical inclusive OR instructions
9564 ;; %%% This used to optimize known byte-wide and operations to memory.
9565 ;; If this is considered useful, it should be done with splitters.
9567 (define_expand "iordi3"
9568   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9569         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9570                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9571   "TARGET_64BIT"
9572   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9574 (define_insn "*iordi_1_rex64"
9575   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9576         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9577                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9578    (clobber (reg:CC FLAGS_REG))]
9579   "TARGET_64BIT
9580    && ix86_binary_operator_ok (IOR, DImode, operands)"
9581   "or{q}\t{%2, %0|%0, %2}"
9582   [(set_attr "type" "alu")
9583    (set_attr "mode" "DI")])
9585 (define_insn "*iordi_2_rex64"
9586   [(set (reg FLAGS_REG)
9587         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9588                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9589                  (const_int 0)))
9590    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9591         (ior:DI (match_dup 1) (match_dup 2)))]
9592   "TARGET_64BIT
9593    && ix86_match_ccmode (insn, CCNOmode)
9594    && ix86_binary_operator_ok (IOR, DImode, operands)"
9595   "or{q}\t{%2, %0|%0, %2}"
9596   [(set_attr "type" "alu")
9597    (set_attr "mode" "DI")])
9599 (define_insn "*iordi_3_rex64"
9600   [(set (reg FLAGS_REG)
9601         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9602                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9603                  (const_int 0)))
9604    (clobber (match_scratch:DI 0 "=r"))]
9605   "TARGET_64BIT
9606    && ix86_match_ccmode (insn, CCNOmode)
9607    && ix86_binary_operator_ok (IOR, DImode, operands)"
9608   "or{q}\t{%2, %0|%0, %2}"
9609   [(set_attr "type" "alu")
9610    (set_attr "mode" "DI")])
9613 (define_expand "iorsi3"
9614   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9615         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9616                 (match_operand:SI 2 "general_operand" "")))]
9617   ""
9618   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9620 (define_insn "*iorsi_1"
9621   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9622         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9623                 (match_operand:SI 2 "general_operand" "ri,g")))
9624    (clobber (reg:CC FLAGS_REG))]
9625   "ix86_binary_operator_ok (IOR, SImode, operands)"
9626   "or{l}\t{%2, %0|%0, %2}"
9627   [(set_attr "type" "alu")
9628    (set_attr "mode" "SI")])
9630 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9631 (define_insn "*iorsi_1_zext"
9632   [(set (match_operand:DI 0 "register_operand" "=r")
9633         (zero_extend:DI
9634           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9635                   (match_operand:SI 2 "general_operand" "g"))))
9636    (clobber (reg:CC FLAGS_REG))]
9637   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9638   "or{l}\t{%2, %k0|%k0, %2}"
9639   [(set_attr "type" "alu")
9640    (set_attr "mode" "SI")])
9642 (define_insn "*iorsi_1_zext_imm"
9643   [(set (match_operand:DI 0 "register_operand" "=r")
9644         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9645                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9646    (clobber (reg:CC FLAGS_REG))]
9647   "TARGET_64BIT"
9648   "or{l}\t{%2, %k0|%k0, %2}"
9649   [(set_attr "type" "alu")
9650    (set_attr "mode" "SI")])
9652 (define_insn "*iorsi_2"
9653   [(set (reg FLAGS_REG)
9654         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9655                          (match_operand:SI 2 "general_operand" "g,ri"))
9656                  (const_int 0)))
9657    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9658         (ior:SI (match_dup 1) (match_dup 2)))]
9659   "ix86_match_ccmode (insn, CCNOmode)
9660    && ix86_binary_operator_ok (IOR, SImode, operands)"
9661   "or{l}\t{%2, %0|%0, %2}"
9662   [(set_attr "type" "alu")
9663    (set_attr "mode" "SI")])
9665 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9666 ;; ??? Special case for immediate operand is missing - it is tricky.
9667 (define_insn "*iorsi_2_zext"
9668   [(set (reg FLAGS_REG)
9669         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9670                          (match_operand:SI 2 "general_operand" "g"))
9671                  (const_int 0)))
9672    (set (match_operand:DI 0 "register_operand" "=r")
9673         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9674   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9675    && ix86_binary_operator_ok (IOR, SImode, operands)"
9676   "or{l}\t{%2, %k0|%k0, %2}"
9677   [(set_attr "type" "alu")
9678    (set_attr "mode" "SI")])
9680 (define_insn "*iorsi_2_zext_imm"
9681   [(set (reg FLAGS_REG)
9682         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9683                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9684                  (const_int 0)))
9685    (set (match_operand:DI 0 "register_operand" "=r")
9686         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9687   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9688    && ix86_binary_operator_ok (IOR, SImode, operands)"
9689   "or{l}\t{%2, %k0|%k0, %2}"
9690   [(set_attr "type" "alu")
9691    (set_attr "mode" "SI")])
9693 (define_insn "*iorsi_3"
9694   [(set (reg FLAGS_REG)
9695         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9696                          (match_operand:SI 2 "general_operand" "g"))
9697                  (const_int 0)))
9698    (clobber (match_scratch:SI 0 "=r"))]
9699   "ix86_match_ccmode (insn, CCNOmode)
9700    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9701   "or{l}\t{%2, %0|%0, %2}"
9702   [(set_attr "type" "alu")
9703    (set_attr "mode" "SI")])
9705 (define_expand "iorhi3"
9706   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9707         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9708                 (match_operand:HI 2 "general_operand" "")))]
9709   "TARGET_HIMODE_MATH"
9710   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9712 (define_insn "*iorhi_1"
9713   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9714         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9715                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9716    (clobber (reg:CC FLAGS_REG))]
9717   "ix86_binary_operator_ok (IOR, HImode, operands)"
9718   "or{w}\t{%2, %0|%0, %2}"
9719   [(set_attr "type" "alu")
9720    (set_attr "mode" "HI")])
9722 (define_insn "*iorhi_2"
9723   [(set (reg FLAGS_REG)
9724         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9725                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9726                  (const_int 0)))
9727    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9728         (ior:HI (match_dup 1) (match_dup 2)))]
9729   "ix86_match_ccmode (insn, CCNOmode)
9730    && ix86_binary_operator_ok (IOR, HImode, operands)"
9731   "or{w}\t{%2, %0|%0, %2}"
9732   [(set_attr "type" "alu")
9733    (set_attr "mode" "HI")])
9735 (define_insn "*iorhi_3"
9736   [(set (reg FLAGS_REG)
9737         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9738                          (match_operand:HI 2 "general_operand" "rmn"))
9739                  (const_int 0)))
9740    (clobber (match_scratch:HI 0 "=r"))]
9741   "ix86_match_ccmode (insn, CCNOmode)
9742    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9743   "or{w}\t{%2, %0|%0, %2}"
9744   [(set_attr "type" "alu")
9745    (set_attr "mode" "HI")])
9747 (define_expand "iorqi3"
9748   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9749         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9750                 (match_operand:QI 2 "general_operand" "")))]
9751   "TARGET_QIMODE_MATH"
9752   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9754 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9755 (define_insn "*iorqi_1"
9756   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9757         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9758                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9759    (clobber (reg:CC FLAGS_REG))]
9760   "ix86_binary_operator_ok (IOR, QImode, operands)"
9761   "@
9762    or{b}\t{%2, %0|%0, %2}
9763    or{b}\t{%2, %0|%0, %2}
9764    or{l}\t{%k2, %k0|%k0, %k2}"
9765   [(set_attr "type" "alu")
9766    (set_attr "mode" "QI,QI,SI")])
9768 (define_insn "*iorqi_1_slp"
9769   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9770         (ior:QI (match_dup 0)
9771                 (match_operand:QI 1 "general_operand" "qmn,qn")))
9772    (clobber (reg:CC FLAGS_REG))]
9773   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9774    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9775   "or{b}\t{%1, %0|%0, %1}"
9776   [(set_attr "type" "alu1")
9777    (set_attr "mode" "QI")])
9779 (define_insn "*iorqi_2"
9780   [(set (reg FLAGS_REG)
9781         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9782                          (match_operand:QI 2 "general_operand" "qmn,qn"))
9783                  (const_int 0)))
9784    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9785         (ior:QI (match_dup 1) (match_dup 2)))]
9786   "ix86_match_ccmode (insn, CCNOmode)
9787    && ix86_binary_operator_ok (IOR, QImode, operands)"
9788   "or{b}\t{%2, %0|%0, %2}"
9789   [(set_attr "type" "alu")
9790    (set_attr "mode" "QI")])
9792 (define_insn "*iorqi_2_slp"
9793   [(set (reg FLAGS_REG)
9794         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9795                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9796                  (const_int 0)))
9797    (set (strict_low_part (match_dup 0))
9798         (ior:QI (match_dup 0) (match_dup 1)))]
9799   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9800    && ix86_match_ccmode (insn, CCNOmode)
9801    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9802   "or{b}\t{%1, %0|%0, %1}"
9803   [(set_attr "type" "alu1")
9804    (set_attr "mode" "QI")])
9806 (define_insn "*iorqi_3"
9807   [(set (reg FLAGS_REG)
9808         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9809                          (match_operand:QI 2 "general_operand" "qmn"))
9810                  (const_int 0)))
9811    (clobber (match_scratch:QI 0 "=q"))]
9812   "ix86_match_ccmode (insn, CCNOmode)
9813    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9814   "or{b}\t{%2, %0|%0, %2}"
9815   [(set_attr "type" "alu")
9816    (set_attr "mode" "QI")])
9818 (define_insn "*iorqi_ext_0"
9819   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9820                          (const_int 8)
9821                          (const_int 8))
9822         (ior:SI
9823           (zero_extract:SI
9824             (match_operand 1 "ext_register_operand" "0")
9825             (const_int 8)
9826             (const_int 8))
9827           (match_operand 2 "const_int_operand" "n")))
9828    (clobber (reg:CC FLAGS_REG))]
9829   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9830   "or{b}\t{%2, %h0|%h0, %2}"
9831   [(set_attr "type" "alu")
9832    (set_attr "length_immediate" "1")
9833    (set_attr "mode" "QI")])
9835 (define_insn "*iorqi_ext_1"
9836   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9837                          (const_int 8)
9838                          (const_int 8))
9839         (ior:SI
9840           (zero_extract:SI
9841             (match_operand 1 "ext_register_operand" "0")
9842             (const_int 8)
9843             (const_int 8))
9844           (zero_extend:SI
9845             (match_operand:QI 2 "general_operand" "Qm"))))
9846    (clobber (reg:CC FLAGS_REG))]
9847   "!TARGET_64BIT
9848    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9849   "or{b}\t{%2, %h0|%h0, %2}"
9850   [(set_attr "type" "alu")
9851    (set_attr "length_immediate" "0")
9852    (set_attr "mode" "QI")])
9854 (define_insn "*iorqi_ext_1_rex64"
9855   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9856                          (const_int 8)
9857                          (const_int 8))
9858         (ior:SI
9859           (zero_extract:SI
9860             (match_operand 1 "ext_register_operand" "0")
9861             (const_int 8)
9862             (const_int 8))
9863           (zero_extend:SI
9864             (match_operand 2 "ext_register_operand" "Q"))))
9865    (clobber (reg:CC FLAGS_REG))]
9866   "TARGET_64BIT
9867    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9868   "or{b}\t{%2, %h0|%h0, %2}"
9869   [(set_attr "type" "alu")
9870    (set_attr "length_immediate" "0")
9871    (set_attr "mode" "QI")])
9873 (define_insn "*iorqi_ext_2"
9874   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9875                          (const_int 8)
9876                          (const_int 8))
9877         (ior:SI
9878           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9879                            (const_int 8)
9880                            (const_int 8))
9881           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9882                            (const_int 8)
9883                            (const_int 8))))
9884    (clobber (reg:CC FLAGS_REG))]
9885   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9886   "ior{b}\t{%h2, %h0|%h0, %h2}"
9887   [(set_attr "type" "alu")
9888    (set_attr "length_immediate" "0")
9889    (set_attr "mode" "QI")])
9891 (define_split
9892   [(set (match_operand 0 "register_operand" "")
9893         (ior (match_operand 1 "register_operand" "")
9894              (match_operand 2 "const_int_operand" "")))
9895    (clobber (reg:CC FLAGS_REG))]
9896    "reload_completed
9897     && QI_REG_P (operands[0])
9898     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9899     && !(INTVAL (operands[2]) & ~(255 << 8))
9900     && GET_MODE (operands[0]) != QImode"
9901   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9902                    (ior:SI (zero_extract:SI (match_dup 1)
9903                                             (const_int 8) (const_int 8))
9904                            (match_dup 2)))
9905               (clobber (reg:CC FLAGS_REG))])]
9906   "operands[0] = gen_lowpart (SImode, operands[0]);
9907    operands[1] = gen_lowpart (SImode, operands[1]);
9908    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9910 ;; Since OR can be encoded with sign extended immediate, this is only
9911 ;; profitable when 7th bit is set.
9912 (define_split
9913   [(set (match_operand 0 "register_operand" "")
9914         (ior (match_operand 1 "general_operand" "")
9915              (match_operand 2 "const_int_operand" "")))
9916    (clobber (reg:CC FLAGS_REG))]
9917    "reload_completed
9918     && ANY_QI_REG_P (operands[0])
9919     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9920     && !(INTVAL (operands[2]) & ~255)
9921     && (INTVAL (operands[2]) & 128)
9922     && GET_MODE (operands[0]) != QImode"
9923   [(parallel [(set (strict_low_part (match_dup 0))
9924                    (ior:QI (match_dup 1)
9925                            (match_dup 2)))
9926               (clobber (reg:CC FLAGS_REG))])]
9927   "operands[0] = gen_lowpart (QImode, operands[0]);
9928    operands[1] = gen_lowpart (QImode, operands[1]);
9929    operands[2] = gen_lowpart (QImode, operands[2]);")
9931 ;; Logical XOR instructions
9933 ;; %%% This used to optimize known byte-wide and operations to memory.
9934 ;; If this is considered useful, it should be done with splitters.
9936 (define_expand "xordi3"
9937   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9938         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9939                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9940   "TARGET_64BIT"
9941   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9943 (define_insn "*xordi_1_rex64"
9944   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9945         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9946                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9947    (clobber (reg:CC FLAGS_REG))]
9948   "TARGET_64BIT
9949    && ix86_binary_operator_ok (XOR, DImode, operands)"
9950   "xor{q}\t{%2, %0|%0, %2}"
9951   [(set_attr "type" "alu")
9952    (set_attr "mode" "DI")])
9954 (define_insn "*xordi_2_rex64"
9955   [(set (reg FLAGS_REG)
9956         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9957                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9958                  (const_int 0)))
9959    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9960         (xor:DI (match_dup 1) (match_dup 2)))]
9961   "TARGET_64BIT
9962    && ix86_match_ccmode (insn, CCNOmode)
9963    && ix86_binary_operator_ok (XOR, DImode, operands)"
9964   "xor{q}\t{%2, %0|%0, %2}"
9965   [(set_attr "type" "alu")
9966    (set_attr "mode" "DI")])
9968 (define_insn "*xordi_3_rex64"
9969   [(set (reg FLAGS_REG)
9970         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9971                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9972                  (const_int 0)))
9973    (clobber (match_scratch:DI 0 "=r"))]
9974   "TARGET_64BIT
9975    && ix86_match_ccmode (insn, CCNOmode)
9976    && ix86_binary_operator_ok (XOR, DImode, operands)"
9977   "xor{q}\t{%2, %0|%0, %2}"
9978   [(set_attr "type" "alu")
9979    (set_attr "mode" "DI")])
9981 (define_expand "xorsi3"
9982   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9983         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9984                 (match_operand:SI 2 "general_operand" "")))]
9985   ""
9986   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9988 (define_insn "*xorsi_1"
9989   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9990         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9991                 (match_operand:SI 2 "general_operand" "ri,rm")))
9992    (clobber (reg:CC FLAGS_REG))]
9993   "ix86_binary_operator_ok (XOR, SImode, operands)"
9994   "xor{l}\t{%2, %0|%0, %2}"
9995   [(set_attr "type" "alu")
9996    (set_attr "mode" "SI")])
9998 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9999 ;; Add speccase for immediates
10000 (define_insn "*xorsi_1_zext"
10001   [(set (match_operand:DI 0 "register_operand" "=r")
10002         (zero_extend:DI
10003           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10004                   (match_operand:SI 2 "general_operand" "g"))))
10005    (clobber (reg:CC FLAGS_REG))]
10006   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10007   "xor{l}\t{%2, %k0|%k0, %2}"
10008   [(set_attr "type" "alu")
10009    (set_attr "mode" "SI")])
10011 (define_insn "*xorsi_1_zext_imm"
10012   [(set (match_operand:DI 0 "register_operand" "=r")
10013         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10014                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10015    (clobber (reg:CC FLAGS_REG))]
10016   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10017   "xor{l}\t{%2, %k0|%k0, %2}"
10018   [(set_attr "type" "alu")
10019    (set_attr "mode" "SI")])
10021 (define_insn "*xorsi_2"
10022   [(set (reg FLAGS_REG)
10023         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10024                          (match_operand:SI 2 "general_operand" "g,ri"))
10025                  (const_int 0)))
10026    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10027         (xor:SI (match_dup 1) (match_dup 2)))]
10028   "ix86_match_ccmode (insn, CCNOmode)
10029    && ix86_binary_operator_ok (XOR, SImode, operands)"
10030   "xor{l}\t{%2, %0|%0, %2}"
10031   [(set_attr "type" "alu")
10032    (set_attr "mode" "SI")])
10034 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10035 ;; ??? Special case for immediate operand is missing - it is tricky.
10036 (define_insn "*xorsi_2_zext"
10037   [(set (reg FLAGS_REG)
10038         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10039                          (match_operand:SI 2 "general_operand" "g"))
10040                  (const_int 0)))
10041    (set (match_operand:DI 0 "register_operand" "=r")
10042         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10043   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10044    && ix86_binary_operator_ok (XOR, SImode, operands)"
10045   "xor{l}\t{%2, %k0|%k0, %2}"
10046   [(set_attr "type" "alu")
10047    (set_attr "mode" "SI")])
10049 (define_insn "*xorsi_2_zext_imm"
10050   [(set (reg FLAGS_REG)
10051         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10052                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10053                  (const_int 0)))
10054    (set (match_operand:DI 0 "register_operand" "=r")
10055         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10056   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10057    && ix86_binary_operator_ok (XOR, SImode, operands)"
10058   "xor{l}\t{%2, %k0|%k0, %2}"
10059   [(set_attr "type" "alu")
10060    (set_attr "mode" "SI")])
10062 (define_insn "*xorsi_3"
10063   [(set (reg FLAGS_REG)
10064         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10065                          (match_operand:SI 2 "general_operand" "g"))
10066                  (const_int 0)))
10067    (clobber (match_scratch:SI 0 "=r"))]
10068   "ix86_match_ccmode (insn, CCNOmode)
10069    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10070   "xor{l}\t{%2, %0|%0, %2}"
10071   [(set_attr "type" "alu")
10072    (set_attr "mode" "SI")])
10074 (define_expand "xorhi3"
10075   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10076         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10077                 (match_operand:HI 2 "general_operand" "")))]
10078   "TARGET_HIMODE_MATH"
10079   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10081 (define_insn "*xorhi_1"
10082   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10083         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10084                 (match_operand:HI 2 "general_operand" "rmn,rn")))
10085    (clobber (reg:CC FLAGS_REG))]
10086   "ix86_binary_operator_ok (XOR, HImode, operands)"
10087   "xor{w}\t{%2, %0|%0, %2}"
10088   [(set_attr "type" "alu")
10089    (set_attr "mode" "HI")])
10091 (define_insn "*xorhi_2"
10092   [(set (reg FLAGS_REG)
10093         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10094                          (match_operand:HI 2 "general_operand" "rmn,rn"))
10095                  (const_int 0)))
10096    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10097         (xor:HI (match_dup 1) (match_dup 2)))]
10098   "ix86_match_ccmode (insn, CCNOmode)
10099    && ix86_binary_operator_ok (XOR, HImode, operands)"
10100   "xor{w}\t{%2, %0|%0, %2}"
10101   [(set_attr "type" "alu")
10102    (set_attr "mode" "HI")])
10104 (define_insn "*xorhi_3"
10105   [(set (reg FLAGS_REG)
10106         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10107                          (match_operand:HI 2 "general_operand" "rmn"))
10108                  (const_int 0)))
10109    (clobber (match_scratch:HI 0 "=r"))]
10110   "ix86_match_ccmode (insn, CCNOmode)
10111    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10112   "xor{w}\t{%2, %0|%0, %2}"
10113   [(set_attr "type" "alu")
10114    (set_attr "mode" "HI")])
10116 (define_expand "xorqi3"
10117   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10118         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10119                 (match_operand:QI 2 "general_operand" "")))]
10120   "TARGET_QIMODE_MATH"
10121   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10123 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10124 (define_insn "*xorqi_1"
10125   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10126         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10127                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10128    (clobber (reg:CC FLAGS_REG))]
10129   "ix86_binary_operator_ok (XOR, QImode, operands)"
10130   "@
10131    xor{b}\t{%2, %0|%0, %2}
10132    xor{b}\t{%2, %0|%0, %2}
10133    xor{l}\t{%k2, %k0|%k0, %k2}"
10134   [(set_attr "type" "alu")
10135    (set_attr "mode" "QI,QI,SI")])
10137 (define_insn "*xorqi_1_slp"
10138   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10139         (xor:QI (match_dup 0)
10140                 (match_operand:QI 1 "general_operand" "qn,qmn")))
10141    (clobber (reg:CC FLAGS_REG))]
10142   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10143    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10144   "xor{b}\t{%1, %0|%0, %1}"
10145   [(set_attr "type" "alu1")
10146    (set_attr "mode" "QI")])
10148 (define_insn "*xorqi_ext_0"
10149   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10150                          (const_int 8)
10151                          (const_int 8))
10152         (xor:SI
10153           (zero_extract:SI
10154             (match_operand 1 "ext_register_operand" "0")
10155             (const_int 8)
10156             (const_int 8))
10157           (match_operand 2 "const_int_operand" "n")))
10158    (clobber (reg:CC FLAGS_REG))]
10159   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10160   "xor{b}\t{%2, %h0|%h0, %2}"
10161   [(set_attr "type" "alu")
10162    (set_attr "length_immediate" "1")
10163    (set_attr "mode" "QI")])
10165 (define_insn "*xorqi_ext_1"
10166   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10167                          (const_int 8)
10168                          (const_int 8))
10169         (xor:SI
10170           (zero_extract:SI
10171             (match_operand 1 "ext_register_operand" "0")
10172             (const_int 8)
10173             (const_int 8))
10174           (zero_extend:SI
10175             (match_operand:QI 2 "general_operand" "Qm"))))
10176    (clobber (reg:CC FLAGS_REG))]
10177   "!TARGET_64BIT
10178    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10179   "xor{b}\t{%2, %h0|%h0, %2}"
10180   [(set_attr "type" "alu")
10181    (set_attr "length_immediate" "0")
10182    (set_attr "mode" "QI")])
10184 (define_insn "*xorqi_ext_1_rex64"
10185   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10186                          (const_int 8)
10187                          (const_int 8))
10188         (xor:SI
10189           (zero_extract:SI
10190             (match_operand 1 "ext_register_operand" "0")
10191             (const_int 8)
10192             (const_int 8))
10193           (zero_extend:SI
10194             (match_operand 2 "ext_register_operand" "Q"))))
10195    (clobber (reg:CC FLAGS_REG))]
10196   "TARGET_64BIT
10197    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10198   "xor{b}\t{%2, %h0|%h0, %2}"
10199   [(set_attr "type" "alu")
10200    (set_attr "length_immediate" "0")
10201    (set_attr "mode" "QI")])
10203 (define_insn "*xorqi_ext_2"
10204   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10205                          (const_int 8)
10206                          (const_int 8))
10207         (xor:SI
10208           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10209                            (const_int 8)
10210                            (const_int 8))
10211           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10212                            (const_int 8)
10213                            (const_int 8))))
10214    (clobber (reg:CC FLAGS_REG))]
10215   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10216   "xor{b}\t{%h2, %h0|%h0, %h2}"
10217   [(set_attr "type" "alu")
10218    (set_attr "length_immediate" "0")
10219    (set_attr "mode" "QI")])
10221 (define_insn "*xorqi_cc_1"
10222   [(set (reg FLAGS_REG)
10223         (compare
10224           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10225                   (match_operand:QI 2 "general_operand" "qmn,qn"))
10226           (const_int 0)))
10227    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10228         (xor:QI (match_dup 1) (match_dup 2)))]
10229   "ix86_match_ccmode (insn, CCNOmode)
10230    && ix86_binary_operator_ok (XOR, QImode, operands)"
10231   "xor{b}\t{%2, %0|%0, %2}"
10232   [(set_attr "type" "alu")
10233    (set_attr "mode" "QI")])
10235 (define_insn "*xorqi_2_slp"
10236   [(set (reg FLAGS_REG)
10237         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10238                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10239                  (const_int 0)))
10240    (set (strict_low_part (match_dup 0))
10241         (xor:QI (match_dup 0) (match_dup 1)))]
10242   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10243    && ix86_match_ccmode (insn, CCNOmode)
10244    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10245   "xor{b}\t{%1, %0|%0, %1}"
10246   [(set_attr "type" "alu1")
10247    (set_attr "mode" "QI")])
10249 (define_insn "*xorqi_cc_2"
10250   [(set (reg FLAGS_REG)
10251         (compare
10252           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10253                   (match_operand:QI 2 "general_operand" "qmn"))
10254           (const_int 0)))
10255    (clobber (match_scratch:QI 0 "=q"))]
10256   "ix86_match_ccmode (insn, CCNOmode)
10257    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10258   "xor{b}\t{%2, %0|%0, %2}"
10259   [(set_attr "type" "alu")
10260    (set_attr "mode" "QI")])
10262 (define_insn "*xorqi_cc_ext_1"
10263   [(set (reg FLAGS_REG)
10264         (compare
10265           (xor:SI
10266             (zero_extract:SI
10267               (match_operand 1 "ext_register_operand" "0")
10268               (const_int 8)
10269               (const_int 8))
10270             (match_operand:QI 2 "general_operand" "qmn"))
10271           (const_int 0)))
10272    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10273                          (const_int 8)
10274                          (const_int 8))
10275         (xor:SI
10276           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10277           (match_dup 2)))]
10278   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10279   "xor{b}\t{%2, %h0|%h0, %2}"
10280   [(set_attr "type" "alu")
10281    (set_attr "mode" "QI")])
10283 (define_insn "*xorqi_cc_ext_1_rex64"
10284   [(set (reg FLAGS_REG)
10285         (compare
10286           (xor:SI
10287             (zero_extract:SI
10288               (match_operand 1 "ext_register_operand" "0")
10289               (const_int 8)
10290               (const_int 8))
10291             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10292           (const_int 0)))
10293    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10294                          (const_int 8)
10295                          (const_int 8))
10296         (xor:SI
10297           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10298           (match_dup 2)))]
10299   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10300   "xor{b}\t{%2, %h0|%h0, %2}"
10301   [(set_attr "type" "alu")
10302    (set_attr "mode" "QI")])
10304 (define_expand "xorqi_cc_ext_1"
10305   [(parallel [
10306      (set (reg:CCNO FLAGS_REG)
10307           (compare:CCNO
10308             (xor:SI
10309               (zero_extract:SI
10310                 (match_operand 1 "ext_register_operand" "")
10311                 (const_int 8)
10312                 (const_int 8))
10313               (match_operand:QI 2 "general_operand" ""))
10314             (const_int 0)))
10315      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10316                            (const_int 8)
10317                            (const_int 8))
10318           (xor:SI
10319             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10320             (match_dup 2)))])]
10321   ""
10322   "")
10324 (define_split
10325   [(set (match_operand 0 "register_operand" "")
10326         (xor (match_operand 1 "register_operand" "")
10327              (match_operand 2 "const_int_operand" "")))
10328    (clobber (reg:CC FLAGS_REG))]
10329    "reload_completed
10330     && QI_REG_P (operands[0])
10331     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10332     && !(INTVAL (operands[2]) & ~(255 << 8))
10333     && GET_MODE (operands[0]) != QImode"
10334   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10335                    (xor:SI (zero_extract:SI (match_dup 1)
10336                                             (const_int 8) (const_int 8))
10337                            (match_dup 2)))
10338               (clobber (reg:CC FLAGS_REG))])]
10339   "operands[0] = gen_lowpart (SImode, operands[0]);
10340    operands[1] = gen_lowpart (SImode, operands[1]);
10341    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10343 ;; Since XOR can be encoded with sign extended immediate, this is only
10344 ;; profitable when 7th bit is set.
10345 (define_split
10346   [(set (match_operand 0 "register_operand" "")
10347         (xor (match_operand 1 "general_operand" "")
10348              (match_operand 2 "const_int_operand" "")))
10349    (clobber (reg:CC FLAGS_REG))]
10350    "reload_completed
10351     && ANY_QI_REG_P (operands[0])
10352     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10353     && !(INTVAL (operands[2]) & ~255)
10354     && (INTVAL (operands[2]) & 128)
10355     && GET_MODE (operands[0]) != QImode"
10356   [(parallel [(set (strict_low_part (match_dup 0))
10357                    (xor:QI (match_dup 1)
10358                            (match_dup 2)))
10359               (clobber (reg:CC FLAGS_REG))])]
10360   "operands[0] = gen_lowpart (QImode, operands[0]);
10361    operands[1] = gen_lowpart (QImode, operands[1]);
10362    operands[2] = gen_lowpart (QImode, operands[2]);")
10364 ;; Negation instructions
10366 (define_expand "negti2"
10367   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10368         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10369   "TARGET_64BIT"
10370   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10372 (define_insn "*negti2_1"
10373   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10374         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10375    (clobber (reg:CC FLAGS_REG))]
10376   "TARGET_64BIT
10377    && ix86_unary_operator_ok (NEG, TImode, operands)"
10378   "#")
10380 (define_split
10381   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10382         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10383    (clobber (reg:CC FLAGS_REG))]
10384   "TARGET_64BIT && reload_completed"
10385   [(parallel
10386     [(set (reg:CCZ FLAGS_REG)
10387           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10388      (set (match_dup 0) (neg:DI (match_dup 1)))])
10389    (parallel
10390     [(set (match_dup 2)
10391           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10392                             (match_dup 3))
10393                    (const_int 0)))
10394      (clobber (reg:CC FLAGS_REG))])
10395    (parallel
10396     [(set (match_dup 2)
10397           (neg:DI (match_dup 2)))
10398      (clobber (reg:CC FLAGS_REG))])]
10399   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10401 (define_expand "negdi2"
10402   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10403         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10404   ""
10405   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10407 (define_insn "*negdi2_1"
10408   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10409         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10410    (clobber (reg:CC FLAGS_REG))]
10411   "!TARGET_64BIT
10412    && ix86_unary_operator_ok (NEG, DImode, operands)"
10413   "#")
10415 (define_split
10416   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10417         (neg:DI (match_operand:DI 1 "general_operand" "")))
10418    (clobber (reg:CC FLAGS_REG))]
10419   "!TARGET_64BIT && reload_completed"
10420   [(parallel
10421     [(set (reg:CCZ FLAGS_REG)
10422           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10423      (set (match_dup 0) (neg:SI (match_dup 1)))])
10424    (parallel
10425     [(set (match_dup 2)
10426           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10427                             (match_dup 3))
10428                    (const_int 0)))
10429      (clobber (reg:CC FLAGS_REG))])
10430    (parallel
10431     [(set (match_dup 2)
10432           (neg:SI (match_dup 2)))
10433      (clobber (reg:CC FLAGS_REG))])]
10434   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10436 (define_insn "*negdi2_1_rex64"
10437   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10438         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10439    (clobber (reg:CC FLAGS_REG))]
10440   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10441   "neg{q}\t%0"
10442   [(set_attr "type" "negnot")
10443    (set_attr "mode" "DI")])
10445 ;; The problem with neg is that it does not perform (compare x 0),
10446 ;; it really performs (compare 0 x), which leaves us with the zero
10447 ;; flag being the only useful item.
10449 (define_insn "*negdi2_cmpz_rex64"
10450   [(set (reg:CCZ FLAGS_REG)
10451         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10452                      (const_int 0)))
10453    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10454         (neg:DI (match_dup 1)))]
10455   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10456   "neg{q}\t%0"
10457   [(set_attr "type" "negnot")
10458    (set_attr "mode" "DI")])
10461 (define_expand "negsi2"
10462   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10463         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10464   ""
10465   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10467 (define_insn "*negsi2_1"
10468   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10469         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10470    (clobber (reg:CC FLAGS_REG))]
10471   "ix86_unary_operator_ok (NEG, SImode, operands)"
10472   "neg{l}\t%0"
10473   [(set_attr "type" "negnot")
10474    (set_attr "mode" "SI")])
10476 ;; Combine is quite creative about this pattern.
10477 (define_insn "*negsi2_1_zext"
10478   [(set (match_operand:DI 0 "register_operand" "=r")
10479         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10480                                         (const_int 32)))
10481                      (const_int 32)))
10482    (clobber (reg:CC FLAGS_REG))]
10483   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10484   "neg{l}\t%k0"
10485   [(set_attr "type" "negnot")
10486    (set_attr "mode" "SI")])
10488 ;; The problem with neg is that it does not perform (compare x 0),
10489 ;; it really performs (compare 0 x), which leaves us with the zero
10490 ;; flag being the only useful item.
10492 (define_insn "*negsi2_cmpz"
10493   [(set (reg:CCZ FLAGS_REG)
10494         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10495                      (const_int 0)))
10496    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10497         (neg:SI (match_dup 1)))]
10498   "ix86_unary_operator_ok (NEG, SImode, operands)"
10499   "neg{l}\t%0"
10500   [(set_attr "type" "negnot")
10501    (set_attr "mode" "SI")])
10503 (define_insn "*negsi2_cmpz_zext"
10504   [(set (reg:CCZ FLAGS_REG)
10505         (compare:CCZ (lshiftrt:DI
10506                        (neg:DI (ashift:DI
10507                                  (match_operand:DI 1 "register_operand" "0")
10508                                  (const_int 32)))
10509                        (const_int 32))
10510                      (const_int 0)))
10511    (set (match_operand:DI 0 "register_operand" "=r")
10512         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10513                                         (const_int 32)))
10514                      (const_int 32)))]
10515   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10516   "neg{l}\t%k0"
10517   [(set_attr "type" "negnot")
10518    (set_attr "mode" "SI")])
10520 (define_expand "neghi2"
10521   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10522         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10523   "TARGET_HIMODE_MATH"
10524   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10526 (define_insn "*neghi2_1"
10527   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10528         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10529    (clobber (reg:CC FLAGS_REG))]
10530   "ix86_unary_operator_ok (NEG, HImode, operands)"
10531   "neg{w}\t%0"
10532   [(set_attr "type" "negnot")
10533    (set_attr "mode" "HI")])
10535 (define_insn "*neghi2_cmpz"
10536   [(set (reg:CCZ FLAGS_REG)
10537         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10538                      (const_int 0)))
10539    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10540         (neg:HI (match_dup 1)))]
10541   "ix86_unary_operator_ok (NEG, HImode, operands)"
10542   "neg{w}\t%0"
10543   [(set_attr "type" "negnot")
10544    (set_attr "mode" "HI")])
10546 (define_expand "negqi2"
10547   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10548         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10549   "TARGET_QIMODE_MATH"
10550   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10552 (define_insn "*negqi2_1"
10553   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10554         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10555    (clobber (reg:CC FLAGS_REG))]
10556   "ix86_unary_operator_ok (NEG, QImode, operands)"
10557   "neg{b}\t%0"
10558   [(set_attr "type" "negnot")
10559    (set_attr "mode" "QI")])
10561 (define_insn "*negqi2_cmpz"
10562   [(set (reg:CCZ FLAGS_REG)
10563         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10564                      (const_int 0)))
10565    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10566         (neg:QI (match_dup 1)))]
10567   "ix86_unary_operator_ok (NEG, QImode, operands)"
10568   "neg{b}\t%0"
10569   [(set_attr "type" "negnot")
10570    (set_attr "mode" "QI")])
10572 ;; Changing of sign for FP values is doable using integer unit too.
10574 (define_expand "<code><mode>2"
10575   [(set (match_operand:X87MODEF 0 "register_operand" "")
10576         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10577   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10578   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10580 (define_insn "*absneg<mode>2_mixed"
10581   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10582         (match_operator:MODEF 3 "absneg_operator"
10583           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10584    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10585    (clobber (reg:CC FLAGS_REG))]
10586   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10587   "#")
10589 (define_insn "*absneg<mode>2_sse"
10590   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10591         (match_operator:MODEF 3 "absneg_operator"
10592           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10593    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10594    (clobber (reg:CC FLAGS_REG))]
10595   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10596   "#")
10598 (define_insn "*absneg<mode>2_i387"
10599   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10600         (match_operator:X87MODEF 3 "absneg_operator"
10601           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10602    (use (match_operand 2 "" ""))
10603    (clobber (reg:CC FLAGS_REG))]
10604   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10605   "#")
10607 (define_expand "<code>tf2"
10608   [(set (match_operand:TF 0 "register_operand" "")
10609         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10610   "TARGET_SSE2"
10611   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10613 (define_insn "*absnegtf2_sse"
10614   [(set (match_operand:TF 0 "register_operand" "=x,x")
10615         (match_operator:TF 3 "absneg_operator"
10616           [(match_operand:TF 1 "register_operand" "0,x")]))
10617    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10618    (clobber (reg:CC FLAGS_REG))]
10619   "TARGET_SSE2"
10620   "#")
10622 ;; Splitters for fp abs and neg.
10624 (define_split
10625   [(set (match_operand 0 "fp_register_operand" "")
10626         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10627    (use (match_operand 2 "" ""))
10628    (clobber (reg:CC FLAGS_REG))]
10629   "reload_completed"
10630   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10632 (define_split
10633   [(set (match_operand 0 "register_operand" "")
10634         (match_operator 3 "absneg_operator"
10635           [(match_operand 1 "register_operand" "")]))
10636    (use (match_operand 2 "nonimmediate_operand" ""))
10637    (clobber (reg:CC FLAGS_REG))]
10638   "reload_completed && SSE_REG_P (operands[0])"
10639   [(set (match_dup 0) (match_dup 3))]
10641   enum machine_mode mode = GET_MODE (operands[0]);
10642   enum machine_mode vmode = GET_MODE (operands[2]);
10643   rtx tmp;
10645   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10646   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10647   if (operands_match_p (operands[0], operands[2]))
10648     {
10649       tmp = operands[1];
10650       operands[1] = operands[2];
10651       operands[2] = tmp;
10652     }
10653   if (GET_CODE (operands[3]) == ABS)
10654     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10655   else
10656     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10657   operands[3] = tmp;
10660 (define_split
10661   [(set (match_operand:SF 0 "register_operand" "")
10662         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10663    (use (match_operand:V4SF 2 "" ""))
10664    (clobber (reg:CC FLAGS_REG))]
10665   "reload_completed"
10666   [(parallel [(set (match_dup 0) (match_dup 1))
10667               (clobber (reg:CC FLAGS_REG))])]
10669   rtx tmp;
10670   operands[0] = gen_lowpart (SImode, operands[0]);
10671   if (GET_CODE (operands[1]) == ABS)
10672     {
10673       tmp = gen_int_mode (0x7fffffff, SImode);
10674       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10675     }
10676   else
10677     {
10678       tmp = gen_int_mode (0x80000000, SImode);
10679       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10680     }
10681   operands[1] = tmp;
10684 (define_split
10685   [(set (match_operand:DF 0 "register_operand" "")
10686         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10687    (use (match_operand 2 "" ""))
10688    (clobber (reg:CC FLAGS_REG))]
10689   "reload_completed"
10690   [(parallel [(set (match_dup 0) (match_dup 1))
10691               (clobber (reg:CC FLAGS_REG))])]
10693   rtx tmp;
10694   if (TARGET_64BIT)
10695     {
10696       tmp = gen_lowpart (DImode, operands[0]);
10697       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10698       operands[0] = tmp;
10700       if (GET_CODE (operands[1]) == ABS)
10701         tmp = const0_rtx;
10702       else
10703         tmp = gen_rtx_NOT (DImode, tmp);
10704     }
10705   else
10706     {
10707       operands[0] = gen_highpart (SImode, operands[0]);
10708       if (GET_CODE (operands[1]) == ABS)
10709         {
10710           tmp = gen_int_mode (0x7fffffff, SImode);
10711           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10712         }
10713       else
10714         {
10715           tmp = gen_int_mode (0x80000000, SImode);
10716           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10717         }
10718     }
10719   operands[1] = tmp;
10722 (define_split
10723   [(set (match_operand:XF 0 "register_operand" "")
10724         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10725    (use (match_operand 2 "" ""))
10726    (clobber (reg:CC FLAGS_REG))]
10727   "reload_completed"
10728   [(parallel [(set (match_dup 0) (match_dup 1))
10729               (clobber (reg:CC FLAGS_REG))])]
10731   rtx tmp;
10732   operands[0] = gen_rtx_REG (SImode,
10733                              true_regnum (operands[0])
10734                              + (TARGET_64BIT ? 1 : 2));
10735   if (GET_CODE (operands[1]) == ABS)
10736     {
10737       tmp = GEN_INT (0x7fff);
10738       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10739     }
10740   else
10741     {
10742       tmp = GEN_INT (0x8000);
10743       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10744     }
10745   operands[1] = tmp;
10748 ;; Conditionalize these after reload. If they match before reload, we
10749 ;; lose the clobber and ability to use integer instructions.
10751 (define_insn "*<code><mode>2_1"
10752   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10753         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10754   "TARGET_80387
10755    && (reload_completed
10756        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10757   "f<absnegprefix>"
10758   [(set_attr "type" "fsgn")
10759    (set_attr "mode" "<MODE>")])
10761 (define_insn "*<code>extendsfdf2"
10762   [(set (match_operand:DF 0 "register_operand" "=f")
10763         (absneg:DF (float_extend:DF
10764                      (match_operand:SF 1 "register_operand" "0"))))]
10765   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10766   "f<absnegprefix>"
10767   [(set_attr "type" "fsgn")
10768    (set_attr "mode" "DF")])
10770 (define_insn "*<code>extendsfxf2"
10771   [(set (match_operand:XF 0 "register_operand" "=f")
10772         (absneg:XF (float_extend:XF
10773                      (match_operand:SF 1 "register_operand" "0"))))]
10774   "TARGET_80387"
10775   "f<absnegprefix>"
10776   [(set_attr "type" "fsgn")
10777    (set_attr "mode" "XF")])
10779 (define_insn "*<code>extenddfxf2"
10780   [(set (match_operand:XF 0 "register_operand" "=f")
10781         (absneg:XF (float_extend:XF
10782                       (match_operand:DF 1 "register_operand" "0"))))]
10783   "TARGET_80387"
10784   "f<absnegprefix>"
10785   [(set_attr "type" "fsgn")
10786    (set_attr "mode" "XF")])
10788 ;; Copysign instructions
10790 (define_mode_iterator CSGNMODE [SF DF TF])
10791 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10793 (define_expand "copysign<mode>3"
10794   [(match_operand:CSGNMODE 0 "register_operand" "")
10795    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10796    (match_operand:CSGNMODE 2 "register_operand" "")]
10797   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10798    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10800   ix86_expand_copysign (operands);
10801   DONE;
10804 (define_insn_and_split "copysign<mode>3_const"
10805   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10806         (unspec:CSGNMODE
10807           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10808            (match_operand:CSGNMODE 2 "register_operand" "0")
10809            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10810           UNSPEC_COPYSIGN))]
10811   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10812    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10813   "#"
10814   "&& reload_completed"
10815   [(const_int 0)]
10817   ix86_split_copysign_const (operands);
10818   DONE;
10821 (define_insn "copysign<mode>3_var"
10822   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10823         (unspec:CSGNMODE
10824           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10825            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10826            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10827            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10828           UNSPEC_COPYSIGN))
10829    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10830   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10831    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10832   "#")
10834 (define_split
10835   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10836         (unspec:CSGNMODE
10837           [(match_operand:CSGNMODE 2 "register_operand" "")
10838            (match_operand:CSGNMODE 3 "register_operand" "")
10839            (match_operand:<CSGNVMODE> 4 "" "")
10840            (match_operand:<CSGNVMODE> 5 "" "")]
10841           UNSPEC_COPYSIGN))
10842    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10843   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10844     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10845    && reload_completed"
10846   [(const_int 0)]
10848   ix86_split_copysign_var (operands);
10849   DONE;
10852 ;; One complement instructions
10854 (define_expand "one_cmpldi2"
10855   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10856         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10857   "TARGET_64BIT"
10858   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10860 (define_insn "*one_cmpldi2_1_rex64"
10861   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10862         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10863   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10864   "not{q}\t%0"
10865   [(set_attr "type" "negnot")
10866    (set_attr "mode" "DI")])
10868 (define_insn "*one_cmpldi2_2_rex64"
10869   [(set (reg FLAGS_REG)
10870         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10871                  (const_int 0)))
10872    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10873         (not:DI (match_dup 1)))]
10874   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10875    && ix86_unary_operator_ok (NOT, DImode, operands)"
10876   "#"
10877   [(set_attr "type" "alu1")
10878    (set_attr "mode" "DI")])
10880 (define_split
10881   [(set (match_operand 0 "flags_reg_operand" "")
10882         (match_operator 2 "compare_operator"
10883           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10884            (const_int 0)]))
10885    (set (match_operand:DI 1 "nonimmediate_operand" "")
10886         (not:DI (match_dup 3)))]
10887   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10888   [(parallel [(set (match_dup 0)
10889                    (match_op_dup 2
10890                      [(xor:DI (match_dup 3) (const_int -1))
10891                       (const_int 0)]))
10892               (set (match_dup 1)
10893                    (xor:DI (match_dup 3) (const_int -1)))])]
10894   "")
10896 (define_expand "one_cmplsi2"
10897   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10898         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10899   ""
10900   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10902 (define_insn "*one_cmplsi2_1"
10903   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10904         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10905   "ix86_unary_operator_ok (NOT, SImode, operands)"
10906   "not{l}\t%0"
10907   [(set_attr "type" "negnot")
10908    (set_attr "mode" "SI")])
10910 ;; ??? Currently never generated - xor is used instead.
10911 (define_insn "*one_cmplsi2_1_zext"
10912   [(set (match_operand:DI 0 "register_operand" "=r")
10913         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10914   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10915   "not{l}\t%k0"
10916   [(set_attr "type" "negnot")
10917    (set_attr "mode" "SI")])
10919 (define_insn "*one_cmplsi2_2"
10920   [(set (reg FLAGS_REG)
10921         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10922                  (const_int 0)))
10923    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10924         (not:SI (match_dup 1)))]
10925   "ix86_match_ccmode (insn, CCNOmode)
10926    && ix86_unary_operator_ok (NOT, SImode, operands)"
10927   "#"
10928   [(set_attr "type" "alu1")
10929    (set_attr "mode" "SI")])
10931 (define_split
10932   [(set (match_operand 0 "flags_reg_operand" "")
10933         (match_operator 2 "compare_operator"
10934           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10935            (const_int 0)]))
10936    (set (match_operand:SI 1 "nonimmediate_operand" "")
10937         (not:SI (match_dup 3)))]
10938   "ix86_match_ccmode (insn, CCNOmode)"
10939   [(parallel [(set (match_dup 0)
10940                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10941                                     (const_int 0)]))
10942               (set (match_dup 1)
10943                    (xor:SI (match_dup 3) (const_int -1)))])]
10944   "")
10946 ;; ??? Currently never generated - xor is used instead.
10947 (define_insn "*one_cmplsi2_2_zext"
10948   [(set (reg FLAGS_REG)
10949         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10950                  (const_int 0)))
10951    (set (match_operand:DI 0 "register_operand" "=r")
10952         (zero_extend:DI (not:SI (match_dup 1))))]
10953   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10954    && ix86_unary_operator_ok (NOT, SImode, operands)"
10955   "#"
10956   [(set_attr "type" "alu1")
10957    (set_attr "mode" "SI")])
10959 (define_split
10960   [(set (match_operand 0 "flags_reg_operand" "")
10961         (match_operator 2 "compare_operator"
10962           [(not:SI (match_operand:SI 3 "register_operand" ""))
10963            (const_int 0)]))
10964    (set (match_operand:DI 1 "register_operand" "")
10965         (zero_extend:DI (not:SI (match_dup 3))))]
10966   "ix86_match_ccmode (insn, CCNOmode)"
10967   [(parallel [(set (match_dup 0)
10968                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10969                                     (const_int 0)]))
10970               (set (match_dup 1)
10971                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10972   "")
10974 (define_expand "one_cmplhi2"
10975   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10976         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10977   "TARGET_HIMODE_MATH"
10978   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10980 (define_insn "*one_cmplhi2_1"
10981   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10982         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10983   "ix86_unary_operator_ok (NOT, HImode, operands)"
10984   "not{w}\t%0"
10985   [(set_attr "type" "negnot")
10986    (set_attr "mode" "HI")])
10988 (define_insn "*one_cmplhi2_2"
10989   [(set (reg FLAGS_REG)
10990         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10991                  (const_int 0)))
10992    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10993         (not:HI (match_dup 1)))]
10994   "ix86_match_ccmode (insn, CCNOmode)
10995    && ix86_unary_operator_ok (NEG, HImode, operands)"
10996   "#"
10997   [(set_attr "type" "alu1")
10998    (set_attr "mode" "HI")])
11000 (define_split
11001   [(set (match_operand 0 "flags_reg_operand" "")
11002         (match_operator 2 "compare_operator"
11003           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11004            (const_int 0)]))
11005    (set (match_operand:HI 1 "nonimmediate_operand" "")
11006         (not:HI (match_dup 3)))]
11007   "ix86_match_ccmode (insn, CCNOmode)"
11008   [(parallel [(set (match_dup 0)
11009                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11010                                     (const_int 0)]))
11011               (set (match_dup 1)
11012                    (xor:HI (match_dup 3) (const_int -1)))])]
11013   "")
11015 ;; %%% Potential partial reg stall on alternative 1.  What to do?
11016 (define_expand "one_cmplqi2"
11017   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11018         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11019   "TARGET_QIMODE_MATH"
11020   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11022 (define_insn "*one_cmplqi2_1"
11023   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11024         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11025   "ix86_unary_operator_ok (NOT, QImode, operands)"
11026   "@
11027    not{b}\t%0
11028    not{l}\t%k0"
11029   [(set_attr "type" "negnot")
11030    (set_attr "mode" "QI,SI")])
11032 (define_insn "*one_cmplqi2_2"
11033   [(set (reg FLAGS_REG)
11034         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11035                  (const_int 0)))
11036    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11037         (not:QI (match_dup 1)))]
11038   "ix86_match_ccmode (insn, CCNOmode)
11039    && ix86_unary_operator_ok (NOT, QImode, operands)"
11040   "#"
11041   [(set_attr "type" "alu1")
11042    (set_attr "mode" "QI")])
11044 (define_split
11045   [(set (match_operand 0 "flags_reg_operand" "")
11046         (match_operator 2 "compare_operator"
11047           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11048            (const_int 0)]))
11049    (set (match_operand:QI 1 "nonimmediate_operand" "")
11050         (not:QI (match_dup 3)))]
11051   "ix86_match_ccmode (insn, CCNOmode)"
11052   [(parallel [(set (match_dup 0)
11053                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11054                                     (const_int 0)]))
11055               (set (match_dup 1)
11056                    (xor:QI (match_dup 3) (const_int -1)))])]
11057   "")
11059 ;; Arithmetic shift instructions
11061 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11062 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
11063 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11064 ;; from the assembler input.
11066 ;; This instruction shifts the target reg/mem as usual, but instead of
11067 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
11068 ;; is a left shift double, bits are taken from the high order bits of
11069 ;; reg, else if the insn is a shift right double, bits are taken from the
11070 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
11071 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11073 ;; Since sh[lr]d does not change the `reg' operand, that is done
11074 ;; separately, making all shifts emit pairs of shift double and normal
11075 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
11076 ;; support a 63 bit shift, each shift where the count is in a reg expands
11077 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11079 ;; If the shift count is a constant, we need never emit more than one
11080 ;; shift pair, instead using moves and sign extension for counts greater
11081 ;; than 31.
11083 (define_expand "ashlti3"
11084   [(set (match_operand:TI 0 "register_operand" "")
11085         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11086                    (match_operand:QI 2 "nonmemory_operand" "")))]
11087   "TARGET_64BIT"
11088   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11090 ;; This pattern must be defined before *ashlti3_1 to prevent
11091 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11093 (define_insn "*avx_ashlti3"
11094   [(set (match_operand:TI 0 "register_operand" "=x")
11095         (ashift:TI (match_operand:TI 1 "register_operand" "x")
11096                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11097   "TARGET_AVX"
11099   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11100   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11102   [(set_attr "type" "sseishft")
11103    (set_attr "prefix" "vex")
11104    (set_attr "mode" "TI")])
11106 (define_insn "sse2_ashlti3"
11107   [(set (match_operand:TI 0 "register_operand" "=x")
11108         (ashift:TI (match_operand:TI 1 "register_operand" "0")
11109                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11110   "TARGET_SSE2"
11112   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11113   return "pslldq\t{%2, %0|%0, %2}";
11115   [(set_attr "type" "sseishft")
11116    (set_attr "prefix_data16" "1")
11117    (set_attr "mode" "TI")])
11119 (define_insn "*ashlti3_1"
11120   [(set (match_operand:TI 0 "register_operand" "=&r,r")
11121         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11122                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11123    (clobber (reg:CC FLAGS_REG))]
11124   "TARGET_64BIT"
11125   "#"
11126   [(set_attr "type" "multi")])
11128 (define_peephole2
11129   [(match_scratch:DI 3 "r")
11130    (parallel [(set (match_operand:TI 0 "register_operand" "")
11131                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11132                               (match_operand:QI 2 "nonmemory_operand" "")))
11133               (clobber (reg:CC FLAGS_REG))])
11134    (match_dup 3)]
11135   "TARGET_64BIT"
11136   [(const_int 0)]
11137   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11139 (define_split
11140   [(set (match_operand:TI 0 "register_operand" "")
11141         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11142                    (match_operand:QI 2 "nonmemory_operand" "")))
11143    (clobber (reg:CC FLAGS_REG))]
11144   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11145                     ? epilogue_completed : reload_completed)"
11146   [(const_int 0)]
11147   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11149 (define_insn "x86_64_shld"
11150   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11151         (ior:DI (ashift:DI (match_dup 0)
11152                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11153                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11154                   (minus:QI (const_int 64) (match_dup 2)))))
11155    (clobber (reg:CC FLAGS_REG))]
11156   "TARGET_64BIT"
11157   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11158   [(set_attr "type" "ishift")
11159    (set_attr "prefix_0f" "1")
11160    (set_attr "mode" "DI")
11161    (set_attr "athlon_decode" "vector")
11162    (set_attr "amdfam10_decode" "vector")])
11164 (define_expand "x86_64_shift_adj_1"
11165   [(set (reg:CCZ FLAGS_REG)
11166         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11167                              (const_int 64))
11168                      (const_int 0)))
11169    (set (match_operand:DI 0 "register_operand" "")
11170         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11171                          (match_operand:DI 1 "register_operand" "")
11172                          (match_dup 0)))
11173    (set (match_dup 1)
11174         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11175                          (match_operand:DI 3 "register_operand" "r")
11176                          (match_dup 1)))]
11177   "TARGET_64BIT"
11178   "")
11180 (define_expand "x86_64_shift_adj_2"
11181   [(use (match_operand:DI 0 "register_operand" ""))
11182    (use (match_operand:DI 1 "register_operand" ""))
11183    (use (match_operand:QI 2 "register_operand" ""))]
11184   "TARGET_64BIT"
11186   rtx label = gen_label_rtx ();
11187   rtx tmp;
11189   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11191   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11192   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11193   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11194                               gen_rtx_LABEL_REF (VOIDmode, label),
11195                               pc_rtx);
11196   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11197   JUMP_LABEL (tmp) = label;
11199   emit_move_insn (operands[0], operands[1]);
11200   ix86_expand_clear (operands[1]);
11202   emit_label (label);
11203   LABEL_NUSES (label) = 1;
11205   DONE;
11208 (define_expand "ashldi3"
11209   [(set (match_operand:DI 0 "shiftdi_operand" "")
11210         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11211                    (match_operand:QI 2 "nonmemory_operand" "")))]
11212   ""
11213   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11215 (define_insn "*ashldi3_1_rex64"
11216   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11217         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11218                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11219    (clobber (reg:CC FLAGS_REG))]
11220   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11222   switch (get_attr_type (insn))
11223     {
11224     case TYPE_ALU:
11225       gcc_assert (operands[2] == const1_rtx);
11226       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11227       return "add{q}\t%0, %0";
11229     case TYPE_LEA:
11230       gcc_assert (CONST_INT_P (operands[2]));
11231       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11232       operands[1] = gen_rtx_MULT (DImode, operands[1],
11233                                   GEN_INT (1 << INTVAL (operands[2])));
11234       return "lea{q}\t{%a1, %0|%0, %a1}";
11236     default:
11237       if (REG_P (operands[2]))
11238         return "sal{q}\t{%b2, %0|%0, %b2}";
11239       else if (operands[2] == const1_rtx
11240                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11241         return "sal{q}\t%0";
11242       else
11243         return "sal{q}\t{%2, %0|%0, %2}";
11244     }
11246   [(set (attr "type")
11247      (cond [(eq_attr "alternative" "1")
11248               (const_string "lea")
11249             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11250                           (const_int 0))
11251                       (match_operand 0 "register_operand" ""))
11252                  (match_operand 2 "const1_operand" ""))
11253               (const_string "alu")
11254            ]
11255            (const_string "ishift")))
11256    (set_attr "mode" "DI")])
11258 ;; Convert lea to the lea pattern to avoid flags dependency.
11259 (define_split
11260   [(set (match_operand:DI 0 "register_operand" "")
11261         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11262                    (match_operand:QI 2 "immediate_operand" "")))
11263    (clobber (reg:CC FLAGS_REG))]
11264   "TARGET_64BIT && reload_completed
11265    && true_regnum (operands[0]) != true_regnum (operands[1])"
11266   [(set (match_dup 0)
11267         (mult:DI (match_dup 1)
11268                  (match_dup 2)))]
11269   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11271 ;; This pattern can't accept a variable shift count, since shifts by
11272 ;; zero don't affect the flags.  We assume that shifts by constant
11273 ;; zero are optimized away.
11274 (define_insn "*ashldi3_cmp_rex64"
11275   [(set (reg FLAGS_REG)
11276         (compare
11277           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11278                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11279           (const_int 0)))
11280    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11281         (ashift:DI (match_dup 1) (match_dup 2)))]
11282   "TARGET_64BIT
11283    && (optimize_function_for_size_p (cfun)
11284        || !TARGET_PARTIAL_FLAG_REG_STALL
11285        || (operands[2] == const1_rtx
11286            && (TARGET_SHIFT1
11287                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11288    && ix86_match_ccmode (insn, CCGOCmode)
11289    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11291   switch (get_attr_type (insn))
11292     {
11293     case TYPE_ALU:
11294       gcc_assert (operands[2] == const1_rtx);
11295       return "add{q}\t%0, %0";
11297     default:
11298       if (REG_P (operands[2]))
11299         return "sal{q}\t{%b2, %0|%0, %b2}";
11300       else if (operands[2] == const1_rtx
11301                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11302         return "sal{q}\t%0";
11303       else
11304         return "sal{q}\t{%2, %0|%0, %2}";
11305     }
11307   [(set (attr "type")
11308      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11309                           (const_int 0))
11310                       (match_operand 0 "register_operand" ""))
11311                  (match_operand 2 "const1_operand" ""))
11312               (const_string "alu")
11313            ]
11314            (const_string "ishift")))
11315    (set_attr "mode" "DI")])
11317 (define_insn "*ashldi3_cconly_rex64"
11318   [(set (reg FLAGS_REG)
11319         (compare
11320           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11321                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11322           (const_int 0)))
11323    (clobber (match_scratch:DI 0 "=r"))]
11324   "TARGET_64BIT
11325    && (optimize_function_for_size_p (cfun)
11326        || !TARGET_PARTIAL_FLAG_REG_STALL
11327        || (operands[2] == const1_rtx
11328            && (TARGET_SHIFT1
11329                || TARGET_DOUBLE_WITH_ADD)))
11330    && ix86_match_ccmode (insn, CCGOCmode)
11331    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11333   switch (get_attr_type (insn))
11334     {
11335     case TYPE_ALU:
11336       gcc_assert (operands[2] == const1_rtx);
11337       return "add{q}\t%0, %0";
11339     default:
11340       if (REG_P (operands[2]))
11341         return "sal{q}\t{%b2, %0|%0, %b2}";
11342       else if (operands[2] == const1_rtx
11343                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11344         return "sal{q}\t%0";
11345       else
11346         return "sal{q}\t{%2, %0|%0, %2}";
11347     }
11349   [(set (attr "type")
11350      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11351                           (const_int 0))
11352                       (match_operand 0 "register_operand" ""))
11353                  (match_operand 2 "const1_operand" ""))
11354               (const_string "alu")
11355            ]
11356            (const_string "ishift")))
11357    (set_attr "mode" "DI")])
11359 (define_insn "*ashldi3_1"
11360   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11361         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11362                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11363    (clobber (reg:CC FLAGS_REG))]
11364   "!TARGET_64BIT"
11365   "#"
11366   [(set_attr "type" "multi")])
11368 ;; By default we don't ask for a scratch register, because when DImode
11369 ;; values are manipulated, registers are already at a premium.  But if
11370 ;; we have one handy, we won't turn it away.
11371 (define_peephole2
11372   [(match_scratch:SI 3 "r")
11373    (parallel [(set (match_operand:DI 0 "register_operand" "")
11374                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11375                               (match_operand:QI 2 "nonmemory_operand" "")))
11376               (clobber (reg:CC FLAGS_REG))])
11377    (match_dup 3)]
11378   "!TARGET_64BIT && TARGET_CMOVE"
11379   [(const_int 0)]
11380   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11382 (define_split
11383   [(set (match_operand:DI 0 "register_operand" "")
11384         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11385                    (match_operand:QI 2 "nonmemory_operand" "")))
11386    (clobber (reg:CC FLAGS_REG))]
11387   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11388                      ? epilogue_completed : reload_completed)"
11389   [(const_int 0)]
11390   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11392 (define_insn "x86_shld"
11393   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11394         (ior:SI (ashift:SI (match_dup 0)
11395                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11396                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11397                   (minus:QI (const_int 32) (match_dup 2)))))
11398    (clobber (reg:CC FLAGS_REG))]
11399   ""
11400   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11401   [(set_attr "type" "ishift")
11402    (set_attr "prefix_0f" "1")
11403    (set_attr "mode" "SI")
11404    (set_attr "pent_pair" "np")
11405    (set_attr "athlon_decode" "vector")
11406    (set_attr "amdfam10_decode" "vector")])
11408 (define_expand "x86_shift_adj_1"
11409   [(set (reg:CCZ FLAGS_REG)
11410         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11411                              (const_int 32))
11412                      (const_int 0)))
11413    (set (match_operand:SI 0 "register_operand" "")
11414         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11415                          (match_operand:SI 1 "register_operand" "")
11416                          (match_dup 0)))
11417    (set (match_dup 1)
11418         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11419                          (match_operand:SI 3 "register_operand" "r")
11420                          (match_dup 1)))]
11421   "TARGET_CMOVE"
11422   "")
11424 (define_expand "x86_shift_adj_2"
11425   [(use (match_operand:SI 0 "register_operand" ""))
11426    (use (match_operand:SI 1 "register_operand" ""))
11427    (use (match_operand:QI 2 "register_operand" ""))]
11428   ""
11430   rtx label = gen_label_rtx ();
11431   rtx tmp;
11433   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11435   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11436   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11437   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11438                               gen_rtx_LABEL_REF (VOIDmode, label),
11439                               pc_rtx);
11440   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11441   JUMP_LABEL (tmp) = label;
11443   emit_move_insn (operands[0], operands[1]);
11444   ix86_expand_clear (operands[1]);
11446   emit_label (label);
11447   LABEL_NUSES (label) = 1;
11449   DONE;
11452 (define_expand "ashlsi3"
11453   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11454         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11455                    (match_operand:QI 2 "nonmemory_operand" "")))]
11456   ""
11457   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11459 (define_insn "*ashlsi3_1"
11460   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11461         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11462                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11463    (clobber (reg:CC FLAGS_REG))]
11464   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11466   switch (get_attr_type (insn))
11467     {
11468     case TYPE_ALU:
11469       gcc_assert (operands[2] == const1_rtx);
11470       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11471       return "add{l}\t%0, %0";
11473     case TYPE_LEA:
11474       return "#";
11476     default:
11477       if (REG_P (operands[2]))
11478         return "sal{l}\t{%b2, %0|%0, %b2}";
11479       else if (operands[2] == const1_rtx
11480                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11481         return "sal{l}\t%0";
11482       else
11483         return "sal{l}\t{%2, %0|%0, %2}";
11484     }
11486   [(set (attr "type")
11487      (cond [(eq_attr "alternative" "1")
11488               (const_string "lea")
11489             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11490                           (const_int 0))
11491                       (match_operand 0 "register_operand" ""))
11492                  (match_operand 2 "const1_operand" ""))
11493               (const_string "alu")
11494            ]
11495            (const_string "ishift")))
11496    (set_attr "mode" "SI")])
11498 ;; Convert lea to the lea pattern to avoid flags dependency.
11499 (define_split
11500   [(set (match_operand 0 "register_operand" "")
11501         (ashift (match_operand 1 "index_register_operand" "")
11502                 (match_operand:QI 2 "const_int_operand" "")))
11503    (clobber (reg:CC FLAGS_REG))]
11504   "reload_completed
11505    && true_regnum (operands[0]) != true_regnum (operands[1])
11506    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11507   [(const_int 0)]
11509   rtx pat;
11510   enum machine_mode mode = GET_MODE (operands[0]);
11512   if (GET_MODE_SIZE (mode) < 4)
11513     operands[0] = gen_lowpart (SImode, operands[0]);
11514   if (mode != Pmode)
11515     operands[1] = gen_lowpart (Pmode, operands[1]);
11516   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11518   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11519   if (Pmode != SImode)
11520     pat = gen_rtx_SUBREG (SImode, pat, 0);
11521   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11522   DONE;
11525 ;; Rare case of shifting RSP is handled by generating move and shift
11526 (define_split
11527   [(set (match_operand 0 "register_operand" "")
11528         (ashift (match_operand 1 "register_operand" "")
11529                 (match_operand:QI 2 "const_int_operand" "")))
11530    (clobber (reg:CC FLAGS_REG))]
11531   "reload_completed
11532    && true_regnum (operands[0]) != true_regnum (operands[1])"
11533   [(const_int 0)]
11535   rtx pat, clob;
11536   emit_move_insn (operands[0], operands[1]);
11537   pat = gen_rtx_SET (VOIDmode, operands[0],
11538                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11539                                      operands[0], operands[2]));
11540   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11541   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11542   DONE;
11545 (define_insn "*ashlsi3_1_zext"
11546   [(set (match_operand:DI 0 "register_operand" "=r,r")
11547         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11548                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11549    (clobber (reg:CC FLAGS_REG))]
11550   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11552   switch (get_attr_type (insn))
11553     {
11554     case TYPE_ALU:
11555       gcc_assert (operands[2] == const1_rtx);
11556       return "add{l}\t%k0, %k0";
11558     case TYPE_LEA:
11559       return "#";
11561     default:
11562       if (REG_P (operands[2]))
11563         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11564       else if (operands[2] == const1_rtx
11565                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11566         return "sal{l}\t%k0";
11567       else
11568         return "sal{l}\t{%2, %k0|%k0, %2}";
11569     }
11571   [(set (attr "type")
11572      (cond [(eq_attr "alternative" "1")
11573               (const_string "lea")
11574             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11575                      (const_int 0))
11576                  (match_operand 2 "const1_operand" ""))
11577               (const_string "alu")
11578            ]
11579            (const_string "ishift")))
11580    (set_attr "mode" "SI")])
11582 ;; Convert lea to the lea pattern to avoid flags dependency.
11583 (define_split
11584   [(set (match_operand:DI 0 "register_operand" "")
11585         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11586                                 (match_operand:QI 2 "const_int_operand" ""))))
11587    (clobber (reg:CC FLAGS_REG))]
11588   "TARGET_64BIT && reload_completed
11589    && true_regnum (operands[0]) != true_regnum (operands[1])"
11590   [(set (match_dup 0) (zero_extend:DI
11591                         (subreg:SI (mult:SI (match_dup 1)
11592                                             (match_dup 2)) 0)))]
11594   operands[1] = gen_lowpart (Pmode, operands[1]);
11595   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11598 ;; This pattern can't accept a variable shift count, since shifts by
11599 ;; zero don't affect the flags.  We assume that shifts by constant
11600 ;; zero are optimized away.
11601 (define_insn "*ashlsi3_cmp"
11602   [(set (reg FLAGS_REG)
11603         (compare
11604           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11605                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11606           (const_int 0)))
11607    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11608         (ashift:SI (match_dup 1) (match_dup 2)))]
11609    "(optimize_function_for_size_p (cfun)
11610      || !TARGET_PARTIAL_FLAG_REG_STALL
11611      || (operands[2] == const1_rtx
11612          && (TARGET_SHIFT1
11613              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11614    && ix86_match_ccmode (insn, CCGOCmode)
11615    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11617   switch (get_attr_type (insn))
11618     {
11619     case TYPE_ALU:
11620       gcc_assert (operands[2] == const1_rtx);
11621       return "add{l}\t%0, %0";
11623     default:
11624       if (REG_P (operands[2]))
11625         return "sal{l}\t{%b2, %0|%0, %b2}";
11626       else if (operands[2] == const1_rtx
11627                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11628         return "sal{l}\t%0";
11629       else
11630         return "sal{l}\t{%2, %0|%0, %2}";
11631     }
11633   [(set (attr "type")
11634      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11635                           (const_int 0))
11636                       (match_operand 0 "register_operand" ""))
11637                  (match_operand 2 "const1_operand" ""))
11638               (const_string "alu")
11639            ]
11640            (const_string "ishift")))
11641    (set_attr "mode" "SI")])
11643 (define_insn "*ashlsi3_cconly"
11644   [(set (reg FLAGS_REG)
11645         (compare
11646           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11647                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11648           (const_int 0)))
11649    (clobber (match_scratch:SI 0 "=r"))]
11650   "(optimize_function_for_size_p (cfun)
11651     || !TARGET_PARTIAL_FLAG_REG_STALL
11652     || (operands[2] == const1_rtx
11653         && (TARGET_SHIFT1
11654             || TARGET_DOUBLE_WITH_ADD)))
11655    && ix86_match_ccmode (insn, CCGOCmode)
11656    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11658   switch (get_attr_type (insn))
11659     {
11660     case TYPE_ALU:
11661       gcc_assert (operands[2] == const1_rtx);
11662       return "add{l}\t%0, %0";
11664     default:
11665       if (REG_P (operands[2]))
11666         return "sal{l}\t{%b2, %0|%0, %b2}";
11667       else if (operands[2] == const1_rtx
11668                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11669         return "sal{l}\t%0";
11670       else
11671         return "sal{l}\t{%2, %0|%0, %2}";
11672     }
11674   [(set (attr "type")
11675      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11676                           (const_int 0))
11677                       (match_operand 0 "register_operand" ""))
11678                  (match_operand 2 "const1_operand" ""))
11679               (const_string "alu")
11680            ]
11681            (const_string "ishift")))
11682    (set_attr "mode" "SI")])
11684 (define_insn "*ashlsi3_cmp_zext"
11685   [(set (reg FLAGS_REG)
11686         (compare
11687           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11688                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11689           (const_int 0)))
11690    (set (match_operand:DI 0 "register_operand" "=r")
11691         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11692   "TARGET_64BIT
11693    && (optimize_function_for_size_p (cfun)
11694        || !TARGET_PARTIAL_FLAG_REG_STALL
11695        || (operands[2] == const1_rtx
11696            && (TARGET_SHIFT1
11697                || TARGET_DOUBLE_WITH_ADD)))
11698    && ix86_match_ccmode (insn, CCGOCmode)
11699    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11701   switch (get_attr_type (insn))
11702     {
11703     case TYPE_ALU:
11704       gcc_assert (operands[2] == const1_rtx);
11705       return "add{l}\t%k0, %k0";
11707     default:
11708       if (REG_P (operands[2]))
11709         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11710       else if (operands[2] == const1_rtx
11711                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11712         return "sal{l}\t%k0";
11713       else
11714         return "sal{l}\t{%2, %k0|%k0, %2}";
11715     }
11717   [(set (attr "type")
11718      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11719                      (const_int 0))
11720                  (match_operand 2 "const1_operand" ""))
11721               (const_string "alu")
11722            ]
11723            (const_string "ishift")))
11724    (set_attr "mode" "SI")])
11726 (define_expand "ashlhi3"
11727   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11728         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11729                    (match_operand:QI 2 "nonmemory_operand" "")))]
11730   "TARGET_HIMODE_MATH"
11731   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11733 (define_insn "*ashlhi3_1_lea"
11734   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11735         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11736                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11737    (clobber (reg:CC FLAGS_REG))]
11738   "!TARGET_PARTIAL_REG_STALL
11739    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11741   switch (get_attr_type (insn))
11742     {
11743     case TYPE_LEA:
11744       return "#";
11745     case TYPE_ALU:
11746       gcc_assert (operands[2] == const1_rtx);
11747       return "add{w}\t%0, %0";
11749     default:
11750       if (REG_P (operands[2]))
11751         return "sal{w}\t{%b2, %0|%0, %b2}";
11752       else if (operands[2] == const1_rtx
11753                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11754         return "sal{w}\t%0";
11755       else
11756         return "sal{w}\t{%2, %0|%0, %2}";
11757     }
11759   [(set (attr "type")
11760      (cond [(eq_attr "alternative" "1")
11761               (const_string "lea")
11762             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11763                           (const_int 0))
11764                       (match_operand 0 "register_operand" ""))
11765                  (match_operand 2 "const1_operand" ""))
11766               (const_string "alu")
11767            ]
11768            (const_string "ishift")))
11769    (set_attr "mode" "HI,SI")])
11771 (define_insn "*ashlhi3_1"
11772   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11773         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11774                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11775    (clobber (reg:CC FLAGS_REG))]
11776   "TARGET_PARTIAL_REG_STALL
11777    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11779   switch (get_attr_type (insn))
11780     {
11781     case TYPE_ALU:
11782       gcc_assert (operands[2] == const1_rtx);
11783       return "add{w}\t%0, %0";
11785     default:
11786       if (REG_P (operands[2]))
11787         return "sal{w}\t{%b2, %0|%0, %b2}";
11788       else if (operands[2] == const1_rtx
11789                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11790         return "sal{w}\t%0";
11791       else
11792         return "sal{w}\t{%2, %0|%0, %2}";
11793     }
11795   [(set (attr "type")
11796      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11797                           (const_int 0))
11798                       (match_operand 0 "register_operand" ""))
11799                  (match_operand 2 "const1_operand" ""))
11800               (const_string "alu")
11801            ]
11802            (const_string "ishift")))
11803    (set_attr "mode" "HI")])
11805 ;; This pattern can't accept a variable shift count, since shifts by
11806 ;; zero don't affect the flags.  We assume that shifts by constant
11807 ;; zero are optimized away.
11808 (define_insn "*ashlhi3_cmp"
11809   [(set (reg FLAGS_REG)
11810         (compare
11811           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11812                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11813           (const_int 0)))
11814    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11815         (ashift:HI (match_dup 1) (match_dup 2)))]
11816   "(optimize_function_for_size_p (cfun)
11817     || !TARGET_PARTIAL_FLAG_REG_STALL
11818     || (operands[2] == const1_rtx
11819         && (TARGET_SHIFT1
11820             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11821    && ix86_match_ccmode (insn, CCGOCmode)
11822    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11824   switch (get_attr_type (insn))
11825     {
11826     case TYPE_ALU:
11827       gcc_assert (operands[2] == const1_rtx);
11828       return "add{w}\t%0, %0";
11830     default:
11831       if (REG_P (operands[2]))
11832         return "sal{w}\t{%b2, %0|%0, %b2}";
11833       else if (operands[2] == const1_rtx
11834                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11835         return "sal{w}\t%0";
11836       else
11837         return "sal{w}\t{%2, %0|%0, %2}";
11838     }
11840   [(set (attr "type")
11841      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11842                           (const_int 0))
11843                       (match_operand 0 "register_operand" ""))
11844                  (match_operand 2 "const1_operand" ""))
11845               (const_string "alu")
11846            ]
11847            (const_string "ishift")))
11848    (set_attr "mode" "HI")])
11850 (define_insn "*ashlhi3_cconly"
11851   [(set (reg FLAGS_REG)
11852         (compare
11853           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11854                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11855           (const_int 0)))
11856    (clobber (match_scratch:HI 0 "=r"))]
11857   "(optimize_function_for_size_p (cfun)
11858     || !TARGET_PARTIAL_FLAG_REG_STALL
11859     || (operands[2] == const1_rtx
11860         && (TARGET_SHIFT1
11861             || TARGET_DOUBLE_WITH_ADD)))
11862    && ix86_match_ccmode (insn, CCGOCmode)
11863    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11865   switch (get_attr_type (insn))
11866     {
11867     case TYPE_ALU:
11868       gcc_assert (operands[2] == const1_rtx);
11869       return "add{w}\t%0, %0";
11871     default:
11872       if (REG_P (operands[2]))
11873         return "sal{w}\t{%b2, %0|%0, %b2}";
11874       else if (operands[2] == const1_rtx
11875                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11876         return "sal{w}\t%0";
11877       else
11878         return "sal{w}\t{%2, %0|%0, %2}";
11879     }
11881   [(set (attr "type")
11882      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11883                           (const_int 0))
11884                       (match_operand 0 "register_operand" ""))
11885                  (match_operand 2 "const1_operand" ""))
11886               (const_string "alu")
11887            ]
11888            (const_string "ishift")))
11889    (set_attr "mode" "HI")])
11891 (define_expand "ashlqi3"
11892   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11893         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11894                    (match_operand:QI 2 "nonmemory_operand" "")))]
11895   "TARGET_QIMODE_MATH"
11896   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11898 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11900 (define_insn "*ashlqi3_1_lea"
11901   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11902         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11903                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11904    (clobber (reg:CC FLAGS_REG))]
11905   "!TARGET_PARTIAL_REG_STALL
11906    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11908   switch (get_attr_type (insn))
11909     {
11910     case TYPE_LEA:
11911       return "#";
11912     case TYPE_ALU:
11913       gcc_assert (operands[2] == const1_rtx);
11914       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11915         return "add{l}\t%k0, %k0";
11916       else
11917         return "add{b}\t%0, %0";
11919     default:
11920       if (REG_P (operands[2]))
11921         {
11922           if (get_attr_mode (insn) == MODE_SI)
11923             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11924           else
11925             return "sal{b}\t{%b2, %0|%0, %b2}";
11926         }
11927       else if (operands[2] == const1_rtx
11928                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11929         {
11930           if (get_attr_mode (insn) == MODE_SI)
11931             return "sal{l}\t%0";
11932           else
11933             return "sal{b}\t%0";
11934         }
11935       else
11936         {
11937           if (get_attr_mode (insn) == MODE_SI)
11938             return "sal{l}\t{%2, %k0|%k0, %2}";
11939           else
11940             return "sal{b}\t{%2, %0|%0, %2}";
11941         }
11942     }
11944   [(set (attr "type")
11945      (cond [(eq_attr "alternative" "2")
11946               (const_string "lea")
11947             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11948                           (const_int 0))
11949                       (match_operand 0 "register_operand" ""))
11950                  (match_operand 2 "const1_operand" ""))
11951               (const_string "alu")
11952            ]
11953            (const_string "ishift")))
11954    (set_attr "mode" "QI,SI,SI")])
11956 (define_insn "*ashlqi3_1"
11957   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11958         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11959                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11960    (clobber (reg:CC FLAGS_REG))]
11961   "TARGET_PARTIAL_REG_STALL
11962    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11964   switch (get_attr_type (insn))
11965     {
11966     case TYPE_ALU:
11967       gcc_assert (operands[2] == const1_rtx);
11968       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11969         return "add{l}\t%k0, %k0";
11970       else
11971         return "add{b}\t%0, %0";
11973     default:
11974       if (REG_P (operands[2]))
11975         {
11976           if (get_attr_mode (insn) == MODE_SI)
11977             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11978           else
11979             return "sal{b}\t{%b2, %0|%0, %b2}";
11980         }
11981       else if (operands[2] == const1_rtx
11982                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11983         {
11984           if (get_attr_mode (insn) == MODE_SI)
11985             return "sal{l}\t%0";
11986           else
11987             return "sal{b}\t%0";
11988         }
11989       else
11990         {
11991           if (get_attr_mode (insn) == MODE_SI)
11992             return "sal{l}\t{%2, %k0|%k0, %2}";
11993           else
11994             return "sal{b}\t{%2, %0|%0, %2}";
11995         }
11996     }
11998   [(set (attr "type")
11999      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12000                           (const_int 0))
12001                       (match_operand 0 "register_operand" ""))
12002                  (match_operand 2 "const1_operand" ""))
12003               (const_string "alu")
12004            ]
12005            (const_string "ishift")))
12006    (set_attr "mode" "QI,SI")])
12008 ;; This pattern can't accept a variable shift count, since shifts by
12009 ;; zero don't affect the flags.  We assume that shifts by constant
12010 ;; zero are optimized away.
12011 (define_insn "*ashlqi3_cmp"
12012   [(set (reg FLAGS_REG)
12013         (compare
12014           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12015                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12016           (const_int 0)))
12017    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12018         (ashift:QI (match_dup 1) (match_dup 2)))]
12019   "(optimize_function_for_size_p (cfun)
12020     || !TARGET_PARTIAL_FLAG_REG_STALL
12021     || (operands[2] == const1_rtx
12022         && (TARGET_SHIFT1
12023             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12024    && ix86_match_ccmode (insn, CCGOCmode)
12025    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12027   switch (get_attr_type (insn))
12028     {
12029     case TYPE_ALU:
12030       gcc_assert (operands[2] == const1_rtx);
12031       return "add{b}\t%0, %0";
12033     default:
12034       if (REG_P (operands[2]))
12035         return "sal{b}\t{%b2, %0|%0, %b2}";
12036       else if (operands[2] == const1_rtx
12037                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12038         return "sal{b}\t%0";
12039       else
12040         return "sal{b}\t{%2, %0|%0, %2}";
12041     }
12043   [(set (attr "type")
12044      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12045                           (const_int 0))
12046                       (match_operand 0 "register_operand" ""))
12047                  (match_operand 2 "const1_operand" ""))
12048               (const_string "alu")
12049            ]
12050            (const_string "ishift")))
12051    (set_attr "mode" "QI")])
12053 (define_insn "*ashlqi3_cconly"
12054   [(set (reg FLAGS_REG)
12055         (compare
12056           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12057                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12058           (const_int 0)))
12059    (clobber (match_scratch:QI 0 "=q"))]
12060   "(optimize_function_for_size_p (cfun)
12061     || !TARGET_PARTIAL_FLAG_REG_STALL
12062     || (operands[2] == const1_rtx
12063         && (TARGET_SHIFT1
12064             || TARGET_DOUBLE_WITH_ADD)))
12065    && ix86_match_ccmode (insn, CCGOCmode)
12066    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12068   switch (get_attr_type (insn))
12069     {
12070     case TYPE_ALU:
12071       gcc_assert (operands[2] == const1_rtx);
12072       return "add{b}\t%0, %0";
12074     default:
12075       if (REG_P (operands[2]))
12076         return "sal{b}\t{%b2, %0|%0, %b2}";
12077       else if (operands[2] == const1_rtx
12078                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12079         return "sal{b}\t%0";
12080       else
12081         return "sal{b}\t{%2, %0|%0, %2}";
12082     }
12084   [(set (attr "type")
12085      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12086                           (const_int 0))
12087                       (match_operand 0 "register_operand" ""))
12088                  (match_operand 2 "const1_operand" ""))
12089               (const_string "alu")
12090            ]
12091            (const_string "ishift")))
12092    (set_attr "mode" "QI")])
12094 ;; See comment above `ashldi3' about how this works.
12096 (define_expand "ashrti3"
12097   [(set (match_operand:TI 0 "register_operand" "")
12098         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12099                      (match_operand:QI 2 "nonmemory_operand" "")))]
12100   "TARGET_64BIT"
12101   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12103 (define_insn "*ashrti3_1"
12104   [(set (match_operand:TI 0 "register_operand" "=r")
12105         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12106                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12107    (clobber (reg:CC FLAGS_REG))]
12108   "TARGET_64BIT"
12109   "#"
12110   [(set_attr "type" "multi")])
12112 (define_peephole2
12113   [(match_scratch:DI 3 "r")
12114    (parallel [(set (match_operand:TI 0 "register_operand" "")
12115                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12116                                 (match_operand:QI 2 "nonmemory_operand" "")))
12117               (clobber (reg:CC FLAGS_REG))])
12118    (match_dup 3)]
12119   "TARGET_64BIT"
12120   [(const_int 0)]
12121   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12123 (define_split
12124   [(set (match_operand:TI 0 "register_operand" "")
12125         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12126                      (match_operand:QI 2 "nonmemory_operand" "")))
12127    (clobber (reg:CC FLAGS_REG))]
12128   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12129                     ? epilogue_completed : reload_completed)"
12130   [(const_int 0)]
12131   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12133 (define_insn "x86_64_shrd"
12134   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12135         (ior:DI (ashiftrt:DI (match_dup 0)
12136                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
12137                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12138                   (minus:QI (const_int 64) (match_dup 2)))))
12139    (clobber (reg:CC FLAGS_REG))]
12140   "TARGET_64BIT"
12141   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12142   [(set_attr "type" "ishift")
12143    (set_attr "prefix_0f" "1")
12144    (set_attr "mode" "DI")
12145    (set_attr "athlon_decode" "vector")
12146    (set_attr "amdfam10_decode" "vector")])
12148 (define_expand "ashrdi3"
12149   [(set (match_operand:DI 0 "shiftdi_operand" "")
12150         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12151                      (match_operand:QI 2 "nonmemory_operand" "")))]
12152   ""
12153   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12155 (define_expand "x86_64_shift_adj_3"
12156   [(use (match_operand:DI 0 "register_operand" ""))
12157    (use (match_operand:DI 1 "register_operand" ""))
12158    (use (match_operand:QI 2 "register_operand" ""))]
12159   ""
12161   rtx label = gen_label_rtx ();
12162   rtx tmp;
12164   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12166   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12167   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12168   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12169                               gen_rtx_LABEL_REF (VOIDmode, label),
12170                               pc_rtx);
12171   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12172   JUMP_LABEL (tmp) = label;
12174   emit_move_insn (operands[0], operands[1]);
12175   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12177   emit_label (label);
12178   LABEL_NUSES (label) = 1;
12180   DONE;
12183 (define_insn "ashrdi3_63_rex64"
12184   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12185         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12186                      (match_operand:DI 2 "const_int_operand" "i,i")))
12187    (clobber (reg:CC FLAGS_REG))]
12188   "TARGET_64BIT && INTVAL (operands[2]) == 63
12189    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12190    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12191   "@
12192    {cqto|cqo}
12193    sar{q}\t{%2, %0|%0, %2}"
12194   [(set_attr "type" "imovx,ishift")
12195    (set_attr "prefix_0f" "0,*")
12196    (set_attr "length_immediate" "0,*")
12197    (set_attr "modrm" "0,1")
12198    (set_attr "mode" "DI")])
12200 (define_insn "*ashrdi3_1_one_bit_rex64"
12201   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12202         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12203                      (match_operand:QI 2 "const1_operand" "")))
12204    (clobber (reg:CC FLAGS_REG))]
12205   "TARGET_64BIT
12206    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12207    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12208   "sar{q}\t%0"
12209   [(set_attr "type" "ishift")
12210    (set (attr "length")
12211      (if_then_else (match_operand:DI 0 "register_operand" "")
12212         (const_string "2")
12213         (const_string "*")))])
12215 (define_insn "*ashrdi3_1_rex64"
12216   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12217         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12218                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12219    (clobber (reg:CC FLAGS_REG))]
12220   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12221   "@
12222    sar{q}\t{%2, %0|%0, %2}
12223    sar{q}\t{%b2, %0|%0, %b2}"
12224   [(set_attr "type" "ishift")
12225    (set_attr "mode" "DI")])
12227 ;; This pattern can't accept a variable shift count, since shifts by
12228 ;; zero don't affect the flags.  We assume that shifts by constant
12229 ;; zero are optimized away.
12230 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12231   [(set (reg FLAGS_REG)
12232         (compare
12233           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12234                        (match_operand:QI 2 "const1_operand" ""))
12235           (const_int 0)))
12236    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12237         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12238   "TARGET_64BIT
12239    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12240    && ix86_match_ccmode (insn, CCGOCmode)
12241    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12242   "sar{q}\t%0"
12243   [(set_attr "type" "ishift")
12244    (set (attr "length")
12245      (if_then_else (match_operand:DI 0 "register_operand" "")
12246         (const_string "2")
12247         (const_string "*")))])
12249 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12250   [(set (reg FLAGS_REG)
12251         (compare
12252           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12253                        (match_operand:QI 2 "const1_operand" ""))
12254           (const_int 0)))
12255    (clobber (match_scratch:DI 0 "=r"))]
12256   "TARGET_64BIT
12257    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12258    && ix86_match_ccmode (insn, CCGOCmode)
12259    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12260   "sar{q}\t%0"
12261   [(set_attr "type" "ishift")
12262    (set_attr "length" "2")])
12264 ;; This pattern can't accept a variable shift count, since shifts by
12265 ;; zero don't affect the flags.  We assume that shifts by constant
12266 ;; zero are optimized away.
12267 (define_insn "*ashrdi3_cmp_rex64"
12268   [(set (reg FLAGS_REG)
12269         (compare
12270           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12271                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12272           (const_int 0)))
12273    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12274         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12275   "TARGET_64BIT
12276    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12277    && ix86_match_ccmode (insn, CCGOCmode)
12278    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12279   "sar{q}\t{%2, %0|%0, %2}"
12280   [(set_attr "type" "ishift")
12281    (set_attr "mode" "DI")])
12283 (define_insn "*ashrdi3_cconly_rex64"
12284   [(set (reg FLAGS_REG)
12285         (compare
12286           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12287                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12288           (const_int 0)))
12289    (clobber (match_scratch:DI 0 "=r"))]
12290   "TARGET_64BIT
12291    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12292    && ix86_match_ccmode (insn, CCGOCmode)
12293    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12294   "sar{q}\t{%2, %0|%0, %2}"
12295   [(set_attr "type" "ishift")
12296    (set_attr "mode" "DI")])
12298 (define_insn "*ashrdi3_1"
12299   [(set (match_operand:DI 0 "register_operand" "=r")
12300         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12301                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12302    (clobber (reg:CC FLAGS_REG))]
12303   "!TARGET_64BIT"
12304   "#"
12305   [(set_attr "type" "multi")])
12307 ;; By default we don't ask for a scratch register, because when DImode
12308 ;; values are manipulated, registers are already at a premium.  But if
12309 ;; we have one handy, we won't turn it away.
12310 (define_peephole2
12311   [(match_scratch:SI 3 "r")
12312    (parallel [(set (match_operand:DI 0 "register_operand" "")
12313                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12314                                 (match_operand:QI 2 "nonmemory_operand" "")))
12315               (clobber (reg:CC FLAGS_REG))])
12316    (match_dup 3)]
12317   "!TARGET_64BIT && TARGET_CMOVE"
12318   [(const_int 0)]
12319   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12321 (define_split
12322   [(set (match_operand:DI 0 "register_operand" "")
12323         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12324                      (match_operand:QI 2 "nonmemory_operand" "")))
12325    (clobber (reg:CC FLAGS_REG))]
12326   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12327                      ? epilogue_completed : reload_completed)"
12328   [(const_int 0)]
12329   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12331 (define_insn "x86_shrd"
12332   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12333         (ior:SI (ashiftrt:SI (match_dup 0)
12334                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
12335                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12336                   (minus:QI (const_int 32) (match_dup 2)))))
12337    (clobber (reg:CC FLAGS_REG))]
12338   ""
12339   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12340   [(set_attr "type" "ishift")
12341    (set_attr "prefix_0f" "1")
12342    (set_attr "pent_pair" "np")
12343    (set_attr "mode" "SI")])
12345 (define_expand "x86_shift_adj_3"
12346   [(use (match_operand:SI 0 "register_operand" ""))
12347    (use (match_operand:SI 1 "register_operand" ""))
12348    (use (match_operand:QI 2 "register_operand" ""))]
12349   ""
12351   rtx label = gen_label_rtx ();
12352   rtx tmp;
12354   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12356   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12357   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12358   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12359                               gen_rtx_LABEL_REF (VOIDmode, label),
12360                               pc_rtx);
12361   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12362   JUMP_LABEL (tmp) = label;
12364   emit_move_insn (operands[0], operands[1]);
12365   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12367   emit_label (label);
12368   LABEL_NUSES (label) = 1;
12370   DONE;
12373 (define_expand "ashrsi3_31"
12374   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12375                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12376                                 (match_operand:SI 2 "const_int_operand" "i,i")))
12377               (clobber (reg:CC FLAGS_REG))])]
12378   "")
12380 (define_insn "*ashrsi3_31"
12381   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12382         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12383                      (match_operand:SI 2 "const_int_operand" "i,i")))
12384    (clobber (reg:CC FLAGS_REG))]
12385   "INTVAL (operands[2]) == 31
12386    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12387    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12388   "@
12389    {cltd|cdq}
12390    sar{l}\t{%2, %0|%0, %2}"
12391   [(set_attr "type" "imovx,ishift")
12392    (set_attr "prefix_0f" "0,*")
12393    (set_attr "length_immediate" "0,*")
12394    (set_attr "modrm" "0,1")
12395    (set_attr "mode" "SI")])
12397 (define_insn "*ashrsi3_31_zext"
12398   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12399         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12400                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12401    (clobber (reg:CC FLAGS_REG))]
12402   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12403    && INTVAL (operands[2]) == 31
12404    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12405   "@
12406    {cltd|cdq}
12407    sar{l}\t{%2, %k0|%k0, %2}"
12408   [(set_attr "type" "imovx,ishift")
12409    (set_attr "prefix_0f" "0,*")
12410    (set_attr "length_immediate" "0,*")
12411    (set_attr "modrm" "0,1")
12412    (set_attr "mode" "SI")])
12414 (define_expand "ashrsi3"
12415   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12416         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12417                      (match_operand:QI 2 "nonmemory_operand" "")))]
12418   ""
12419   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12421 (define_insn "*ashrsi3_1_one_bit"
12422   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12423         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12424                      (match_operand:QI 2 "const1_operand" "")))
12425    (clobber (reg:CC FLAGS_REG))]
12426   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12427    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12428   "sar{l}\t%0"
12429   [(set_attr "type" "ishift")
12430    (set (attr "length")
12431      (if_then_else (match_operand:SI 0 "register_operand" "")
12432         (const_string "2")
12433         (const_string "*")))])
12435 (define_insn "*ashrsi3_1_one_bit_zext"
12436   [(set (match_operand:DI 0 "register_operand" "=r")
12437         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12438                                      (match_operand:QI 2 "const1_operand" ""))))
12439    (clobber (reg:CC FLAGS_REG))]
12440   "TARGET_64BIT
12441    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12442    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12443   "sar{l}\t%k0"
12444   [(set_attr "type" "ishift")
12445    (set_attr "length" "2")])
12447 (define_insn "*ashrsi3_1"
12448   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12449         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12450                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12451    (clobber (reg:CC FLAGS_REG))]
12452   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12453   "@
12454    sar{l}\t{%2, %0|%0, %2}
12455    sar{l}\t{%b2, %0|%0, %b2}"
12456   [(set_attr "type" "ishift")
12457    (set_attr "mode" "SI")])
12459 (define_insn "*ashrsi3_1_zext"
12460   [(set (match_operand:DI 0 "register_operand" "=r,r")
12461         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12462                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12463    (clobber (reg:CC FLAGS_REG))]
12464   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12465   "@
12466    sar{l}\t{%2, %k0|%k0, %2}
12467    sar{l}\t{%b2, %k0|%k0, %b2}"
12468   [(set_attr "type" "ishift")
12469    (set_attr "mode" "SI")])
12471 ;; This pattern can't accept a variable shift count, since shifts by
12472 ;; zero don't affect the flags.  We assume that shifts by constant
12473 ;; zero are optimized away.
12474 (define_insn "*ashrsi3_one_bit_cmp"
12475   [(set (reg FLAGS_REG)
12476         (compare
12477           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12478                        (match_operand:QI 2 "const1_operand" ""))
12479           (const_int 0)))
12480    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12481         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12482   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12483    && ix86_match_ccmode (insn, CCGOCmode)
12484    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12485   "sar{l}\t%0"
12486   [(set_attr "type" "ishift")
12487    (set (attr "length")
12488      (if_then_else (match_operand:SI 0 "register_operand" "")
12489         (const_string "2")
12490         (const_string "*")))])
12492 (define_insn "*ashrsi3_one_bit_cconly"
12493   [(set (reg FLAGS_REG)
12494         (compare
12495           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12496                        (match_operand:QI 2 "const1_operand" ""))
12497           (const_int 0)))
12498    (clobber (match_scratch:SI 0 "=r"))]
12499   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12500    && ix86_match_ccmode (insn, CCGOCmode)
12501    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12502   "sar{l}\t%0"
12503   [(set_attr "type" "ishift")
12504    (set_attr "length" "2")])
12506 (define_insn "*ashrsi3_one_bit_cmp_zext"
12507   [(set (reg FLAGS_REG)
12508         (compare
12509           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12510                        (match_operand:QI 2 "const1_operand" ""))
12511           (const_int 0)))
12512    (set (match_operand:DI 0 "register_operand" "=r")
12513         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12514   "TARGET_64BIT
12515    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12516    && ix86_match_ccmode (insn, CCmode)
12517    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12518   "sar{l}\t%k0"
12519   [(set_attr "type" "ishift")
12520    (set_attr "length" "2")])
12522 ;; This pattern can't accept a variable shift count, since shifts by
12523 ;; zero don't affect the flags.  We assume that shifts by constant
12524 ;; zero are optimized away.
12525 (define_insn "*ashrsi3_cmp"
12526   [(set (reg FLAGS_REG)
12527         (compare
12528           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12529                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12530           (const_int 0)))
12531    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12532         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12533   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12534    && ix86_match_ccmode (insn, CCGOCmode)
12535    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12536   "sar{l}\t{%2, %0|%0, %2}"
12537   [(set_attr "type" "ishift")
12538    (set_attr "mode" "SI")])
12540 (define_insn "*ashrsi3_cconly"
12541   [(set (reg FLAGS_REG)
12542         (compare
12543           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12544                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12545           (const_int 0)))
12546    (clobber (match_scratch:SI 0 "=r"))]
12547   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12548    && ix86_match_ccmode (insn, CCGOCmode)
12549    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12550   "sar{l}\t{%2, %0|%0, %2}"
12551   [(set_attr "type" "ishift")
12552    (set_attr "mode" "SI")])
12554 (define_insn "*ashrsi3_cmp_zext"
12555   [(set (reg FLAGS_REG)
12556         (compare
12557           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12558                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12559           (const_int 0)))
12560    (set (match_operand:DI 0 "register_operand" "=r")
12561         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12562   "TARGET_64BIT
12563    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12564    && ix86_match_ccmode (insn, CCGOCmode)
12565    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12566   "sar{l}\t{%2, %k0|%k0, %2}"
12567   [(set_attr "type" "ishift")
12568    (set_attr "mode" "SI")])
12570 (define_expand "ashrhi3"
12571   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12572         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12573                      (match_operand:QI 2 "nonmemory_operand" "")))]
12574   "TARGET_HIMODE_MATH"
12575   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12577 (define_insn "*ashrhi3_1_one_bit"
12578   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12579         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12580                      (match_operand:QI 2 "const1_operand" "")))
12581    (clobber (reg:CC FLAGS_REG))]
12582   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12583    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12584   "sar{w}\t%0"
12585   [(set_attr "type" "ishift")
12586    (set (attr "length")
12587      (if_then_else (match_operand 0 "register_operand" "")
12588         (const_string "2")
12589         (const_string "*")))])
12591 (define_insn "*ashrhi3_1"
12592   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12593         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12594                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12595    (clobber (reg:CC FLAGS_REG))]
12596   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12597   "@
12598    sar{w}\t{%2, %0|%0, %2}
12599    sar{w}\t{%b2, %0|%0, %b2}"
12600   [(set_attr "type" "ishift")
12601    (set_attr "mode" "HI")])
12603 ;; This pattern can't accept a variable shift count, since shifts by
12604 ;; zero don't affect the flags.  We assume that shifts by constant
12605 ;; zero are optimized away.
12606 (define_insn "*ashrhi3_one_bit_cmp"
12607   [(set (reg FLAGS_REG)
12608         (compare
12609           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12610                        (match_operand:QI 2 "const1_operand" ""))
12611           (const_int 0)))
12612    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12613         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12614   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12615    && ix86_match_ccmode (insn, CCGOCmode)
12616    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12617   "sar{w}\t%0"
12618   [(set_attr "type" "ishift")
12619    (set (attr "length")
12620      (if_then_else (match_operand 0 "register_operand" "")
12621         (const_string "2")
12622         (const_string "*")))])
12624 (define_insn "*ashrhi3_one_bit_cconly"
12625   [(set (reg FLAGS_REG)
12626         (compare
12627           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12628                        (match_operand:QI 2 "const1_operand" ""))
12629           (const_int 0)))
12630    (clobber (match_scratch:HI 0 "=r"))]
12631   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12632    && ix86_match_ccmode (insn, CCGOCmode)
12633    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12634   "sar{w}\t%0"
12635   [(set_attr "type" "ishift")
12636    (set_attr "length" "2")])
12638 ;; This pattern can't accept a variable shift count, since shifts by
12639 ;; zero don't affect the flags.  We assume that shifts by constant
12640 ;; zero are optimized away.
12641 (define_insn "*ashrhi3_cmp"
12642   [(set (reg FLAGS_REG)
12643         (compare
12644           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12645                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12646           (const_int 0)))
12647    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12648         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12649   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12650    && ix86_match_ccmode (insn, CCGOCmode)
12651    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12652   "sar{w}\t{%2, %0|%0, %2}"
12653   [(set_attr "type" "ishift")
12654    (set_attr "mode" "HI")])
12656 (define_insn "*ashrhi3_cconly"
12657   [(set (reg FLAGS_REG)
12658         (compare
12659           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12660                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12661           (const_int 0)))
12662    (clobber (match_scratch:HI 0 "=r"))]
12663   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12664    && ix86_match_ccmode (insn, CCGOCmode)
12665    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12666   "sar{w}\t{%2, %0|%0, %2}"
12667   [(set_attr "type" "ishift")
12668    (set_attr "mode" "HI")])
12670 (define_expand "ashrqi3"
12671   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12672         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12673                      (match_operand:QI 2 "nonmemory_operand" "")))]
12674   "TARGET_QIMODE_MATH"
12675   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12677 (define_insn "*ashrqi3_1_one_bit"
12678   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12679         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12680                      (match_operand:QI 2 "const1_operand" "")))
12681    (clobber (reg:CC FLAGS_REG))]
12682   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12683    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12684   "sar{b}\t%0"
12685   [(set_attr "type" "ishift")
12686    (set (attr "length")
12687      (if_then_else (match_operand 0 "register_operand" "")
12688         (const_string "2")
12689         (const_string "*")))])
12691 (define_insn "*ashrqi3_1_one_bit_slp"
12692   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12693         (ashiftrt:QI (match_dup 0)
12694                      (match_operand:QI 1 "const1_operand" "")))
12695    (clobber (reg:CC FLAGS_REG))]
12696   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12697    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12698    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12699   "sar{b}\t%0"
12700   [(set_attr "type" "ishift1")
12701    (set (attr "length")
12702      (if_then_else (match_operand 0 "register_operand" "")
12703         (const_string "2")
12704         (const_string "*")))])
12706 (define_insn "*ashrqi3_1"
12707   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12708         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12709                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12710    (clobber (reg:CC FLAGS_REG))]
12711   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12712   "@
12713    sar{b}\t{%2, %0|%0, %2}
12714    sar{b}\t{%b2, %0|%0, %b2}"
12715   [(set_attr "type" "ishift")
12716    (set_attr "mode" "QI")])
12718 (define_insn "*ashrqi3_1_slp"
12719   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12720         (ashiftrt:QI (match_dup 0)
12721                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12722    (clobber (reg:CC FLAGS_REG))]
12723   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12724    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12725   "@
12726    sar{b}\t{%1, %0|%0, %1}
12727    sar{b}\t{%b1, %0|%0, %b1}"
12728   [(set_attr "type" "ishift1")
12729    (set_attr "mode" "QI")])
12731 ;; This pattern can't accept a variable shift count, since shifts by
12732 ;; zero don't affect the flags.  We assume that shifts by constant
12733 ;; zero are optimized away.
12734 (define_insn "*ashrqi3_one_bit_cmp"
12735   [(set (reg FLAGS_REG)
12736         (compare
12737           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12738                        (match_operand:QI 2 "const1_operand" "I"))
12739           (const_int 0)))
12740    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12741         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12742   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12743    && ix86_match_ccmode (insn, CCGOCmode)
12744    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12745   "sar{b}\t%0"
12746   [(set_attr "type" "ishift")
12747    (set (attr "length")
12748      (if_then_else (match_operand 0 "register_operand" "")
12749         (const_string "2")
12750         (const_string "*")))])
12752 (define_insn "*ashrqi3_one_bit_cconly"
12753   [(set (reg FLAGS_REG)
12754         (compare
12755           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12756                        (match_operand:QI 2 "const1_operand" ""))
12757           (const_int 0)))
12758    (clobber (match_scratch:QI 0 "=q"))]
12759   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12760    && ix86_match_ccmode (insn, CCGOCmode)
12761    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12762   "sar{b}\t%0"
12763   [(set_attr "type" "ishift")
12764    (set_attr "length" "2")])
12766 ;; This pattern can't accept a variable shift count, since shifts by
12767 ;; zero don't affect the flags.  We assume that shifts by constant
12768 ;; zero are optimized away.
12769 (define_insn "*ashrqi3_cmp"
12770   [(set (reg FLAGS_REG)
12771         (compare
12772           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12773                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12774           (const_int 0)))
12775    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12776         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12777   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12778    && ix86_match_ccmode (insn, CCGOCmode)
12779    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12780   "sar{b}\t{%2, %0|%0, %2}"
12781   [(set_attr "type" "ishift")
12782    (set_attr "mode" "QI")])
12784 (define_insn "*ashrqi3_cconly"
12785   [(set (reg FLAGS_REG)
12786         (compare
12787           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12788                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12789           (const_int 0)))
12790    (clobber (match_scratch:QI 0 "=q"))]
12791   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12792    && ix86_match_ccmode (insn, CCGOCmode)
12793    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12794   "sar{b}\t{%2, %0|%0, %2}"
12795   [(set_attr "type" "ishift")
12796    (set_attr "mode" "QI")])
12799 ;; Logical shift instructions
12801 ;; See comment above `ashldi3' about how this works.
12803 (define_expand "lshrti3"
12804   [(set (match_operand:TI 0 "register_operand" "")
12805         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12806                      (match_operand:QI 2 "nonmemory_operand" "")))]
12807   "TARGET_64BIT"
12808   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12810 ;; This pattern must be defined before *lshrti3_1 to prevent
12811 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12813 (define_insn "*avx_lshrti3"
12814   [(set (match_operand:TI 0 "register_operand" "=x")
12815         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12816                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12817   "TARGET_AVX"
12819   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12820   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12822   [(set_attr "type" "sseishft")
12823    (set_attr "prefix" "vex")
12824    (set_attr "mode" "TI")])
12826 (define_insn "sse2_lshrti3"
12827   [(set (match_operand:TI 0 "register_operand" "=x")
12828         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12829                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12830   "TARGET_SSE2"
12832   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12833   return "psrldq\t{%2, %0|%0, %2}";
12835   [(set_attr "type" "sseishft")
12836    (set_attr "prefix_data16" "1")
12837    (set_attr "mode" "TI")])
12839 (define_insn "*lshrti3_1"
12840   [(set (match_operand:TI 0 "register_operand" "=r")
12841         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12842                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12843    (clobber (reg:CC FLAGS_REG))]
12844   "TARGET_64BIT"
12845   "#"
12846   [(set_attr "type" "multi")])
12848 (define_peephole2
12849   [(match_scratch:DI 3 "r")
12850    (parallel [(set (match_operand:TI 0 "register_operand" "")
12851                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12852                                 (match_operand:QI 2 "nonmemory_operand" "")))
12853               (clobber (reg:CC FLAGS_REG))])
12854    (match_dup 3)]
12855   "TARGET_64BIT"
12856   [(const_int 0)]
12857   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12859 (define_split
12860   [(set (match_operand:TI 0 "register_operand" "")
12861         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12862                      (match_operand:QI 2 "nonmemory_operand" "")))
12863    (clobber (reg:CC FLAGS_REG))]
12864   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12865                     ? epilogue_completed : reload_completed)"
12866   [(const_int 0)]
12867   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12869 (define_expand "lshrdi3"
12870   [(set (match_operand:DI 0 "shiftdi_operand" "")
12871         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12872                      (match_operand:QI 2 "nonmemory_operand" "")))]
12873   ""
12874   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12876 (define_insn "*lshrdi3_1_one_bit_rex64"
12877   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12878         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12879                      (match_operand:QI 2 "const1_operand" "")))
12880    (clobber (reg:CC FLAGS_REG))]
12881   "TARGET_64BIT
12882    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12883    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12884   "shr{q}\t%0"
12885   [(set_attr "type" "ishift")
12886    (set (attr "length")
12887      (if_then_else (match_operand:DI 0 "register_operand" "")
12888         (const_string "2")
12889         (const_string "*")))])
12891 (define_insn "*lshrdi3_1_rex64"
12892   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12893         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12894                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12895    (clobber (reg:CC FLAGS_REG))]
12896   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12897   "@
12898    shr{q}\t{%2, %0|%0, %2}
12899    shr{q}\t{%b2, %0|%0, %b2}"
12900   [(set_attr "type" "ishift")
12901    (set_attr "mode" "DI")])
12903 ;; This pattern can't accept a variable shift count, since shifts by
12904 ;; zero don't affect the flags.  We assume that shifts by constant
12905 ;; zero are optimized away.
12906 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12907   [(set (reg FLAGS_REG)
12908         (compare
12909           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12910                        (match_operand:QI 2 "const1_operand" ""))
12911           (const_int 0)))
12912    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12913         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12914   "TARGET_64BIT
12915    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12916    && ix86_match_ccmode (insn, CCGOCmode)
12917    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12918   "shr{q}\t%0"
12919   [(set_attr "type" "ishift")
12920    (set (attr "length")
12921      (if_then_else (match_operand:DI 0 "register_operand" "")
12922         (const_string "2")
12923         (const_string "*")))])
12925 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12926   [(set (reg FLAGS_REG)
12927         (compare
12928           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12929                        (match_operand:QI 2 "const1_operand" ""))
12930           (const_int 0)))
12931    (clobber (match_scratch:DI 0 "=r"))]
12932   "TARGET_64BIT
12933    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12934    && ix86_match_ccmode (insn, CCGOCmode)
12935    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12936   "shr{q}\t%0"
12937   [(set_attr "type" "ishift")
12938    (set_attr "length" "2")])
12940 ;; This pattern can't accept a variable shift count, since shifts by
12941 ;; zero don't affect the flags.  We assume that shifts by constant
12942 ;; zero are optimized away.
12943 (define_insn "*lshrdi3_cmp_rex64"
12944   [(set (reg FLAGS_REG)
12945         (compare
12946           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12947                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12948           (const_int 0)))
12949    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12950         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12951   "TARGET_64BIT
12952    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12953    && ix86_match_ccmode (insn, CCGOCmode)
12954    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12955   "shr{q}\t{%2, %0|%0, %2}"
12956   [(set_attr "type" "ishift")
12957    (set_attr "mode" "DI")])
12959 (define_insn "*lshrdi3_cconly_rex64"
12960   [(set (reg FLAGS_REG)
12961         (compare
12962           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12963                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12964           (const_int 0)))
12965    (clobber (match_scratch:DI 0 "=r"))]
12966   "TARGET_64BIT
12967    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12968    && ix86_match_ccmode (insn, CCGOCmode)
12969    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12970   "shr{q}\t{%2, %0|%0, %2}"
12971   [(set_attr "type" "ishift")
12972    (set_attr "mode" "DI")])
12974 (define_insn "*lshrdi3_1"
12975   [(set (match_operand:DI 0 "register_operand" "=r")
12976         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12977                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12978    (clobber (reg:CC FLAGS_REG))]
12979   "!TARGET_64BIT"
12980   "#"
12981   [(set_attr "type" "multi")])
12983 ;; By default we don't ask for a scratch register, because when DImode
12984 ;; values are manipulated, registers are already at a premium.  But if
12985 ;; we have one handy, we won't turn it away.
12986 (define_peephole2
12987   [(match_scratch:SI 3 "r")
12988    (parallel [(set (match_operand:DI 0 "register_operand" "")
12989                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12990                                 (match_operand:QI 2 "nonmemory_operand" "")))
12991               (clobber (reg:CC FLAGS_REG))])
12992    (match_dup 3)]
12993   "!TARGET_64BIT && TARGET_CMOVE"
12994   [(const_int 0)]
12995   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12997 (define_split
12998   [(set (match_operand:DI 0 "register_operand" "")
12999         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13000                      (match_operand:QI 2 "nonmemory_operand" "")))
13001    (clobber (reg:CC FLAGS_REG))]
13002   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13003                      ? epilogue_completed : reload_completed)"
13004   [(const_int 0)]
13005   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
13007 (define_expand "lshrsi3"
13008   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13009         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13010                      (match_operand:QI 2 "nonmemory_operand" "")))]
13011   ""
13012   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13014 (define_insn "*lshrsi3_1_one_bit"
13015   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13016         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13017                      (match_operand:QI 2 "const1_operand" "")))
13018    (clobber (reg:CC FLAGS_REG))]
13019   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13020    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13021   "shr{l}\t%0"
13022   [(set_attr "type" "ishift")
13023    (set (attr "length")
13024      (if_then_else (match_operand:SI 0 "register_operand" "")
13025         (const_string "2")
13026         (const_string "*")))])
13028 (define_insn "*lshrsi3_1_one_bit_zext"
13029   [(set (match_operand:DI 0 "register_operand" "=r")
13030         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13031                      (match_operand:QI 2 "const1_operand" "")))
13032    (clobber (reg:CC FLAGS_REG))]
13033   "TARGET_64BIT
13034    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13035    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13036   "shr{l}\t%k0"
13037   [(set_attr "type" "ishift")
13038    (set_attr "length" "2")])
13040 (define_insn "*lshrsi3_1"
13041   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13042         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13043                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13044    (clobber (reg:CC FLAGS_REG))]
13045   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13046   "@
13047    shr{l}\t{%2, %0|%0, %2}
13048    shr{l}\t{%b2, %0|%0, %b2}"
13049   [(set_attr "type" "ishift")
13050    (set_attr "mode" "SI")])
13052 (define_insn "*lshrsi3_1_zext"
13053   [(set (match_operand:DI 0 "register_operand" "=r,r")
13054         (zero_extend:DI
13055           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13056                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13057    (clobber (reg:CC FLAGS_REG))]
13058   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13059   "@
13060    shr{l}\t{%2, %k0|%k0, %2}
13061    shr{l}\t{%b2, %k0|%k0, %b2}"
13062   [(set_attr "type" "ishift")
13063    (set_attr "mode" "SI")])
13065 ;; This pattern can't accept a variable shift count, since shifts by
13066 ;; zero don't affect the flags.  We assume that shifts by constant
13067 ;; zero are optimized away.
13068 (define_insn "*lshrsi3_one_bit_cmp"
13069   [(set (reg FLAGS_REG)
13070         (compare
13071           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13072                        (match_operand:QI 2 "const1_operand" ""))
13073           (const_int 0)))
13074    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13075         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13076   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13077    && ix86_match_ccmode (insn, CCGOCmode)
13078    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13079   "shr{l}\t%0"
13080   [(set_attr "type" "ishift")
13081    (set (attr "length")
13082      (if_then_else (match_operand:SI 0 "register_operand" "")
13083         (const_string "2")
13084         (const_string "*")))])
13086 (define_insn "*lshrsi3_one_bit_cconly"
13087   [(set (reg FLAGS_REG)
13088         (compare
13089           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13090                        (match_operand:QI 2 "const1_operand" ""))
13091           (const_int 0)))
13092    (clobber (match_scratch:SI 0 "=r"))]
13093   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13094    && ix86_match_ccmode (insn, CCGOCmode)
13095    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13096   "shr{l}\t%0"
13097   [(set_attr "type" "ishift")
13098    (set_attr "length" "2")])
13100 (define_insn "*lshrsi3_cmp_one_bit_zext"
13101   [(set (reg FLAGS_REG)
13102         (compare
13103           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13104                        (match_operand:QI 2 "const1_operand" ""))
13105           (const_int 0)))
13106    (set (match_operand:DI 0 "register_operand" "=r")
13107         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13108   "TARGET_64BIT
13109    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13110    && ix86_match_ccmode (insn, CCGOCmode)
13111    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13112   "shr{l}\t%k0"
13113   [(set_attr "type" "ishift")
13114    (set_attr "length" "2")])
13116 ;; This pattern can't accept a variable shift count, since shifts by
13117 ;; zero don't affect the flags.  We assume that shifts by constant
13118 ;; zero are optimized away.
13119 (define_insn "*lshrsi3_cmp"
13120   [(set (reg FLAGS_REG)
13121         (compare
13122           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13123                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13124           (const_int 0)))
13125    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13126         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13127   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13128    && ix86_match_ccmode (insn, CCGOCmode)
13129    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13130   "shr{l}\t{%2, %0|%0, %2}"
13131   [(set_attr "type" "ishift")
13132    (set_attr "mode" "SI")])
13134 (define_insn "*lshrsi3_cconly"
13135   [(set (reg FLAGS_REG)
13136       (compare
13137         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13138                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
13139         (const_int 0)))
13140    (clobber (match_scratch:SI 0 "=r"))]
13141   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13142    && ix86_match_ccmode (insn, CCGOCmode)
13143    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13144   "shr{l}\t{%2, %0|%0, %2}"
13145   [(set_attr "type" "ishift")
13146    (set_attr "mode" "SI")])
13148 (define_insn "*lshrsi3_cmp_zext"
13149   [(set (reg FLAGS_REG)
13150         (compare
13151           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13152                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13153           (const_int 0)))
13154    (set (match_operand:DI 0 "register_operand" "=r")
13155         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13156   "TARGET_64BIT
13157    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13158    && ix86_match_ccmode (insn, CCGOCmode)
13159    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13160   "shr{l}\t{%2, %k0|%k0, %2}"
13161   [(set_attr "type" "ishift")
13162    (set_attr "mode" "SI")])
13164 (define_expand "lshrhi3"
13165   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13166         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13167                      (match_operand:QI 2 "nonmemory_operand" "")))]
13168   "TARGET_HIMODE_MATH"
13169   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13171 (define_insn "*lshrhi3_1_one_bit"
13172   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13173         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13174                      (match_operand:QI 2 "const1_operand" "")))
13175    (clobber (reg:CC FLAGS_REG))]
13176   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13177    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13178   "shr{w}\t%0"
13179   [(set_attr "type" "ishift")
13180    (set (attr "length")
13181      (if_then_else (match_operand 0 "register_operand" "")
13182         (const_string "2")
13183         (const_string "*")))])
13185 (define_insn "*lshrhi3_1"
13186   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13187         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13188                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13189    (clobber (reg:CC FLAGS_REG))]
13190   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13191   "@
13192    shr{w}\t{%2, %0|%0, %2}
13193    shr{w}\t{%b2, %0|%0, %b2}"
13194   [(set_attr "type" "ishift")
13195    (set_attr "mode" "HI")])
13197 ;; This pattern can't accept a variable shift count, since shifts by
13198 ;; zero don't affect the flags.  We assume that shifts by constant
13199 ;; zero are optimized away.
13200 (define_insn "*lshrhi3_one_bit_cmp"
13201   [(set (reg FLAGS_REG)
13202         (compare
13203           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13204                        (match_operand:QI 2 "const1_operand" ""))
13205           (const_int 0)))
13206    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13207         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13208   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13209    && ix86_match_ccmode (insn, CCGOCmode)
13210    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13211   "shr{w}\t%0"
13212   [(set_attr "type" "ishift")
13213    (set (attr "length")
13214      (if_then_else (match_operand:SI 0 "register_operand" "")
13215         (const_string "2")
13216         (const_string "*")))])
13218 (define_insn "*lshrhi3_one_bit_cconly"
13219   [(set (reg FLAGS_REG)
13220         (compare
13221           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13222                        (match_operand:QI 2 "const1_operand" ""))
13223           (const_int 0)))
13224    (clobber (match_scratch:HI 0 "=r"))]
13225   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13226    && ix86_match_ccmode (insn, CCGOCmode)
13227    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13228   "shr{w}\t%0"
13229   [(set_attr "type" "ishift")
13230    (set_attr "length" "2")])
13232 ;; This pattern can't accept a variable shift count, since shifts by
13233 ;; zero don't affect the flags.  We assume that shifts by constant
13234 ;; zero are optimized away.
13235 (define_insn "*lshrhi3_cmp"
13236   [(set (reg FLAGS_REG)
13237         (compare
13238           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13239                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13240           (const_int 0)))
13241    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13242         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13243   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13244    && ix86_match_ccmode (insn, CCGOCmode)
13245    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13246   "shr{w}\t{%2, %0|%0, %2}"
13247   [(set_attr "type" "ishift")
13248    (set_attr "mode" "HI")])
13250 (define_insn "*lshrhi3_cconly"
13251   [(set (reg FLAGS_REG)
13252         (compare
13253           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13254                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13255           (const_int 0)))
13256    (clobber (match_scratch:HI 0 "=r"))]
13257   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13258    && ix86_match_ccmode (insn, CCGOCmode)
13259    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13260   "shr{w}\t{%2, %0|%0, %2}"
13261   [(set_attr "type" "ishift")
13262    (set_attr "mode" "HI")])
13264 (define_expand "lshrqi3"
13265   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13266         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13267                      (match_operand:QI 2 "nonmemory_operand" "")))]
13268   "TARGET_QIMODE_MATH"
13269   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13271 (define_insn "*lshrqi3_1_one_bit"
13272   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13273         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13274                      (match_operand:QI 2 "const1_operand" "")))
13275    (clobber (reg:CC FLAGS_REG))]
13276   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13277    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13278   "shr{b}\t%0"
13279   [(set_attr "type" "ishift")
13280    (set (attr "length")
13281      (if_then_else (match_operand 0 "register_operand" "")
13282         (const_string "2")
13283         (const_string "*")))])
13285 (define_insn "*lshrqi3_1_one_bit_slp"
13286   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13287         (lshiftrt:QI (match_dup 0)
13288                      (match_operand:QI 1 "const1_operand" "")))
13289    (clobber (reg:CC FLAGS_REG))]
13290   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13291    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13292   "shr{b}\t%0"
13293   [(set_attr "type" "ishift1")
13294    (set (attr "length")
13295      (if_then_else (match_operand 0 "register_operand" "")
13296         (const_string "2")
13297         (const_string "*")))])
13299 (define_insn "*lshrqi3_1"
13300   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13301         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13302                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13303    (clobber (reg:CC FLAGS_REG))]
13304   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13305   "@
13306    shr{b}\t{%2, %0|%0, %2}
13307    shr{b}\t{%b2, %0|%0, %b2}"
13308   [(set_attr "type" "ishift")
13309    (set_attr "mode" "QI")])
13311 (define_insn "*lshrqi3_1_slp"
13312   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13313         (lshiftrt:QI (match_dup 0)
13314                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13315    (clobber (reg:CC FLAGS_REG))]
13316   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13317    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13318   "@
13319    shr{b}\t{%1, %0|%0, %1}
13320    shr{b}\t{%b1, %0|%0, %b1}"
13321   [(set_attr "type" "ishift1")
13322    (set_attr "mode" "QI")])
13324 ;; This pattern can't accept a variable shift count, since shifts by
13325 ;; zero don't affect the flags.  We assume that shifts by constant
13326 ;; zero are optimized away.
13327 (define_insn "*lshrqi2_one_bit_cmp"
13328   [(set (reg FLAGS_REG)
13329         (compare
13330           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13331                        (match_operand:QI 2 "const1_operand" ""))
13332           (const_int 0)))
13333    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13334         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13335   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13336    && ix86_match_ccmode (insn, CCGOCmode)
13337    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13338   "shr{b}\t%0"
13339   [(set_attr "type" "ishift")
13340    (set (attr "length")
13341      (if_then_else (match_operand:SI 0 "register_operand" "")
13342         (const_string "2")
13343         (const_string "*")))])
13345 (define_insn "*lshrqi2_one_bit_cconly"
13346   [(set (reg FLAGS_REG)
13347         (compare
13348           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13349                        (match_operand:QI 2 "const1_operand" ""))
13350           (const_int 0)))
13351    (clobber (match_scratch:QI 0 "=q"))]
13352   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13353    && ix86_match_ccmode (insn, CCGOCmode)
13354    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13355   "shr{b}\t%0"
13356   [(set_attr "type" "ishift")
13357    (set_attr "length" "2")])
13359 ;; This pattern can't accept a variable shift count, since shifts by
13360 ;; zero don't affect the flags.  We assume that shifts by constant
13361 ;; zero are optimized away.
13362 (define_insn "*lshrqi2_cmp"
13363   [(set (reg FLAGS_REG)
13364         (compare
13365           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13366                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13367           (const_int 0)))
13368    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13369         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13370   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13371    && ix86_match_ccmode (insn, CCGOCmode)
13372    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13373   "shr{b}\t{%2, %0|%0, %2}"
13374   [(set_attr "type" "ishift")
13375    (set_attr "mode" "QI")])
13377 (define_insn "*lshrqi2_cconly"
13378   [(set (reg FLAGS_REG)
13379         (compare
13380           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13381                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13382           (const_int 0)))
13383    (clobber (match_scratch:QI 0 "=q"))]
13384   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13385    && ix86_match_ccmode (insn, CCGOCmode)
13386    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13387   "shr{b}\t{%2, %0|%0, %2}"
13388   [(set_attr "type" "ishift")
13389    (set_attr "mode" "QI")])
13391 ;; Rotate instructions
13393 (define_expand "rotldi3"
13394   [(set (match_operand:DI 0 "shiftdi_operand" "")
13395         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13396                    (match_operand:QI 2 "nonmemory_operand" "")))]
13397  ""
13399   if (TARGET_64BIT)
13400     {
13401       ix86_expand_binary_operator (ROTATE, DImode, operands);
13402       DONE;
13403     }
13404   if (!const_1_to_31_operand (operands[2], VOIDmode))
13405     FAIL;
13406   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13407   DONE;
13410 ;; Implement rotation using two double-precision shift instructions
13411 ;; and a scratch register.
13412 (define_insn_and_split "ix86_rotldi3"
13413  [(set (match_operand:DI 0 "register_operand" "=r")
13414        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13415                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13416   (clobber (reg:CC FLAGS_REG))
13417   (clobber (match_scratch:SI 3 "=&r"))]
13418  "!TARGET_64BIT"
13419  ""
13420  "&& reload_completed"
13421  [(set (match_dup 3) (match_dup 4))
13422   (parallel
13423    [(set (match_dup 4)
13424          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13425                  (lshiftrt:SI (match_dup 5)
13426                               (minus:QI (const_int 32) (match_dup 2)))))
13427     (clobber (reg:CC FLAGS_REG))])
13428   (parallel
13429    [(set (match_dup 5)
13430          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13431                  (lshiftrt:SI (match_dup 3)
13432                               (minus:QI (const_int 32) (match_dup 2)))))
13433     (clobber (reg:CC FLAGS_REG))])]
13434  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13436 (define_insn "*rotlsi3_1_one_bit_rex64"
13437   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13438         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13439                    (match_operand:QI 2 "const1_operand" "")))
13440    (clobber (reg:CC FLAGS_REG))]
13441   "TARGET_64BIT
13442    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13443    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13444   "rol{q}\t%0"
13445   [(set_attr "type" "rotate")
13446    (set (attr "length")
13447      (if_then_else (match_operand:DI 0 "register_operand" "")
13448         (const_string "2")
13449         (const_string "*")))])
13451 (define_insn "*rotldi3_1_rex64"
13452   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13453         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13454                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13455    (clobber (reg:CC FLAGS_REG))]
13456   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13457   "@
13458    rol{q}\t{%2, %0|%0, %2}
13459    rol{q}\t{%b2, %0|%0, %b2}"
13460   [(set_attr "type" "rotate")
13461    (set_attr "mode" "DI")])
13463 (define_expand "rotlsi3"
13464   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13465         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13466                    (match_operand:QI 2 "nonmemory_operand" "")))]
13467   ""
13468   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13470 (define_insn "*rotlsi3_1_one_bit"
13471   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13472         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13473                    (match_operand:QI 2 "const1_operand" "")))
13474    (clobber (reg:CC FLAGS_REG))]
13475   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13476    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13477   "rol{l}\t%0"
13478   [(set_attr "type" "rotate")
13479    (set (attr "length")
13480      (if_then_else (match_operand:SI 0 "register_operand" "")
13481         (const_string "2")
13482         (const_string "*")))])
13484 (define_insn "*rotlsi3_1_one_bit_zext"
13485   [(set (match_operand:DI 0 "register_operand" "=r")
13486         (zero_extend:DI
13487           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13488                      (match_operand:QI 2 "const1_operand" ""))))
13489    (clobber (reg:CC FLAGS_REG))]
13490   "TARGET_64BIT
13491    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13492    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13493   "rol{l}\t%k0"
13494   [(set_attr "type" "rotate")
13495    (set_attr "length" "2")])
13497 (define_insn "*rotlsi3_1"
13498   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13499         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13500                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13501    (clobber (reg:CC FLAGS_REG))]
13502   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13503   "@
13504    rol{l}\t{%2, %0|%0, %2}
13505    rol{l}\t{%b2, %0|%0, %b2}"
13506   [(set_attr "type" "rotate")
13507    (set_attr "mode" "SI")])
13509 (define_insn "*rotlsi3_1_zext"
13510   [(set (match_operand:DI 0 "register_operand" "=r,r")
13511         (zero_extend:DI
13512           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13513                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13514    (clobber (reg:CC FLAGS_REG))]
13515   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13516   "@
13517    rol{l}\t{%2, %k0|%k0, %2}
13518    rol{l}\t{%b2, %k0|%k0, %b2}"
13519   [(set_attr "type" "rotate")
13520    (set_attr "mode" "SI")])
13522 (define_expand "rotlhi3"
13523   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13524         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13525                    (match_operand:QI 2 "nonmemory_operand" "")))]
13526   "TARGET_HIMODE_MATH"
13527   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13529 (define_insn "*rotlhi3_1_one_bit"
13530   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13531         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13532                    (match_operand:QI 2 "const1_operand" "")))
13533    (clobber (reg:CC FLAGS_REG))]
13534   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13535    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13536   "rol{w}\t%0"
13537   [(set_attr "type" "rotate")
13538    (set (attr "length")
13539      (if_then_else (match_operand 0 "register_operand" "")
13540         (const_string "2")
13541         (const_string "*")))])
13543 (define_insn "*rotlhi3_1"
13544   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13545         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13546                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13547    (clobber (reg:CC FLAGS_REG))]
13548   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13549   "@
13550    rol{w}\t{%2, %0|%0, %2}
13551    rol{w}\t{%b2, %0|%0, %b2}"
13552   [(set_attr "type" "rotate")
13553    (set_attr "mode" "HI")])
13555 (define_split
13556  [(set (match_operand:HI 0 "register_operand" "")
13557        (rotate:HI (match_dup 0) (const_int 8)))
13558   (clobber (reg:CC FLAGS_REG))]
13559  "reload_completed"
13560  [(parallel [(set (strict_low_part (match_dup 0))
13561                   (bswap:HI (match_dup 0)))
13562              (clobber (reg:CC FLAGS_REG))])]
13563  "")
13565 (define_expand "rotlqi3"
13566   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13567         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13568                    (match_operand:QI 2 "nonmemory_operand" "")))]
13569   "TARGET_QIMODE_MATH"
13570   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13572 (define_insn "*rotlqi3_1_one_bit_slp"
13573   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13574         (rotate:QI (match_dup 0)
13575                    (match_operand:QI 1 "const1_operand" "")))
13576    (clobber (reg:CC FLAGS_REG))]
13577   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13578    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13579   "rol{b}\t%0"
13580   [(set_attr "type" "rotate1")
13581    (set (attr "length")
13582      (if_then_else (match_operand 0 "register_operand" "")
13583         (const_string "2")
13584         (const_string "*")))])
13586 (define_insn "*rotlqi3_1_one_bit"
13587   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13588         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13589                    (match_operand:QI 2 "const1_operand" "")))
13590    (clobber (reg:CC FLAGS_REG))]
13591   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13592    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13593   "rol{b}\t%0"
13594   [(set_attr "type" "rotate")
13595    (set (attr "length")
13596      (if_then_else (match_operand 0 "register_operand" "")
13597         (const_string "2")
13598         (const_string "*")))])
13600 (define_insn "*rotlqi3_1_slp"
13601   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13602         (rotate:QI (match_dup 0)
13603                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13604    (clobber (reg:CC FLAGS_REG))]
13605   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13606    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13607   "@
13608    rol{b}\t{%1, %0|%0, %1}
13609    rol{b}\t{%b1, %0|%0, %b1}"
13610   [(set_attr "type" "rotate1")
13611    (set_attr "mode" "QI")])
13613 (define_insn "*rotlqi3_1"
13614   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13615         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13616                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13617    (clobber (reg:CC FLAGS_REG))]
13618   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13619   "@
13620    rol{b}\t{%2, %0|%0, %2}
13621    rol{b}\t{%b2, %0|%0, %b2}"
13622   [(set_attr "type" "rotate")
13623    (set_attr "mode" "QI")])
13625 (define_expand "rotrdi3"
13626   [(set (match_operand:DI 0 "shiftdi_operand" "")
13627         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13628                    (match_operand:QI 2 "nonmemory_operand" "")))]
13629  ""
13631   if (TARGET_64BIT)
13632     {
13633       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13634       DONE;
13635     }
13636   if (!const_1_to_31_operand (operands[2], VOIDmode))
13637     FAIL;
13638   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13639   DONE;
13642 ;; Implement rotation using two double-precision shift instructions
13643 ;; and a scratch register.
13644 (define_insn_and_split "ix86_rotrdi3"
13645  [(set (match_operand:DI 0 "register_operand" "=r")
13646        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13647                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13648   (clobber (reg:CC FLAGS_REG))
13649   (clobber (match_scratch:SI 3 "=&r"))]
13650  "!TARGET_64BIT"
13651  ""
13652  "&& reload_completed"
13653  [(set (match_dup 3) (match_dup 4))
13654   (parallel
13655    [(set (match_dup 4)
13656          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13657                  (ashift:SI (match_dup 5)
13658                             (minus:QI (const_int 32) (match_dup 2)))))
13659     (clobber (reg:CC FLAGS_REG))])
13660   (parallel
13661    [(set (match_dup 5)
13662          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13663                  (ashift:SI (match_dup 3)
13664                             (minus:QI (const_int 32) (match_dup 2)))))
13665     (clobber (reg:CC FLAGS_REG))])]
13666  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13668 (define_insn "*rotrdi3_1_one_bit_rex64"
13669   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13670         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13671                      (match_operand:QI 2 "const1_operand" "")))
13672    (clobber (reg:CC FLAGS_REG))]
13673   "TARGET_64BIT
13674    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13675    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13676   "ror{q}\t%0"
13677   [(set_attr "type" "rotate")
13678    (set (attr "length")
13679      (if_then_else (match_operand:DI 0 "register_operand" "")
13680         (const_string "2")
13681         (const_string "*")))])
13683 (define_insn "*rotrdi3_1_rex64"
13684   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13685         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13686                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13687    (clobber (reg:CC FLAGS_REG))]
13688   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13689   "@
13690    ror{q}\t{%2, %0|%0, %2}
13691    ror{q}\t{%b2, %0|%0, %b2}"
13692   [(set_attr "type" "rotate")
13693    (set_attr "mode" "DI")])
13695 (define_expand "rotrsi3"
13696   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13697         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13698                      (match_operand:QI 2 "nonmemory_operand" "")))]
13699   ""
13700   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13702 (define_insn "*rotrsi3_1_one_bit"
13703   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13704         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13705                      (match_operand:QI 2 "const1_operand" "")))
13706    (clobber (reg:CC FLAGS_REG))]
13707   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13708    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13709   "ror{l}\t%0"
13710   [(set_attr "type" "rotate")
13711    (set (attr "length")
13712      (if_then_else (match_operand:SI 0 "register_operand" "")
13713         (const_string "2")
13714         (const_string "*")))])
13716 (define_insn "*rotrsi3_1_one_bit_zext"
13717   [(set (match_operand:DI 0 "register_operand" "=r")
13718         (zero_extend:DI
13719           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13720                        (match_operand:QI 2 "const1_operand" ""))))
13721    (clobber (reg:CC FLAGS_REG))]
13722   "TARGET_64BIT
13723    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13724    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13725   "ror{l}\t%k0"
13726   [(set_attr "type" "rotate")
13727    (set (attr "length")
13728      (if_then_else (match_operand:SI 0 "register_operand" "")
13729         (const_string "2")
13730         (const_string "*")))])
13732 (define_insn "*rotrsi3_1"
13733   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13734         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13735                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13736    (clobber (reg:CC FLAGS_REG))]
13737   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13738   "@
13739    ror{l}\t{%2, %0|%0, %2}
13740    ror{l}\t{%b2, %0|%0, %b2}"
13741   [(set_attr "type" "rotate")
13742    (set_attr "mode" "SI")])
13744 (define_insn "*rotrsi3_1_zext"
13745   [(set (match_operand:DI 0 "register_operand" "=r,r")
13746         (zero_extend:DI
13747           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13748                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13749    (clobber (reg:CC FLAGS_REG))]
13750   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13751   "@
13752    ror{l}\t{%2, %k0|%k0, %2}
13753    ror{l}\t{%b2, %k0|%k0, %b2}"
13754   [(set_attr "type" "rotate")
13755    (set_attr "mode" "SI")])
13757 (define_expand "rotrhi3"
13758   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13759         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13760                      (match_operand:QI 2 "nonmemory_operand" "")))]
13761   "TARGET_HIMODE_MATH"
13762   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13764 (define_insn "*rotrhi3_one_bit"
13765   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13766         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13767                      (match_operand:QI 2 "const1_operand" "")))
13768    (clobber (reg:CC FLAGS_REG))]
13769   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13770    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13771   "ror{w}\t%0"
13772   [(set_attr "type" "rotate")
13773    (set (attr "length")
13774      (if_then_else (match_operand 0 "register_operand" "")
13775         (const_string "2")
13776         (const_string "*")))])
13778 (define_insn "*rotrhi3_1"
13779   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13780         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13781                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13782    (clobber (reg:CC FLAGS_REG))]
13783   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13784   "@
13785    ror{w}\t{%2, %0|%0, %2}
13786    ror{w}\t{%b2, %0|%0, %b2}"
13787   [(set_attr "type" "rotate")
13788    (set_attr "mode" "HI")])
13790 (define_split
13791  [(set (match_operand:HI 0 "register_operand" "")
13792        (rotatert:HI (match_dup 0) (const_int 8)))
13793   (clobber (reg:CC FLAGS_REG))]
13794  "reload_completed"
13795  [(parallel [(set (strict_low_part (match_dup 0))
13796                   (bswap:HI (match_dup 0)))
13797              (clobber (reg:CC FLAGS_REG))])]
13798  "")
13800 (define_expand "rotrqi3"
13801   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13802         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13803                      (match_operand:QI 2 "nonmemory_operand" "")))]
13804   "TARGET_QIMODE_MATH"
13805   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13807 (define_insn "*rotrqi3_1_one_bit"
13808   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13809         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13810                      (match_operand:QI 2 "const1_operand" "")))
13811    (clobber (reg:CC FLAGS_REG))]
13812   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13813    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13814   "ror{b}\t%0"
13815   [(set_attr "type" "rotate")
13816    (set (attr "length")
13817      (if_then_else (match_operand 0 "register_operand" "")
13818         (const_string "2")
13819         (const_string "*")))])
13821 (define_insn "*rotrqi3_1_one_bit_slp"
13822   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13823         (rotatert:QI (match_dup 0)
13824                      (match_operand:QI 1 "const1_operand" "")))
13825    (clobber (reg:CC FLAGS_REG))]
13826   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13827    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13828   "ror{b}\t%0"
13829   [(set_attr "type" "rotate1")
13830    (set (attr "length")
13831      (if_then_else (match_operand 0 "register_operand" "")
13832         (const_string "2")
13833         (const_string "*")))])
13835 (define_insn "*rotrqi3_1"
13836   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13837         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13838                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13839    (clobber (reg:CC FLAGS_REG))]
13840   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13841   "@
13842    ror{b}\t{%2, %0|%0, %2}
13843    ror{b}\t{%b2, %0|%0, %b2}"
13844   [(set_attr "type" "rotate")
13845    (set_attr "mode" "QI")])
13847 (define_insn "*rotrqi3_1_slp"
13848   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13849         (rotatert:QI (match_dup 0)
13850                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13851    (clobber (reg:CC FLAGS_REG))]
13852   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13853    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13854   "@
13855    ror{b}\t{%1, %0|%0, %1}
13856    ror{b}\t{%b1, %0|%0, %b1}"
13857   [(set_attr "type" "rotate1")
13858    (set_attr "mode" "QI")])
13860 ;; Bit set / bit test instructions
13862 (define_expand "extv"
13863   [(set (match_operand:SI 0 "register_operand" "")
13864         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13865                          (match_operand:SI 2 "const8_operand" "")
13866                          (match_operand:SI 3 "const8_operand" "")))]
13867   ""
13869   /* Handle extractions from %ah et al.  */
13870   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13871     FAIL;
13873   /* From mips.md: extract_bit_field doesn't verify that our source
13874      matches the predicate, so check it again here.  */
13875   if (! ext_register_operand (operands[1], VOIDmode))
13876     FAIL;
13879 (define_expand "extzv"
13880   [(set (match_operand:SI 0 "register_operand" "")
13881         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13882                          (match_operand:SI 2 "const8_operand" "")
13883                          (match_operand:SI 3 "const8_operand" "")))]
13884   ""
13886   /* Handle extractions from %ah et al.  */
13887   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13888     FAIL;
13890   /* From mips.md: extract_bit_field doesn't verify that our source
13891      matches the predicate, so check it again here.  */
13892   if (! ext_register_operand (operands[1], VOIDmode))
13893     FAIL;
13896 (define_expand "insv"
13897   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13898                       (match_operand 1 "const8_operand" "")
13899                       (match_operand 2 "const8_operand" ""))
13900         (match_operand 3 "register_operand" ""))]
13901   ""
13903   /* Handle insertions to %ah et al.  */
13904   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13905     FAIL;
13907   /* From mips.md: insert_bit_field doesn't verify that our source
13908      matches the predicate, so check it again here.  */
13909   if (! ext_register_operand (operands[0], VOIDmode))
13910     FAIL;
13912   if (TARGET_64BIT)
13913     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13914   else
13915     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13917   DONE;
13920 ;; %%% bts, btr, btc, bt.
13921 ;; In general these instructions are *slow* when applied to memory,
13922 ;; since they enforce atomic operation.  When applied to registers,
13923 ;; it depends on the cpu implementation.  They're never faster than
13924 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13925 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13926 ;; within the instruction itself, so operating on bits in the high
13927 ;; 32-bits of a register becomes easier.
13929 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13930 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13931 ;; negdf respectively, so they can never be disabled entirely.
13933 (define_insn "*btsq"
13934   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13935                          (const_int 1)
13936                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13937         (const_int 1))
13938    (clobber (reg:CC FLAGS_REG))]
13939   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13940   "bts{q}\t{%1, %0|%0, %1}"
13941   [(set_attr "type" "alu1")])
13943 (define_insn "*btrq"
13944   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13945                          (const_int 1)
13946                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13947         (const_int 0))
13948    (clobber (reg:CC FLAGS_REG))]
13949   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13950   "btr{q}\t{%1, %0|%0, %1}"
13951   [(set_attr "type" "alu1")])
13953 (define_insn "*btcq"
13954   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13955                          (const_int 1)
13956                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13957         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13958    (clobber (reg:CC FLAGS_REG))]
13959   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13960   "btc{q}\t{%1, %0|%0, %1}"
13961   [(set_attr "type" "alu1")])
13963 ;; Allow Nocona to avoid these instructions if a register is available.
13965 (define_peephole2
13966   [(match_scratch:DI 2 "r")
13967    (parallel [(set (zero_extract:DI
13968                      (match_operand:DI 0 "register_operand" "")
13969                      (const_int 1)
13970                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13971                    (const_int 1))
13972               (clobber (reg:CC FLAGS_REG))])]
13973   "TARGET_64BIT && !TARGET_USE_BT"
13974   [(const_int 0)]
13976   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13977   rtx op1;
13979   if (HOST_BITS_PER_WIDE_INT >= 64)
13980     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13981   else if (i < HOST_BITS_PER_WIDE_INT)
13982     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13983   else
13984     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13986   op1 = immed_double_const (lo, hi, DImode);
13987   if (i >= 31)
13988     {
13989       emit_move_insn (operands[2], op1);
13990       op1 = operands[2];
13991     }
13993   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13994   DONE;
13997 (define_peephole2
13998   [(match_scratch:DI 2 "r")
13999    (parallel [(set (zero_extract:DI
14000                      (match_operand:DI 0 "register_operand" "")
14001                      (const_int 1)
14002                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14003                    (const_int 0))
14004               (clobber (reg:CC FLAGS_REG))])]
14005   "TARGET_64BIT && !TARGET_USE_BT"
14006   [(const_int 0)]
14008   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14009   rtx op1;
14011   if (HOST_BITS_PER_WIDE_INT >= 64)
14012     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14013   else if (i < HOST_BITS_PER_WIDE_INT)
14014     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14015   else
14016     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14018   op1 = immed_double_const (~lo, ~hi, DImode);
14019   if (i >= 32)
14020     {
14021       emit_move_insn (operands[2], op1);
14022       op1 = operands[2];
14023     }
14025   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14026   DONE;
14029 (define_peephole2
14030   [(match_scratch:DI 2 "r")
14031    (parallel [(set (zero_extract:DI
14032                      (match_operand:DI 0 "register_operand" "")
14033                      (const_int 1)
14034                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14035               (not:DI (zero_extract:DI
14036                         (match_dup 0) (const_int 1) (match_dup 1))))
14037               (clobber (reg:CC FLAGS_REG))])]
14038   "TARGET_64BIT && !TARGET_USE_BT"
14039   [(const_int 0)]
14041   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14042   rtx op1;
14044   if (HOST_BITS_PER_WIDE_INT >= 64)
14045     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14046   else if (i < HOST_BITS_PER_WIDE_INT)
14047     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14048   else
14049     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14051   op1 = immed_double_const (lo, hi, DImode);
14052   if (i >= 31)
14053     {
14054       emit_move_insn (operands[2], op1);
14055       op1 = operands[2];
14056     }
14058   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14059   DONE;
14062 (define_insn "*btdi_rex64"
14063   [(set (reg:CCC FLAGS_REG)
14064         (compare:CCC
14065           (zero_extract:DI
14066             (match_operand:DI 0 "register_operand" "r")
14067             (const_int 1)
14068             (match_operand:DI 1 "nonmemory_operand" "rN"))
14069           (const_int 0)))]
14070   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14071   "bt{q}\t{%1, %0|%0, %1}"
14072   [(set_attr "type" "alu1")])
14074 (define_insn "*btsi"
14075   [(set (reg:CCC FLAGS_REG)
14076         (compare:CCC
14077           (zero_extract:SI
14078             (match_operand:SI 0 "register_operand" "r")
14079             (const_int 1)
14080             (match_operand:SI 1 "nonmemory_operand" "rN"))
14081           (const_int 0)))]
14082   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14083   "bt{l}\t{%1, %0|%0, %1}"
14084   [(set_attr "type" "alu1")])
14086 ;; Store-flag instructions.
14088 ;; For all sCOND expanders, also expand the compare or test insn that
14089 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
14091 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
14092 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
14093 ;; way, which can later delete the movzx if only QImode is needed.
14095 (define_expand "s<code>"
14096   [(set (match_operand:QI 0 "register_operand" "")
14097         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14098   ""
14099   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14101 (define_expand "s<code>"
14102   [(set (match_operand:QI 0 "register_operand" "")
14103         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14104   "TARGET_80387 || TARGET_SSE"
14105   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14107 (define_insn "*setcc_1"
14108   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14109         (match_operator:QI 1 "ix86_comparison_operator"
14110           [(reg FLAGS_REG) (const_int 0)]))]
14111   ""
14112   "set%C1\t%0"
14113   [(set_attr "type" "setcc")
14114    (set_attr "mode" "QI")])
14116 (define_insn "*setcc_2"
14117   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14118         (match_operator:QI 1 "ix86_comparison_operator"
14119           [(reg FLAGS_REG) (const_int 0)]))]
14120   ""
14121   "set%C1\t%0"
14122   [(set_attr "type" "setcc")
14123    (set_attr "mode" "QI")])
14125 ;; In general it is not safe to assume too much about CCmode registers,
14126 ;; so simplify-rtx stops when it sees a second one.  Under certain
14127 ;; conditions this is safe on x86, so help combine not create
14129 ;;      seta    %al
14130 ;;      testb   %al, %al
14131 ;;      sete    %al
14133 (define_split
14134   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14135         (ne:QI (match_operator 1 "ix86_comparison_operator"
14136                  [(reg FLAGS_REG) (const_int 0)])
14137             (const_int 0)))]
14138   ""
14139   [(set (match_dup 0) (match_dup 1))]
14141   PUT_MODE (operands[1], QImode);
14144 (define_split
14145   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14146         (ne:QI (match_operator 1 "ix86_comparison_operator"
14147                  [(reg FLAGS_REG) (const_int 0)])
14148             (const_int 0)))]
14149   ""
14150   [(set (match_dup 0) (match_dup 1))]
14152   PUT_MODE (operands[1], QImode);
14155 (define_split
14156   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14157         (eq:QI (match_operator 1 "ix86_comparison_operator"
14158                  [(reg FLAGS_REG) (const_int 0)])
14159             (const_int 0)))]
14160   ""
14161   [(set (match_dup 0) (match_dup 1))]
14163   rtx new_op1 = copy_rtx (operands[1]);
14164   operands[1] = new_op1;
14165   PUT_MODE (new_op1, QImode);
14166   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14167                                              GET_MODE (XEXP (new_op1, 0))));
14169   /* Make sure that (a) the CCmode we have for the flags is strong
14170      enough for the reversed compare or (b) we have a valid FP compare.  */
14171   if (! ix86_comparison_operator (new_op1, VOIDmode))
14172     FAIL;
14175 (define_split
14176   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14177         (eq:QI (match_operator 1 "ix86_comparison_operator"
14178                  [(reg FLAGS_REG) (const_int 0)])
14179             (const_int 0)))]
14180   ""
14181   [(set (match_dup 0) (match_dup 1))]
14183   rtx new_op1 = copy_rtx (operands[1]);
14184   operands[1] = new_op1;
14185   PUT_MODE (new_op1, QImode);
14186   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14187                                              GET_MODE (XEXP (new_op1, 0))));
14189   /* Make sure that (a) the CCmode we have for the flags is strong
14190      enough for the reversed compare or (b) we have a valid FP compare.  */
14191   if (! ix86_comparison_operator (new_op1, VOIDmode))
14192     FAIL;
14195 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14196 ;; subsequent logical operations are used to imitate conditional moves.
14197 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14198 ;; it directly.
14200 (define_insn "*avx_setcc<mode>"
14201   [(set (match_operand:MODEF 0 "register_operand" "=x")
14202         (match_operator:MODEF 1 "avx_comparison_float_operator"
14203           [(match_operand:MODEF 2 "register_operand" "x")
14204            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14205   "TARGET_AVX"
14206   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14207   [(set_attr "type" "ssecmp")
14208    (set_attr "prefix" "vex")
14209    (set_attr "mode" "<MODE>")])
14211 (define_insn "*sse_setcc<mode>"
14212   [(set (match_operand:MODEF 0 "register_operand" "=x")
14213         (match_operator:MODEF 1 "sse_comparison_operator"
14214           [(match_operand:MODEF 2 "register_operand" "0")
14215            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14216   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14217   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14218   [(set_attr "type" "ssecmp")
14219    (set_attr "mode" "<MODE>")])
14221 (define_insn "*sse5_setcc<mode>"
14222   [(set (match_operand:MODEF 0 "register_operand" "=x")
14223         (match_operator:MODEF 1 "sse5_comparison_float_operator"
14224           [(match_operand:MODEF 2 "register_operand" "x")
14225            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14226   "TARGET_SSE5"
14227   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14228   [(set_attr "type" "sse4arg")
14229    (set_attr "mode" "<MODE>")])
14232 ;; Basic conditional jump instructions.
14233 ;; We ignore the overflow flag for signed branch instructions.
14235 ;; For all bCOND expanders, also expand the compare or test insn that
14236 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
14238 (define_expand "b<code>"
14239   [(set (pc)
14240         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14241                                    (const_int 0))
14242                       (label_ref (match_operand 0 ""))
14243                       (pc)))]
14244   ""
14245   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14247 (define_expand "b<code>"
14248   [(set (pc)
14249         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14250                                   (const_int 0))
14251                       (label_ref (match_operand 0 ""))
14252                       (pc)))]
14253   "TARGET_80387 || TARGET_SSE_MATH"
14254   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14256 (define_insn "*jcc_1"
14257   [(set (pc)
14258         (if_then_else (match_operator 1 "ix86_comparison_operator"
14259                                       [(reg FLAGS_REG) (const_int 0)])
14260                       (label_ref (match_operand 0 "" ""))
14261                       (pc)))]
14262   ""
14263   "%+j%C1\t%l0"
14264   [(set_attr "type" "ibr")
14265    (set_attr "modrm" "0")
14266    (set (attr "length")
14267            (if_then_else (and (ge (minus (match_dup 0) (pc))
14268                                   (const_int -126))
14269                               (lt (minus (match_dup 0) (pc))
14270                                   (const_int 128)))
14271              (const_int 2)
14272              (const_int 6)))])
14274 (define_insn "*jcc_2"
14275   [(set (pc)
14276         (if_then_else (match_operator 1 "ix86_comparison_operator"
14277                                       [(reg FLAGS_REG) (const_int 0)])
14278                       (pc)
14279                       (label_ref (match_operand 0 "" ""))))]
14280   ""
14281   "%+j%c1\t%l0"
14282   [(set_attr "type" "ibr")
14283    (set_attr "modrm" "0")
14284    (set (attr "length")
14285            (if_then_else (and (ge (minus (match_dup 0) (pc))
14286                                   (const_int -126))
14287                               (lt (minus (match_dup 0) (pc))
14288                                   (const_int 128)))
14289              (const_int 2)
14290              (const_int 6)))])
14292 ;; In general it is not safe to assume too much about CCmode registers,
14293 ;; so simplify-rtx stops when it sees a second one.  Under certain
14294 ;; conditions this is safe on x86, so help combine not create
14296 ;;      seta    %al
14297 ;;      testb   %al, %al
14298 ;;      je      Lfoo
14300 (define_split
14301   [(set (pc)
14302         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14303                                       [(reg FLAGS_REG) (const_int 0)])
14304                           (const_int 0))
14305                       (label_ref (match_operand 1 "" ""))
14306                       (pc)))]
14307   ""
14308   [(set (pc)
14309         (if_then_else (match_dup 0)
14310                       (label_ref (match_dup 1))
14311                       (pc)))]
14313   PUT_MODE (operands[0], VOIDmode);
14316 (define_split
14317   [(set (pc)
14318         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14319                                       [(reg FLAGS_REG) (const_int 0)])
14320                           (const_int 0))
14321                       (label_ref (match_operand 1 "" ""))
14322                       (pc)))]
14323   ""
14324   [(set (pc)
14325         (if_then_else (match_dup 0)
14326                       (label_ref (match_dup 1))
14327                       (pc)))]
14329   rtx new_op0 = copy_rtx (operands[0]);
14330   operands[0] = new_op0;
14331   PUT_MODE (new_op0, VOIDmode);
14332   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14333                                              GET_MODE (XEXP (new_op0, 0))));
14335   /* Make sure that (a) the CCmode we have for the flags is strong
14336      enough for the reversed compare or (b) we have a valid FP compare.  */
14337   if (! ix86_comparison_operator (new_op0, VOIDmode))
14338     FAIL;
14341 ;; zero_extend in SImode is correct, since this is what combine pass
14342 ;; generates from shift insn with QImode operand.  Actually, the mode of
14343 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14344 ;; appropriate modulo of the bit offset value.
14346 (define_insn_and_split "*jcc_btdi_rex64"
14347   [(set (pc)
14348         (if_then_else (match_operator 0 "bt_comparison_operator"
14349                         [(zero_extract:DI
14350                            (match_operand:DI 1 "register_operand" "r")
14351                            (const_int 1)
14352                            (zero_extend:SI
14353                              (match_operand:QI 2 "register_operand" "r")))
14354                          (const_int 0)])
14355                       (label_ref (match_operand 3 "" ""))
14356                       (pc)))
14357    (clobber (reg:CC FLAGS_REG))]
14358   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14359   "#"
14360   "&& 1"
14361   [(set (reg:CCC FLAGS_REG)
14362         (compare:CCC
14363           (zero_extract:DI
14364             (match_dup 1)
14365             (const_int 1)
14366             (match_dup 2))
14367           (const_int 0)))
14368    (set (pc)
14369         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14370                       (label_ref (match_dup 3))
14371                       (pc)))]
14373   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14375   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14378 ;; avoid useless masking of bit offset operand
14379 (define_insn_and_split "*jcc_btdi_mask_rex64"
14380   [(set (pc)
14381         (if_then_else (match_operator 0 "bt_comparison_operator"
14382                         [(zero_extract:DI
14383                            (match_operand:DI 1 "register_operand" "r")
14384                            (const_int 1)
14385                            (and:SI
14386                              (match_operand:SI 2 "register_operand" "r")
14387                              (match_operand:SI 3 "const_int_operand" "n")))])
14388                       (label_ref (match_operand 4 "" ""))
14389                       (pc)))
14390    (clobber (reg:CC FLAGS_REG))]
14391   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14392    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14393   "#"
14394   "&& 1"
14395   [(set (reg:CCC FLAGS_REG)
14396         (compare:CCC
14397           (zero_extract:DI
14398             (match_dup 1)
14399             (const_int 1)
14400             (match_dup 2))
14401           (const_int 0)))
14402    (set (pc)
14403         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14404                       (label_ref (match_dup 4))
14405                       (pc)))]
14407   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14409   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14412 (define_insn_and_split "*jcc_btsi"
14413   [(set (pc)
14414         (if_then_else (match_operator 0 "bt_comparison_operator"
14415                         [(zero_extract:SI
14416                            (match_operand:SI 1 "register_operand" "r")
14417                            (const_int 1)
14418                            (zero_extend:SI
14419                              (match_operand:QI 2 "register_operand" "r")))
14420                          (const_int 0)])
14421                       (label_ref (match_operand 3 "" ""))
14422                       (pc)))
14423    (clobber (reg:CC FLAGS_REG))]
14424   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14425   "#"
14426   "&& 1"
14427   [(set (reg:CCC FLAGS_REG)
14428         (compare:CCC
14429           (zero_extract:SI
14430             (match_dup 1)
14431             (const_int 1)
14432             (match_dup 2))
14433           (const_int 0)))
14434    (set (pc)
14435         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14436                       (label_ref (match_dup 3))
14437                       (pc)))]
14439   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14441   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14444 ;; avoid useless masking of bit offset operand
14445 (define_insn_and_split "*jcc_btsi_mask"
14446   [(set (pc)
14447         (if_then_else (match_operator 0 "bt_comparison_operator"
14448                         [(zero_extract:SI
14449                            (match_operand:SI 1 "register_operand" "r")
14450                            (const_int 1)
14451                            (and:SI
14452                              (match_operand:SI 2 "register_operand" "r")
14453                              (match_operand:SI 3 "const_int_operand" "n")))])
14454                       (label_ref (match_operand 4 "" ""))
14455                       (pc)))
14456    (clobber (reg:CC FLAGS_REG))]
14457   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14458    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14459   "#"
14460   "&& 1"
14461   [(set (reg:CCC FLAGS_REG)
14462         (compare:CCC
14463           (zero_extract:SI
14464             (match_dup 1)
14465             (const_int 1)
14466             (match_dup 2))
14467           (const_int 0)))
14468    (set (pc)
14469         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14470                       (label_ref (match_dup 4))
14471                       (pc)))]
14472   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14474 (define_insn_and_split "*jcc_btsi_1"
14475   [(set (pc)
14476         (if_then_else (match_operator 0 "bt_comparison_operator"
14477                         [(and:SI
14478                            (lshiftrt:SI
14479                              (match_operand:SI 1 "register_operand" "r")
14480                              (match_operand:QI 2 "register_operand" "r"))
14481                            (const_int 1))
14482                          (const_int 0)])
14483                       (label_ref (match_operand 3 "" ""))
14484                       (pc)))
14485    (clobber (reg:CC FLAGS_REG))]
14486   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14487   "#"
14488   "&& 1"
14489   [(set (reg:CCC FLAGS_REG)
14490         (compare:CCC
14491           (zero_extract:SI
14492             (match_dup 1)
14493             (const_int 1)
14494             (match_dup 2))
14495           (const_int 0)))
14496    (set (pc)
14497         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14498                       (label_ref (match_dup 3))
14499                       (pc)))]
14501   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14503   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14506 ;; avoid useless masking of bit offset operand
14507 (define_insn_and_split "*jcc_btsi_mask_1"
14508   [(set (pc)
14509         (if_then_else
14510           (match_operator 0 "bt_comparison_operator"
14511             [(and:SI
14512                (lshiftrt:SI
14513                  (match_operand:SI 1 "register_operand" "r")
14514                  (subreg:QI
14515                    (and:SI
14516                      (match_operand:SI 2 "register_operand" "r")
14517                      (match_operand:SI 3 "const_int_operand" "n")) 0))
14518                (const_int 1))
14519              (const_int 0)])
14520           (label_ref (match_operand 4 "" ""))
14521           (pc)))
14522    (clobber (reg:CC FLAGS_REG))]
14523   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14524    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14525   "#"
14526   "&& 1"
14527   [(set (reg:CCC FLAGS_REG)
14528         (compare:CCC
14529           (zero_extract:SI
14530             (match_dup 1)
14531             (const_int 1)
14532             (match_dup 2))
14533           (const_int 0)))
14534    (set (pc)
14535         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14536                       (label_ref (match_dup 4))
14537                       (pc)))]
14538   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14540 ;; Define combination compare-and-branch fp compare instructions to use
14541 ;; during early optimization.  Splitting the operation apart early makes
14542 ;; for bad code when we want to reverse the operation.
14544 (define_insn "*fp_jcc_1_mixed"
14545   [(set (pc)
14546         (if_then_else (match_operator 0 "comparison_operator"
14547                         [(match_operand 1 "register_operand" "f,x")
14548                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14549           (label_ref (match_operand 3 "" ""))
14550           (pc)))
14551    (clobber (reg:CCFP FPSR_REG))
14552    (clobber (reg:CCFP FLAGS_REG))]
14553   "TARGET_MIX_SSE_I387
14554    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14555    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14556    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14557   "#")
14559 (define_insn "*fp_jcc_1_sse"
14560   [(set (pc)
14561         (if_then_else (match_operator 0 "comparison_operator"
14562                         [(match_operand 1 "register_operand" "x")
14563                          (match_operand 2 "nonimmediate_operand" "xm")])
14564           (label_ref (match_operand 3 "" ""))
14565           (pc)))
14566    (clobber (reg:CCFP FPSR_REG))
14567    (clobber (reg:CCFP FLAGS_REG))]
14568   "TARGET_SSE_MATH
14569    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14570    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14571    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14572   "#")
14574 (define_insn "*fp_jcc_1_387"
14575   [(set (pc)
14576         (if_then_else (match_operator 0 "comparison_operator"
14577                         [(match_operand 1 "register_operand" "f")
14578                          (match_operand 2 "register_operand" "f")])
14579           (label_ref (match_operand 3 "" ""))
14580           (pc)))
14581    (clobber (reg:CCFP FPSR_REG))
14582    (clobber (reg:CCFP FLAGS_REG))]
14583   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14584    && TARGET_CMOVE
14585    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14586    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14587   "#")
14589 (define_insn "*fp_jcc_2_mixed"
14590   [(set (pc)
14591         (if_then_else (match_operator 0 "comparison_operator"
14592                         [(match_operand 1 "register_operand" "f,x")
14593                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14594           (pc)
14595           (label_ref (match_operand 3 "" ""))))
14596    (clobber (reg:CCFP FPSR_REG))
14597    (clobber (reg:CCFP FLAGS_REG))]
14598   "TARGET_MIX_SSE_I387
14599    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14600    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14601    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14602   "#")
14604 (define_insn "*fp_jcc_2_sse"
14605   [(set (pc)
14606         (if_then_else (match_operator 0 "comparison_operator"
14607                         [(match_operand 1 "register_operand" "x")
14608                          (match_operand 2 "nonimmediate_operand" "xm")])
14609           (pc)
14610           (label_ref (match_operand 3 "" ""))))
14611    (clobber (reg:CCFP FPSR_REG))
14612    (clobber (reg:CCFP FLAGS_REG))]
14613   "TARGET_SSE_MATH
14614    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14615    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14616    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14617   "#")
14619 (define_insn "*fp_jcc_2_387"
14620   [(set (pc)
14621         (if_then_else (match_operator 0 "comparison_operator"
14622                         [(match_operand 1 "register_operand" "f")
14623                          (match_operand 2 "register_operand" "f")])
14624           (pc)
14625           (label_ref (match_operand 3 "" ""))))
14626    (clobber (reg:CCFP FPSR_REG))
14627    (clobber (reg:CCFP FLAGS_REG))]
14628   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14629    && TARGET_CMOVE
14630    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14631    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14632   "#")
14634 (define_insn "*fp_jcc_3_387"
14635   [(set (pc)
14636         (if_then_else (match_operator 0 "comparison_operator"
14637                         [(match_operand 1 "register_operand" "f")
14638                          (match_operand 2 "nonimmediate_operand" "fm")])
14639           (label_ref (match_operand 3 "" ""))
14640           (pc)))
14641    (clobber (reg:CCFP FPSR_REG))
14642    (clobber (reg:CCFP FLAGS_REG))
14643    (clobber (match_scratch:HI 4 "=a"))]
14644   "TARGET_80387
14645    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14646    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14647    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14648    && SELECT_CC_MODE (GET_CODE (operands[0]),
14649                       operands[1], operands[2]) == CCFPmode
14650    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14651   "#")
14653 (define_insn "*fp_jcc_4_387"
14654   [(set (pc)
14655         (if_then_else (match_operator 0 "comparison_operator"
14656                         [(match_operand 1 "register_operand" "f")
14657                          (match_operand 2 "nonimmediate_operand" "fm")])
14658           (pc)
14659           (label_ref (match_operand 3 "" ""))))
14660    (clobber (reg:CCFP FPSR_REG))
14661    (clobber (reg:CCFP FLAGS_REG))
14662    (clobber (match_scratch:HI 4 "=a"))]
14663   "TARGET_80387
14664    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14665    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14666    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14667    && SELECT_CC_MODE (GET_CODE (operands[0]),
14668                       operands[1], operands[2]) == CCFPmode
14669    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14670   "#")
14672 (define_insn "*fp_jcc_5_387"
14673   [(set (pc)
14674         (if_then_else (match_operator 0 "comparison_operator"
14675                         [(match_operand 1 "register_operand" "f")
14676                          (match_operand 2 "register_operand" "f")])
14677           (label_ref (match_operand 3 "" ""))
14678           (pc)))
14679    (clobber (reg:CCFP FPSR_REG))
14680    (clobber (reg:CCFP FLAGS_REG))
14681    (clobber (match_scratch:HI 4 "=a"))]
14682   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14683    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14684    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14685   "#")
14687 (define_insn "*fp_jcc_6_387"
14688   [(set (pc)
14689         (if_then_else (match_operator 0 "comparison_operator"
14690                         [(match_operand 1 "register_operand" "f")
14691                          (match_operand 2 "register_operand" "f")])
14692           (pc)
14693           (label_ref (match_operand 3 "" ""))))
14694    (clobber (reg:CCFP FPSR_REG))
14695    (clobber (reg:CCFP FLAGS_REG))
14696    (clobber (match_scratch:HI 4 "=a"))]
14697   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14698    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14699    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14700   "#")
14702 (define_insn "*fp_jcc_7_387"
14703   [(set (pc)
14704         (if_then_else (match_operator 0 "comparison_operator"
14705                         [(match_operand 1 "register_operand" "f")
14706                          (match_operand 2 "const0_operand" "")])
14707           (label_ref (match_operand 3 "" ""))
14708           (pc)))
14709    (clobber (reg:CCFP FPSR_REG))
14710    (clobber (reg:CCFP FLAGS_REG))
14711    (clobber (match_scratch:HI 4 "=a"))]
14712   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14713    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14714    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14715    && SELECT_CC_MODE (GET_CODE (operands[0]),
14716                       operands[1], operands[2]) == CCFPmode
14717    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14718   "#")
14720 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14721 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14722 ;; with a precedence over other operators and is always put in the first
14723 ;; place. Swap condition and operands to match ficom instruction.
14725 (define_insn "*fp_jcc_8<mode>_387"
14726   [(set (pc)
14727         (if_then_else (match_operator 0 "comparison_operator"
14728                         [(match_operator 1 "float_operator"
14729                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14730                            (match_operand 3 "register_operand" "f,f")])
14731           (label_ref (match_operand 4 "" ""))
14732           (pc)))
14733    (clobber (reg:CCFP FPSR_REG))
14734    (clobber (reg:CCFP FLAGS_REG))
14735    (clobber (match_scratch:HI 5 "=a,a"))]
14736   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14737    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14738    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14739    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14740    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14741    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14742   "#")
14744 (define_split
14745   [(set (pc)
14746         (if_then_else (match_operator 0 "comparison_operator"
14747                         [(match_operand 1 "register_operand" "")
14748                          (match_operand 2 "nonimmediate_operand" "")])
14749           (match_operand 3 "" "")
14750           (match_operand 4 "" "")))
14751    (clobber (reg:CCFP FPSR_REG))
14752    (clobber (reg:CCFP FLAGS_REG))]
14753   "reload_completed"
14754   [(const_int 0)]
14756   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14757                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14758   DONE;
14761 (define_split
14762   [(set (pc)
14763         (if_then_else (match_operator 0 "comparison_operator"
14764                         [(match_operand 1 "register_operand" "")
14765                          (match_operand 2 "general_operand" "")])
14766           (match_operand 3 "" "")
14767           (match_operand 4 "" "")))
14768    (clobber (reg:CCFP FPSR_REG))
14769    (clobber (reg:CCFP FLAGS_REG))
14770    (clobber (match_scratch:HI 5 "=a"))]
14771   "reload_completed"
14772   [(const_int 0)]
14774   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14775                         operands[3], operands[4], operands[5], NULL_RTX);
14776   DONE;
14779 (define_split
14780   [(set (pc)
14781         (if_then_else (match_operator 0 "comparison_operator"
14782                         [(match_operator 1 "float_operator"
14783                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14784                            (match_operand 3 "register_operand" "")])
14785           (match_operand 4 "" "")
14786           (match_operand 5 "" "")))
14787    (clobber (reg:CCFP FPSR_REG))
14788    (clobber (reg:CCFP FLAGS_REG))
14789    (clobber (match_scratch:HI 6 "=a"))]
14790   "reload_completed"
14791   [(const_int 0)]
14793   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14794   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14795                         operands[3], operands[7],
14796                         operands[4], operands[5], operands[6], NULL_RTX);
14797   DONE;
14800 ;; %%% Kill this when reload knows how to do it.
14801 (define_split
14802   [(set (pc)
14803         (if_then_else (match_operator 0 "comparison_operator"
14804                         [(match_operator 1 "float_operator"
14805                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14806                            (match_operand 3 "register_operand" "")])
14807           (match_operand 4 "" "")
14808           (match_operand 5 "" "")))
14809    (clobber (reg:CCFP FPSR_REG))
14810    (clobber (reg:CCFP FLAGS_REG))
14811    (clobber (match_scratch:HI 6 "=a"))]
14812   "reload_completed"
14813   [(const_int 0)]
14815   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14816   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14817   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14818                         operands[3], operands[7],
14819                         operands[4], operands[5], operands[6], operands[2]);
14820   DONE;
14823 ;; Unconditional and other jump instructions
14825 (define_insn "jump"
14826   [(set (pc)
14827         (label_ref (match_operand 0 "" "")))]
14828   ""
14829   "jmp\t%l0"
14830   [(set_attr "type" "ibr")
14831    (set (attr "length")
14832            (if_then_else (and (ge (minus (match_dup 0) (pc))
14833                                   (const_int -126))
14834                               (lt (minus (match_dup 0) (pc))
14835                                   (const_int 128)))
14836              (const_int 2)
14837              (const_int 5)))
14838    (set_attr "modrm" "0")])
14840 (define_expand "indirect_jump"
14841   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14842   ""
14843   "")
14845 (define_insn "*indirect_jump"
14846   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14847   ""
14848   "jmp\t%A0"
14849   [(set_attr "type" "ibr")
14850    (set_attr "length_immediate" "0")])
14852 (define_expand "tablejump"
14853   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14854               (use (label_ref (match_operand 1 "" "")))])]
14855   ""
14857   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14858      relative.  Convert the relative address to an absolute address.  */
14859   if (flag_pic)
14860     {
14861       rtx op0, op1;
14862       enum rtx_code code;
14864       /* We can't use @GOTOFF for text labels on VxWorks;
14865          see gotoff_operand.  */
14866       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14867         {
14868           code = PLUS;
14869           op0 = operands[0];
14870           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14871         }
14872       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14873         {
14874           code = PLUS;
14875           op0 = operands[0];
14876           op1 = pic_offset_table_rtx;
14877         }
14878       else
14879         {
14880           code = MINUS;
14881           op0 = pic_offset_table_rtx;
14882           op1 = operands[0];
14883         }
14885       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14886                                          OPTAB_DIRECT);
14887     }
14890 (define_insn "*tablejump_1"
14891   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14892    (use (label_ref (match_operand 1 "" "")))]
14893   ""
14894   "jmp\t%A0"
14895   [(set_attr "type" "ibr")
14896    (set_attr "length_immediate" "0")])
14898 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14900 (define_peephole2
14901   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14902    (set (match_operand:QI 1 "register_operand" "")
14903         (match_operator:QI 2 "ix86_comparison_operator"
14904           [(reg FLAGS_REG) (const_int 0)]))
14905    (set (match_operand 3 "q_regs_operand" "")
14906         (zero_extend (match_dup 1)))]
14907   "(peep2_reg_dead_p (3, operands[1])
14908     || operands_match_p (operands[1], operands[3]))
14909    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14910   [(set (match_dup 4) (match_dup 0))
14911    (set (strict_low_part (match_dup 5))
14912         (match_dup 2))]
14914   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14915   operands[5] = gen_lowpart (QImode, operands[3]);
14916   ix86_expand_clear (operands[3]);
14919 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14921 (define_peephole2
14922   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14923    (set (match_operand:QI 1 "register_operand" "")
14924         (match_operator:QI 2 "ix86_comparison_operator"
14925           [(reg FLAGS_REG) (const_int 0)]))
14926    (parallel [(set (match_operand 3 "q_regs_operand" "")
14927                    (zero_extend (match_dup 1)))
14928               (clobber (reg:CC FLAGS_REG))])]
14929   "(peep2_reg_dead_p (3, operands[1])
14930     || operands_match_p (operands[1], operands[3]))
14931    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14932   [(set (match_dup 4) (match_dup 0))
14933    (set (strict_low_part (match_dup 5))
14934         (match_dup 2))]
14936   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14937   operands[5] = gen_lowpart (QImode, operands[3]);
14938   ix86_expand_clear (operands[3]);
14941 ;; Call instructions.
14943 ;; The predicates normally associated with named expanders are not properly
14944 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14945 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14947 ;; Call subroutine returning no value.
14949 (define_expand "call_pop"
14950   [(parallel [(call (match_operand:QI 0 "" "")
14951                     (match_operand:SI 1 "" ""))
14952               (set (reg:SI SP_REG)
14953                    (plus:SI (reg:SI SP_REG)
14954                             (match_operand:SI 3 "" "")))])]
14955   "!TARGET_64BIT"
14957   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14958   DONE;
14961 (define_insn "*call_pop_0"
14962   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14963          (match_operand:SI 1 "" ""))
14964    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14965                             (match_operand:SI 2 "immediate_operand" "")))]
14966   "!TARGET_64BIT"
14968   if (SIBLING_CALL_P (insn))
14969     return "jmp\t%P0";
14970   else
14971     return "call\t%P0";
14973   [(set_attr "type" "call")])
14975 (define_insn "*call_pop_1"
14976   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14977          (match_operand:SI 1 "" ""))
14978    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14979                             (match_operand:SI 2 "immediate_operand" "i")))]
14980   "!TARGET_64BIT"
14982   if (constant_call_address_operand (operands[0], Pmode))
14983     {
14984       if (SIBLING_CALL_P (insn))
14985         return "jmp\t%P0";
14986       else
14987         return "call\t%P0";
14988     }
14989   if (SIBLING_CALL_P (insn))
14990     return "jmp\t%A0";
14991   else
14992     return "call\t%A0";
14994   [(set_attr "type" "call")])
14996 (define_expand "call"
14997   [(call (match_operand:QI 0 "" "")
14998          (match_operand 1 "" ""))
14999    (use (match_operand 2 "" ""))]
15000   ""
15002   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15003   DONE;
15006 (define_expand "sibcall"
15007   [(call (match_operand:QI 0 "" "")
15008          (match_operand 1 "" ""))
15009    (use (match_operand 2 "" ""))]
15010   ""
15012   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15013   DONE;
15016 (define_insn "*call_0"
15017   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15018          (match_operand 1 "" ""))]
15019   ""
15021   if (SIBLING_CALL_P (insn))
15022     return "jmp\t%P0";
15023   else
15024     return "call\t%P0";
15026   [(set_attr "type" "call")])
15028 (define_insn "*call_1"
15029   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15030          (match_operand 1 "" ""))]
15031   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15033   if (constant_call_address_operand (operands[0], Pmode))
15034     return "call\t%P0";
15035   return "call\t%A0";
15037   [(set_attr "type" "call")])
15039 (define_insn "*sibcall_1"
15040   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15041          (match_operand 1 "" ""))]
15042   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15044   if (constant_call_address_operand (operands[0], Pmode))
15045     return "jmp\t%P0";
15046   return "jmp\t%A0";
15048   [(set_attr "type" "call")])
15050 (define_insn "*call_1_rex64"
15051   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15052          (match_operand 1 "" ""))]
15053   "!SIBLING_CALL_P (insn) && TARGET_64BIT
15054    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15056   if (constant_call_address_operand (operands[0], Pmode))
15057     return "call\t%P0";
15058   return "call\t%A0";
15060   [(set_attr "type" "call")])
15062 (define_insn "*call_1_rex64_ms_sysv"
15063   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15064          (match_operand 1 "" ""))
15065    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15066    (clobber (reg:TI XMM6_REG))
15067    (clobber (reg:TI XMM7_REG))
15068    (clobber (reg:TI XMM8_REG))
15069    (clobber (reg:TI XMM9_REG))
15070    (clobber (reg:TI XMM10_REG))
15071    (clobber (reg:TI XMM11_REG))
15072    (clobber (reg:TI XMM12_REG))
15073    (clobber (reg:TI XMM13_REG))
15074    (clobber (reg:TI XMM14_REG))
15075    (clobber (reg:TI XMM15_REG))
15076    (clobber (reg:DI SI_REG))
15077    (clobber (reg:DI DI_REG))]
15078   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15080   if (constant_call_address_operand (operands[0], Pmode))
15081     return "call\t%P0";
15082   return "call\t%A0";
15084   [(set_attr "type" "call")])
15086 (define_insn "*call_1_rex64_large"
15087   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15088          (match_operand 1 "" ""))]
15089   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15090   "call\t%A0"
15091   [(set_attr "type" "call")])
15093 (define_insn "*sibcall_1_rex64"
15094   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15095          (match_operand 1 "" ""))]
15096   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15097   "jmp\t%P0"
15098   [(set_attr "type" "call")])
15100 (define_insn "*sibcall_1_rex64_v"
15101   [(call (mem:QI (reg:DI R11_REG))
15102          (match_operand 0 "" ""))]
15103   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15104   "jmp\t{*%%}r11"
15105   [(set_attr "type" "call")])
15108 ;; Call subroutine, returning value in operand 0
15110 (define_expand "call_value_pop"
15111   [(parallel [(set (match_operand 0 "" "")
15112                    (call (match_operand:QI 1 "" "")
15113                          (match_operand:SI 2 "" "")))
15114               (set (reg:SI SP_REG)
15115                    (plus:SI (reg:SI SP_REG)
15116                             (match_operand:SI 4 "" "")))])]
15117   "!TARGET_64BIT"
15119   ix86_expand_call (operands[0], operands[1], operands[2],
15120                     operands[3], operands[4], 0);
15121   DONE;
15124 (define_expand "call_value"
15125   [(set (match_operand 0 "" "")
15126         (call (match_operand:QI 1 "" "")
15127               (match_operand:SI 2 "" "")))
15128    (use (match_operand:SI 3 "" ""))]
15129   ;; Operand 2 not used on the i386.
15130   ""
15132   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15133   DONE;
15136 (define_expand "sibcall_value"
15137   [(set (match_operand 0 "" "")
15138         (call (match_operand:QI 1 "" "")
15139               (match_operand:SI 2 "" "")))
15140    (use (match_operand:SI 3 "" ""))]
15141   ;; Operand 2 not used on the i386.
15142   ""
15144   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15145   DONE;
15148 ;; Call subroutine returning any type.
15150 (define_expand "untyped_call"
15151   [(parallel [(call (match_operand 0 "" "")
15152                     (const_int 0))
15153               (match_operand 1 "" "")
15154               (match_operand 2 "" "")])]
15155   ""
15157   int i;
15159   /* In order to give reg-stack an easier job in validating two
15160      coprocessor registers as containing a possible return value,
15161      simply pretend the untyped call returns a complex long double
15162      value.  */
15164   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15165                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15166                     operands[0], const0_rtx,
15167                     GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
15168                                                       : X64_SSE_REGPARM_MAX)
15169                              - 1),
15170                     NULL, 0);
15172   for (i = 0; i < XVECLEN (operands[2], 0); i++)
15173     {
15174       rtx set = XVECEXP (operands[2], 0, i);
15175       emit_move_insn (SET_DEST (set), SET_SRC (set));
15176     }
15178   /* The optimizer does not know that the call sets the function value
15179      registers we stored in the result block.  We avoid problems by
15180      claiming that all hard registers are used and clobbered at this
15181      point.  */
15182   emit_insn (gen_blockage ());
15184   DONE;
15187 ;; Prologue and epilogue instructions
15189 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15190 ;; all of memory.  This blocks insns from being moved across this point.
15192 (define_insn "blockage"
15193   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15194   ""
15195   ""
15196   [(set_attr "length" "0")])
15198 ;; Do not schedule instructions accessing memory across this point.
15200 (define_expand "memory_blockage"
15201   [(set (match_dup 0)
15202         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15203   ""
15205   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15206   MEM_VOLATILE_P (operands[0]) = 1;
15209 (define_insn "*memory_blockage"
15210   [(set (match_operand:BLK 0 "" "")
15211         (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15212   ""
15213   ""
15214   [(set_attr "length" "0")])
15216 ;; As USE insns aren't meaningful after reload, this is used instead
15217 ;; to prevent deleting instructions setting registers for PIC code
15218 (define_insn "prologue_use"
15219   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15220   ""
15221   ""
15222   [(set_attr "length" "0")])
15224 ;; Insn emitted into the body of a function to return from a function.
15225 ;; This is only done if the function's epilogue is known to be simple.
15226 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15228 (define_expand "return"
15229   [(return)]
15230   "ix86_can_use_return_insn_p ()"
15232   if (crtl->args.pops_args)
15233     {
15234       rtx popc = GEN_INT (crtl->args.pops_args);
15235       emit_jump_insn (gen_return_pop_internal (popc));
15236       DONE;
15237     }
15240 (define_insn "return_internal"
15241   [(return)]
15242   "reload_completed"
15243   "ret"
15244   [(set_attr "length" "1")
15245    (set_attr "length_immediate" "0")
15246    (set_attr "modrm" "0")])
15248 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15249 ;; instruction Athlon and K8 have.
15251 (define_insn "return_internal_long"
15252   [(return)
15253    (unspec [(const_int 0)] UNSPEC_REP)]
15254   "reload_completed"
15255   "rep\;ret"
15256   [(set_attr "length" "1")
15257    (set_attr "length_immediate" "0")
15258    (set_attr "prefix_rep" "1")
15259    (set_attr "modrm" "0")])
15261 (define_insn "return_pop_internal"
15262   [(return)
15263    (use (match_operand:SI 0 "const_int_operand" ""))]
15264   "reload_completed"
15265   "ret\t%0"
15266   [(set_attr "length" "3")
15267    (set_attr "length_immediate" "2")
15268    (set_attr "modrm" "0")])
15270 (define_insn "return_indirect_internal"
15271   [(return)
15272    (use (match_operand:SI 0 "register_operand" "r"))]
15273   "reload_completed"
15274   "jmp\t%A0"
15275   [(set_attr "type" "ibr")
15276    (set_attr "length_immediate" "0")])
15278 (define_insn "nop"
15279   [(const_int 0)]
15280   ""
15281   "nop"
15282   [(set_attr "length" "1")
15283    (set_attr "length_immediate" "0")
15284    (set_attr "modrm" "0")])
15286 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
15287 ;; branch prediction penalty for the third jump in a 16-byte
15288 ;; block on K8.
15290 (define_insn "align"
15291   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15292   ""
15294 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15295   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15296 #else
15297   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15298      The align insn is used to avoid 3 jump instructions in the row to improve
15299      branch prediction and the benefits hardly outweigh the cost of extra 8
15300      nops on the average inserted by full alignment pseudo operation.  */
15301 #endif
15302   return "";
15304   [(set_attr "length" "16")])
15306 (define_expand "prologue"
15307   [(const_int 0)]
15308   ""
15309   "ix86_expand_prologue (); DONE;")
15311 (define_insn "set_got"
15312   [(set (match_operand:SI 0 "register_operand" "=r")
15313         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15314    (clobber (reg:CC FLAGS_REG))]
15315   "!TARGET_64BIT"
15316   { return output_set_got (operands[0], NULL_RTX); }
15317   [(set_attr "type" "multi")
15318    (set_attr "length" "12")])
15320 (define_insn "set_got_labelled"
15321   [(set (match_operand:SI 0 "register_operand" "=r")
15322         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15323          UNSPEC_SET_GOT))
15324    (clobber (reg:CC FLAGS_REG))]
15325   "!TARGET_64BIT"
15326   { return output_set_got (operands[0], operands[1]); }
15327   [(set_attr "type" "multi")
15328    (set_attr "length" "12")])
15330 (define_insn "set_got_rex64"
15331   [(set (match_operand:DI 0 "register_operand" "=r")
15332         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15333   "TARGET_64BIT"
15334   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15335   [(set_attr "type" "lea")
15336    (set_attr "length" "6")])
15338 (define_insn "set_rip_rex64"
15339   [(set (match_operand:DI 0 "register_operand" "=r")
15340         (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15341   "TARGET_64BIT"
15342   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15343   [(set_attr "type" "lea")
15344    (set_attr "length" "6")])
15346 (define_insn "set_got_offset_rex64"
15347   [(set (match_operand:DI 0 "register_operand" "=r")
15348         (unspec:DI
15349           [(label_ref (match_operand 1 "" ""))]
15350           UNSPEC_SET_GOT_OFFSET))]
15351   "TARGET_64BIT"
15352   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15353   [(set_attr "type" "imov")
15354    (set_attr "length" "11")])
15356 (define_expand "epilogue"
15357   [(const_int 0)]
15358   ""
15359   "ix86_expand_epilogue (1); DONE;")
15361 (define_expand "sibcall_epilogue"
15362   [(const_int 0)]
15363   ""
15364   "ix86_expand_epilogue (0); DONE;")
15366 (define_expand "eh_return"
15367   [(use (match_operand 0 "register_operand" ""))]
15368   ""
15370   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15372   /* Tricky bit: we write the address of the handler to which we will
15373      be returning into someone else's stack frame, one word below the
15374      stack address we wish to restore.  */
15375   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15376   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15377   tmp = gen_rtx_MEM (Pmode, tmp);
15378   emit_move_insn (tmp, ra);
15380   if (Pmode == SImode)
15381     emit_jump_insn (gen_eh_return_si (sa));
15382   else
15383     emit_jump_insn (gen_eh_return_di (sa));
15384   emit_barrier ();
15385   DONE;
15388 (define_insn_and_split "eh_return_<mode>"
15389   [(set (pc)
15390         (unspec [(match_operand:P 0 "register_operand" "c")]
15391                  UNSPEC_EH_RETURN))]
15392   ""
15393   "#"
15394   "reload_completed"
15395   [(const_int 0)]
15396   "ix86_expand_epilogue (2); DONE;")
15398 (define_insn "leave"
15399   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15400    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15401    (clobber (mem:BLK (scratch)))]
15402   "!TARGET_64BIT"
15403   "leave"
15404   [(set_attr "type" "leave")])
15406 (define_insn "leave_rex64"
15407   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15408    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15409    (clobber (mem:BLK (scratch)))]
15410   "TARGET_64BIT"
15411   "leave"
15412   [(set_attr "type" "leave")])
15414 (define_expand "ffssi2"
15415   [(parallel
15416      [(set (match_operand:SI 0 "register_operand" "")
15417            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15418       (clobber (match_scratch:SI 2 ""))
15419       (clobber (reg:CC FLAGS_REG))])]
15420   ""
15422   if (TARGET_CMOVE)
15423     {
15424       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15425       DONE;
15426     }
15429 (define_expand "ffs_cmove"
15430   [(set (match_dup 2) (const_int -1))
15431    (parallel [(set (reg:CCZ FLAGS_REG)
15432                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15433                                 (const_int 0)))
15434               (set (match_operand:SI 0 "register_operand" "")
15435                    (ctz:SI (match_dup 1)))])
15436    (set (match_dup 0) (if_then_else:SI
15437                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15438                         (match_dup 2)
15439                         (match_dup 0)))
15440    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15441               (clobber (reg:CC FLAGS_REG))])]
15442   "TARGET_CMOVE"
15443   "operands[2] = gen_reg_rtx (SImode);")
15445 (define_insn_and_split "*ffs_no_cmove"
15446   [(set (match_operand:SI 0 "register_operand" "=r")
15447         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15448    (clobber (match_scratch:SI 2 "=&q"))
15449    (clobber (reg:CC FLAGS_REG))]
15450   "!TARGET_CMOVE"
15451   "#"
15452   "&& reload_completed"
15453   [(parallel [(set (reg:CCZ FLAGS_REG)
15454                    (compare:CCZ (match_dup 1) (const_int 0)))
15455               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15456    (set (strict_low_part (match_dup 3))
15457         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15458    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15459               (clobber (reg:CC FLAGS_REG))])
15460    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15461               (clobber (reg:CC FLAGS_REG))])
15462    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15463               (clobber (reg:CC FLAGS_REG))])]
15465   operands[3] = gen_lowpart (QImode, operands[2]);
15466   ix86_expand_clear (operands[2]);
15469 (define_insn "*ffssi_1"
15470   [(set (reg:CCZ FLAGS_REG)
15471         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15472                      (const_int 0)))
15473    (set (match_operand:SI 0 "register_operand" "=r")
15474         (ctz:SI (match_dup 1)))]
15475   ""
15476   "bsf{l}\t{%1, %0|%0, %1}"
15477   [(set_attr "prefix_0f" "1")])
15479 (define_expand "ffsdi2"
15480   [(set (match_dup 2) (const_int -1))
15481    (parallel [(set (reg:CCZ FLAGS_REG)
15482                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15483                                 (const_int 0)))
15484               (set (match_operand:DI 0 "register_operand" "")
15485                    (ctz:DI (match_dup 1)))])
15486    (set (match_dup 0) (if_then_else:DI
15487                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15488                         (match_dup 2)
15489                         (match_dup 0)))
15490    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15491               (clobber (reg:CC FLAGS_REG))])]
15492   "TARGET_64BIT"
15493   "operands[2] = gen_reg_rtx (DImode);")
15495 (define_insn "*ffsdi_1"
15496   [(set (reg:CCZ FLAGS_REG)
15497         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15498                      (const_int 0)))
15499    (set (match_operand:DI 0 "register_operand" "=r")
15500         (ctz:DI (match_dup 1)))]
15501   "TARGET_64BIT"
15502   "bsf{q}\t{%1, %0|%0, %1}"
15503   [(set_attr "prefix_0f" "1")])
15505 (define_insn "ctzsi2"
15506   [(set (match_operand:SI 0 "register_operand" "=r")
15507         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15508    (clobber (reg:CC FLAGS_REG))]
15509   ""
15510   "bsf{l}\t{%1, %0|%0, %1}"
15511   [(set_attr "prefix_0f" "1")])
15513 (define_insn "ctzdi2"
15514   [(set (match_operand:DI 0 "register_operand" "=r")
15515         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15516    (clobber (reg:CC FLAGS_REG))]
15517   "TARGET_64BIT"
15518   "bsf{q}\t{%1, %0|%0, %1}"
15519   [(set_attr "prefix_0f" "1")])
15521 (define_expand "clzsi2"
15522   [(parallel
15523      [(set (match_operand:SI 0 "register_operand" "")
15524            (minus:SI (const_int 31)
15525                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15526       (clobber (reg:CC FLAGS_REG))])
15527    (parallel
15528      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15529       (clobber (reg:CC FLAGS_REG))])]
15530   ""
15532   if (TARGET_ABM)
15533     {
15534       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15535       DONE;
15536     }
15539 (define_insn "clzsi2_abm"
15540   [(set (match_operand:SI 0 "register_operand" "=r")
15541         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15542    (clobber (reg:CC FLAGS_REG))]
15543   "TARGET_ABM"
15544   "lzcnt{l}\t{%1, %0|%0, %1}"
15545   [(set_attr "prefix_rep" "1")
15546    (set_attr "type" "bitmanip")
15547    (set_attr "mode" "SI")])
15549 (define_insn "*bsr"
15550   [(set (match_operand:SI 0 "register_operand" "=r")
15551         (minus:SI (const_int 31)
15552                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15553    (clobber (reg:CC FLAGS_REG))]
15554   ""
15555   "bsr{l}\t{%1, %0|%0, %1}"
15556   [(set_attr "prefix_0f" "1")
15557    (set_attr "mode" "SI")])
15559 (define_insn "popcount<mode>2"
15560   [(set (match_operand:SWI248 0 "register_operand" "=r")
15561         (popcount:SWI248
15562           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15563    (clobber (reg:CC FLAGS_REG))]
15564   "TARGET_POPCNT"
15566 #if TARGET_MACHO
15567   return "popcnt\t{%1, %0|%0, %1}";
15568 #else
15569   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15570 #endif
15572   [(set_attr "prefix_rep" "1")
15573    (set_attr "type" "bitmanip")
15574    (set_attr "mode" "<MODE>")])
15576 (define_insn "*popcount<mode>2_cmp"
15577   [(set (reg FLAGS_REG)
15578         (compare
15579           (popcount:SWI248
15580             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15581           (const_int 0)))
15582    (set (match_operand:SWI248 0 "register_operand" "=r")
15583         (popcount:SWI248 (match_dup 1)))]
15584   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15586 #if TARGET_MACHO
15587   return "popcnt\t{%1, %0|%0, %1}";
15588 #else
15589   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15590 #endif
15592   [(set_attr "prefix_rep" "1")
15593    (set_attr "type" "bitmanip")
15594    (set_attr "mode" "<MODE>")])
15596 (define_insn "*popcountsi2_cmp_zext"
15597   [(set (reg FLAGS_REG)
15598         (compare
15599           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15600           (const_int 0)))
15601    (set (match_operand:DI 0 "register_operand" "=r")
15602         (zero_extend:DI(popcount:SI (match_dup 1))))]
15603   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15605 #if TARGET_MACHO
15606   return "popcnt\t{%1, %0|%0, %1}";
15607 #else
15608   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15609 #endif
15611   [(set_attr "prefix_rep" "1")
15612    (set_attr "type" "bitmanip")
15613    (set_attr "mode" "SI")])
15615 (define_expand "bswapsi2"
15616   [(set (match_operand:SI 0 "register_operand" "")
15617         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15618   ""
15620   if (!TARGET_BSWAP)
15621     {
15622       rtx x = operands[0];
15624       emit_move_insn (x, operands[1]);
15625       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15626       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15627       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15628       DONE;
15629     }
15632 (define_insn "*bswapsi_1"
15633   [(set (match_operand:SI 0 "register_operand" "=r")
15634         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15635   "TARGET_BSWAP"
15636   "bswap\t%0"
15637   [(set_attr "prefix_0f" "1")
15638    (set_attr "length" "2")])
15640 (define_insn "*bswaphi_lowpart_1"
15641   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15642         (bswap:HI (match_dup 0)))
15643    (clobber (reg:CC FLAGS_REG))]
15644   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15645   "@
15646     xchg{b}\t{%h0, %b0|%b0, %h0}
15647     rol{w}\t{$8, %0|%0, 8}"
15648   [(set_attr "length" "2,4")
15649    (set_attr "mode" "QI,HI")])
15651 (define_insn "bswaphi_lowpart"
15652   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15653         (bswap:HI (match_dup 0)))
15654    (clobber (reg:CC FLAGS_REG))]
15655   ""
15656   "rol{w}\t{$8, %0|%0, 8}"
15657   [(set_attr "length" "4")
15658    (set_attr "mode" "HI")])
15660 (define_insn "bswapdi2"
15661   [(set (match_operand:DI 0 "register_operand" "=r")
15662         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15663   "TARGET_64BIT"
15664   "bswap\t%0"
15665   [(set_attr "prefix_0f" "1")
15666    (set_attr "length" "3")])
15668 (define_expand "clzdi2"
15669   [(parallel
15670      [(set (match_operand:DI 0 "register_operand" "")
15671            (minus:DI (const_int 63)
15672                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15673       (clobber (reg:CC FLAGS_REG))])
15674    (parallel
15675      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15676       (clobber (reg:CC FLAGS_REG))])]
15677   "TARGET_64BIT"
15679   if (TARGET_ABM)
15680     {
15681       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15682       DONE;
15683     }
15686 (define_insn "clzdi2_abm"
15687   [(set (match_operand:DI 0 "register_operand" "=r")
15688         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15689    (clobber (reg:CC FLAGS_REG))]
15690   "TARGET_64BIT && TARGET_ABM"
15691   "lzcnt{q}\t{%1, %0|%0, %1}"
15692   [(set_attr "prefix_rep" "1")
15693    (set_attr "type" "bitmanip")
15694    (set_attr "mode" "DI")])
15696 (define_insn "*bsr_rex64"
15697   [(set (match_operand:DI 0 "register_operand" "=r")
15698         (minus:DI (const_int 63)
15699                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15700    (clobber (reg:CC FLAGS_REG))]
15701   "TARGET_64BIT"
15702   "bsr{q}\t{%1, %0|%0, %1}"
15703   [(set_attr "prefix_0f" "1")
15704    (set_attr "mode" "DI")])
15706 (define_expand "clzhi2"
15707   [(parallel
15708      [(set (match_operand:HI 0 "register_operand" "")
15709            (minus:HI (const_int 15)
15710                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15711       (clobber (reg:CC FLAGS_REG))])
15712    (parallel
15713      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15714       (clobber (reg:CC FLAGS_REG))])]
15715   ""
15717   if (TARGET_ABM)
15718     {
15719       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15720       DONE;
15721     }
15724 (define_insn "clzhi2_abm"
15725   [(set (match_operand:HI 0 "register_operand" "=r")
15726         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15727    (clobber (reg:CC FLAGS_REG))]
15728   "TARGET_ABM"
15729   "lzcnt{w}\t{%1, %0|%0, %1}"
15730   [(set_attr "prefix_rep" "1")
15731    (set_attr "type" "bitmanip")
15732    (set_attr "mode" "HI")])
15734 (define_insn "*bsrhi"
15735   [(set (match_operand:HI 0 "register_operand" "=r")
15736         (minus:HI (const_int 15)
15737                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15738    (clobber (reg:CC FLAGS_REG))]
15739   ""
15740   "bsr{w}\t{%1, %0|%0, %1}"
15741   [(set_attr "prefix_0f" "1")
15742    (set_attr "mode" "HI")])
15744 (define_expand "paritydi2"
15745   [(set (match_operand:DI 0 "register_operand" "")
15746         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15747   "! TARGET_POPCNT"
15749   rtx scratch = gen_reg_rtx (QImode);
15750   rtx cond;
15752   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15753                                 NULL_RTX, operands[1]));
15755   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15756                          gen_rtx_REG (CCmode, FLAGS_REG),
15757                          const0_rtx);
15758   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15760   if (TARGET_64BIT)
15761     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15762   else
15763     {
15764       rtx tmp = gen_reg_rtx (SImode);
15766       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15767       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15768     }
15769   DONE;
15772 (define_insn_and_split "paritydi2_cmp"
15773   [(set (reg:CC FLAGS_REG)
15774         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15775    (clobber (match_scratch:DI 0 "=r"))
15776    (clobber (match_scratch:SI 1 "=&r"))
15777    (clobber (match_scratch:HI 2 "=Q"))]
15778   "! TARGET_POPCNT"
15779   "#"
15780   "&& reload_completed"
15781   [(parallel
15782      [(set (match_dup 1)
15783            (xor:SI (match_dup 1) (match_dup 4)))
15784       (clobber (reg:CC FLAGS_REG))])
15785    (parallel
15786      [(set (reg:CC FLAGS_REG)
15787            (parity:CC (match_dup 1)))
15788       (clobber (match_dup 1))
15789       (clobber (match_dup 2))])]
15791   operands[4] = gen_lowpart (SImode, operands[3]);
15793   if (TARGET_64BIT)
15794     {
15795       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15796       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15797     }
15798   else
15799     operands[1] = gen_highpart (SImode, operands[3]);
15802 (define_expand "paritysi2"
15803   [(set (match_operand:SI 0 "register_operand" "")
15804         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15805   "! TARGET_POPCNT"
15807   rtx scratch = gen_reg_rtx (QImode);
15808   rtx cond;
15810   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15812   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15813                          gen_rtx_REG (CCmode, FLAGS_REG),
15814                          const0_rtx);
15815   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15817   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15818   DONE;
15821 (define_insn_and_split "paritysi2_cmp"
15822   [(set (reg:CC FLAGS_REG)
15823         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15824    (clobber (match_scratch:SI 0 "=r"))
15825    (clobber (match_scratch:HI 1 "=&Q"))]
15826   "! TARGET_POPCNT"
15827   "#"
15828   "&& reload_completed"
15829   [(parallel
15830      [(set (match_dup 1)
15831            (xor:HI (match_dup 1) (match_dup 3)))
15832       (clobber (reg:CC FLAGS_REG))])
15833    (parallel
15834      [(set (reg:CC FLAGS_REG)
15835            (parity:CC (match_dup 1)))
15836       (clobber (match_dup 1))])]
15838   operands[3] = gen_lowpart (HImode, operands[2]);
15840   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15841   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15844 (define_insn "*parityhi2_cmp"
15845   [(set (reg:CC FLAGS_REG)
15846         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15847    (clobber (match_scratch:HI 0 "=Q"))]
15848   "! TARGET_POPCNT"
15849   "xor{b}\t{%h0, %b0|%b0, %h0}"
15850   [(set_attr "length" "2")
15851    (set_attr "mode" "HI")])
15853 (define_insn "*parityqi2_cmp"
15854   [(set (reg:CC FLAGS_REG)
15855         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15856   "! TARGET_POPCNT"
15857   "test{b}\t%0, %0"
15858   [(set_attr "length" "2")
15859    (set_attr "mode" "QI")])
15861 ;; Thread-local storage patterns for ELF.
15863 ;; Note that these code sequences must appear exactly as shown
15864 ;; in order to allow linker relaxation.
15866 (define_insn "*tls_global_dynamic_32_gnu"
15867   [(set (match_operand:SI 0 "register_operand" "=a")
15868         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15869                     (match_operand:SI 2 "tls_symbolic_operand" "")
15870                     (match_operand:SI 3 "call_insn_operand" "")]
15871                     UNSPEC_TLS_GD))
15872    (clobber (match_scratch:SI 4 "=d"))
15873    (clobber (match_scratch:SI 5 "=c"))
15874    (clobber (reg:CC FLAGS_REG))]
15875   "!TARGET_64BIT && TARGET_GNU_TLS"
15876   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15877   [(set_attr "type" "multi")
15878    (set_attr "length" "12")])
15880 (define_insn "*tls_global_dynamic_32_sun"
15881   [(set (match_operand:SI 0 "register_operand" "=a")
15882         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15883                     (match_operand:SI 2 "tls_symbolic_operand" "")
15884                     (match_operand:SI 3 "call_insn_operand" "")]
15885                     UNSPEC_TLS_GD))
15886    (clobber (match_scratch:SI 4 "=d"))
15887    (clobber (match_scratch:SI 5 "=c"))
15888    (clobber (reg:CC FLAGS_REG))]
15889   "!TARGET_64BIT && TARGET_SUN_TLS"
15890   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15891         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15892   [(set_attr "type" "multi")
15893    (set_attr "length" "14")])
15895 (define_expand "tls_global_dynamic_32"
15896   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15897                    (unspec:SI
15898                     [(match_dup 2)
15899                      (match_operand:SI 1 "tls_symbolic_operand" "")
15900                      (match_dup 3)]
15901                     UNSPEC_TLS_GD))
15902               (clobber (match_scratch:SI 4 ""))
15903               (clobber (match_scratch:SI 5 ""))
15904               (clobber (reg:CC FLAGS_REG))])]
15905   ""
15907   if (flag_pic)
15908     operands[2] = pic_offset_table_rtx;
15909   else
15910     {
15911       operands[2] = gen_reg_rtx (Pmode);
15912       emit_insn (gen_set_got (operands[2]));
15913     }
15914   if (TARGET_GNU2_TLS)
15915     {
15916        emit_insn (gen_tls_dynamic_gnu2_32
15917                   (operands[0], operands[1], operands[2]));
15918        DONE;
15919     }
15920   operands[3] = ix86_tls_get_addr ();
15923 (define_insn "*tls_global_dynamic_64"
15924   [(set (match_operand:DI 0 "register_operand" "=a")
15925         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15926                  (match_operand:DI 3 "" "")))
15927    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15928               UNSPEC_TLS_GD)]
15929   "TARGET_64BIT"
15930   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15931   [(set_attr "type" "multi")
15932    (set_attr "length" "16")])
15934 (define_expand "tls_global_dynamic_64"
15935   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15936                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15937               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15938                          UNSPEC_TLS_GD)])]
15939   ""
15941   if (TARGET_GNU2_TLS)
15942     {
15943        emit_insn (gen_tls_dynamic_gnu2_64
15944                   (operands[0], operands[1]));
15945        DONE;
15946     }
15947   operands[2] = ix86_tls_get_addr ();
15950 (define_insn "*tls_local_dynamic_base_32_gnu"
15951   [(set (match_operand:SI 0 "register_operand" "=a")
15952         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15953                     (match_operand:SI 2 "call_insn_operand" "")]
15954                    UNSPEC_TLS_LD_BASE))
15955    (clobber (match_scratch:SI 3 "=d"))
15956    (clobber (match_scratch:SI 4 "=c"))
15957    (clobber (reg:CC FLAGS_REG))]
15958   "!TARGET_64BIT && TARGET_GNU_TLS"
15959   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15960   [(set_attr "type" "multi")
15961    (set_attr "length" "11")])
15963 (define_insn "*tls_local_dynamic_base_32_sun"
15964   [(set (match_operand:SI 0 "register_operand" "=a")
15965         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15966                     (match_operand:SI 2 "call_insn_operand" "")]
15967                    UNSPEC_TLS_LD_BASE))
15968    (clobber (match_scratch:SI 3 "=d"))
15969    (clobber (match_scratch:SI 4 "=c"))
15970    (clobber (reg:CC FLAGS_REG))]
15971   "!TARGET_64BIT && TARGET_SUN_TLS"
15972   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15973         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15974   [(set_attr "type" "multi")
15975    (set_attr "length" "13")])
15977 (define_expand "tls_local_dynamic_base_32"
15978   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15979                    (unspec:SI [(match_dup 1) (match_dup 2)]
15980                               UNSPEC_TLS_LD_BASE))
15981               (clobber (match_scratch:SI 3 ""))
15982               (clobber (match_scratch:SI 4 ""))
15983               (clobber (reg:CC FLAGS_REG))])]
15984   ""
15986   if (flag_pic)
15987     operands[1] = pic_offset_table_rtx;
15988   else
15989     {
15990       operands[1] = gen_reg_rtx (Pmode);
15991       emit_insn (gen_set_got (operands[1]));
15992     }
15993   if (TARGET_GNU2_TLS)
15994     {
15995        emit_insn (gen_tls_dynamic_gnu2_32
15996                   (operands[0], ix86_tls_module_base (), operands[1]));
15997        DONE;
15998     }
15999   operands[2] = ix86_tls_get_addr ();
16002 (define_insn "*tls_local_dynamic_base_64"
16003   [(set (match_operand:DI 0 "register_operand" "=a")
16004         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
16005                  (match_operand:DI 2 "" "")))
16006    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16007   "TARGET_64BIT"
16008   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16009   [(set_attr "type" "multi")
16010    (set_attr "length" "12")])
16012 (define_expand "tls_local_dynamic_base_64"
16013   [(parallel [(set (match_operand:DI 0 "register_operand" "")
16014                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16015               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16016   ""
16018   if (TARGET_GNU2_TLS)
16019     {
16020        emit_insn (gen_tls_dynamic_gnu2_64
16021                   (operands[0], ix86_tls_module_base ()));
16022        DONE;
16023     }
16024   operands[1] = ix86_tls_get_addr ();
16027 ;; Local dynamic of a single variable is a lose.  Show combine how
16028 ;; to convert that back to global dynamic.
16030 (define_insn_and_split "*tls_local_dynamic_32_once"
16031   [(set (match_operand:SI 0 "register_operand" "=a")
16032         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16033                              (match_operand:SI 2 "call_insn_operand" "")]
16034                             UNSPEC_TLS_LD_BASE)
16035                  (const:SI (unspec:SI
16036                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
16037                             UNSPEC_DTPOFF))))
16038    (clobber (match_scratch:SI 4 "=d"))
16039    (clobber (match_scratch:SI 5 "=c"))
16040    (clobber (reg:CC FLAGS_REG))]
16041   ""
16042   "#"
16043   ""
16044   [(parallel [(set (match_dup 0)
16045                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16046                               UNSPEC_TLS_GD))
16047               (clobber (match_dup 4))
16048               (clobber (match_dup 5))
16049               (clobber (reg:CC FLAGS_REG))])]
16050   "")
16052 ;; Load and add the thread base pointer from %gs:0.
16054 (define_insn "*load_tp_si"
16055   [(set (match_operand:SI 0 "register_operand" "=r")
16056         (unspec:SI [(const_int 0)] UNSPEC_TP))]
16057   "!TARGET_64BIT"
16058   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16059   [(set_attr "type" "imov")
16060    (set_attr "modrm" "0")
16061    (set_attr "length" "7")
16062    (set_attr "memory" "load")
16063    (set_attr "imm_disp" "false")])
16065 (define_insn "*add_tp_si"
16066   [(set (match_operand:SI 0 "register_operand" "=r")
16067         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16068                  (match_operand:SI 1 "register_operand" "0")))
16069    (clobber (reg:CC FLAGS_REG))]
16070   "!TARGET_64BIT"
16071   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16072   [(set_attr "type" "alu")
16073    (set_attr "modrm" "0")
16074    (set_attr "length" "7")
16075    (set_attr "memory" "load")
16076    (set_attr "imm_disp" "false")])
16078 (define_insn "*load_tp_di"
16079   [(set (match_operand:DI 0 "register_operand" "=r")
16080         (unspec:DI [(const_int 0)] UNSPEC_TP))]
16081   "TARGET_64BIT"
16082   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16083   [(set_attr "type" "imov")
16084    (set_attr "modrm" "0")
16085    (set_attr "length" "7")
16086    (set_attr "memory" "load")
16087    (set_attr "imm_disp" "false")])
16089 (define_insn "*add_tp_di"
16090   [(set (match_operand:DI 0 "register_operand" "=r")
16091         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16092                  (match_operand:DI 1 "register_operand" "0")))
16093    (clobber (reg:CC FLAGS_REG))]
16094   "TARGET_64BIT"
16095   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16096   [(set_attr "type" "alu")
16097    (set_attr "modrm" "0")
16098    (set_attr "length" "7")
16099    (set_attr "memory" "load")
16100    (set_attr "imm_disp" "false")])
16102 ;; GNU2 TLS patterns can be split.
16104 (define_expand "tls_dynamic_gnu2_32"
16105   [(set (match_dup 3)
16106         (plus:SI (match_operand:SI 2 "register_operand" "")
16107                  (const:SI
16108                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16109                              UNSPEC_TLSDESC))))
16110    (parallel
16111     [(set (match_operand:SI 0 "register_operand" "")
16112           (unspec:SI [(match_dup 1) (match_dup 3)
16113                       (match_dup 2) (reg:SI SP_REG)]
16114                       UNSPEC_TLSDESC))
16115      (clobber (reg:CC FLAGS_REG))])]
16116   "!TARGET_64BIT && TARGET_GNU2_TLS"
16118   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16119   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16122 (define_insn "*tls_dynamic_lea_32"
16123   [(set (match_operand:SI 0 "register_operand" "=r")
16124         (plus:SI (match_operand:SI 1 "register_operand" "b")
16125                  (const:SI
16126                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16127                               UNSPEC_TLSDESC))))]
16128   "!TARGET_64BIT && TARGET_GNU2_TLS"
16129   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16130   [(set_attr "type" "lea")
16131    (set_attr "mode" "SI")
16132    (set_attr "length" "6")
16133    (set_attr "length_address" "4")])
16135 (define_insn "*tls_dynamic_call_32"
16136   [(set (match_operand:SI 0 "register_operand" "=a")
16137         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16138                     (match_operand:SI 2 "register_operand" "0")
16139                     ;; we have to make sure %ebx still points to the GOT
16140                     (match_operand:SI 3 "register_operand" "b")
16141                     (reg:SI SP_REG)]
16142                    UNSPEC_TLSDESC))
16143    (clobber (reg:CC FLAGS_REG))]
16144   "!TARGET_64BIT && TARGET_GNU2_TLS"
16145   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16146   [(set_attr "type" "call")
16147    (set_attr "length" "2")
16148    (set_attr "length_address" "0")])
16150 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16151   [(set (match_operand:SI 0 "register_operand" "=&a")
16152         (plus:SI
16153          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16154                      (match_operand:SI 4 "" "")
16155                      (match_operand:SI 2 "register_operand" "b")
16156                      (reg:SI SP_REG)]
16157                     UNSPEC_TLSDESC)
16158          (const:SI (unspec:SI
16159                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
16160                     UNSPEC_DTPOFF))))
16161    (clobber (reg:CC FLAGS_REG))]
16162   "!TARGET_64BIT && TARGET_GNU2_TLS"
16163   "#"
16164   ""
16165   [(set (match_dup 0) (match_dup 5))]
16167   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16168   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16171 (define_expand "tls_dynamic_gnu2_64"
16172   [(set (match_dup 2)
16173         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16174                    UNSPEC_TLSDESC))
16175    (parallel
16176     [(set (match_operand:DI 0 "register_operand" "")
16177           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16178                      UNSPEC_TLSDESC))
16179      (clobber (reg:CC FLAGS_REG))])]
16180   "TARGET_64BIT && TARGET_GNU2_TLS"
16182   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16183   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16186 (define_insn "*tls_dynamic_lea_64"
16187   [(set (match_operand:DI 0 "register_operand" "=r")
16188         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16189                    UNSPEC_TLSDESC))]
16190   "TARGET_64BIT && TARGET_GNU2_TLS"
16191   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16192   [(set_attr "type" "lea")
16193    (set_attr "mode" "DI")
16194    (set_attr "length" "7")
16195    (set_attr "length_address" "4")])
16197 (define_insn "*tls_dynamic_call_64"
16198   [(set (match_operand:DI 0 "register_operand" "=a")
16199         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16200                     (match_operand:DI 2 "register_operand" "0")
16201                     (reg:DI SP_REG)]
16202                    UNSPEC_TLSDESC))
16203    (clobber (reg:CC FLAGS_REG))]
16204   "TARGET_64BIT && TARGET_GNU2_TLS"
16205   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16206   [(set_attr "type" "call")
16207    (set_attr "length" "2")
16208    (set_attr "length_address" "0")])
16210 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16211   [(set (match_operand:DI 0 "register_operand" "=&a")
16212         (plus:DI
16213          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16214                      (match_operand:DI 3 "" "")
16215                      (reg:DI SP_REG)]
16216                     UNSPEC_TLSDESC)
16217          (const:DI (unspec:DI
16218                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16219                     UNSPEC_DTPOFF))))
16220    (clobber (reg:CC FLAGS_REG))]
16221   "TARGET_64BIT && TARGET_GNU2_TLS"
16222   "#"
16223   ""
16224   [(set (match_dup 0) (match_dup 4))]
16226   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16227   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16232 ;; These patterns match the binary 387 instructions for addM3, subM3,
16233 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16234 ;; SFmode.  The first is the normal insn, the second the same insn but
16235 ;; with one operand a conversion, and the third the same insn but with
16236 ;; the other operand a conversion.  The conversion may be SFmode or
16237 ;; SImode if the target mode DFmode, but only SImode if the target mode
16238 ;; is SFmode.
16240 ;; Gcc is slightly more smart about handling normal two address instructions
16241 ;; so use special patterns for add and mull.
16243 (define_insn "*fop_<mode>_comm_mixed_avx"
16244   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16245         (match_operator:MODEF 3 "binary_fp_operator"
16246           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16247            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16248   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16249    && COMMUTATIVE_ARITH_P (operands[3])
16250    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16251   "* return output_387_binary_op (insn, operands);"
16252   [(set (attr "type")
16253         (if_then_else (eq_attr "alternative" "1")
16254            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16255               (const_string "ssemul")
16256               (const_string "sseadd"))
16257            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16258               (const_string "fmul")
16259               (const_string "fop"))))
16260    (set_attr "prefix" "orig,maybe_vex")
16261    (set_attr "mode" "<MODE>")])
16263 (define_insn "*fop_<mode>_comm_mixed"
16264   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16265         (match_operator:MODEF 3 "binary_fp_operator"
16266           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16267            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16268   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16269    && COMMUTATIVE_ARITH_P (operands[3])
16270    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16271   "* return output_387_binary_op (insn, operands);"
16272   [(set (attr "type")
16273         (if_then_else (eq_attr "alternative" "1")
16274            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16275               (const_string "ssemul")
16276               (const_string "sseadd"))
16277            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16278               (const_string "fmul")
16279               (const_string "fop"))))
16280    (set_attr "mode" "<MODE>")])
16282 (define_insn "*fop_<mode>_comm_avx"
16283   [(set (match_operand:MODEF 0 "register_operand" "=x")
16284         (match_operator:MODEF 3 "binary_fp_operator"
16285           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16286            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16287   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16288    && COMMUTATIVE_ARITH_P (operands[3])
16289    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16290   "* return output_387_binary_op (insn, operands);"
16291   [(set (attr "type")
16292         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16293            (const_string "ssemul")
16294            (const_string "sseadd")))
16295    (set_attr "prefix" "vex")
16296    (set_attr "mode" "<MODE>")])
16298 (define_insn "*fop_<mode>_comm_sse"
16299   [(set (match_operand:MODEF 0 "register_operand" "=x")
16300         (match_operator:MODEF 3 "binary_fp_operator"
16301           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16302            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16303   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16304    && COMMUTATIVE_ARITH_P (operands[3])
16305    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16306   "* return output_387_binary_op (insn, operands);"
16307   [(set (attr "type")
16308         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16309            (const_string "ssemul")
16310            (const_string "sseadd")))
16311    (set_attr "mode" "<MODE>")])
16313 (define_insn "*fop_<mode>_comm_i387"
16314   [(set (match_operand:MODEF 0 "register_operand" "=f")
16315         (match_operator:MODEF 3 "binary_fp_operator"
16316           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16317            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16318   "TARGET_80387
16319    && COMMUTATIVE_ARITH_P (operands[3])
16320    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16321   "* return output_387_binary_op (insn, operands);"
16322   [(set (attr "type")
16323         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16324            (const_string "fmul")
16325            (const_string "fop")))
16326    (set_attr "mode" "<MODE>")])
16328 (define_insn "*fop_<mode>_1_mixed_avx"
16329   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16330         (match_operator:MODEF 3 "binary_fp_operator"
16331           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16332            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16333   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16334    && !COMMUTATIVE_ARITH_P (operands[3])
16335    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16336   "* return output_387_binary_op (insn, operands);"
16337   [(set (attr "type")
16338         (cond [(and (eq_attr "alternative" "2")
16339                     (match_operand:MODEF 3 "mult_operator" ""))
16340                  (const_string "ssemul")
16341                (and (eq_attr "alternative" "2")
16342                     (match_operand:MODEF 3 "div_operator" ""))
16343                  (const_string "ssediv")
16344                (eq_attr "alternative" "2")
16345                  (const_string "sseadd")
16346                (match_operand:MODEF 3 "mult_operator" "")
16347                  (const_string "fmul")
16348                (match_operand:MODEF 3 "div_operator" "")
16349                  (const_string "fdiv")
16350               ]
16351               (const_string "fop")))
16352    (set_attr "prefix" "orig,orig,maybe_vex")
16353    (set_attr "mode" "<MODE>")])
16355 (define_insn "*fop_<mode>_1_mixed"
16356   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16357         (match_operator:MODEF 3 "binary_fp_operator"
16358           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16359            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16360   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16361    && !COMMUTATIVE_ARITH_P (operands[3])
16362    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16363   "* return output_387_binary_op (insn, operands);"
16364   [(set (attr "type")
16365         (cond [(and (eq_attr "alternative" "2")
16366                     (match_operand:MODEF 3 "mult_operator" ""))
16367                  (const_string "ssemul")
16368                (and (eq_attr "alternative" "2")
16369                     (match_operand:MODEF 3 "div_operator" ""))
16370                  (const_string "ssediv")
16371                (eq_attr "alternative" "2")
16372                  (const_string "sseadd")
16373                (match_operand:MODEF 3 "mult_operator" "")
16374                  (const_string "fmul")
16375                (match_operand:MODEF 3 "div_operator" "")
16376                  (const_string "fdiv")
16377               ]
16378               (const_string "fop")))
16379    (set_attr "mode" "<MODE>")])
16381 (define_insn "*rcpsf2_sse"
16382   [(set (match_operand:SF 0 "register_operand" "=x")
16383         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16384                    UNSPEC_RCP))]
16385   "TARGET_SSE_MATH"
16386   "%vrcpss\t{%1, %d0|%d0, %1}"
16387   [(set_attr "type" "sse")
16388    (set_attr "prefix" "maybe_vex")
16389    (set_attr "mode" "SF")])
16391 (define_insn "*fop_<mode>_1_avx"
16392   [(set (match_operand:MODEF 0 "register_operand" "=x")
16393         (match_operator:MODEF 3 "binary_fp_operator"
16394           [(match_operand:MODEF 1 "register_operand" "x")
16395            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16396   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16397    && !COMMUTATIVE_ARITH_P (operands[3])"
16398   "* return output_387_binary_op (insn, operands);"
16399   [(set (attr "type")
16400         (cond [(match_operand:MODEF 3 "mult_operator" "")
16401                  (const_string "ssemul")
16402                (match_operand:MODEF 3 "div_operator" "")
16403                  (const_string "ssediv")
16404               ]
16405               (const_string "sseadd")))
16406    (set_attr "prefix" "vex")
16407    (set_attr "mode" "<MODE>")])
16409 (define_insn "*fop_<mode>_1_sse"
16410   [(set (match_operand:MODEF 0 "register_operand" "=x")
16411         (match_operator:MODEF 3 "binary_fp_operator"
16412           [(match_operand:MODEF 1 "register_operand" "0")
16413            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16414   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16415    && !COMMUTATIVE_ARITH_P (operands[3])"
16416   "* return output_387_binary_op (insn, operands);"
16417   [(set (attr "type")
16418         (cond [(match_operand:MODEF 3 "mult_operator" "")
16419                  (const_string "ssemul")
16420                (match_operand:MODEF 3 "div_operator" "")
16421                  (const_string "ssediv")
16422               ]
16423               (const_string "sseadd")))
16424    (set_attr "mode" "<MODE>")])
16426 ;; This pattern is not fully shadowed by the pattern above.
16427 (define_insn "*fop_<mode>_1_i387"
16428   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16429         (match_operator:MODEF 3 "binary_fp_operator"
16430           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16431            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16432   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16433    && !COMMUTATIVE_ARITH_P (operands[3])
16434    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16435   "* return output_387_binary_op (insn, operands);"
16436   [(set (attr "type")
16437         (cond [(match_operand:MODEF 3 "mult_operator" "")
16438                  (const_string "fmul")
16439                (match_operand:MODEF 3 "div_operator" "")
16440                  (const_string "fdiv")
16441               ]
16442               (const_string "fop")))
16443    (set_attr "mode" "<MODE>")])
16445 ;; ??? Add SSE splitters for these!
16446 (define_insn "*fop_<MODEF:mode>_2_i387"
16447   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16448         (match_operator:MODEF 3 "binary_fp_operator"
16449           [(float:MODEF
16450              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16451            (match_operand:MODEF 2 "register_operand" "0,0")]))]
16452   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16453    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16454   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16455   [(set (attr "type")
16456         (cond [(match_operand:MODEF 3 "mult_operator" "")
16457                  (const_string "fmul")
16458                (match_operand:MODEF 3 "div_operator" "")
16459                  (const_string "fdiv")
16460               ]
16461               (const_string "fop")))
16462    (set_attr "fp_int_src" "true")
16463    (set_attr "mode" "<X87MODEI12:MODE>")])
16465 (define_insn "*fop_<MODEF:mode>_3_i387"
16466   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16467         (match_operator:MODEF 3 "binary_fp_operator"
16468           [(match_operand:MODEF 1 "register_operand" "0,0")
16469            (float:MODEF
16470              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16471   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16472    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16473   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16474   [(set (attr "type")
16475         (cond [(match_operand:MODEF 3 "mult_operator" "")
16476                  (const_string "fmul")
16477                (match_operand:MODEF 3 "div_operator" "")
16478                  (const_string "fdiv")
16479               ]
16480               (const_string "fop")))
16481    (set_attr "fp_int_src" "true")
16482    (set_attr "mode" "<MODE>")])
16484 (define_insn "*fop_df_4_i387"
16485   [(set (match_operand:DF 0 "register_operand" "=f,f")
16486         (match_operator:DF 3 "binary_fp_operator"
16487            [(float_extend:DF
16488              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16489             (match_operand:DF 2 "register_operand" "0,f")]))]
16490   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16491    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16492   "* return output_387_binary_op (insn, operands);"
16493   [(set (attr "type")
16494         (cond [(match_operand:DF 3 "mult_operator" "")
16495                  (const_string "fmul")
16496                (match_operand:DF 3 "div_operator" "")
16497                  (const_string "fdiv")
16498               ]
16499               (const_string "fop")))
16500    (set_attr "mode" "SF")])
16502 (define_insn "*fop_df_5_i387"
16503   [(set (match_operand:DF 0 "register_operand" "=f,f")
16504         (match_operator:DF 3 "binary_fp_operator"
16505           [(match_operand:DF 1 "register_operand" "0,f")
16506            (float_extend:DF
16507             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16508   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16509   "* return output_387_binary_op (insn, operands);"
16510   [(set (attr "type")
16511         (cond [(match_operand:DF 3 "mult_operator" "")
16512                  (const_string "fmul")
16513                (match_operand:DF 3 "div_operator" "")
16514                  (const_string "fdiv")
16515               ]
16516               (const_string "fop")))
16517    (set_attr "mode" "SF")])
16519 (define_insn "*fop_df_6_i387"
16520   [(set (match_operand:DF 0 "register_operand" "=f,f")
16521         (match_operator:DF 3 "binary_fp_operator"
16522           [(float_extend:DF
16523             (match_operand:SF 1 "register_operand" "0,f"))
16524            (float_extend:DF
16525             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16526   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16527   "* return output_387_binary_op (insn, operands);"
16528   [(set (attr "type")
16529         (cond [(match_operand:DF 3 "mult_operator" "")
16530                  (const_string "fmul")
16531                (match_operand:DF 3 "div_operator" "")
16532                  (const_string "fdiv")
16533               ]
16534               (const_string "fop")))
16535    (set_attr "mode" "SF")])
16537 (define_insn "*fop_xf_comm_i387"
16538   [(set (match_operand:XF 0 "register_operand" "=f")
16539         (match_operator:XF 3 "binary_fp_operator"
16540                         [(match_operand:XF 1 "register_operand" "%0")
16541                          (match_operand:XF 2 "register_operand" "f")]))]
16542   "TARGET_80387
16543    && COMMUTATIVE_ARITH_P (operands[3])"
16544   "* return output_387_binary_op (insn, operands);"
16545   [(set (attr "type")
16546         (if_then_else (match_operand:XF 3 "mult_operator" "")
16547            (const_string "fmul")
16548            (const_string "fop")))
16549    (set_attr "mode" "XF")])
16551 (define_insn "*fop_xf_1_i387"
16552   [(set (match_operand:XF 0 "register_operand" "=f,f")
16553         (match_operator:XF 3 "binary_fp_operator"
16554                         [(match_operand:XF 1 "register_operand" "0,f")
16555                          (match_operand:XF 2 "register_operand" "f,0")]))]
16556   "TARGET_80387
16557    && !COMMUTATIVE_ARITH_P (operands[3])"
16558   "* return output_387_binary_op (insn, operands);"
16559   [(set (attr "type")
16560         (cond [(match_operand:XF 3 "mult_operator" "")
16561                  (const_string "fmul")
16562                (match_operand:XF 3 "div_operator" "")
16563                  (const_string "fdiv")
16564               ]
16565               (const_string "fop")))
16566    (set_attr "mode" "XF")])
16568 (define_insn "*fop_xf_2_i387"
16569   [(set (match_operand:XF 0 "register_operand" "=f,f")
16570         (match_operator:XF 3 "binary_fp_operator"
16571           [(float:XF
16572              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16573            (match_operand:XF 2 "register_operand" "0,0")]))]
16574   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16575   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16576   [(set (attr "type")
16577         (cond [(match_operand:XF 3 "mult_operator" "")
16578                  (const_string "fmul")
16579                (match_operand:XF 3 "div_operator" "")
16580                  (const_string "fdiv")
16581               ]
16582               (const_string "fop")))
16583    (set_attr "fp_int_src" "true")
16584    (set_attr "mode" "<MODE>")])
16586 (define_insn "*fop_xf_3_i387"
16587   [(set (match_operand:XF 0 "register_operand" "=f,f")
16588         (match_operator:XF 3 "binary_fp_operator"
16589           [(match_operand:XF 1 "register_operand" "0,0")
16590            (float:XF
16591              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16592   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16593   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16594   [(set (attr "type")
16595         (cond [(match_operand:XF 3 "mult_operator" "")
16596                  (const_string "fmul")
16597                (match_operand:XF 3 "div_operator" "")
16598                  (const_string "fdiv")
16599               ]
16600               (const_string "fop")))
16601    (set_attr "fp_int_src" "true")
16602    (set_attr "mode" "<MODE>")])
16604 (define_insn "*fop_xf_4_i387"
16605   [(set (match_operand:XF 0 "register_operand" "=f,f")
16606         (match_operator:XF 3 "binary_fp_operator"
16607            [(float_extend:XF
16608               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16609             (match_operand:XF 2 "register_operand" "0,f")]))]
16610   "TARGET_80387"
16611   "* return output_387_binary_op (insn, operands);"
16612   [(set (attr "type")
16613         (cond [(match_operand:XF 3 "mult_operator" "")
16614                  (const_string "fmul")
16615                (match_operand:XF 3 "div_operator" "")
16616                  (const_string "fdiv")
16617               ]
16618               (const_string "fop")))
16619    (set_attr "mode" "<MODE>")])
16621 (define_insn "*fop_xf_5_i387"
16622   [(set (match_operand:XF 0 "register_operand" "=f,f")
16623         (match_operator:XF 3 "binary_fp_operator"
16624           [(match_operand:XF 1 "register_operand" "0,f")
16625            (float_extend:XF
16626              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16627   "TARGET_80387"
16628   "* return output_387_binary_op (insn, operands);"
16629   [(set (attr "type")
16630         (cond [(match_operand:XF 3 "mult_operator" "")
16631                  (const_string "fmul")
16632                (match_operand:XF 3 "div_operator" "")
16633                  (const_string "fdiv")
16634               ]
16635               (const_string "fop")))
16636    (set_attr "mode" "<MODE>")])
16638 (define_insn "*fop_xf_6_i387"
16639   [(set (match_operand:XF 0 "register_operand" "=f,f")
16640         (match_operator:XF 3 "binary_fp_operator"
16641           [(float_extend:XF
16642              (match_operand:MODEF 1 "register_operand" "0,f"))
16643            (float_extend:XF
16644              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16645   "TARGET_80387"
16646   "* return output_387_binary_op (insn, operands);"
16647   [(set (attr "type")
16648         (cond [(match_operand:XF 3 "mult_operator" "")
16649                  (const_string "fmul")
16650                (match_operand:XF 3 "div_operator" "")
16651                  (const_string "fdiv")
16652               ]
16653               (const_string "fop")))
16654    (set_attr "mode" "<MODE>")])
16656 (define_split
16657   [(set (match_operand 0 "register_operand" "")
16658         (match_operator 3 "binary_fp_operator"
16659            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16660             (match_operand 2 "register_operand" "")]))]
16661   "reload_completed
16662    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16663   [(const_int 0)]
16665   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16666   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16667   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16668                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16669                                           GET_MODE (operands[3]),
16670                                           operands[4],
16671                                           operands[2])));
16672   ix86_free_from_memory (GET_MODE (operands[1]));
16673   DONE;
16676 (define_split
16677   [(set (match_operand 0 "register_operand" "")
16678         (match_operator 3 "binary_fp_operator"
16679            [(match_operand 1 "register_operand" "")
16680             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16681   "reload_completed
16682    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16683   [(const_int 0)]
16685   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16686   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16687   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16688                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16689                                           GET_MODE (operands[3]),
16690                                           operands[1],
16691                                           operands[4])));
16692   ix86_free_from_memory (GET_MODE (operands[2]));
16693   DONE;
16696 ;; FPU special functions.
16698 ;; This pattern implements a no-op XFmode truncation for
16699 ;; all fancy i386 XFmode math functions.
16701 (define_insn "truncxf<mode>2_i387_noop_unspec"
16702   [(set (match_operand:MODEF 0 "register_operand" "=f")
16703         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16704         UNSPEC_TRUNC_NOOP))]
16705   "TARGET_USE_FANCY_MATH_387"
16706   "* return output_387_reg_move (insn, operands);"
16707   [(set_attr "type" "fmov")
16708    (set_attr "mode" "<MODE>")])
16710 (define_insn "sqrtxf2"
16711   [(set (match_operand:XF 0 "register_operand" "=f")
16712         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16713   "TARGET_USE_FANCY_MATH_387"
16714   "fsqrt"
16715   [(set_attr "type" "fpspc")
16716    (set_attr "mode" "XF")
16717    (set_attr "athlon_decode" "direct")
16718    (set_attr "amdfam10_decode" "direct")])
16720 (define_insn "sqrt_extend<mode>xf2_i387"
16721   [(set (match_operand:XF 0 "register_operand" "=f")
16722         (sqrt:XF
16723           (float_extend:XF
16724             (match_operand:MODEF 1 "register_operand" "0"))))]
16725   "TARGET_USE_FANCY_MATH_387"
16726   "fsqrt"
16727   [(set_attr "type" "fpspc")
16728    (set_attr "mode" "XF")
16729    (set_attr "athlon_decode" "direct")
16730    (set_attr "amdfam10_decode" "direct")])
16732 (define_insn "*rsqrtsf2_sse"
16733   [(set (match_operand:SF 0 "register_operand" "=x")
16734         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16735                    UNSPEC_RSQRT))]
16736   "TARGET_SSE_MATH"
16737   "%vrsqrtss\t{%1, %d0|%d0, %1}"
16738   [(set_attr "type" "sse")
16739    (set_attr "prefix" "maybe_vex")
16740    (set_attr "mode" "SF")])
16742 (define_expand "rsqrtsf2"
16743   [(set (match_operand:SF 0 "register_operand" "")
16744         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16745                    UNSPEC_RSQRT))]
16746   "TARGET_SSE_MATH"
16748   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16749   DONE;
16752 (define_insn "*sqrt<mode>2_sse"
16753   [(set (match_operand:MODEF 0 "register_operand" "=x")
16754         (sqrt:MODEF
16755           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16756   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16757   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16758   [(set_attr "type" "sse")
16759    (set_attr "prefix" "maybe_vex")
16760    (set_attr "mode" "<MODE>")
16761    (set_attr "athlon_decode" "*")
16762    (set_attr "amdfam10_decode" "*")])
16764 (define_expand "sqrt<mode>2"
16765   [(set (match_operand:MODEF 0 "register_operand" "")
16766         (sqrt:MODEF
16767           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16768   "TARGET_USE_FANCY_MATH_387
16769    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16771   if (<MODE>mode == SFmode
16772       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16773       && flag_finite_math_only && !flag_trapping_math
16774       && flag_unsafe_math_optimizations)
16775     {
16776       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16777       DONE;
16778     }
16780   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16781     {
16782       rtx op0 = gen_reg_rtx (XFmode);
16783       rtx op1 = force_reg (<MODE>mode, operands[1]);
16785       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16786       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16787       DONE;
16788    }
16791 (define_insn "fpremxf4_i387"
16792   [(set (match_operand:XF 0 "register_operand" "=f")
16793         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16794                     (match_operand:XF 3 "register_operand" "1")]
16795                    UNSPEC_FPREM_F))
16796    (set (match_operand:XF 1 "register_operand" "=u")
16797         (unspec:XF [(match_dup 2) (match_dup 3)]
16798                    UNSPEC_FPREM_U))
16799    (set (reg:CCFP FPSR_REG)
16800         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16801                      UNSPEC_C2_FLAG))]
16802   "TARGET_USE_FANCY_MATH_387"
16803   "fprem"
16804   [(set_attr "type" "fpspc")
16805    (set_attr "mode" "XF")])
16807 (define_expand "fmodxf3"
16808   [(use (match_operand:XF 0 "register_operand" ""))
16809    (use (match_operand:XF 1 "general_operand" ""))
16810    (use (match_operand:XF 2 "general_operand" ""))]
16811   "TARGET_USE_FANCY_MATH_387"
16813   rtx label = gen_label_rtx ();
16815   rtx op1 = gen_reg_rtx (XFmode);
16816   rtx op2 = gen_reg_rtx (XFmode);
16818   emit_move_insn (op2, operands[2]);
16819   emit_move_insn (op1, operands[1]);
16821   emit_label (label);
16822   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16823   ix86_emit_fp_unordered_jump (label);
16824   LABEL_NUSES (label) = 1;
16826   emit_move_insn (operands[0], op1);
16827   DONE;
16830 (define_expand "fmod<mode>3"
16831   [(use (match_operand:MODEF 0 "register_operand" ""))
16832    (use (match_operand:MODEF 1 "general_operand" ""))
16833    (use (match_operand:MODEF 2 "general_operand" ""))]
16834   "TARGET_USE_FANCY_MATH_387"
16836   rtx label = gen_label_rtx ();
16838   rtx op1 = gen_reg_rtx (XFmode);
16839   rtx op2 = gen_reg_rtx (XFmode);
16841   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16842   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16844   emit_label (label);
16845   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16846   ix86_emit_fp_unordered_jump (label);
16847   LABEL_NUSES (label) = 1;
16849   /* Truncate the result properly for strict SSE math.  */
16850   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16851       && !TARGET_MIX_SSE_I387)
16852     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16853   else
16854     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16856   DONE;
16859 (define_insn "fprem1xf4_i387"
16860   [(set (match_operand:XF 0 "register_operand" "=f")
16861         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16862                     (match_operand:XF 3 "register_operand" "1")]
16863                    UNSPEC_FPREM1_F))
16864    (set (match_operand:XF 1 "register_operand" "=u")
16865         (unspec:XF [(match_dup 2) (match_dup 3)]
16866                    UNSPEC_FPREM1_U))
16867    (set (reg:CCFP FPSR_REG)
16868         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16869                      UNSPEC_C2_FLAG))]
16870   "TARGET_USE_FANCY_MATH_387"
16871   "fprem1"
16872   [(set_attr "type" "fpspc")
16873    (set_attr "mode" "XF")])
16875 (define_expand "remainderxf3"
16876   [(use (match_operand:XF 0 "register_operand" ""))
16877    (use (match_operand:XF 1 "general_operand" ""))
16878    (use (match_operand:XF 2 "general_operand" ""))]
16879   "TARGET_USE_FANCY_MATH_387"
16881   rtx label = gen_label_rtx ();
16883   rtx op1 = gen_reg_rtx (XFmode);
16884   rtx op2 = gen_reg_rtx (XFmode);
16886   emit_move_insn (op2, operands[2]);
16887   emit_move_insn (op1, operands[1]);
16889   emit_label (label);
16890   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16891   ix86_emit_fp_unordered_jump (label);
16892   LABEL_NUSES (label) = 1;
16894   emit_move_insn (operands[0], op1);
16895   DONE;
16898 (define_expand "remainder<mode>3"
16899   [(use (match_operand:MODEF 0 "register_operand" ""))
16900    (use (match_operand:MODEF 1 "general_operand" ""))
16901    (use (match_operand:MODEF 2 "general_operand" ""))]
16902   "TARGET_USE_FANCY_MATH_387"
16904   rtx label = gen_label_rtx ();
16906   rtx op1 = gen_reg_rtx (XFmode);
16907   rtx op2 = gen_reg_rtx (XFmode);
16909   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16910   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16912   emit_label (label);
16914   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16915   ix86_emit_fp_unordered_jump (label);
16916   LABEL_NUSES (label) = 1;
16918   /* Truncate the result properly for strict SSE math.  */
16919   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16920       && !TARGET_MIX_SSE_I387)
16921     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16922   else
16923     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16925   DONE;
16928 (define_insn "*sinxf2_i387"
16929   [(set (match_operand:XF 0 "register_operand" "=f")
16930         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16931   "TARGET_USE_FANCY_MATH_387
16932    && flag_unsafe_math_optimizations"
16933   "fsin"
16934   [(set_attr "type" "fpspc")
16935    (set_attr "mode" "XF")])
16937 (define_insn "*sin_extend<mode>xf2_i387"
16938   [(set (match_operand:XF 0 "register_operand" "=f")
16939         (unspec:XF [(float_extend:XF
16940                       (match_operand:MODEF 1 "register_operand" "0"))]
16941                    UNSPEC_SIN))]
16942   "TARGET_USE_FANCY_MATH_387
16943    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16944        || TARGET_MIX_SSE_I387)
16945    && flag_unsafe_math_optimizations"
16946   "fsin"
16947   [(set_attr "type" "fpspc")
16948    (set_attr "mode" "XF")])
16950 (define_insn "*cosxf2_i387"
16951   [(set (match_operand:XF 0 "register_operand" "=f")
16952         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16953   "TARGET_USE_FANCY_MATH_387
16954    && flag_unsafe_math_optimizations"
16955   "fcos"
16956   [(set_attr "type" "fpspc")
16957    (set_attr "mode" "XF")])
16959 (define_insn "*cos_extend<mode>xf2_i387"
16960   [(set (match_operand:XF 0 "register_operand" "=f")
16961         (unspec:XF [(float_extend:XF
16962                       (match_operand:MODEF 1 "register_operand" "0"))]
16963                    UNSPEC_COS))]
16964   "TARGET_USE_FANCY_MATH_387
16965    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16966        || TARGET_MIX_SSE_I387)
16967    && flag_unsafe_math_optimizations"
16968   "fcos"
16969   [(set_attr "type" "fpspc")
16970    (set_attr "mode" "XF")])
16972 ;; When sincos pattern is defined, sin and cos builtin functions will be
16973 ;; expanded to sincos pattern with one of its outputs left unused.
16974 ;; CSE pass will figure out if two sincos patterns can be combined,
16975 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16976 ;; depending on the unused output.
16978 (define_insn "sincosxf3"
16979   [(set (match_operand:XF 0 "register_operand" "=f")
16980         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16981                    UNSPEC_SINCOS_COS))
16982    (set (match_operand:XF 1 "register_operand" "=u")
16983         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16984   "TARGET_USE_FANCY_MATH_387
16985    && flag_unsafe_math_optimizations"
16986   "fsincos"
16987   [(set_attr "type" "fpspc")
16988    (set_attr "mode" "XF")])
16990 (define_split
16991   [(set (match_operand:XF 0 "register_operand" "")
16992         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16993                    UNSPEC_SINCOS_COS))
16994    (set (match_operand:XF 1 "register_operand" "")
16995         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16996   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16997    && !(reload_completed || reload_in_progress)"
16998   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16999   "")
17001 (define_split
17002   [(set (match_operand:XF 0 "register_operand" "")
17003         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17004                    UNSPEC_SINCOS_COS))
17005    (set (match_operand:XF 1 "register_operand" "")
17006         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17007   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17008    && !(reload_completed || reload_in_progress)"
17009   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17010   "")
17012 (define_insn "sincos_extend<mode>xf3_i387"
17013   [(set (match_operand:XF 0 "register_operand" "=f")
17014         (unspec:XF [(float_extend:XF
17015                       (match_operand:MODEF 2 "register_operand" "0"))]
17016                    UNSPEC_SINCOS_COS))
17017    (set (match_operand:XF 1 "register_operand" "=u")
17018         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17019   "TARGET_USE_FANCY_MATH_387
17020    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17021        || TARGET_MIX_SSE_I387)
17022    && flag_unsafe_math_optimizations"
17023   "fsincos"
17024   [(set_attr "type" "fpspc")
17025    (set_attr "mode" "XF")])
17027 (define_split
17028   [(set (match_operand:XF 0 "register_operand" "")
17029         (unspec:XF [(float_extend:XF
17030                       (match_operand:MODEF 2 "register_operand" ""))]
17031                    UNSPEC_SINCOS_COS))
17032    (set (match_operand:XF 1 "register_operand" "")
17033         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17034   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17035    && !(reload_completed || reload_in_progress)"
17036   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17037   "")
17039 (define_split
17040   [(set (match_operand:XF 0 "register_operand" "")
17041         (unspec:XF [(float_extend:XF
17042                       (match_operand:MODEF 2 "register_operand" ""))]
17043                    UNSPEC_SINCOS_COS))
17044    (set (match_operand:XF 1 "register_operand" "")
17045         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17046   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17047    && !(reload_completed || reload_in_progress)"
17048   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17049   "")
17051 (define_expand "sincos<mode>3"
17052   [(use (match_operand:MODEF 0 "register_operand" ""))
17053    (use (match_operand:MODEF 1 "register_operand" ""))
17054    (use (match_operand:MODEF 2 "register_operand" ""))]
17055   "TARGET_USE_FANCY_MATH_387
17056    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17057        || TARGET_MIX_SSE_I387)
17058    && flag_unsafe_math_optimizations"
17060   rtx op0 = gen_reg_rtx (XFmode);
17061   rtx op1 = gen_reg_rtx (XFmode);
17063   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17064   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17065   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17066   DONE;
17069 (define_insn "fptanxf4_i387"
17070   [(set (match_operand:XF 0 "register_operand" "=f")
17071         (match_operand:XF 3 "const_double_operand" "F"))
17072    (set (match_operand:XF 1 "register_operand" "=u")
17073         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17074                    UNSPEC_TAN))]
17075   "TARGET_USE_FANCY_MATH_387
17076    && flag_unsafe_math_optimizations
17077    && standard_80387_constant_p (operands[3]) == 2"
17078   "fptan"
17079   [(set_attr "type" "fpspc")
17080    (set_attr "mode" "XF")])
17082 (define_insn "fptan_extend<mode>xf4_i387"
17083   [(set (match_operand:MODEF 0 "register_operand" "=f")
17084         (match_operand:MODEF 3 "const_double_operand" "F"))
17085    (set (match_operand:XF 1 "register_operand" "=u")
17086         (unspec:XF [(float_extend:XF
17087                       (match_operand:MODEF 2 "register_operand" "0"))]
17088                    UNSPEC_TAN))]
17089   "TARGET_USE_FANCY_MATH_387
17090    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17091        || TARGET_MIX_SSE_I387)
17092    && flag_unsafe_math_optimizations
17093    && standard_80387_constant_p (operands[3]) == 2"
17094   "fptan"
17095   [(set_attr "type" "fpspc")
17096    (set_attr "mode" "XF")])
17098 (define_expand "tanxf2"
17099   [(use (match_operand:XF 0 "register_operand" ""))
17100    (use (match_operand:XF 1 "register_operand" ""))]
17101   "TARGET_USE_FANCY_MATH_387
17102    && flag_unsafe_math_optimizations"
17104   rtx one = gen_reg_rtx (XFmode);
17105   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17107   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17108   DONE;
17111 (define_expand "tan<mode>2"
17112   [(use (match_operand:MODEF 0 "register_operand" ""))
17113    (use (match_operand:MODEF 1 "register_operand" ""))]
17114   "TARGET_USE_FANCY_MATH_387
17115    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17116        || TARGET_MIX_SSE_I387)
17117    && flag_unsafe_math_optimizations"
17119   rtx op0 = gen_reg_rtx (XFmode);
17121   rtx one = gen_reg_rtx (<MODE>mode);
17122   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17124   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17125                                              operands[1], op2));
17126   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17127   DONE;
17130 (define_insn "*fpatanxf3_i387"
17131   [(set (match_operand:XF 0 "register_operand" "=f")
17132         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17133                     (match_operand:XF 2 "register_operand" "u")]
17134                    UNSPEC_FPATAN))
17135    (clobber (match_scratch:XF 3 "=2"))]
17136   "TARGET_USE_FANCY_MATH_387
17137    && flag_unsafe_math_optimizations"
17138   "fpatan"
17139   [(set_attr "type" "fpspc")
17140    (set_attr "mode" "XF")])
17142 (define_insn "fpatan_extend<mode>xf3_i387"
17143   [(set (match_operand:XF 0 "register_operand" "=f")
17144         (unspec:XF [(float_extend:XF
17145                       (match_operand:MODEF 1 "register_operand" "0"))
17146                     (float_extend:XF
17147                       (match_operand:MODEF 2 "register_operand" "u"))]
17148                    UNSPEC_FPATAN))
17149    (clobber (match_scratch:XF 3 "=2"))]
17150   "TARGET_USE_FANCY_MATH_387
17151    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17152        || TARGET_MIX_SSE_I387)
17153    && flag_unsafe_math_optimizations"
17154   "fpatan"
17155   [(set_attr "type" "fpspc")
17156    (set_attr "mode" "XF")])
17158 (define_expand "atan2xf3"
17159   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17160                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
17161                                (match_operand:XF 1 "register_operand" "")]
17162                               UNSPEC_FPATAN))
17163               (clobber (match_scratch:XF 3 ""))])]
17164   "TARGET_USE_FANCY_MATH_387
17165    && flag_unsafe_math_optimizations"
17166   "")
17168 (define_expand "atan2<mode>3"
17169   [(use (match_operand:MODEF 0 "register_operand" ""))
17170    (use (match_operand:MODEF 1 "register_operand" ""))
17171    (use (match_operand:MODEF 2 "register_operand" ""))]
17172   "TARGET_USE_FANCY_MATH_387
17173    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17174        || TARGET_MIX_SSE_I387)
17175    && flag_unsafe_math_optimizations"
17177   rtx op0 = gen_reg_rtx (XFmode);
17179   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17180   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17181   DONE;
17184 (define_expand "atanxf2"
17185   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17186                    (unspec:XF [(match_dup 2)
17187                                (match_operand:XF 1 "register_operand" "")]
17188                               UNSPEC_FPATAN))
17189               (clobber (match_scratch:XF 3 ""))])]
17190   "TARGET_USE_FANCY_MATH_387
17191    && flag_unsafe_math_optimizations"
17193   operands[2] = gen_reg_rtx (XFmode);
17194   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17197 (define_expand "atan<mode>2"
17198   [(use (match_operand:MODEF 0 "register_operand" ""))
17199    (use (match_operand:MODEF 1 "register_operand" ""))]
17200   "TARGET_USE_FANCY_MATH_387
17201    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17202        || TARGET_MIX_SSE_I387)
17203    && flag_unsafe_math_optimizations"
17205   rtx op0 = gen_reg_rtx (XFmode);
17207   rtx op2 = gen_reg_rtx (<MODE>mode);
17208   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17210   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17211   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17212   DONE;
17215 (define_expand "asinxf2"
17216   [(set (match_dup 2)
17217         (mult:XF (match_operand:XF 1 "register_operand" "")
17218                  (match_dup 1)))
17219    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17220    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17221    (parallel [(set (match_operand:XF 0 "register_operand" "")
17222                    (unspec:XF [(match_dup 5) (match_dup 1)]
17223                               UNSPEC_FPATAN))
17224               (clobber (match_scratch:XF 6 ""))])]
17225   "TARGET_USE_FANCY_MATH_387
17226    && flag_unsafe_math_optimizations"
17228   int i;
17230   if (optimize_insn_for_size_p ())
17231     FAIL;
17233   for (i = 2; i < 6; i++)
17234     operands[i] = gen_reg_rtx (XFmode);
17236   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17239 (define_expand "asin<mode>2"
17240   [(use (match_operand:MODEF 0 "register_operand" ""))
17241    (use (match_operand:MODEF 1 "general_operand" ""))]
17242  "TARGET_USE_FANCY_MATH_387
17243    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17244        || TARGET_MIX_SSE_I387)
17245    && flag_unsafe_math_optimizations"
17247   rtx op0 = gen_reg_rtx (XFmode);
17248   rtx op1 = gen_reg_rtx (XFmode);
17250   if (optimize_insn_for_size_p ())
17251     FAIL;
17253   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17254   emit_insn (gen_asinxf2 (op0, op1));
17255   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17256   DONE;
17259 (define_expand "acosxf2"
17260   [(set (match_dup 2)
17261         (mult:XF (match_operand:XF 1 "register_operand" "")
17262                  (match_dup 1)))
17263    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17264    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17265    (parallel [(set (match_operand:XF 0 "register_operand" "")
17266                    (unspec:XF [(match_dup 1) (match_dup 5)]
17267                               UNSPEC_FPATAN))
17268               (clobber (match_scratch:XF 6 ""))])]
17269   "TARGET_USE_FANCY_MATH_387
17270    && flag_unsafe_math_optimizations"
17272   int i;
17274   if (optimize_insn_for_size_p ())
17275     FAIL;
17277   for (i = 2; i < 6; i++)
17278     operands[i] = gen_reg_rtx (XFmode);
17280   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17283 (define_expand "acos<mode>2"
17284   [(use (match_operand:MODEF 0 "register_operand" ""))
17285    (use (match_operand:MODEF 1 "general_operand" ""))]
17286  "TARGET_USE_FANCY_MATH_387
17287    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17288        || TARGET_MIX_SSE_I387)
17289    && flag_unsafe_math_optimizations"
17291   rtx op0 = gen_reg_rtx (XFmode);
17292   rtx op1 = gen_reg_rtx (XFmode);
17294   if (optimize_insn_for_size_p ())
17295     FAIL;
17297   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17298   emit_insn (gen_acosxf2 (op0, op1));
17299   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17300   DONE;
17303 (define_insn "fyl2xxf3_i387"
17304   [(set (match_operand:XF 0 "register_operand" "=f")
17305         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17306                     (match_operand:XF 2 "register_operand" "u")]
17307                    UNSPEC_FYL2X))
17308    (clobber (match_scratch:XF 3 "=2"))]
17309   "TARGET_USE_FANCY_MATH_387
17310    && flag_unsafe_math_optimizations"
17311   "fyl2x"
17312   [(set_attr "type" "fpspc")
17313    (set_attr "mode" "XF")])
17315 (define_insn "fyl2x_extend<mode>xf3_i387"
17316   [(set (match_operand:XF 0 "register_operand" "=f")
17317         (unspec:XF [(float_extend:XF
17318                       (match_operand:MODEF 1 "register_operand" "0"))
17319                     (match_operand:XF 2 "register_operand" "u")]
17320                    UNSPEC_FYL2X))
17321    (clobber (match_scratch:XF 3 "=2"))]
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   "fyl2x"
17327   [(set_attr "type" "fpspc")
17328    (set_attr "mode" "XF")])
17330 (define_expand "logxf2"
17331   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17332                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17333                                (match_dup 2)] UNSPEC_FYL2X))
17334               (clobber (match_scratch:XF 3 ""))])]
17335   "TARGET_USE_FANCY_MATH_387
17336    && flag_unsafe_math_optimizations"
17338   operands[2] = gen_reg_rtx (XFmode);
17339   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17342 (define_expand "log<mode>2"
17343   [(use (match_operand:MODEF 0 "register_operand" ""))
17344    (use (match_operand:MODEF 1 "register_operand" ""))]
17345   "TARGET_USE_FANCY_MATH_387
17346    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17347        || TARGET_MIX_SSE_I387)
17348    && flag_unsafe_math_optimizations"
17350   rtx op0 = gen_reg_rtx (XFmode);
17352   rtx op2 = gen_reg_rtx (XFmode);
17353   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17355   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17356   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17357   DONE;
17360 (define_expand "log10xf2"
17361   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17362                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17363                                (match_dup 2)] UNSPEC_FYL2X))
17364               (clobber (match_scratch:XF 3 ""))])]
17365   "TARGET_USE_FANCY_MATH_387
17366    && flag_unsafe_math_optimizations"
17368   operands[2] = gen_reg_rtx (XFmode);
17369   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17372 (define_expand "log10<mode>2"
17373   [(use (match_operand:MODEF 0 "register_operand" ""))
17374    (use (match_operand:MODEF 1 "register_operand" ""))]
17375   "TARGET_USE_FANCY_MATH_387
17376    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17377        || TARGET_MIX_SSE_I387)
17378    && flag_unsafe_math_optimizations"
17380   rtx op0 = gen_reg_rtx (XFmode);
17382   rtx op2 = gen_reg_rtx (XFmode);
17383   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17385   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17386   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17387   DONE;
17390 (define_expand "log2xf2"
17391   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17392                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17393                                (match_dup 2)] UNSPEC_FYL2X))
17394               (clobber (match_scratch:XF 3 ""))])]
17395   "TARGET_USE_FANCY_MATH_387
17396    && flag_unsafe_math_optimizations"
17398   operands[2] = gen_reg_rtx (XFmode);
17399   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17402 (define_expand "log2<mode>2"
17403   [(use (match_operand:MODEF 0 "register_operand" ""))
17404    (use (match_operand:MODEF 1 "register_operand" ""))]
17405   "TARGET_USE_FANCY_MATH_387
17406    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17407        || TARGET_MIX_SSE_I387)
17408    && flag_unsafe_math_optimizations"
17410   rtx op0 = gen_reg_rtx (XFmode);
17412   rtx op2 = gen_reg_rtx (XFmode);
17413   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17415   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17416   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17417   DONE;
17420 (define_insn "fyl2xp1xf3_i387"
17421   [(set (match_operand:XF 0 "register_operand" "=f")
17422         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17423                     (match_operand:XF 2 "register_operand" "u")]
17424                    UNSPEC_FYL2XP1))
17425    (clobber (match_scratch:XF 3 "=2"))]
17426   "TARGET_USE_FANCY_MATH_387
17427    && flag_unsafe_math_optimizations"
17428   "fyl2xp1"
17429   [(set_attr "type" "fpspc")
17430    (set_attr "mode" "XF")])
17432 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17433   [(set (match_operand:XF 0 "register_operand" "=f")
17434         (unspec:XF [(float_extend:XF
17435                       (match_operand:MODEF 1 "register_operand" "0"))
17436                     (match_operand:XF 2 "register_operand" "u")]
17437                    UNSPEC_FYL2XP1))
17438    (clobber (match_scratch:XF 3 "=2"))]
17439   "TARGET_USE_FANCY_MATH_387
17440    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17441        || TARGET_MIX_SSE_I387)
17442    && flag_unsafe_math_optimizations"
17443   "fyl2xp1"
17444   [(set_attr "type" "fpspc")
17445    (set_attr "mode" "XF")])
17447 (define_expand "log1pxf2"
17448   [(use (match_operand:XF 0 "register_operand" ""))
17449    (use (match_operand:XF 1 "register_operand" ""))]
17450   "TARGET_USE_FANCY_MATH_387
17451    && flag_unsafe_math_optimizations"
17453   if (optimize_insn_for_size_p ())
17454     FAIL;
17456   ix86_emit_i387_log1p (operands[0], operands[1]);
17457   DONE;
17460 (define_expand "log1p<mode>2"
17461   [(use (match_operand:MODEF 0 "register_operand" ""))
17462    (use (match_operand:MODEF 1 "register_operand" ""))]
17463   "TARGET_USE_FANCY_MATH_387
17464    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17465        || TARGET_MIX_SSE_I387)
17466    && flag_unsafe_math_optimizations"
17468   rtx op0;
17470   if (optimize_insn_for_size_p ())
17471     FAIL;
17473   op0 = gen_reg_rtx (XFmode);
17475   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17477   ix86_emit_i387_log1p (op0, operands[1]);
17478   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17479   DONE;
17482 (define_insn "fxtractxf3_i387"
17483   [(set (match_operand:XF 0 "register_operand" "=f")
17484         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17485                    UNSPEC_XTRACT_FRACT))
17486    (set (match_operand:XF 1 "register_operand" "=u")
17487         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17488   "TARGET_USE_FANCY_MATH_387
17489    && flag_unsafe_math_optimizations"
17490   "fxtract"
17491   [(set_attr "type" "fpspc")
17492    (set_attr "mode" "XF")])
17494 (define_insn "fxtract_extend<mode>xf3_i387"
17495   [(set (match_operand:XF 0 "register_operand" "=f")
17496         (unspec:XF [(float_extend:XF
17497                       (match_operand:MODEF 2 "register_operand" "0"))]
17498                    UNSPEC_XTRACT_FRACT))
17499    (set (match_operand:XF 1 "register_operand" "=u")
17500         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17501   "TARGET_USE_FANCY_MATH_387
17502    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17503        || TARGET_MIX_SSE_I387)
17504    && flag_unsafe_math_optimizations"
17505   "fxtract"
17506   [(set_attr "type" "fpspc")
17507    (set_attr "mode" "XF")])
17509 (define_expand "logbxf2"
17510   [(parallel [(set (match_dup 2)
17511                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17512                               UNSPEC_XTRACT_FRACT))
17513               (set (match_operand:XF 0 "register_operand" "")
17514                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17515   "TARGET_USE_FANCY_MATH_387
17516    && flag_unsafe_math_optimizations"
17518   operands[2] = gen_reg_rtx (XFmode);
17521 (define_expand "logb<mode>2"
17522   [(use (match_operand:MODEF 0 "register_operand" ""))
17523    (use (match_operand:MODEF 1 "register_operand" ""))]
17524   "TARGET_USE_FANCY_MATH_387
17525    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17526        || TARGET_MIX_SSE_I387)
17527    && flag_unsafe_math_optimizations"
17529   rtx op0 = gen_reg_rtx (XFmode);
17530   rtx op1 = gen_reg_rtx (XFmode);
17532   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17533   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17534   DONE;
17537 (define_expand "ilogbxf2"
17538   [(use (match_operand:SI 0 "register_operand" ""))
17539    (use (match_operand:XF 1 "register_operand" ""))]
17540   "TARGET_USE_FANCY_MATH_387
17541    && flag_unsafe_math_optimizations"
17543   rtx op0, op1;
17545   if (optimize_insn_for_size_p ())
17546     FAIL;
17548   op0 = gen_reg_rtx (XFmode);
17549   op1 = gen_reg_rtx (XFmode);
17551   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17552   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17553   DONE;
17556 (define_expand "ilogb<mode>2"
17557   [(use (match_operand:SI 0 "register_operand" ""))
17558    (use (match_operand:MODEF 1 "register_operand" ""))]
17559   "TARGET_USE_FANCY_MATH_387
17560    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17561        || TARGET_MIX_SSE_I387)
17562    && flag_unsafe_math_optimizations"
17564   rtx op0, op1;
17566   if (optimize_insn_for_size_p ())
17567     FAIL;
17569   op0 = gen_reg_rtx (XFmode);
17570   op1 = gen_reg_rtx (XFmode);
17572   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17573   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17574   DONE;
17577 (define_insn "*f2xm1xf2_i387"
17578   [(set (match_operand:XF 0 "register_operand" "=f")
17579         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17580                    UNSPEC_F2XM1))]
17581   "TARGET_USE_FANCY_MATH_387
17582    && flag_unsafe_math_optimizations"
17583   "f2xm1"
17584   [(set_attr "type" "fpspc")
17585    (set_attr "mode" "XF")])
17587 (define_insn "*fscalexf4_i387"
17588   [(set (match_operand:XF 0 "register_operand" "=f")
17589         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17590                     (match_operand:XF 3 "register_operand" "1")]
17591                    UNSPEC_FSCALE_FRACT))
17592    (set (match_operand:XF 1 "register_operand" "=u")
17593         (unspec:XF [(match_dup 2) (match_dup 3)]
17594                    UNSPEC_FSCALE_EXP))]
17595   "TARGET_USE_FANCY_MATH_387
17596    && flag_unsafe_math_optimizations"
17597   "fscale"
17598   [(set_attr "type" "fpspc")
17599    (set_attr "mode" "XF")])
17601 (define_expand "expNcorexf3"
17602   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17603                                (match_operand:XF 2 "register_operand" "")))
17604    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17605    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17606    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17607    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17608    (parallel [(set (match_operand:XF 0 "register_operand" "")
17609                    (unspec:XF [(match_dup 8) (match_dup 4)]
17610                               UNSPEC_FSCALE_FRACT))
17611               (set (match_dup 9)
17612                    (unspec:XF [(match_dup 8) (match_dup 4)]
17613                               UNSPEC_FSCALE_EXP))])]
17614   "TARGET_USE_FANCY_MATH_387
17615    && flag_unsafe_math_optimizations"
17617   int i;
17619   if (optimize_insn_for_size_p ())
17620     FAIL;
17622   for (i = 3; i < 10; i++)
17623     operands[i] = gen_reg_rtx (XFmode);
17625   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17628 (define_expand "expxf2"
17629   [(use (match_operand:XF 0 "register_operand" ""))
17630    (use (match_operand:XF 1 "register_operand" ""))]
17631   "TARGET_USE_FANCY_MATH_387
17632    && flag_unsafe_math_optimizations"
17634   rtx op2;
17636   if (optimize_insn_for_size_p ())
17637     FAIL;
17639   op2 = gen_reg_rtx (XFmode);
17640   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17642   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17643   DONE;
17646 (define_expand "exp<mode>2"
17647   [(use (match_operand:MODEF 0 "register_operand" ""))
17648    (use (match_operand:MODEF 1 "general_operand" ""))]
17649  "TARGET_USE_FANCY_MATH_387
17650    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17651        || TARGET_MIX_SSE_I387)
17652    && flag_unsafe_math_optimizations"
17654   rtx op0, op1;
17656   if (optimize_insn_for_size_p ())
17657     FAIL;
17659   op0 = gen_reg_rtx (XFmode);
17660   op1 = gen_reg_rtx (XFmode);
17662   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17663   emit_insn (gen_expxf2 (op0, op1));
17664   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17665   DONE;
17668 (define_expand "exp10xf2"
17669   [(use (match_operand:XF 0 "register_operand" ""))
17670    (use (match_operand:XF 1 "register_operand" ""))]
17671   "TARGET_USE_FANCY_MATH_387
17672    && flag_unsafe_math_optimizations"
17674   rtx op2;
17676   if (optimize_insn_for_size_p ())
17677     FAIL;
17679   op2 = gen_reg_rtx (XFmode);
17680   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17682   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17683   DONE;
17686 (define_expand "exp10<mode>2"
17687   [(use (match_operand:MODEF 0 "register_operand" ""))
17688    (use (match_operand:MODEF 1 "general_operand" ""))]
17689  "TARGET_USE_FANCY_MATH_387
17690    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17691        || TARGET_MIX_SSE_I387)
17692    && flag_unsafe_math_optimizations"
17694   rtx op0, op1;
17696   if (optimize_insn_for_size_p ())
17697     FAIL;
17699   op0 = gen_reg_rtx (XFmode);
17700   op1 = gen_reg_rtx (XFmode);
17702   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17703   emit_insn (gen_exp10xf2 (op0, op1));
17704   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17705   DONE;
17708 (define_expand "exp2xf2"
17709   [(use (match_operand:XF 0 "register_operand" ""))
17710    (use (match_operand:XF 1 "register_operand" ""))]
17711   "TARGET_USE_FANCY_MATH_387
17712    && flag_unsafe_math_optimizations"
17714   rtx op2;
17716   if (optimize_insn_for_size_p ())
17717     FAIL;
17719   op2 = gen_reg_rtx (XFmode);
17720   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17722   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17723   DONE;
17726 (define_expand "exp2<mode>2"
17727   [(use (match_operand:MODEF 0 "register_operand" ""))
17728    (use (match_operand:MODEF 1 "general_operand" ""))]
17729  "TARGET_USE_FANCY_MATH_387
17730    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17731        || TARGET_MIX_SSE_I387)
17732    && flag_unsafe_math_optimizations"
17734   rtx op0, op1;
17736   if (optimize_insn_for_size_p ())
17737     FAIL;
17739   op0 = gen_reg_rtx (XFmode);
17740   op1 = gen_reg_rtx (XFmode);
17742   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17743   emit_insn (gen_exp2xf2 (op0, op1));
17744   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17745   DONE;
17748 (define_expand "expm1xf2"
17749   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17750                                (match_dup 2)))
17751    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17752    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17753    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17754    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17755    (parallel [(set (match_dup 7)
17756                    (unspec:XF [(match_dup 6) (match_dup 4)]
17757                               UNSPEC_FSCALE_FRACT))
17758               (set (match_dup 8)
17759                    (unspec:XF [(match_dup 6) (match_dup 4)]
17760                               UNSPEC_FSCALE_EXP))])
17761    (parallel [(set (match_dup 10)
17762                    (unspec:XF [(match_dup 9) (match_dup 8)]
17763                               UNSPEC_FSCALE_FRACT))
17764               (set (match_dup 11)
17765                    (unspec:XF [(match_dup 9) (match_dup 8)]
17766                               UNSPEC_FSCALE_EXP))])
17767    (set (match_dup 12) (minus:XF (match_dup 10)
17768                                  (float_extend:XF (match_dup 13))))
17769    (set (match_operand:XF 0 "register_operand" "")
17770         (plus:XF (match_dup 12) (match_dup 7)))]
17771   "TARGET_USE_FANCY_MATH_387
17772    && flag_unsafe_math_optimizations"
17774   int i;
17776   if (optimize_insn_for_size_p ())
17777     FAIL;
17779   for (i = 2; i < 13; i++)
17780     operands[i] = gen_reg_rtx (XFmode);
17782   operands[13]
17783     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17785   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17788 (define_expand "expm1<mode>2"
17789   [(use (match_operand:MODEF 0 "register_operand" ""))
17790    (use (match_operand:MODEF 1 "general_operand" ""))]
17791  "TARGET_USE_FANCY_MATH_387
17792    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17793        || TARGET_MIX_SSE_I387)
17794    && flag_unsafe_math_optimizations"
17796   rtx op0, op1;
17798   if (optimize_insn_for_size_p ())
17799     FAIL;
17801   op0 = gen_reg_rtx (XFmode);
17802   op1 = gen_reg_rtx (XFmode);
17804   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17805   emit_insn (gen_expm1xf2 (op0, op1));
17806   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17807   DONE;
17810 (define_expand "ldexpxf3"
17811   [(set (match_dup 3)
17812         (float:XF (match_operand:SI 2 "register_operand" "")))
17813    (parallel [(set (match_operand:XF 0 " register_operand" "")
17814                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17815                                (match_dup 3)]
17816                               UNSPEC_FSCALE_FRACT))
17817               (set (match_dup 4)
17818                    (unspec:XF [(match_dup 1) (match_dup 3)]
17819                               UNSPEC_FSCALE_EXP))])]
17820   "TARGET_USE_FANCY_MATH_387
17821    && flag_unsafe_math_optimizations"
17823   if (optimize_insn_for_size_p ())
17824     FAIL;
17826   operands[3] = gen_reg_rtx (XFmode);
17827   operands[4] = gen_reg_rtx (XFmode);
17830 (define_expand "ldexp<mode>3"
17831   [(use (match_operand:MODEF 0 "register_operand" ""))
17832    (use (match_operand:MODEF 1 "general_operand" ""))
17833    (use (match_operand:SI 2 "register_operand" ""))]
17834  "TARGET_USE_FANCY_MATH_387
17835    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17836        || TARGET_MIX_SSE_I387)
17837    && flag_unsafe_math_optimizations"
17839   rtx op0, op1;
17841   if (optimize_insn_for_size_p ())
17842     FAIL;
17844   op0 = gen_reg_rtx (XFmode);
17845   op1 = gen_reg_rtx (XFmode);
17847   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17848   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17849   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17850   DONE;
17853 (define_expand "scalbxf3"
17854   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17855                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17856                                (match_operand:XF 2 "register_operand" "")]
17857                               UNSPEC_FSCALE_FRACT))
17858               (set (match_dup 3)
17859                    (unspec:XF [(match_dup 1) (match_dup 2)]
17860                               UNSPEC_FSCALE_EXP))])]
17861   "TARGET_USE_FANCY_MATH_387
17862    && flag_unsafe_math_optimizations"
17864   if (optimize_insn_for_size_p ())
17865     FAIL;
17867   operands[3] = gen_reg_rtx (XFmode);
17870 (define_expand "scalb<mode>3"
17871   [(use (match_operand:MODEF 0 "register_operand" ""))
17872    (use (match_operand:MODEF 1 "general_operand" ""))
17873    (use (match_operand:MODEF 2 "register_operand" ""))]
17874  "TARGET_USE_FANCY_MATH_387
17875    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17876        || TARGET_MIX_SSE_I387)
17877    && flag_unsafe_math_optimizations"
17879   rtx op0, op1, op2;
17881   if (optimize_insn_for_size_p ())
17882     FAIL;
17884   op0 = gen_reg_rtx (XFmode);
17885   op1 = gen_reg_rtx (XFmode);
17886   op2 = gen_reg_rtx (XFmode);
17888   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17889   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17890   emit_insn (gen_scalbxf3 (op0, op1, op2));
17891   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17892   DONE;
17896 (define_insn "sse4_1_round<mode>2"
17897   [(set (match_operand:MODEF 0 "register_operand" "=x")
17898         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17899                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17900                       UNSPEC_ROUND))]
17901   "TARGET_ROUND"
17902   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17903   [(set_attr "type" "ssecvt")
17904    (set_attr "prefix_extra" "1")
17905    (set_attr "prefix" "maybe_vex")
17906    (set_attr "mode" "<MODE>")])
17908 (define_insn "rintxf2"
17909   [(set (match_operand:XF 0 "register_operand" "=f")
17910         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17911                    UNSPEC_FRNDINT))]
17912   "TARGET_USE_FANCY_MATH_387
17913    && flag_unsafe_math_optimizations"
17914   "frndint"
17915   [(set_attr "type" "fpspc")
17916    (set_attr "mode" "XF")])
17918 (define_expand "rint<mode>2"
17919   [(use (match_operand:MODEF 0 "register_operand" ""))
17920    (use (match_operand:MODEF 1 "register_operand" ""))]
17921   "(TARGET_USE_FANCY_MATH_387
17922     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17923         || TARGET_MIX_SSE_I387)
17924     && flag_unsafe_math_optimizations)
17925    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17926        && !flag_trapping_math)"
17928   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17929       && !flag_trapping_math)
17930     {
17931       if (!TARGET_ROUND && optimize_insn_for_size_p ())
17932         FAIL;
17933       if (TARGET_ROUND)
17934         emit_insn (gen_sse4_1_round<mode>2
17935                    (operands[0], operands[1], GEN_INT (0x04)));
17936       else
17937         ix86_expand_rint (operand0, operand1);
17938     }
17939   else
17940     {
17941       rtx op0 = gen_reg_rtx (XFmode);
17942       rtx op1 = gen_reg_rtx (XFmode);
17944       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17945       emit_insn (gen_rintxf2 (op0, op1));
17947       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17948     }
17949   DONE;
17952 (define_expand "round<mode>2"
17953   [(match_operand:MODEF 0 "register_operand" "")
17954    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17955   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17956    && !flag_trapping_math && !flag_rounding_math"
17958   if (optimize_insn_for_size_p ())
17959     FAIL;
17960   if (TARGET_64BIT || (<MODE>mode != DFmode))
17961     ix86_expand_round (operand0, operand1);
17962   else
17963     ix86_expand_rounddf_32 (operand0, operand1);
17964   DONE;
17967 (define_insn_and_split "*fistdi2_1"
17968   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17969         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17970                    UNSPEC_FIST))]
17971   "TARGET_USE_FANCY_MATH_387
17972    && !(reload_completed || reload_in_progress)"
17973   "#"
17974   "&& 1"
17975   [(const_int 0)]
17977   if (memory_operand (operands[0], VOIDmode))
17978     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17979   else
17980     {
17981       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17982       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17983                                          operands[2]));
17984     }
17985   DONE;
17987   [(set_attr "type" "fpspc")
17988    (set_attr "mode" "DI")])
17990 (define_insn "fistdi2"
17991   [(set (match_operand:DI 0 "memory_operand" "=m")
17992         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17993                    UNSPEC_FIST))
17994    (clobber (match_scratch:XF 2 "=&1f"))]
17995   "TARGET_USE_FANCY_MATH_387"
17996   "* return output_fix_trunc (insn, operands, 0);"
17997   [(set_attr "type" "fpspc")
17998    (set_attr "mode" "DI")])
18000 (define_insn "fistdi2_with_temp"
18001   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18002         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18003                    UNSPEC_FIST))
18004    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18005    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18006   "TARGET_USE_FANCY_MATH_387"
18007   "#"
18008   [(set_attr "type" "fpspc")
18009    (set_attr "mode" "DI")])
18011 (define_split
18012   [(set (match_operand:DI 0 "register_operand" "")
18013         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18014                    UNSPEC_FIST))
18015    (clobber (match_operand:DI 2 "memory_operand" ""))
18016    (clobber (match_scratch 3 ""))]
18017   "reload_completed"
18018   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18019               (clobber (match_dup 3))])
18020    (set (match_dup 0) (match_dup 2))]
18021   "")
18023 (define_split
18024   [(set (match_operand:DI 0 "memory_operand" "")
18025         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18026                    UNSPEC_FIST))
18027    (clobber (match_operand:DI 2 "memory_operand" ""))
18028    (clobber (match_scratch 3 ""))]
18029   "reload_completed"
18030   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18031               (clobber (match_dup 3))])]
18032   "")
18034 (define_insn_and_split "*fist<mode>2_1"
18035   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18036         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18037                            UNSPEC_FIST))]
18038   "TARGET_USE_FANCY_MATH_387
18039    && !(reload_completed || reload_in_progress)"
18040   "#"
18041   "&& 1"
18042   [(const_int 0)]
18044   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18045   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18046                                         operands[2]));
18047   DONE;
18049   [(set_attr "type" "fpspc")
18050    (set_attr "mode" "<MODE>")])
18052 (define_insn "fist<mode>2"
18053   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18054         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18055                            UNSPEC_FIST))]
18056   "TARGET_USE_FANCY_MATH_387"
18057   "* return output_fix_trunc (insn, operands, 0);"
18058   [(set_attr "type" "fpspc")
18059    (set_attr "mode" "<MODE>")])
18061 (define_insn "fist<mode>2_with_temp"
18062   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18063         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18064                            UNSPEC_FIST))
18065    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18066   "TARGET_USE_FANCY_MATH_387"
18067   "#"
18068   [(set_attr "type" "fpspc")
18069    (set_attr "mode" "<MODE>")])
18071 (define_split
18072   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18073         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18074                            UNSPEC_FIST))
18075    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18076   "reload_completed"
18077   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18078    (set (match_dup 0) (match_dup 2))]
18079   "")
18081 (define_split
18082   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18083         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18084                            UNSPEC_FIST))
18085    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18086   "reload_completed"
18087   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18088   "")
18090 (define_expand "lrintxf<mode>2"
18091   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18092      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18093                       UNSPEC_FIST))]
18094   "TARGET_USE_FANCY_MATH_387"
18095   "")
18097 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18098   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18099      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18100                         UNSPEC_FIX_NOTRUNC))]
18101   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18102    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18103   "")
18105 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18106   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18107    (match_operand:MODEF 1 "register_operand" "")]
18108   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18109    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18110    && !flag_trapping_math && !flag_rounding_math"
18112   if (optimize_insn_for_size_p ())
18113     FAIL;
18114   ix86_expand_lround (operand0, operand1);
18115   DONE;
18118 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18119 (define_insn_and_split "frndintxf2_floor"
18120   [(set (match_operand:XF 0 "register_operand" "")
18121         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18122          UNSPEC_FRNDINT_FLOOR))
18123    (clobber (reg:CC FLAGS_REG))]
18124   "TARGET_USE_FANCY_MATH_387
18125    && flag_unsafe_math_optimizations
18126    && !(reload_completed || reload_in_progress)"
18127   "#"
18128   "&& 1"
18129   [(const_int 0)]
18131   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18133   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18134   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18136   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18137                                         operands[2], operands[3]));
18138   DONE;
18140   [(set_attr "type" "frndint")
18141    (set_attr "i387_cw" "floor")
18142    (set_attr "mode" "XF")])
18144 (define_insn "frndintxf2_floor_i387"
18145   [(set (match_operand:XF 0 "register_operand" "=f")
18146         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18147          UNSPEC_FRNDINT_FLOOR))
18148    (use (match_operand:HI 2 "memory_operand" "m"))
18149    (use (match_operand:HI 3 "memory_operand" "m"))]
18150   "TARGET_USE_FANCY_MATH_387
18151    && flag_unsafe_math_optimizations"
18152   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18153   [(set_attr "type" "frndint")
18154    (set_attr "i387_cw" "floor")
18155    (set_attr "mode" "XF")])
18157 (define_expand "floorxf2"
18158   [(use (match_operand:XF 0 "register_operand" ""))
18159    (use (match_operand:XF 1 "register_operand" ""))]
18160   "TARGET_USE_FANCY_MATH_387
18161    && flag_unsafe_math_optimizations"
18163   if (optimize_insn_for_size_p ())
18164     FAIL;
18165   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18166   DONE;
18169 (define_expand "floor<mode>2"
18170   [(use (match_operand:MODEF 0 "register_operand" ""))
18171    (use (match_operand:MODEF 1 "register_operand" ""))]
18172   "(TARGET_USE_FANCY_MATH_387
18173     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18174         || TARGET_MIX_SSE_I387)
18175     && flag_unsafe_math_optimizations)
18176    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18177        && !flag_trapping_math)"
18179   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18180       && !flag_trapping_math
18181       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18182     {
18183       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18184         FAIL;
18185       if (TARGET_ROUND)
18186         emit_insn (gen_sse4_1_round<mode>2
18187                    (operands[0], operands[1], GEN_INT (0x01)));
18188       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18189         ix86_expand_floorceil (operand0, operand1, true);
18190       else
18191         ix86_expand_floorceildf_32 (operand0, operand1, true);
18192     }
18193   else
18194     {
18195       rtx op0, op1;
18197       if (optimize_insn_for_size_p ())
18198         FAIL;
18200       op0 = gen_reg_rtx (XFmode);
18201       op1 = gen_reg_rtx (XFmode);
18202       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18203       emit_insn (gen_frndintxf2_floor (op0, op1));
18205       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18206     }
18207   DONE;
18210 (define_insn_and_split "*fist<mode>2_floor_1"
18211   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18212         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18213          UNSPEC_FIST_FLOOR))
18214    (clobber (reg:CC FLAGS_REG))]
18215   "TARGET_USE_FANCY_MATH_387
18216    && flag_unsafe_math_optimizations
18217    && !(reload_completed || reload_in_progress)"
18218   "#"
18219   "&& 1"
18220   [(const_int 0)]
18222   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18224   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18225   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18226   if (memory_operand (operands[0], VOIDmode))
18227     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18228                                       operands[2], operands[3]));
18229   else
18230     {
18231       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18232       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18233                                                   operands[2], operands[3],
18234                                                   operands[4]));
18235     }
18236   DONE;
18238   [(set_attr "type" "fistp")
18239    (set_attr "i387_cw" "floor")
18240    (set_attr "mode" "<MODE>")])
18242 (define_insn "fistdi2_floor"
18243   [(set (match_operand:DI 0 "memory_operand" "=m")
18244         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18245          UNSPEC_FIST_FLOOR))
18246    (use (match_operand:HI 2 "memory_operand" "m"))
18247    (use (match_operand:HI 3 "memory_operand" "m"))
18248    (clobber (match_scratch:XF 4 "=&1f"))]
18249   "TARGET_USE_FANCY_MATH_387
18250    && flag_unsafe_math_optimizations"
18251   "* return output_fix_trunc (insn, operands, 0);"
18252   [(set_attr "type" "fistp")
18253    (set_attr "i387_cw" "floor")
18254    (set_attr "mode" "DI")])
18256 (define_insn "fistdi2_floor_with_temp"
18257   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18258         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18259          UNSPEC_FIST_FLOOR))
18260    (use (match_operand:HI 2 "memory_operand" "m,m"))
18261    (use (match_operand:HI 3 "memory_operand" "m,m"))
18262    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18263    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18264   "TARGET_USE_FANCY_MATH_387
18265    && flag_unsafe_math_optimizations"
18266   "#"
18267   [(set_attr "type" "fistp")
18268    (set_attr "i387_cw" "floor")
18269    (set_attr "mode" "DI")])
18271 (define_split
18272   [(set (match_operand:DI 0 "register_operand" "")
18273         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18274          UNSPEC_FIST_FLOOR))
18275    (use (match_operand:HI 2 "memory_operand" ""))
18276    (use (match_operand:HI 3 "memory_operand" ""))
18277    (clobber (match_operand:DI 4 "memory_operand" ""))
18278    (clobber (match_scratch 5 ""))]
18279   "reload_completed"
18280   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18281               (use (match_dup 2))
18282               (use (match_dup 3))
18283               (clobber (match_dup 5))])
18284    (set (match_dup 0) (match_dup 4))]
18285   "")
18287 (define_split
18288   [(set (match_operand:DI 0 "memory_operand" "")
18289         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18290          UNSPEC_FIST_FLOOR))
18291    (use (match_operand:HI 2 "memory_operand" ""))
18292    (use (match_operand:HI 3 "memory_operand" ""))
18293    (clobber (match_operand:DI 4 "memory_operand" ""))
18294    (clobber (match_scratch 5 ""))]
18295   "reload_completed"
18296   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18297               (use (match_dup 2))
18298               (use (match_dup 3))
18299               (clobber (match_dup 5))])]
18300   "")
18302 (define_insn "fist<mode>2_floor"
18303   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18304         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18305          UNSPEC_FIST_FLOOR))
18306    (use (match_operand:HI 2 "memory_operand" "m"))
18307    (use (match_operand:HI 3 "memory_operand" "m"))]
18308   "TARGET_USE_FANCY_MATH_387
18309    && flag_unsafe_math_optimizations"
18310   "* return output_fix_trunc (insn, operands, 0);"
18311   [(set_attr "type" "fistp")
18312    (set_attr "i387_cw" "floor")
18313    (set_attr "mode" "<MODE>")])
18315 (define_insn "fist<mode>2_floor_with_temp"
18316   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18317         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18318          UNSPEC_FIST_FLOOR))
18319    (use (match_operand:HI 2 "memory_operand" "m,m"))
18320    (use (match_operand:HI 3 "memory_operand" "m,m"))
18321    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18322   "TARGET_USE_FANCY_MATH_387
18323    && flag_unsafe_math_optimizations"
18324   "#"
18325   [(set_attr "type" "fistp")
18326    (set_attr "i387_cw" "floor")
18327    (set_attr "mode" "<MODE>")])
18329 (define_split
18330   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18331         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18332          UNSPEC_FIST_FLOOR))
18333    (use (match_operand:HI 2 "memory_operand" ""))
18334    (use (match_operand:HI 3 "memory_operand" ""))
18335    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18336   "reload_completed"
18337   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18338                                   UNSPEC_FIST_FLOOR))
18339               (use (match_dup 2))
18340               (use (match_dup 3))])
18341    (set (match_dup 0) (match_dup 4))]
18342   "")
18344 (define_split
18345   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18346         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18347          UNSPEC_FIST_FLOOR))
18348    (use (match_operand:HI 2 "memory_operand" ""))
18349    (use (match_operand:HI 3 "memory_operand" ""))
18350    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18351   "reload_completed"
18352   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18353                                   UNSPEC_FIST_FLOOR))
18354               (use (match_dup 2))
18355               (use (match_dup 3))])]
18356   "")
18358 (define_expand "lfloorxf<mode>2"
18359   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18360                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18361                     UNSPEC_FIST_FLOOR))
18362               (clobber (reg:CC FLAGS_REG))])]
18363   "TARGET_USE_FANCY_MATH_387
18364    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18365    && flag_unsafe_math_optimizations"
18366   "")
18368 (define_expand "lfloor<mode>di2"
18369   [(match_operand:DI 0 "nonimmediate_operand" "")
18370    (match_operand:MODEF 1 "register_operand" "")]
18371   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18372    && !flag_trapping_math"
18374   if (optimize_insn_for_size_p ())
18375     FAIL;
18376   ix86_expand_lfloorceil (operand0, operand1, true);
18377   DONE;
18380 (define_expand "lfloor<mode>si2"
18381   [(match_operand:SI 0 "nonimmediate_operand" "")
18382    (match_operand:MODEF 1 "register_operand" "")]
18383   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18384    && !flag_trapping_math"
18386   if (optimize_insn_for_size_p () && TARGET_64BIT)
18387     FAIL;
18388   ix86_expand_lfloorceil (operand0, operand1, true);
18389   DONE;
18392 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18393 (define_insn_and_split "frndintxf2_ceil"
18394   [(set (match_operand:XF 0 "register_operand" "")
18395         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18396          UNSPEC_FRNDINT_CEIL))
18397    (clobber (reg:CC FLAGS_REG))]
18398   "TARGET_USE_FANCY_MATH_387
18399    && flag_unsafe_math_optimizations
18400    && !(reload_completed || reload_in_progress)"
18401   "#"
18402   "&& 1"
18403   [(const_int 0)]
18405   ix86_optimize_mode_switching[I387_CEIL] = 1;
18407   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18408   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18410   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18411                                        operands[2], operands[3]));
18412   DONE;
18414   [(set_attr "type" "frndint")
18415    (set_attr "i387_cw" "ceil")
18416    (set_attr "mode" "XF")])
18418 (define_insn "frndintxf2_ceil_i387"
18419   [(set (match_operand:XF 0 "register_operand" "=f")
18420         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18421          UNSPEC_FRNDINT_CEIL))
18422    (use (match_operand:HI 2 "memory_operand" "m"))
18423    (use (match_operand:HI 3 "memory_operand" "m"))]
18424   "TARGET_USE_FANCY_MATH_387
18425    && flag_unsafe_math_optimizations"
18426   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18427   [(set_attr "type" "frndint")
18428    (set_attr "i387_cw" "ceil")
18429    (set_attr "mode" "XF")])
18431 (define_expand "ceilxf2"
18432   [(use (match_operand:XF 0 "register_operand" ""))
18433    (use (match_operand:XF 1 "register_operand" ""))]
18434   "TARGET_USE_FANCY_MATH_387
18435    && flag_unsafe_math_optimizations"
18437   if (optimize_insn_for_size_p ())
18438     FAIL;
18439   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18440   DONE;
18443 (define_expand "ceil<mode>2"
18444   [(use (match_operand:MODEF 0 "register_operand" ""))
18445    (use (match_operand:MODEF 1 "register_operand" ""))]
18446   "(TARGET_USE_FANCY_MATH_387
18447     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18448         || TARGET_MIX_SSE_I387)
18449     && flag_unsafe_math_optimizations)
18450    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18451        && !flag_trapping_math)"
18453   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18454       && !flag_trapping_math
18455       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18456     {
18457       if (TARGET_ROUND)
18458         emit_insn (gen_sse4_1_round<mode>2
18459                    (operands[0], operands[1], GEN_INT (0x02)));
18460       else if (optimize_insn_for_size_p ())
18461         FAIL;
18462       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18463         ix86_expand_floorceil (operand0, operand1, false);
18464       else
18465         ix86_expand_floorceildf_32 (operand0, operand1, false);
18466     }
18467   else
18468     {
18469       rtx op0, op1;
18471       if (optimize_insn_for_size_p ())
18472         FAIL;
18474       op0 = gen_reg_rtx (XFmode);
18475       op1 = gen_reg_rtx (XFmode);
18476       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18477       emit_insn (gen_frndintxf2_ceil (op0, op1));
18479       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18480     }
18481   DONE;
18484 (define_insn_and_split "*fist<mode>2_ceil_1"
18485   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18486         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18487          UNSPEC_FIST_CEIL))
18488    (clobber (reg:CC FLAGS_REG))]
18489   "TARGET_USE_FANCY_MATH_387
18490    && flag_unsafe_math_optimizations
18491    && !(reload_completed || reload_in_progress)"
18492   "#"
18493   "&& 1"
18494   [(const_int 0)]
18496   ix86_optimize_mode_switching[I387_CEIL] = 1;
18498   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18499   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18500   if (memory_operand (operands[0], VOIDmode))
18501     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18502                                      operands[2], operands[3]));
18503   else
18504     {
18505       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18506       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18507                                                  operands[2], operands[3],
18508                                                  operands[4]));
18509     }
18510   DONE;
18512   [(set_attr "type" "fistp")
18513    (set_attr "i387_cw" "ceil")
18514    (set_attr "mode" "<MODE>")])
18516 (define_insn "fistdi2_ceil"
18517   [(set (match_operand:DI 0 "memory_operand" "=m")
18518         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18519          UNSPEC_FIST_CEIL))
18520    (use (match_operand:HI 2 "memory_operand" "m"))
18521    (use (match_operand:HI 3 "memory_operand" "m"))
18522    (clobber (match_scratch:XF 4 "=&1f"))]
18523   "TARGET_USE_FANCY_MATH_387
18524    && flag_unsafe_math_optimizations"
18525   "* return output_fix_trunc (insn, operands, 0);"
18526   [(set_attr "type" "fistp")
18527    (set_attr "i387_cw" "ceil")
18528    (set_attr "mode" "DI")])
18530 (define_insn "fistdi2_ceil_with_temp"
18531   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18532         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18533          UNSPEC_FIST_CEIL))
18534    (use (match_operand:HI 2 "memory_operand" "m,m"))
18535    (use (match_operand:HI 3 "memory_operand" "m,m"))
18536    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18537    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18538   "TARGET_USE_FANCY_MATH_387
18539    && flag_unsafe_math_optimizations"
18540   "#"
18541   [(set_attr "type" "fistp")
18542    (set_attr "i387_cw" "ceil")
18543    (set_attr "mode" "DI")])
18545 (define_split
18546   [(set (match_operand:DI 0 "register_operand" "")
18547         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18548          UNSPEC_FIST_CEIL))
18549    (use (match_operand:HI 2 "memory_operand" ""))
18550    (use (match_operand:HI 3 "memory_operand" ""))
18551    (clobber (match_operand:DI 4 "memory_operand" ""))
18552    (clobber (match_scratch 5 ""))]
18553   "reload_completed"
18554   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18555               (use (match_dup 2))
18556               (use (match_dup 3))
18557               (clobber (match_dup 5))])
18558    (set (match_dup 0) (match_dup 4))]
18559   "")
18561 (define_split
18562   [(set (match_operand:DI 0 "memory_operand" "")
18563         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18564          UNSPEC_FIST_CEIL))
18565    (use (match_operand:HI 2 "memory_operand" ""))
18566    (use (match_operand:HI 3 "memory_operand" ""))
18567    (clobber (match_operand:DI 4 "memory_operand" ""))
18568    (clobber (match_scratch 5 ""))]
18569   "reload_completed"
18570   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18571               (use (match_dup 2))
18572               (use (match_dup 3))
18573               (clobber (match_dup 5))])]
18574   "")
18576 (define_insn "fist<mode>2_ceil"
18577   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18578         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18579          UNSPEC_FIST_CEIL))
18580    (use (match_operand:HI 2 "memory_operand" "m"))
18581    (use (match_operand:HI 3 "memory_operand" "m"))]
18582   "TARGET_USE_FANCY_MATH_387
18583    && flag_unsafe_math_optimizations"
18584   "* return output_fix_trunc (insn, operands, 0);"
18585   [(set_attr "type" "fistp")
18586    (set_attr "i387_cw" "ceil")
18587    (set_attr "mode" "<MODE>")])
18589 (define_insn "fist<mode>2_ceil_with_temp"
18590   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18591         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18592          UNSPEC_FIST_CEIL))
18593    (use (match_operand:HI 2 "memory_operand" "m,m"))
18594    (use (match_operand:HI 3 "memory_operand" "m,m"))
18595    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18596   "TARGET_USE_FANCY_MATH_387
18597    && flag_unsafe_math_optimizations"
18598   "#"
18599   [(set_attr "type" "fistp")
18600    (set_attr "i387_cw" "ceil")
18601    (set_attr "mode" "<MODE>")])
18603 (define_split
18604   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18605         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18606          UNSPEC_FIST_CEIL))
18607    (use (match_operand:HI 2 "memory_operand" ""))
18608    (use (match_operand:HI 3 "memory_operand" ""))
18609    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18610   "reload_completed"
18611   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18612                                   UNSPEC_FIST_CEIL))
18613               (use (match_dup 2))
18614               (use (match_dup 3))])
18615    (set (match_dup 0) (match_dup 4))]
18616   "")
18618 (define_split
18619   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18620         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18621          UNSPEC_FIST_CEIL))
18622    (use (match_operand:HI 2 "memory_operand" ""))
18623    (use (match_operand:HI 3 "memory_operand" ""))
18624    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18625   "reload_completed"
18626   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18627                                   UNSPEC_FIST_CEIL))
18628               (use (match_dup 2))
18629               (use (match_dup 3))])]
18630   "")
18632 (define_expand "lceilxf<mode>2"
18633   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18634                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18635                     UNSPEC_FIST_CEIL))
18636               (clobber (reg:CC FLAGS_REG))])]
18637   "TARGET_USE_FANCY_MATH_387
18638    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18639    && flag_unsafe_math_optimizations"
18640   "")
18642 (define_expand "lceil<mode>di2"
18643   [(match_operand:DI 0 "nonimmediate_operand" "")
18644    (match_operand:MODEF 1 "register_operand" "")]
18645   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18646    && !flag_trapping_math"
18648   ix86_expand_lfloorceil (operand0, operand1, false);
18649   DONE;
18652 (define_expand "lceil<mode>si2"
18653   [(match_operand:SI 0 "nonimmediate_operand" "")
18654    (match_operand:MODEF 1 "register_operand" "")]
18655   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18656    && !flag_trapping_math"
18658   ix86_expand_lfloorceil (operand0, operand1, false);
18659   DONE;
18662 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18663 (define_insn_and_split "frndintxf2_trunc"
18664   [(set (match_operand:XF 0 "register_operand" "")
18665         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18666          UNSPEC_FRNDINT_TRUNC))
18667    (clobber (reg:CC FLAGS_REG))]
18668   "TARGET_USE_FANCY_MATH_387
18669    && flag_unsafe_math_optimizations
18670    && !(reload_completed || reload_in_progress)"
18671   "#"
18672   "&& 1"
18673   [(const_int 0)]
18675   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18677   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18678   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18680   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18681                                         operands[2], operands[3]));
18682   DONE;
18684   [(set_attr "type" "frndint")
18685    (set_attr "i387_cw" "trunc")
18686    (set_attr "mode" "XF")])
18688 (define_insn "frndintxf2_trunc_i387"
18689   [(set (match_operand:XF 0 "register_operand" "=f")
18690         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18691          UNSPEC_FRNDINT_TRUNC))
18692    (use (match_operand:HI 2 "memory_operand" "m"))
18693    (use (match_operand:HI 3 "memory_operand" "m"))]
18694   "TARGET_USE_FANCY_MATH_387
18695    && flag_unsafe_math_optimizations"
18696   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18697   [(set_attr "type" "frndint")
18698    (set_attr "i387_cw" "trunc")
18699    (set_attr "mode" "XF")])
18701 (define_expand "btruncxf2"
18702   [(use (match_operand:XF 0 "register_operand" ""))
18703    (use (match_operand:XF 1 "register_operand" ""))]
18704   "TARGET_USE_FANCY_MATH_387
18705    && flag_unsafe_math_optimizations"
18707   if (optimize_insn_for_size_p ())
18708     FAIL;
18709   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18710   DONE;
18713 (define_expand "btrunc<mode>2"
18714   [(use (match_operand:MODEF 0 "register_operand" ""))
18715    (use (match_operand:MODEF 1 "register_operand" ""))]
18716   "(TARGET_USE_FANCY_MATH_387
18717     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18718         || TARGET_MIX_SSE_I387)
18719     && flag_unsafe_math_optimizations)
18720    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18721        && !flag_trapping_math)"
18723   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18724       && !flag_trapping_math
18725       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18726     {
18727       if (TARGET_ROUND)
18728         emit_insn (gen_sse4_1_round<mode>2
18729                    (operands[0], operands[1], GEN_INT (0x03)));
18730       else if (optimize_insn_for_size_p ())
18731         FAIL;
18732       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18733         ix86_expand_trunc (operand0, operand1);
18734       else
18735         ix86_expand_truncdf_32 (operand0, operand1);
18736     }
18737   else
18738     {
18739       rtx op0, op1;
18741       if (optimize_insn_for_size_p ())
18742         FAIL;
18744       op0 = gen_reg_rtx (XFmode);
18745       op1 = gen_reg_rtx (XFmode);
18746       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18747       emit_insn (gen_frndintxf2_trunc (op0, op1));
18749       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18750     }
18751   DONE;
18754 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18755 (define_insn_and_split "frndintxf2_mask_pm"
18756   [(set (match_operand:XF 0 "register_operand" "")
18757         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18758          UNSPEC_FRNDINT_MASK_PM))
18759    (clobber (reg:CC FLAGS_REG))]
18760   "TARGET_USE_FANCY_MATH_387
18761    && flag_unsafe_math_optimizations
18762    && !(reload_completed || reload_in_progress)"
18763   "#"
18764   "&& 1"
18765   [(const_int 0)]
18767   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18769   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18770   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18772   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18773                                           operands[2], operands[3]));
18774   DONE;
18776   [(set_attr "type" "frndint")
18777    (set_attr "i387_cw" "mask_pm")
18778    (set_attr "mode" "XF")])
18780 (define_insn "frndintxf2_mask_pm_i387"
18781   [(set (match_operand:XF 0 "register_operand" "=f")
18782         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18783          UNSPEC_FRNDINT_MASK_PM))
18784    (use (match_operand:HI 2 "memory_operand" "m"))
18785    (use (match_operand:HI 3 "memory_operand" "m"))]
18786   "TARGET_USE_FANCY_MATH_387
18787    && flag_unsafe_math_optimizations"
18788   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18789   [(set_attr "type" "frndint")
18790    (set_attr "i387_cw" "mask_pm")
18791    (set_attr "mode" "XF")])
18793 (define_expand "nearbyintxf2"
18794   [(use (match_operand:XF 0 "register_operand" ""))
18795    (use (match_operand:XF 1 "register_operand" ""))]
18796   "TARGET_USE_FANCY_MATH_387
18797    && flag_unsafe_math_optimizations"
18799   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18801   DONE;
18804 (define_expand "nearbyint<mode>2"
18805   [(use (match_operand:MODEF 0 "register_operand" ""))
18806    (use (match_operand:MODEF 1 "register_operand" ""))]
18807   "TARGET_USE_FANCY_MATH_387
18808    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18809        || TARGET_MIX_SSE_I387)
18810    && flag_unsafe_math_optimizations"
18812   rtx op0 = gen_reg_rtx (XFmode);
18813   rtx op1 = gen_reg_rtx (XFmode);
18815   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18816   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18818   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18819   DONE;
18822 (define_insn "fxam<mode>2_i387"
18823   [(set (match_operand:HI 0 "register_operand" "=a")
18824         (unspec:HI
18825           [(match_operand:X87MODEF 1 "register_operand" "f")]
18826           UNSPEC_FXAM))]
18827   "TARGET_USE_FANCY_MATH_387"
18828   "fxam\n\tfnstsw\t%0"
18829   [(set_attr "type" "multi")
18830    (set_attr "unit" "i387")
18831    (set_attr "mode" "<MODE>")])
18833 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18834   [(set (match_operand:HI 0 "register_operand" "")
18835         (unspec:HI
18836           [(match_operand:MODEF 1 "memory_operand" "")]
18837           UNSPEC_FXAM_MEM))]
18838   "TARGET_USE_FANCY_MATH_387
18839    && !(reload_completed || reload_in_progress)"
18840   "#"
18841   "&& 1"
18842   [(set (match_dup 2)(match_dup 1))
18843    (set (match_dup 0)
18844         (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18846   operands[2] = gen_reg_rtx (<MODE>mode);
18848   MEM_VOLATILE_P (operands[1]) = 1;
18850   [(set_attr "type" "multi")
18851    (set_attr "unit" "i387")
18852    (set_attr "mode" "<MODE>")])
18854 (define_expand "isinfxf2"
18855   [(use (match_operand:SI 0 "register_operand" ""))
18856    (use (match_operand:XF 1 "register_operand" ""))]
18857   "TARGET_USE_FANCY_MATH_387
18858    && TARGET_C99_FUNCTIONS"
18860   rtx mask = GEN_INT (0x45);
18861   rtx val = GEN_INT (0x05);
18863   rtx cond;
18865   rtx scratch = gen_reg_rtx (HImode);
18866   rtx res = gen_reg_rtx (QImode);
18868   emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18870   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18871   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18872   cond = gen_rtx_fmt_ee (EQ, QImode,
18873                          gen_rtx_REG (CCmode, FLAGS_REG),
18874                          const0_rtx);
18875   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18876   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18877   DONE;
18880 (define_expand "isinf<mode>2"
18881   [(use (match_operand:SI 0 "register_operand" ""))
18882    (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18883   "TARGET_USE_FANCY_MATH_387
18884    && TARGET_C99_FUNCTIONS
18885    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18887   rtx mask = GEN_INT (0x45);
18888   rtx val = GEN_INT (0x05);
18890   rtx cond;
18892   rtx scratch = gen_reg_rtx (HImode);
18893   rtx res = gen_reg_rtx (QImode);
18895   /* Remove excess precision by forcing value through memory. */
18896   if (memory_operand (operands[1], VOIDmode))
18897     emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18898   else
18899     {
18900       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
18901       rtx temp = assign_386_stack_local (<MODE>mode, slot);
18903       emit_move_insn (temp, operands[1]);
18904       emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18905     }
18907   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18908   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18909   cond = gen_rtx_fmt_ee (EQ, QImode,
18910                          gen_rtx_REG (CCmode, FLAGS_REG),
18911                          const0_rtx);
18912   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18913   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18914   DONE;
18917 (define_expand "signbit<mode>2"
18918   [(use (match_operand:SI 0 "register_operand" ""))
18919    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18920   "TARGET_USE_FANCY_MATH_387
18921    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18923   rtx mask = GEN_INT (0x0200);
18925   rtx scratch = gen_reg_rtx (HImode);
18927   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18928   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18929   DONE;
18932 ;; Block operation instructions
18934 (define_insn "cld"
18935   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18936   ""
18937   "cld"
18938   [(set_attr "length" "1")
18939    (set_attr "length_immediate" "0")
18940    (set_attr "modrm" "0")])
18942 (define_expand "movmemsi"
18943   [(use (match_operand:BLK 0 "memory_operand" ""))
18944    (use (match_operand:BLK 1 "memory_operand" ""))
18945    (use (match_operand:SI 2 "nonmemory_operand" ""))
18946    (use (match_operand:SI 3 "const_int_operand" ""))
18947    (use (match_operand:SI 4 "const_int_operand" ""))
18948    (use (match_operand:SI 5 "const_int_operand" ""))]
18949   ""
18951  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18952                          operands[4], operands[5]))
18953    DONE;
18954  else
18955    FAIL;
18958 (define_expand "movmemdi"
18959   [(use (match_operand:BLK 0 "memory_operand" ""))
18960    (use (match_operand:BLK 1 "memory_operand" ""))
18961    (use (match_operand:DI 2 "nonmemory_operand" ""))
18962    (use (match_operand:DI 3 "const_int_operand" ""))
18963    (use (match_operand:SI 4 "const_int_operand" ""))
18964    (use (match_operand:SI 5 "const_int_operand" ""))]
18965   "TARGET_64BIT"
18967  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18968                          operands[4], operands[5]))
18969    DONE;
18970  else
18971    FAIL;
18974 ;; Most CPUs don't like single string operations
18975 ;; Handle this case here to simplify previous expander.
18977 (define_expand "strmov"
18978   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18979    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18980    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18981               (clobber (reg:CC FLAGS_REG))])
18982    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18983               (clobber (reg:CC FLAGS_REG))])]
18984   ""
18986   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18988   /* If .md ever supports :P for Pmode, these can be directly
18989      in the pattern above.  */
18990   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18991   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18993   /* Can't use this if the user has appropriated esi or edi.  */
18994   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18995       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18996     {
18997       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18998                                       operands[2], operands[3],
18999                                       operands[5], operands[6]));
19000       DONE;
19001     }
19003   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19006 (define_expand "strmov_singleop"
19007   [(parallel [(set (match_operand 1 "memory_operand" "")
19008                    (match_operand 3 "memory_operand" ""))
19009               (set (match_operand 0 "register_operand" "")
19010                    (match_operand 4 "" ""))
19011               (set (match_operand 2 "register_operand" "")
19012                    (match_operand 5 "" ""))])]
19013   ""
19014   "ix86_current_function_needs_cld = 1;")
19016 (define_insn "*strmovdi_rex_1"
19017   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19018         (mem:DI (match_operand:DI 3 "register_operand" "1")))
19019    (set (match_operand:DI 0 "register_operand" "=D")
19020         (plus:DI (match_dup 2)
19021                  (const_int 8)))
19022    (set (match_operand:DI 1 "register_operand" "=S")
19023         (plus:DI (match_dup 3)
19024                  (const_int 8)))]
19025   "TARGET_64BIT"
19026   "movsq"
19027   [(set_attr "type" "str")
19028    (set_attr "mode" "DI")
19029    (set_attr "memory" "both")])
19031 (define_insn "*strmovsi_1"
19032   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19033         (mem:SI (match_operand:SI 3 "register_operand" "1")))
19034    (set (match_operand:SI 0 "register_operand" "=D")
19035         (plus:SI (match_dup 2)
19036                  (const_int 4)))
19037    (set (match_operand:SI 1 "register_operand" "=S")
19038         (plus:SI (match_dup 3)
19039                  (const_int 4)))]
19040   "!TARGET_64BIT"
19041   "movs{l|d}"
19042   [(set_attr "type" "str")
19043    (set_attr "mode" "SI")
19044    (set_attr "memory" "both")])
19046 (define_insn "*strmovsi_rex_1"
19047   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19048         (mem:SI (match_operand:DI 3 "register_operand" "1")))
19049    (set (match_operand:DI 0 "register_operand" "=D")
19050         (plus:DI (match_dup 2)
19051                  (const_int 4)))
19052    (set (match_operand:DI 1 "register_operand" "=S")
19053         (plus:DI (match_dup 3)
19054                  (const_int 4)))]
19055   "TARGET_64BIT"
19056   "movs{l|d}"
19057   [(set_attr "type" "str")
19058    (set_attr "mode" "SI")
19059    (set_attr "memory" "both")])
19061 (define_insn "*strmovhi_1"
19062   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19063         (mem:HI (match_operand:SI 3 "register_operand" "1")))
19064    (set (match_operand:SI 0 "register_operand" "=D")
19065         (plus:SI (match_dup 2)
19066                  (const_int 2)))
19067    (set (match_operand:SI 1 "register_operand" "=S")
19068         (plus:SI (match_dup 3)
19069                  (const_int 2)))]
19070   "!TARGET_64BIT"
19071   "movsw"
19072   [(set_attr "type" "str")
19073    (set_attr "memory" "both")
19074    (set_attr "mode" "HI")])
19076 (define_insn "*strmovhi_rex_1"
19077   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19078         (mem:HI (match_operand:DI 3 "register_operand" "1")))
19079    (set (match_operand:DI 0 "register_operand" "=D")
19080         (plus:DI (match_dup 2)
19081                  (const_int 2)))
19082    (set (match_operand:DI 1 "register_operand" "=S")
19083         (plus:DI (match_dup 3)
19084                  (const_int 2)))]
19085   "TARGET_64BIT"
19086   "movsw"
19087   [(set_attr "type" "str")
19088    (set_attr "memory" "both")
19089    (set_attr "mode" "HI")])
19091 (define_insn "*strmovqi_1"
19092   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19093         (mem:QI (match_operand:SI 3 "register_operand" "1")))
19094    (set (match_operand:SI 0 "register_operand" "=D")
19095         (plus:SI (match_dup 2)
19096                  (const_int 1)))
19097    (set (match_operand:SI 1 "register_operand" "=S")
19098         (plus:SI (match_dup 3)
19099                  (const_int 1)))]
19100   "!TARGET_64BIT"
19101   "movsb"
19102   [(set_attr "type" "str")
19103    (set_attr "memory" "both")
19104    (set_attr "mode" "QI")])
19106 (define_insn "*strmovqi_rex_1"
19107   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19108         (mem:QI (match_operand:DI 3 "register_operand" "1")))
19109    (set (match_operand:DI 0 "register_operand" "=D")
19110         (plus:DI (match_dup 2)
19111                  (const_int 1)))
19112    (set (match_operand:DI 1 "register_operand" "=S")
19113         (plus:DI (match_dup 3)
19114                  (const_int 1)))]
19115   "TARGET_64BIT"
19116   "movsb"
19117   [(set_attr "type" "str")
19118    (set_attr "memory" "both")
19119    (set_attr "mode" "QI")])
19121 (define_expand "rep_mov"
19122   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19123               (set (match_operand 0 "register_operand" "")
19124                    (match_operand 5 "" ""))
19125               (set (match_operand 2 "register_operand" "")
19126                    (match_operand 6 "" ""))
19127               (set (match_operand 1 "memory_operand" "")
19128                    (match_operand 3 "memory_operand" ""))
19129               (use (match_dup 4))])]
19130   ""
19131   "ix86_current_function_needs_cld = 1;")
19133 (define_insn "*rep_movdi_rex64"
19134   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19135    (set (match_operand:DI 0 "register_operand" "=D")
19136         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19137                             (const_int 3))
19138                  (match_operand:DI 3 "register_operand" "0")))
19139    (set (match_operand:DI 1 "register_operand" "=S")
19140         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19141                  (match_operand:DI 4 "register_operand" "1")))
19142    (set (mem:BLK (match_dup 3))
19143         (mem:BLK (match_dup 4)))
19144    (use (match_dup 5))]
19145   "TARGET_64BIT"
19146   "rep movsq"
19147   [(set_attr "type" "str")
19148    (set_attr "prefix_rep" "1")
19149    (set_attr "memory" "both")
19150    (set_attr "mode" "DI")])
19152 (define_insn "*rep_movsi"
19153   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19154    (set (match_operand:SI 0 "register_operand" "=D")
19155         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19156                             (const_int 2))
19157                  (match_operand:SI 3 "register_operand" "0")))
19158    (set (match_operand:SI 1 "register_operand" "=S")
19159         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19160                  (match_operand:SI 4 "register_operand" "1")))
19161    (set (mem:BLK (match_dup 3))
19162         (mem:BLK (match_dup 4)))
19163    (use (match_dup 5))]
19164   "!TARGET_64BIT"
19165   "rep movs{l|d}"
19166   [(set_attr "type" "str")
19167    (set_attr "prefix_rep" "1")
19168    (set_attr "memory" "both")
19169    (set_attr "mode" "SI")])
19171 (define_insn "*rep_movsi_rex64"
19172   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19173    (set (match_operand:DI 0 "register_operand" "=D")
19174         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19175                             (const_int 2))
19176                  (match_operand:DI 3 "register_operand" "0")))
19177    (set (match_operand:DI 1 "register_operand" "=S")
19178         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19179                  (match_operand:DI 4 "register_operand" "1")))
19180    (set (mem:BLK (match_dup 3))
19181         (mem:BLK (match_dup 4)))
19182    (use (match_dup 5))]
19183   "TARGET_64BIT"
19184   "rep movs{l|d}"
19185   [(set_attr "type" "str")
19186    (set_attr "prefix_rep" "1")
19187    (set_attr "memory" "both")
19188    (set_attr "mode" "SI")])
19190 (define_insn "*rep_movqi"
19191   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19192    (set (match_operand:SI 0 "register_operand" "=D")
19193         (plus:SI (match_operand:SI 3 "register_operand" "0")
19194                  (match_operand:SI 5 "register_operand" "2")))
19195    (set (match_operand:SI 1 "register_operand" "=S")
19196         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19197    (set (mem:BLK (match_dup 3))
19198         (mem:BLK (match_dup 4)))
19199    (use (match_dup 5))]
19200   "!TARGET_64BIT"
19201   "rep movsb"
19202   [(set_attr "type" "str")
19203    (set_attr "prefix_rep" "1")
19204    (set_attr "memory" "both")
19205    (set_attr "mode" "SI")])
19207 (define_insn "*rep_movqi_rex64"
19208   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19209    (set (match_operand:DI 0 "register_operand" "=D")
19210         (plus:DI (match_operand:DI 3 "register_operand" "0")
19211                  (match_operand:DI 5 "register_operand" "2")))
19212    (set (match_operand:DI 1 "register_operand" "=S")
19213         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19214    (set (mem:BLK (match_dup 3))
19215         (mem:BLK (match_dup 4)))
19216    (use (match_dup 5))]
19217   "TARGET_64BIT"
19218   "rep movsb"
19219   [(set_attr "type" "str")
19220    (set_attr "prefix_rep" "1")
19221    (set_attr "memory" "both")
19222    (set_attr "mode" "SI")])
19224 (define_expand "setmemsi"
19225    [(use (match_operand:BLK 0 "memory_operand" ""))
19226     (use (match_operand:SI 1 "nonmemory_operand" ""))
19227     (use (match_operand 2 "const_int_operand" ""))
19228     (use (match_operand 3 "const_int_operand" ""))
19229     (use (match_operand:SI 4 "const_int_operand" ""))
19230     (use (match_operand:SI 5 "const_int_operand" ""))]
19231   ""
19233  if (ix86_expand_setmem (operands[0], operands[1],
19234                          operands[2], operands[3],
19235                          operands[4], operands[5]))
19236    DONE;
19237  else
19238    FAIL;
19241 (define_expand "setmemdi"
19242    [(use (match_operand:BLK 0 "memory_operand" ""))
19243     (use (match_operand:DI 1 "nonmemory_operand" ""))
19244     (use (match_operand 2 "const_int_operand" ""))
19245     (use (match_operand 3 "const_int_operand" ""))
19246     (use (match_operand 4 "const_int_operand" ""))
19247     (use (match_operand 5 "const_int_operand" ""))]
19248   "TARGET_64BIT"
19250  if (ix86_expand_setmem (operands[0], operands[1],
19251                          operands[2], operands[3],
19252                          operands[4], operands[5]))
19253    DONE;
19254  else
19255    FAIL;
19258 ;; Most CPUs don't like single string operations
19259 ;; Handle this case here to simplify previous expander.
19261 (define_expand "strset"
19262   [(set (match_operand 1 "memory_operand" "")
19263         (match_operand 2 "register_operand" ""))
19264    (parallel [(set (match_operand 0 "register_operand" "")
19265                    (match_dup 3))
19266               (clobber (reg:CC FLAGS_REG))])]
19267   ""
19269   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19270     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19272   /* If .md ever supports :P for Pmode, this can be directly
19273      in the pattern above.  */
19274   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19275                               GEN_INT (GET_MODE_SIZE (GET_MODE
19276                                                       (operands[2]))));
19277   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19278     {
19279       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19280                                       operands[3]));
19281       DONE;
19282     }
19285 (define_expand "strset_singleop"
19286   [(parallel [(set (match_operand 1 "memory_operand" "")
19287                    (match_operand 2 "register_operand" ""))
19288               (set (match_operand 0 "register_operand" "")
19289                    (match_operand 3 "" ""))])]
19290   ""
19291   "ix86_current_function_needs_cld = 1;")
19293 (define_insn "*strsetdi_rex_1"
19294   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19295         (match_operand:DI 2 "register_operand" "a"))
19296    (set (match_operand:DI 0 "register_operand" "=D")
19297         (plus:DI (match_dup 1)
19298                  (const_int 8)))]
19299   "TARGET_64BIT"
19300   "stosq"
19301   [(set_attr "type" "str")
19302    (set_attr "memory" "store")
19303    (set_attr "mode" "DI")])
19305 (define_insn "*strsetsi_1"
19306   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19307         (match_operand:SI 2 "register_operand" "a"))
19308    (set (match_operand:SI 0 "register_operand" "=D")
19309         (plus:SI (match_dup 1)
19310                  (const_int 4)))]
19311   "!TARGET_64BIT"
19312   "stos{l|d}"
19313   [(set_attr "type" "str")
19314    (set_attr "memory" "store")
19315    (set_attr "mode" "SI")])
19317 (define_insn "*strsetsi_rex_1"
19318   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19319         (match_operand:SI 2 "register_operand" "a"))
19320    (set (match_operand:DI 0 "register_operand" "=D")
19321         (plus:DI (match_dup 1)
19322                  (const_int 4)))]
19323   "TARGET_64BIT"
19324   "stos{l|d}"
19325   [(set_attr "type" "str")
19326    (set_attr "memory" "store")
19327    (set_attr "mode" "SI")])
19329 (define_insn "*strsethi_1"
19330   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19331         (match_operand:HI 2 "register_operand" "a"))
19332    (set (match_operand:SI 0 "register_operand" "=D")
19333         (plus:SI (match_dup 1)
19334                  (const_int 2)))]
19335   "!TARGET_64BIT"
19336   "stosw"
19337   [(set_attr "type" "str")
19338    (set_attr "memory" "store")
19339    (set_attr "mode" "HI")])
19341 (define_insn "*strsethi_rex_1"
19342   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19343         (match_operand:HI 2 "register_operand" "a"))
19344    (set (match_operand:DI 0 "register_operand" "=D")
19345         (plus:DI (match_dup 1)
19346                  (const_int 2)))]
19347   "TARGET_64BIT"
19348   "stosw"
19349   [(set_attr "type" "str")
19350    (set_attr "memory" "store")
19351    (set_attr "mode" "HI")])
19353 (define_insn "*strsetqi_1"
19354   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19355         (match_operand:QI 2 "register_operand" "a"))
19356    (set (match_operand:SI 0 "register_operand" "=D")
19357         (plus:SI (match_dup 1)
19358                  (const_int 1)))]
19359   "!TARGET_64BIT"
19360   "stosb"
19361   [(set_attr "type" "str")
19362    (set_attr "memory" "store")
19363    (set_attr "mode" "QI")])
19365 (define_insn "*strsetqi_rex_1"
19366   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19367         (match_operand:QI 2 "register_operand" "a"))
19368    (set (match_operand:DI 0 "register_operand" "=D")
19369         (plus:DI (match_dup 1)
19370                  (const_int 1)))]
19371   "TARGET_64BIT"
19372   "stosb"
19373   [(set_attr "type" "str")
19374    (set_attr "memory" "store")
19375    (set_attr "mode" "QI")])
19377 (define_expand "rep_stos"
19378   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19379               (set (match_operand 0 "register_operand" "")
19380                    (match_operand 4 "" ""))
19381               (set (match_operand 2 "memory_operand" "") (const_int 0))
19382               (use (match_operand 3 "register_operand" ""))
19383               (use (match_dup 1))])]
19384   ""
19385   "ix86_current_function_needs_cld = 1;")
19387 (define_insn "*rep_stosdi_rex64"
19388   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19389    (set (match_operand:DI 0 "register_operand" "=D")
19390         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19391                             (const_int 3))
19392                  (match_operand:DI 3 "register_operand" "0")))
19393    (set (mem:BLK (match_dup 3))
19394         (const_int 0))
19395    (use (match_operand:DI 2 "register_operand" "a"))
19396    (use (match_dup 4))]
19397   "TARGET_64BIT"
19398   "rep stosq"
19399   [(set_attr "type" "str")
19400    (set_attr "prefix_rep" "1")
19401    (set_attr "memory" "store")
19402    (set_attr "mode" "DI")])
19404 (define_insn "*rep_stossi"
19405   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19406    (set (match_operand:SI 0 "register_operand" "=D")
19407         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19408                             (const_int 2))
19409                  (match_operand:SI 3 "register_operand" "0")))
19410    (set (mem:BLK (match_dup 3))
19411         (const_int 0))
19412    (use (match_operand:SI 2 "register_operand" "a"))
19413    (use (match_dup 4))]
19414   "!TARGET_64BIT"
19415   "rep stos{l|d}"
19416   [(set_attr "type" "str")
19417    (set_attr "prefix_rep" "1")
19418    (set_attr "memory" "store")
19419    (set_attr "mode" "SI")])
19421 (define_insn "*rep_stossi_rex64"
19422   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19423    (set (match_operand:DI 0 "register_operand" "=D")
19424         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19425                             (const_int 2))
19426                  (match_operand:DI 3 "register_operand" "0")))
19427    (set (mem:BLK (match_dup 3))
19428         (const_int 0))
19429    (use (match_operand:SI 2 "register_operand" "a"))
19430    (use (match_dup 4))]
19431   "TARGET_64BIT"
19432   "rep stos{l|d}"
19433   [(set_attr "type" "str")
19434    (set_attr "prefix_rep" "1")
19435    (set_attr "memory" "store")
19436    (set_attr "mode" "SI")])
19438 (define_insn "*rep_stosqi"
19439   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19440    (set (match_operand:SI 0 "register_operand" "=D")
19441         (plus:SI (match_operand:SI 3 "register_operand" "0")
19442                  (match_operand:SI 4 "register_operand" "1")))
19443    (set (mem:BLK (match_dup 3))
19444         (const_int 0))
19445    (use (match_operand:QI 2 "register_operand" "a"))
19446    (use (match_dup 4))]
19447   "!TARGET_64BIT"
19448   "rep stosb"
19449   [(set_attr "type" "str")
19450    (set_attr "prefix_rep" "1")
19451    (set_attr "memory" "store")
19452    (set_attr "mode" "QI")])
19454 (define_insn "*rep_stosqi_rex64"
19455   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19456    (set (match_operand:DI 0 "register_operand" "=D")
19457         (plus:DI (match_operand:DI 3 "register_operand" "0")
19458                  (match_operand:DI 4 "register_operand" "1")))
19459    (set (mem:BLK (match_dup 3))
19460         (const_int 0))
19461    (use (match_operand:QI 2 "register_operand" "a"))
19462    (use (match_dup 4))]
19463   "TARGET_64BIT"
19464   "rep stosb"
19465   [(set_attr "type" "str")
19466    (set_attr "prefix_rep" "1")
19467    (set_attr "memory" "store")
19468    (set_attr "mode" "QI")])
19470 (define_expand "cmpstrnsi"
19471   [(set (match_operand:SI 0 "register_operand" "")
19472         (compare:SI (match_operand:BLK 1 "general_operand" "")
19473                     (match_operand:BLK 2 "general_operand" "")))
19474    (use (match_operand 3 "general_operand" ""))
19475    (use (match_operand 4 "immediate_operand" ""))]
19476   ""
19478   rtx addr1, addr2, out, outlow, count, countreg, align;
19480   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19481     FAIL;
19483   /* Can't use this if the user has appropriated esi or edi.  */
19484   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19485     FAIL;
19487   out = operands[0];
19488   if (!REG_P (out))
19489     out = gen_reg_rtx (SImode);
19491   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19492   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19493   if (addr1 != XEXP (operands[1], 0))
19494     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19495   if (addr2 != XEXP (operands[2], 0))
19496     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19498   count = operands[3];
19499   countreg = ix86_zero_extend_to_Pmode (count);
19501   /* %%% Iff we are testing strict equality, we can use known alignment
19502      to good advantage.  This may be possible with combine, particularly
19503      once cc0 is dead.  */
19504   align = operands[4];
19506   if (CONST_INT_P (count))
19507     {
19508       if (INTVAL (count) == 0)
19509         {
19510           emit_move_insn (operands[0], const0_rtx);
19511           DONE;
19512         }
19513       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19514                                      operands[1], operands[2]));
19515     }
19516   else
19517     {
19518       if (TARGET_64BIT)
19519         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19520       else
19521         emit_insn (gen_cmpsi_1 (countreg, countreg));
19522       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19523                                   operands[1], operands[2]));
19524     }
19526   outlow = gen_lowpart (QImode, out);
19527   emit_insn (gen_cmpintqi (outlow));
19528   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19530   if (operands[0] != out)
19531     emit_move_insn (operands[0], out);
19533   DONE;
19536 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19538 (define_expand "cmpintqi"
19539   [(set (match_dup 1)
19540         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19541    (set (match_dup 2)
19542         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19543    (parallel [(set (match_operand:QI 0 "register_operand" "")
19544                    (minus:QI (match_dup 1)
19545                              (match_dup 2)))
19546               (clobber (reg:CC FLAGS_REG))])]
19547   ""
19548   "operands[1] = gen_reg_rtx (QImode);
19549    operands[2] = gen_reg_rtx (QImode);")
19551 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19552 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19554 (define_expand "cmpstrnqi_nz_1"
19555   [(parallel [(set (reg:CC FLAGS_REG)
19556                    (compare:CC (match_operand 4 "memory_operand" "")
19557                                (match_operand 5 "memory_operand" "")))
19558               (use (match_operand 2 "register_operand" ""))
19559               (use (match_operand:SI 3 "immediate_operand" ""))
19560               (clobber (match_operand 0 "register_operand" ""))
19561               (clobber (match_operand 1 "register_operand" ""))
19562               (clobber (match_dup 2))])]
19563   ""
19564   "ix86_current_function_needs_cld = 1;")
19566 (define_insn "*cmpstrnqi_nz_1"
19567   [(set (reg:CC FLAGS_REG)
19568         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19569                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19570    (use (match_operand:SI 6 "register_operand" "2"))
19571    (use (match_operand:SI 3 "immediate_operand" "i"))
19572    (clobber (match_operand:SI 0 "register_operand" "=S"))
19573    (clobber (match_operand:SI 1 "register_operand" "=D"))
19574    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19575   "!TARGET_64BIT"
19576   "repz cmpsb"
19577   [(set_attr "type" "str")
19578    (set_attr "mode" "QI")
19579    (set_attr "prefix_rep" "1")])
19581 (define_insn "*cmpstrnqi_nz_rex_1"
19582   [(set (reg:CC FLAGS_REG)
19583         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19584                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19585    (use (match_operand:DI 6 "register_operand" "2"))
19586    (use (match_operand:SI 3 "immediate_operand" "i"))
19587    (clobber (match_operand:DI 0 "register_operand" "=S"))
19588    (clobber (match_operand:DI 1 "register_operand" "=D"))
19589    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19590   "TARGET_64BIT"
19591   "repz cmpsb"
19592   [(set_attr "type" "str")
19593    (set_attr "mode" "QI")
19594    (set_attr "prefix_rep" "1")])
19596 ;; The same, but the count is not known to not be zero.
19598 (define_expand "cmpstrnqi_1"
19599   [(parallel [(set (reg:CC FLAGS_REG)
19600                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19601                                      (const_int 0))
19602                   (compare:CC (match_operand 4 "memory_operand" "")
19603                               (match_operand 5 "memory_operand" ""))
19604                   (const_int 0)))
19605               (use (match_operand:SI 3 "immediate_operand" ""))
19606               (use (reg:CC FLAGS_REG))
19607               (clobber (match_operand 0 "register_operand" ""))
19608               (clobber (match_operand 1 "register_operand" ""))
19609               (clobber (match_dup 2))])]
19610   ""
19611   "ix86_current_function_needs_cld = 1;")
19613 (define_insn "*cmpstrnqi_1"
19614   [(set (reg:CC FLAGS_REG)
19615         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19616                              (const_int 0))
19617           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19618                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19619           (const_int 0)))
19620    (use (match_operand:SI 3 "immediate_operand" "i"))
19621    (use (reg:CC FLAGS_REG))
19622    (clobber (match_operand:SI 0 "register_operand" "=S"))
19623    (clobber (match_operand:SI 1 "register_operand" "=D"))
19624    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19625   "!TARGET_64BIT"
19626   "repz cmpsb"
19627   [(set_attr "type" "str")
19628    (set_attr "mode" "QI")
19629    (set_attr "prefix_rep" "1")])
19631 (define_insn "*cmpstrnqi_rex_1"
19632   [(set (reg:CC FLAGS_REG)
19633         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19634                              (const_int 0))
19635           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19636                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19637           (const_int 0)))
19638    (use (match_operand:SI 3 "immediate_operand" "i"))
19639    (use (reg:CC FLAGS_REG))
19640    (clobber (match_operand:DI 0 "register_operand" "=S"))
19641    (clobber (match_operand:DI 1 "register_operand" "=D"))
19642    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19643   "TARGET_64BIT"
19644   "repz cmpsb"
19645   [(set_attr "type" "str")
19646    (set_attr "mode" "QI")
19647    (set_attr "prefix_rep" "1")])
19649 (define_expand "strlensi"
19650   [(set (match_operand:SI 0 "register_operand" "")
19651         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19652                     (match_operand:QI 2 "immediate_operand" "")
19653                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19654   ""
19656  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19657    DONE;
19658  else
19659    FAIL;
19662 (define_expand "strlendi"
19663   [(set (match_operand:DI 0 "register_operand" "")
19664         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19665                     (match_operand:QI 2 "immediate_operand" "")
19666                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19667   ""
19669  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19670    DONE;
19671  else
19672    FAIL;
19675 (define_expand "strlenqi_1"
19676   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19677               (clobber (match_operand 1 "register_operand" ""))
19678               (clobber (reg:CC FLAGS_REG))])]
19679   ""
19680   "ix86_current_function_needs_cld = 1;")
19682 (define_insn "*strlenqi_1"
19683   [(set (match_operand:SI 0 "register_operand" "=&c")
19684         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19685                     (match_operand:QI 2 "register_operand" "a")
19686                     (match_operand:SI 3 "immediate_operand" "i")
19687                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19688    (clobber (match_operand:SI 1 "register_operand" "=D"))
19689    (clobber (reg:CC FLAGS_REG))]
19690   "!TARGET_64BIT"
19691   "repnz scasb"
19692   [(set_attr "type" "str")
19693    (set_attr "mode" "QI")
19694    (set_attr "prefix_rep" "1")])
19696 (define_insn "*strlenqi_rex_1"
19697   [(set (match_operand:DI 0 "register_operand" "=&c")
19698         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19699                     (match_operand:QI 2 "register_operand" "a")
19700                     (match_operand:DI 3 "immediate_operand" "i")
19701                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19702    (clobber (match_operand:DI 1 "register_operand" "=D"))
19703    (clobber (reg:CC FLAGS_REG))]
19704   "TARGET_64BIT"
19705   "repnz scasb"
19706   [(set_attr "type" "str")
19707    (set_attr "mode" "QI")
19708    (set_attr "prefix_rep" "1")])
19710 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19711 ;; handled in combine, but it is not currently up to the task.
19712 ;; When used for their truth value, the cmpstrn* expanders generate
19713 ;; code like this:
19715 ;;   repz cmpsb
19716 ;;   seta       %al
19717 ;;   setb       %dl
19718 ;;   cmpb       %al, %dl
19719 ;;   jcc        label
19721 ;; The intermediate three instructions are unnecessary.
19723 ;; This one handles cmpstrn*_nz_1...
19724 (define_peephole2
19725   [(parallel[
19726      (set (reg:CC FLAGS_REG)
19727           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19728                       (mem:BLK (match_operand 5 "register_operand" ""))))
19729      (use (match_operand 6 "register_operand" ""))
19730      (use (match_operand:SI 3 "immediate_operand" ""))
19731      (clobber (match_operand 0 "register_operand" ""))
19732      (clobber (match_operand 1 "register_operand" ""))
19733      (clobber (match_operand 2 "register_operand" ""))])
19734    (set (match_operand:QI 7 "register_operand" "")
19735         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19736    (set (match_operand:QI 8 "register_operand" "")
19737         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19738    (set (reg FLAGS_REG)
19739         (compare (match_dup 7) (match_dup 8)))
19740   ]
19741   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19742   [(parallel[
19743      (set (reg:CC FLAGS_REG)
19744           (compare:CC (mem:BLK (match_dup 4))
19745                       (mem:BLK (match_dup 5))))
19746      (use (match_dup 6))
19747      (use (match_dup 3))
19748      (clobber (match_dup 0))
19749      (clobber (match_dup 1))
19750      (clobber (match_dup 2))])]
19751   "")
19753 ;; ...and this one handles cmpstrn*_1.
19754 (define_peephole2
19755   [(parallel[
19756      (set (reg:CC FLAGS_REG)
19757           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19758                                (const_int 0))
19759             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19760                         (mem:BLK (match_operand 5 "register_operand" "")))
19761             (const_int 0)))
19762      (use (match_operand:SI 3 "immediate_operand" ""))
19763      (use (reg:CC FLAGS_REG))
19764      (clobber (match_operand 0 "register_operand" ""))
19765      (clobber (match_operand 1 "register_operand" ""))
19766      (clobber (match_operand 2 "register_operand" ""))])
19767    (set (match_operand:QI 7 "register_operand" "")
19768         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19769    (set (match_operand:QI 8 "register_operand" "")
19770         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19771    (set (reg FLAGS_REG)
19772         (compare (match_dup 7) (match_dup 8)))
19773   ]
19774   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19775   [(parallel[
19776      (set (reg:CC FLAGS_REG)
19777           (if_then_else:CC (ne (match_dup 6)
19778                                (const_int 0))
19779             (compare:CC (mem:BLK (match_dup 4))
19780                         (mem:BLK (match_dup 5)))
19781             (const_int 0)))
19782      (use (match_dup 3))
19783      (use (reg:CC FLAGS_REG))
19784      (clobber (match_dup 0))
19785      (clobber (match_dup 1))
19786      (clobber (match_dup 2))])]
19787   "")
19791 ;; Conditional move instructions.
19793 (define_expand "movdicc"
19794   [(set (match_operand:DI 0 "register_operand" "")
19795         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19796                          (match_operand:DI 2 "general_operand" "")
19797                          (match_operand:DI 3 "general_operand" "")))]
19798   "TARGET_64BIT"
19799   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19801 (define_insn "x86_movdicc_0_m1_rex64"
19802   [(set (match_operand:DI 0 "register_operand" "=r")
19803         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19804           (const_int -1)
19805           (const_int 0)))
19806    (clobber (reg:CC FLAGS_REG))]
19807   "TARGET_64BIT"
19808   "sbb{q}\t%0, %0"
19809   ; Since we don't have the proper number of operands for an alu insn,
19810   ; fill in all the blanks.
19811   [(set_attr "type" "alu")
19812    (set_attr "pent_pair" "pu")
19813    (set_attr "memory" "none")
19814    (set_attr "imm_disp" "false")
19815    (set_attr "mode" "DI")
19816    (set_attr "length_immediate" "0")])
19818 (define_insn "*x86_movdicc_0_m1_se"
19819   [(set (match_operand:DI 0 "register_operand" "=r")
19820         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19821                          (const_int 1)
19822                          (const_int 0)))
19823    (clobber (reg:CC FLAGS_REG))]
19824   ""
19825   "sbb{q}\t%0, %0"
19826   [(set_attr "type" "alu")
19827    (set_attr "pent_pair" "pu")
19828    (set_attr "memory" "none")
19829    (set_attr "imm_disp" "false")
19830    (set_attr "mode" "DI")
19831    (set_attr "length_immediate" "0")])
19833 (define_insn "*movdicc_c_rex64"
19834   [(set (match_operand:DI 0 "register_operand" "=r,r")
19835         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19836                                 [(reg FLAGS_REG) (const_int 0)])
19837                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19838                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19839   "TARGET_64BIT && TARGET_CMOVE
19840    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19841   "@
19842    cmov%O2%C1\t{%2, %0|%0, %2}
19843    cmov%O2%c1\t{%3, %0|%0, %3}"
19844   [(set_attr "type" "icmov")
19845    (set_attr "mode" "DI")])
19847 (define_expand "movsicc"
19848   [(set (match_operand:SI 0 "register_operand" "")
19849         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19850                          (match_operand:SI 2 "general_operand" "")
19851                          (match_operand:SI 3 "general_operand" "")))]
19852   ""
19853   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19855 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19856 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19857 ;; So just document what we're doing explicitly.
19859 (define_insn "x86_movsicc_0_m1"
19860   [(set (match_operand:SI 0 "register_operand" "=r")
19861         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19862           (const_int -1)
19863           (const_int 0)))
19864    (clobber (reg:CC FLAGS_REG))]
19865   ""
19866   "sbb{l}\t%0, %0"
19867   ; Since we don't have the proper number of operands for an alu insn,
19868   ; fill in all the blanks.
19869   [(set_attr "type" "alu")
19870    (set_attr "pent_pair" "pu")
19871    (set_attr "memory" "none")
19872    (set_attr "imm_disp" "false")
19873    (set_attr "mode" "SI")
19874    (set_attr "length_immediate" "0")])
19876 (define_insn "*x86_movsicc_0_m1_se"
19877   [(set (match_operand:SI 0 "register_operand" "=r")
19878         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19879                          (const_int 1)
19880                          (const_int 0)))
19881    (clobber (reg:CC FLAGS_REG))]
19882   ""
19883   "sbb{l}\t%0, %0"
19884   [(set_attr "type" "alu")
19885    (set_attr "pent_pair" "pu")
19886    (set_attr "memory" "none")
19887    (set_attr "imm_disp" "false")
19888    (set_attr "mode" "SI")
19889    (set_attr "length_immediate" "0")])
19891 (define_insn "*movsicc_noc"
19892   [(set (match_operand:SI 0 "register_operand" "=r,r")
19893         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19894                                 [(reg FLAGS_REG) (const_int 0)])
19895                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19896                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19897   "TARGET_CMOVE
19898    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19899   "@
19900    cmov%O2%C1\t{%2, %0|%0, %2}
19901    cmov%O2%c1\t{%3, %0|%0, %3}"
19902   [(set_attr "type" "icmov")
19903    (set_attr "mode" "SI")])
19905 (define_expand "movhicc"
19906   [(set (match_operand:HI 0 "register_operand" "")
19907         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19908                          (match_operand:HI 2 "general_operand" "")
19909                          (match_operand:HI 3 "general_operand" "")))]
19910   "TARGET_HIMODE_MATH"
19911   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19913 (define_insn "*movhicc_noc"
19914   [(set (match_operand:HI 0 "register_operand" "=r,r")
19915         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19916                                 [(reg FLAGS_REG) (const_int 0)])
19917                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19918                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19919   "TARGET_CMOVE
19920    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19921   "@
19922    cmov%O2%C1\t{%2, %0|%0, %2}
19923    cmov%O2%c1\t{%3, %0|%0, %3}"
19924   [(set_attr "type" "icmov")
19925    (set_attr "mode" "HI")])
19927 (define_expand "movqicc"
19928   [(set (match_operand:QI 0 "register_operand" "")
19929         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19930                          (match_operand:QI 2 "general_operand" "")
19931                          (match_operand:QI 3 "general_operand" "")))]
19932   "TARGET_QIMODE_MATH"
19933   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19935 (define_insn_and_split "*movqicc_noc"
19936   [(set (match_operand:QI 0 "register_operand" "=r,r")
19937         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19938                                 [(match_operand 4 "flags_reg_operand" "")
19939                                  (const_int 0)])
19940                       (match_operand:QI 2 "register_operand" "r,0")
19941                       (match_operand:QI 3 "register_operand" "0,r")))]
19942   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19943   "#"
19944   "&& reload_completed"
19945   [(set (match_dup 0)
19946         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19947                       (match_dup 2)
19948                       (match_dup 3)))]
19949   "operands[0] = gen_lowpart (SImode, operands[0]);
19950    operands[2] = gen_lowpart (SImode, operands[2]);
19951    operands[3] = gen_lowpart (SImode, operands[3]);"
19952   [(set_attr "type" "icmov")
19953    (set_attr "mode" "SI")])
19955 (define_expand "mov<mode>cc"
19956   [(set (match_operand:X87MODEF 0 "register_operand" "")
19957         (if_then_else:X87MODEF
19958           (match_operand 1 "comparison_operator" "")
19959           (match_operand:X87MODEF 2 "register_operand" "")
19960           (match_operand:X87MODEF 3 "register_operand" "")))]
19961   "(TARGET_80387 && TARGET_CMOVE)
19962    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19963   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19965 (define_insn "*movsfcc_1_387"
19966   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19967         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19968                                 [(reg FLAGS_REG) (const_int 0)])
19969                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19970                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19971   "TARGET_80387 && TARGET_CMOVE
19972    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19973   "@
19974    fcmov%F1\t{%2, %0|%0, %2}
19975    fcmov%f1\t{%3, %0|%0, %3}
19976    cmov%O2%C1\t{%2, %0|%0, %2}
19977    cmov%O2%c1\t{%3, %0|%0, %3}"
19978   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19979    (set_attr "mode" "SF,SF,SI,SI")])
19981 (define_insn "*movdfcc_1"
19982   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19983         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19984                                 [(reg FLAGS_REG) (const_int 0)])
19985                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19986                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19987   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19988    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19989   "@
19990    fcmov%F1\t{%2, %0|%0, %2}
19991    fcmov%f1\t{%3, %0|%0, %3}
19992    #
19993    #"
19994   [(set_attr "type" "fcmov,fcmov,multi,multi")
19995    (set_attr "mode" "DF")])
19997 (define_insn "*movdfcc_1_rex64"
19998   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19999         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20000                                 [(reg FLAGS_REG) (const_int 0)])
20001                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20002                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20003   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20004    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20005   "@
20006    fcmov%F1\t{%2, %0|%0, %2}
20007    fcmov%f1\t{%3, %0|%0, %3}
20008    cmov%O2%C1\t{%2, %0|%0, %2}
20009    cmov%O2%c1\t{%3, %0|%0, %3}"
20010   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20011    (set_attr "mode" "DF")])
20013 (define_split
20014   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20015         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20016                                 [(match_operand 4 "flags_reg_operand" "")
20017                                  (const_int 0)])
20018                       (match_operand:DF 2 "nonimmediate_operand" "")
20019                       (match_operand:DF 3 "nonimmediate_operand" "")))]
20020   "!TARGET_64BIT && reload_completed"
20021   [(set (match_dup 2)
20022         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20023                       (match_dup 5)
20024                       (match_dup 6)))
20025    (set (match_dup 3)
20026         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20027                       (match_dup 7)
20028                       (match_dup 8)))]
20029   "split_di (&operands[2], 2, &operands[5], &operands[7]);
20030    split_di (&operands[0], 1, &operands[2], &operands[3]);")
20032 (define_insn "*movxfcc_1"
20033   [(set (match_operand:XF 0 "register_operand" "=f,f")
20034         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20035                                 [(reg FLAGS_REG) (const_int 0)])
20036                       (match_operand:XF 2 "register_operand" "f,0")
20037                       (match_operand:XF 3 "register_operand" "0,f")))]
20038   "TARGET_80387 && TARGET_CMOVE"
20039   "@
20040    fcmov%F1\t{%2, %0|%0, %2}
20041    fcmov%f1\t{%3, %0|%0, %3}"
20042   [(set_attr "type" "fcmov")
20043    (set_attr "mode" "XF")])
20045 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20046 ;; the scalar versions to have only XMM registers as operands.
20048 ;; SSE5 conditional move
20049 (define_insn "*sse5_pcmov_<mode>"
20050   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20051         (if_then_else:MODEF
20052           (match_operand:MODEF 1 "register_operand" "x,0")
20053           (match_operand:MODEF 2 "register_operand" "0,x")
20054           (match_operand:MODEF 3 "register_operand" "x,x")))]
20055   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20056   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20057   [(set_attr "type" "sse4arg")])
20059 ;; These versions of the min/max patterns are intentionally ignorant of
20060 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20061 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20062 ;; are undefined in this condition, we're certain this is correct.
20064 (define_insn "*avx_<code><mode>3"
20065   [(set (match_operand:MODEF 0 "register_operand" "=x")
20066         (smaxmin:MODEF
20067           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20068           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20069   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20070   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20071   [(set_attr "type" "sseadd")
20072    (set_attr "prefix" "vex")
20073    (set_attr "mode" "<MODE>")])
20075 (define_insn "<code><mode>3"
20076   [(set (match_operand:MODEF 0 "register_operand" "=x")
20077         (smaxmin:MODEF
20078           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20079           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20080   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20081   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20082   [(set_attr "type" "sseadd")
20083    (set_attr "mode" "<MODE>")])
20085 ;; These versions of the min/max patterns implement exactly the operations
20086 ;;   min = (op1 < op2 ? op1 : op2)
20087 ;;   max = (!(op1 < op2) ? op1 : op2)
20088 ;; Their operands are not commutative, and thus they may be used in the
20089 ;; presence of -0.0 and NaN.
20091 (define_insn "*avx_ieee_smin<mode>3"
20092   [(set (match_operand:MODEF 0 "register_operand" "=x")
20093         (unspec:MODEF
20094           [(match_operand:MODEF 1 "register_operand" "x")
20095            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20096          UNSPEC_IEEE_MIN))]
20097   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20098   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20099   [(set_attr "type" "sseadd")
20100    (set_attr "prefix" "vex")
20101    (set_attr "mode" "<MODE>")])
20103 (define_insn "*ieee_smin<mode>3"
20104   [(set (match_operand:MODEF 0 "register_operand" "=x")
20105         (unspec:MODEF
20106           [(match_operand:MODEF 1 "register_operand" "0")
20107            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20108          UNSPEC_IEEE_MIN))]
20109   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20110   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20111   [(set_attr "type" "sseadd")
20112    (set_attr "mode" "<MODE>")])
20114 (define_insn "*avx_ieee_smax<mode>3"
20115   [(set (match_operand:MODEF 0 "register_operand" "=x")
20116         (unspec:MODEF
20117           [(match_operand:MODEF 1 "register_operand" "0")
20118            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20119          UNSPEC_IEEE_MAX))]
20120   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20121   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20122   [(set_attr "type" "sseadd")
20123    (set_attr "prefix" "vex")
20124    (set_attr "mode" "<MODE>")])
20126 (define_insn "*ieee_smax<mode>3"
20127   [(set (match_operand:MODEF 0 "register_operand" "=x")
20128         (unspec:MODEF
20129           [(match_operand:MODEF 1 "register_operand" "0")
20130            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20131          UNSPEC_IEEE_MAX))]
20132   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20133   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20134   [(set_attr "type" "sseadd")
20135    (set_attr "mode" "<MODE>")])
20137 ;; Make two stack loads independent:
20138 ;;   fld aa              fld aa
20139 ;;   fld %st(0)     ->   fld bb
20140 ;;   fmul bb             fmul %st(1), %st
20142 ;; Actually we only match the last two instructions for simplicity.
20143 (define_peephole2
20144   [(set (match_operand 0 "fp_register_operand" "")
20145         (match_operand 1 "fp_register_operand" ""))
20146    (set (match_dup 0)
20147         (match_operator 2 "binary_fp_operator"
20148            [(match_dup 0)
20149             (match_operand 3 "memory_operand" "")]))]
20150   "REGNO (operands[0]) != REGNO (operands[1])"
20151   [(set (match_dup 0) (match_dup 3))
20152    (set (match_dup 0) (match_dup 4))]
20154   ;; The % modifier is not operational anymore in peephole2's, so we have to
20155   ;; swap the operands manually in the case of addition and multiplication.
20156   "if (COMMUTATIVE_ARITH_P (operands[2]))
20157      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20158                                  operands[0], operands[1]);
20159    else
20160      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20161                                  operands[1], operands[0]);")
20163 ;; Conditional addition patterns
20164 (define_expand "add<mode>cc"
20165   [(match_operand:SWI 0 "register_operand" "")
20166    (match_operand 1 "comparison_operator" "")
20167    (match_operand:SWI 2 "register_operand" "")
20168    (match_operand:SWI 3 "const_int_operand" "")]
20169   ""
20170   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20173 ;; Misc patterns (?)
20175 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20176 ;; Otherwise there will be nothing to keep
20178 ;; [(set (reg ebp) (reg esp))]
20179 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20180 ;;  (clobber (eflags)]
20181 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20183 ;; in proper program order.
20184 (define_insn "pro_epilogue_adjust_stack_1"
20185   [(set (match_operand:SI 0 "register_operand" "=r,r")
20186         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20187                  (match_operand:SI 2 "immediate_operand" "i,i")))
20188    (clobber (reg:CC FLAGS_REG))
20189    (clobber (mem:BLK (scratch)))]
20190   "!TARGET_64BIT"
20192   switch (get_attr_type (insn))
20193     {
20194     case TYPE_IMOV:
20195       return "mov{l}\t{%1, %0|%0, %1}";
20197     case TYPE_ALU:
20198       if (CONST_INT_P (operands[2])
20199           && (INTVAL (operands[2]) == 128
20200               || (INTVAL (operands[2]) < 0
20201                   && INTVAL (operands[2]) != -128)))
20202         {
20203           operands[2] = GEN_INT (-INTVAL (operands[2]));
20204           return "sub{l}\t{%2, %0|%0, %2}";
20205         }
20206       return "add{l}\t{%2, %0|%0, %2}";
20208     case TYPE_LEA:
20209       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20210       return "lea{l}\t{%a2, %0|%0, %a2}";
20212     default:
20213       gcc_unreachable ();
20214     }
20216   [(set (attr "type")
20217         (cond [(eq_attr "alternative" "0")
20218                  (const_string "alu")
20219                (match_operand:SI 2 "const0_operand" "")
20220                  (const_string "imov")
20221               ]
20222               (const_string "lea")))
20223    (set_attr "mode" "SI")])
20225 (define_insn "pro_epilogue_adjust_stack_rex64"
20226   [(set (match_operand:DI 0 "register_operand" "=r,r")
20227         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20228                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20229    (clobber (reg:CC FLAGS_REG))
20230    (clobber (mem:BLK (scratch)))]
20231   "TARGET_64BIT"
20233   switch (get_attr_type (insn))
20234     {
20235     case TYPE_IMOV:
20236       return "mov{q}\t{%1, %0|%0, %1}";
20238     case TYPE_ALU:
20239       if (CONST_INT_P (operands[2])
20240           /* Avoid overflows.  */
20241           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20242           && (INTVAL (operands[2]) == 128
20243               || (INTVAL (operands[2]) < 0
20244                   && INTVAL (operands[2]) != -128)))
20245         {
20246           operands[2] = GEN_INT (-INTVAL (operands[2]));
20247           return "sub{q}\t{%2, %0|%0, %2}";
20248         }
20249       return "add{q}\t{%2, %0|%0, %2}";
20251     case TYPE_LEA:
20252       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20253       return "lea{q}\t{%a2, %0|%0, %a2}";
20255     default:
20256       gcc_unreachable ();
20257     }
20259   [(set (attr "type")
20260         (cond [(eq_attr "alternative" "0")
20261                  (const_string "alu")
20262                (match_operand:DI 2 "const0_operand" "")
20263                  (const_string "imov")
20264               ]
20265               (const_string "lea")))
20266    (set_attr "mode" "DI")])
20268 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20269   [(set (match_operand:DI 0 "register_operand" "=r,r")
20270         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20271                  (match_operand:DI 3 "immediate_operand" "i,i")))
20272    (use (match_operand:DI 2 "register_operand" "r,r"))
20273    (clobber (reg:CC FLAGS_REG))
20274    (clobber (mem:BLK (scratch)))]
20275   "TARGET_64BIT"
20277   switch (get_attr_type (insn))
20278     {
20279     case TYPE_ALU:
20280       return "add{q}\t{%2, %0|%0, %2}";
20282     case TYPE_LEA:
20283       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20284       return "lea{q}\t{%a2, %0|%0, %a2}";
20286     default:
20287       gcc_unreachable ();
20288     }
20290   [(set_attr "type" "alu,lea")
20291    (set_attr "mode" "DI")])
20293 (define_insn "allocate_stack_worker_32"
20294   [(set (match_operand:SI 0 "register_operand" "=a")
20295         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20296                             UNSPECV_STACK_PROBE))
20297    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20298    (clobber (reg:CC FLAGS_REG))]
20299   "!TARGET_64BIT && TARGET_STACK_PROBE"
20300   "call\t___chkstk"
20301   [(set_attr "type" "multi")
20302    (set_attr "length" "5")])
20304 (define_insn "allocate_stack_worker_64"
20305   [(set (match_operand:DI 0 "register_operand" "=a")
20306         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20307                             UNSPECV_STACK_PROBE))
20308    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20309    (clobber (reg:DI R10_REG))
20310    (clobber (reg:DI R11_REG))
20311    (clobber (reg:CC FLAGS_REG))]
20312   "TARGET_64BIT && TARGET_STACK_PROBE"
20313   "call\t___chkstk"
20314   [(set_attr "type" "multi")
20315    (set_attr "length" "5")])
20317 (define_expand "allocate_stack"
20318   [(match_operand 0 "register_operand" "")
20319    (match_operand 1 "general_operand" "")]
20320   "TARGET_STACK_PROBE"
20322   rtx x;
20324 #ifndef CHECK_STACK_LIMIT
20325 #define CHECK_STACK_LIMIT 0
20326 #endif
20328   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20329       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20330     {
20331       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20332                                stack_pointer_rtx, 0, OPTAB_DIRECT);
20333       if (x != stack_pointer_rtx)
20334         emit_move_insn (stack_pointer_rtx, x);
20335     }
20336   else
20337     {
20338       x = copy_to_mode_reg (Pmode, operands[1]);
20339       if (TARGET_64BIT)
20340         x = gen_allocate_stack_worker_64 (x, x);
20341       else
20342         x = gen_allocate_stack_worker_32 (x, x);
20343       emit_insn (x);
20344     }
20346   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20347   DONE;
20350 (define_expand "builtin_setjmp_receiver"
20351   [(label_ref (match_operand 0 "" ""))]
20352   "!TARGET_64BIT && flag_pic"
20354 #if TARGET_MACHO
20355   if (TARGET_MACHO)
20356     {
20357       rtx xops[3];
20358       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20359       rtx label_rtx = gen_label_rtx ();
20360       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20361       xops[0] = xops[1] = picreg;
20362       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20363       ix86_expand_binary_operator (MINUS, SImode, xops);
20364     }
20365   else
20366 #endif
20367     emit_insn (gen_set_got (pic_offset_table_rtx));
20368   DONE;
20371 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20373 (define_split
20374   [(set (match_operand 0 "register_operand" "")
20375         (match_operator 3 "promotable_binary_operator"
20376            [(match_operand 1 "register_operand" "")
20377             (match_operand 2 "aligned_operand" "")]))
20378    (clobber (reg:CC FLAGS_REG))]
20379   "! TARGET_PARTIAL_REG_STALL && reload_completed
20380    && ((GET_MODE (operands[0]) == HImode
20381         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20382             /* ??? next two lines just !satisfies_constraint_K (...) */
20383             || !CONST_INT_P (operands[2])
20384             || satisfies_constraint_K (operands[2])))
20385        || (GET_MODE (operands[0]) == QImode
20386            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20387   [(parallel [(set (match_dup 0)
20388                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20389               (clobber (reg:CC FLAGS_REG))])]
20390   "operands[0] = gen_lowpart (SImode, operands[0]);
20391    operands[1] = gen_lowpart (SImode, operands[1]);
20392    if (GET_CODE (operands[3]) != ASHIFT)
20393      operands[2] = gen_lowpart (SImode, operands[2]);
20394    PUT_MODE (operands[3], SImode);")
20396 ; Promote the QImode tests, as i386 has encoding of the AND
20397 ; instruction with 32-bit sign-extended immediate and thus the
20398 ; instruction size is unchanged, except in the %eax case for
20399 ; which it is increased by one byte, hence the ! optimize_size.
20400 (define_split
20401   [(set (match_operand 0 "flags_reg_operand" "")
20402         (match_operator 2 "compare_operator"
20403           [(and (match_operand 3 "aligned_operand" "")
20404                 (match_operand 4 "const_int_operand" ""))
20405            (const_int 0)]))
20406    (set (match_operand 1 "register_operand" "")
20407         (and (match_dup 3) (match_dup 4)))]
20408   "! TARGET_PARTIAL_REG_STALL && reload_completed
20409    && optimize_insn_for_speed_p ()
20410    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20411        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20412    /* Ensure that the operand will remain sign-extended immediate.  */
20413    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20414   [(parallel [(set (match_dup 0)
20415                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20416                                     (const_int 0)]))
20417               (set (match_dup 1)
20418                    (and:SI (match_dup 3) (match_dup 4)))])]
20420   operands[4]
20421     = gen_int_mode (INTVAL (operands[4])
20422                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20423   operands[1] = gen_lowpart (SImode, operands[1]);
20424   operands[3] = gen_lowpart (SImode, operands[3]);
20427 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20428 ; the TEST instruction with 32-bit sign-extended immediate and thus
20429 ; the instruction size would at least double, which is not what we
20430 ; want even with ! optimize_size.
20431 (define_split
20432   [(set (match_operand 0 "flags_reg_operand" "")
20433         (match_operator 1 "compare_operator"
20434           [(and (match_operand:HI 2 "aligned_operand" "")
20435                 (match_operand:HI 3 "const_int_operand" ""))
20436            (const_int 0)]))]
20437   "! TARGET_PARTIAL_REG_STALL && reload_completed
20438    && ! TARGET_FAST_PREFIX
20439    && optimize_insn_for_speed_p ()
20440    /* Ensure that the operand will remain sign-extended immediate.  */
20441    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20442   [(set (match_dup 0)
20443         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20444                          (const_int 0)]))]
20446   operands[3]
20447     = gen_int_mode (INTVAL (operands[3])
20448                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20449   operands[2] = gen_lowpart (SImode, operands[2]);
20452 (define_split
20453   [(set (match_operand 0 "register_operand" "")
20454         (neg (match_operand 1 "register_operand" "")))
20455    (clobber (reg:CC FLAGS_REG))]
20456   "! TARGET_PARTIAL_REG_STALL && reload_completed
20457    && (GET_MODE (operands[0]) == HImode
20458        || (GET_MODE (operands[0]) == QImode
20459            && (TARGET_PROMOTE_QImode
20460                || optimize_insn_for_size_p ())))"
20461   [(parallel [(set (match_dup 0)
20462                    (neg:SI (match_dup 1)))
20463               (clobber (reg:CC FLAGS_REG))])]
20464   "operands[0] = gen_lowpart (SImode, operands[0]);
20465    operands[1] = gen_lowpart (SImode, operands[1]);")
20467 (define_split
20468   [(set (match_operand 0 "register_operand" "")
20469         (not (match_operand 1 "register_operand" "")))]
20470   "! TARGET_PARTIAL_REG_STALL && reload_completed
20471    && (GET_MODE (operands[0]) == HImode
20472        || (GET_MODE (operands[0]) == QImode
20473            && (TARGET_PROMOTE_QImode
20474                || optimize_insn_for_size_p ())))"
20475   [(set (match_dup 0)
20476         (not:SI (match_dup 1)))]
20477   "operands[0] = gen_lowpart (SImode, operands[0]);
20478    operands[1] = gen_lowpart (SImode, operands[1]);")
20480 (define_split
20481   [(set (match_operand 0 "register_operand" "")
20482         (if_then_else (match_operator 1 "comparison_operator"
20483                                 [(reg FLAGS_REG) (const_int 0)])
20484                       (match_operand 2 "register_operand" "")
20485                       (match_operand 3 "register_operand" "")))]
20486   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20487    && (GET_MODE (operands[0]) == HImode
20488        || (GET_MODE (operands[0]) == QImode
20489            && (TARGET_PROMOTE_QImode
20490                || optimize_insn_for_size_p ())))"
20491   [(set (match_dup 0)
20492         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20493   "operands[0] = gen_lowpart (SImode, operands[0]);
20494    operands[2] = gen_lowpart (SImode, operands[2]);
20495    operands[3] = gen_lowpart (SImode, operands[3]);")
20498 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20499 ;; transform a complex memory operation into two memory to register operations.
20501 ;; Don't push memory operands
20502 (define_peephole2
20503   [(set (match_operand:SI 0 "push_operand" "")
20504         (match_operand:SI 1 "memory_operand" ""))
20505    (match_scratch:SI 2 "r")]
20506   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20507    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20508   [(set (match_dup 2) (match_dup 1))
20509    (set (match_dup 0) (match_dup 2))]
20510   "")
20512 (define_peephole2
20513   [(set (match_operand:DI 0 "push_operand" "")
20514         (match_operand:DI 1 "memory_operand" ""))
20515    (match_scratch:DI 2 "r")]
20516   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20517    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20518   [(set (match_dup 2) (match_dup 1))
20519    (set (match_dup 0) (match_dup 2))]
20520   "")
20522 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20523 ;; SImode pushes.
20524 (define_peephole2
20525   [(set (match_operand:SF 0 "push_operand" "")
20526         (match_operand:SF 1 "memory_operand" ""))
20527    (match_scratch:SF 2 "r")]
20528   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20529    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20530   [(set (match_dup 2) (match_dup 1))
20531    (set (match_dup 0) (match_dup 2))]
20532   "")
20534 (define_peephole2
20535   [(set (match_operand:HI 0 "push_operand" "")
20536         (match_operand:HI 1 "memory_operand" ""))
20537    (match_scratch:HI 2 "r")]
20538   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20539    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20540   [(set (match_dup 2) (match_dup 1))
20541    (set (match_dup 0) (match_dup 2))]
20542   "")
20544 (define_peephole2
20545   [(set (match_operand:QI 0 "push_operand" "")
20546         (match_operand:QI 1 "memory_operand" ""))
20547    (match_scratch:QI 2 "q")]
20548   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20549    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20550   [(set (match_dup 2) (match_dup 1))
20551    (set (match_dup 0) (match_dup 2))]
20552   "")
20554 ;; Don't move an immediate directly to memory when the instruction
20555 ;; gets too big.
20556 (define_peephole2
20557   [(match_scratch:SI 1 "r")
20558    (set (match_operand:SI 0 "memory_operand" "")
20559         (const_int 0))]
20560   "optimize_insn_for_speed_p ()
20561    && ! TARGET_USE_MOV0
20562    && TARGET_SPLIT_LONG_MOVES
20563    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20564    && peep2_regno_dead_p (0, FLAGS_REG)"
20565   [(parallel [(set (match_dup 1) (const_int 0))
20566               (clobber (reg:CC FLAGS_REG))])
20567    (set (match_dup 0) (match_dup 1))]
20568   "")
20570 (define_peephole2
20571   [(match_scratch:HI 1 "r")
20572    (set (match_operand:HI 0 "memory_operand" "")
20573         (const_int 0))]
20574   "optimize_insn_for_speed_p ()
20575    && ! TARGET_USE_MOV0
20576    && TARGET_SPLIT_LONG_MOVES
20577    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20578    && peep2_regno_dead_p (0, FLAGS_REG)"
20579   [(parallel [(set (match_dup 2) (const_int 0))
20580               (clobber (reg:CC FLAGS_REG))])
20581    (set (match_dup 0) (match_dup 1))]
20582   "operands[2] = gen_lowpart (SImode, operands[1]);")
20584 (define_peephole2
20585   [(match_scratch:QI 1 "q")
20586    (set (match_operand:QI 0 "memory_operand" "")
20587         (const_int 0))]
20588   "optimize_insn_for_speed_p ()
20589    && ! TARGET_USE_MOV0
20590    && TARGET_SPLIT_LONG_MOVES
20591    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20592    && peep2_regno_dead_p (0, FLAGS_REG)"
20593   [(parallel [(set (match_dup 2) (const_int 0))
20594               (clobber (reg:CC FLAGS_REG))])
20595    (set (match_dup 0) (match_dup 1))]
20596   "operands[2] = gen_lowpart (SImode, operands[1]);")
20598 (define_peephole2
20599   [(match_scratch:SI 2 "r")
20600    (set (match_operand:SI 0 "memory_operand" "")
20601         (match_operand:SI 1 "immediate_operand" ""))]
20602   "optimize_insn_for_speed_p ()
20603    && TARGET_SPLIT_LONG_MOVES
20604    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20605   [(set (match_dup 2) (match_dup 1))
20606    (set (match_dup 0) (match_dup 2))]
20607   "")
20609 (define_peephole2
20610   [(match_scratch:HI 2 "r")
20611    (set (match_operand:HI 0 "memory_operand" "")
20612         (match_operand:HI 1 "immediate_operand" ""))]
20613   "optimize_insn_for_speed_p ()
20614    && TARGET_SPLIT_LONG_MOVES
20615    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20616   [(set (match_dup 2) (match_dup 1))
20617    (set (match_dup 0) (match_dup 2))]
20618   "")
20620 (define_peephole2
20621   [(match_scratch:QI 2 "q")
20622    (set (match_operand:QI 0 "memory_operand" "")
20623         (match_operand:QI 1 "immediate_operand" ""))]
20624   "optimize_insn_for_speed_p ()
20625    && TARGET_SPLIT_LONG_MOVES
20626    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20627   [(set (match_dup 2) (match_dup 1))
20628    (set (match_dup 0) (match_dup 2))]
20629   "")
20631 ;; Don't compare memory with zero, load and use a test instead.
20632 (define_peephole2
20633   [(set (match_operand 0 "flags_reg_operand" "")
20634         (match_operator 1 "compare_operator"
20635           [(match_operand:SI 2 "memory_operand" "")
20636            (const_int 0)]))
20637    (match_scratch:SI 3 "r")]
20638   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20639   [(set (match_dup 3) (match_dup 2))
20640    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20641   "")
20643 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20644 ;; Don't split NOTs with a displacement operand, because resulting XOR
20645 ;; will not be pairable anyway.
20647 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20648 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20649 ;; so this split helps here as well.
20651 ;; Note: Can't do this as a regular split because we can't get proper
20652 ;; lifetime information then.
20654 (define_peephole2
20655   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20656         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20657   "optimize_insn_for_speed_p ()
20658    && ((TARGET_NOT_UNPAIRABLE
20659         && (!MEM_P (operands[0])
20660             || !memory_displacement_operand (operands[0], SImode)))
20661        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20662    && peep2_regno_dead_p (0, FLAGS_REG)"
20663   [(parallel [(set (match_dup 0)
20664                    (xor:SI (match_dup 1) (const_int -1)))
20665               (clobber (reg:CC FLAGS_REG))])]
20666   "")
20668 (define_peephole2
20669   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20670         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20671   "optimize_insn_for_speed_p ()
20672    && ((TARGET_NOT_UNPAIRABLE
20673         && (!MEM_P (operands[0])
20674             || !memory_displacement_operand (operands[0], HImode)))
20675        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20676    && peep2_regno_dead_p (0, FLAGS_REG)"
20677   [(parallel [(set (match_dup 0)
20678                    (xor:HI (match_dup 1) (const_int -1)))
20679               (clobber (reg:CC FLAGS_REG))])]
20680   "")
20682 (define_peephole2
20683   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20684         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20685   "optimize_insn_for_speed_p ()
20686    && ((TARGET_NOT_UNPAIRABLE
20687         && (!MEM_P (operands[0])
20688             || !memory_displacement_operand (operands[0], QImode)))
20689        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20690    && peep2_regno_dead_p (0, FLAGS_REG)"
20691   [(parallel [(set (match_dup 0)
20692                    (xor:QI (match_dup 1) (const_int -1)))
20693               (clobber (reg:CC FLAGS_REG))])]
20694   "")
20696 ;; Non pairable "test imm, reg" instructions can be translated to
20697 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20698 ;; byte opcode instead of two, have a short form for byte operands),
20699 ;; so do it for other CPUs as well.  Given that the value was dead,
20700 ;; this should not create any new dependencies.  Pass on the sub-word
20701 ;; versions if we're concerned about partial register stalls.
20703 (define_peephole2
20704   [(set (match_operand 0 "flags_reg_operand" "")
20705         (match_operator 1 "compare_operator"
20706           [(and:SI (match_operand:SI 2 "register_operand" "")
20707                    (match_operand:SI 3 "immediate_operand" ""))
20708            (const_int 0)]))]
20709   "ix86_match_ccmode (insn, CCNOmode)
20710    && (true_regnum (operands[2]) != AX_REG
20711        || satisfies_constraint_K (operands[3]))
20712    && peep2_reg_dead_p (1, operands[2])"
20713   [(parallel
20714      [(set (match_dup 0)
20715            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20716                             (const_int 0)]))
20717       (set (match_dup 2)
20718            (and:SI (match_dup 2) (match_dup 3)))])]
20719   "")
20721 ;; We don't need to handle HImode case, because it will be promoted to SImode
20722 ;; on ! TARGET_PARTIAL_REG_STALL
20724 (define_peephole2
20725   [(set (match_operand 0 "flags_reg_operand" "")
20726         (match_operator 1 "compare_operator"
20727           [(and:QI (match_operand:QI 2 "register_operand" "")
20728                    (match_operand:QI 3 "immediate_operand" ""))
20729            (const_int 0)]))]
20730   "! TARGET_PARTIAL_REG_STALL
20731    && ix86_match_ccmode (insn, CCNOmode)
20732    && true_regnum (operands[2]) != AX_REG
20733    && peep2_reg_dead_p (1, operands[2])"
20734   [(parallel
20735      [(set (match_dup 0)
20736            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20737                             (const_int 0)]))
20738       (set (match_dup 2)
20739            (and:QI (match_dup 2) (match_dup 3)))])]
20740   "")
20742 (define_peephole2
20743   [(set (match_operand 0 "flags_reg_operand" "")
20744         (match_operator 1 "compare_operator"
20745           [(and:SI
20746              (zero_extract:SI
20747                (match_operand 2 "ext_register_operand" "")
20748                (const_int 8)
20749                (const_int 8))
20750              (match_operand 3 "const_int_operand" ""))
20751            (const_int 0)]))]
20752   "! TARGET_PARTIAL_REG_STALL
20753    && ix86_match_ccmode (insn, CCNOmode)
20754    && true_regnum (operands[2]) != AX_REG
20755    && peep2_reg_dead_p (1, operands[2])"
20756   [(parallel [(set (match_dup 0)
20757                    (match_op_dup 1
20758                      [(and:SI
20759                         (zero_extract:SI
20760                           (match_dup 2)
20761                           (const_int 8)
20762                           (const_int 8))
20763                         (match_dup 3))
20764                       (const_int 0)]))
20765               (set (zero_extract:SI (match_dup 2)
20766                                     (const_int 8)
20767                                     (const_int 8))
20768                    (and:SI
20769                      (zero_extract:SI
20770                        (match_dup 2)
20771                        (const_int 8)
20772                        (const_int 8))
20773                      (match_dup 3)))])]
20774   "")
20776 ;; Don't do logical operations with memory inputs.
20777 (define_peephole2
20778   [(match_scratch:SI 2 "r")
20779    (parallel [(set (match_operand:SI 0 "register_operand" "")
20780                    (match_operator:SI 3 "arith_or_logical_operator"
20781                      [(match_dup 0)
20782                       (match_operand:SI 1 "memory_operand" "")]))
20783               (clobber (reg:CC FLAGS_REG))])]
20784   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20785   [(set (match_dup 2) (match_dup 1))
20786    (parallel [(set (match_dup 0)
20787                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20788               (clobber (reg:CC FLAGS_REG))])]
20789   "")
20791 (define_peephole2
20792   [(match_scratch:SI 2 "r")
20793    (parallel [(set (match_operand:SI 0 "register_operand" "")
20794                    (match_operator:SI 3 "arith_or_logical_operator"
20795                      [(match_operand:SI 1 "memory_operand" "")
20796                       (match_dup 0)]))
20797               (clobber (reg:CC FLAGS_REG))])]
20798   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20799   [(set (match_dup 2) (match_dup 1))
20800    (parallel [(set (match_dup 0)
20801                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20802               (clobber (reg:CC FLAGS_REG))])]
20803   "")
20805 ;; Prefer Load+RegOp to Mov+MemOp.  Watch out for cases when the memory address
20806 ;; refers to the destination of the load!
20808 (define_peephole2
20809   [(set (match_operand:SI 0 "register_operand" "")
20810         (match_operand:SI 1 "register_operand" ""))
20811    (parallel [(set (match_dup 0)
20812                    (match_operator:SI 3 "commutative_operator"
20813                      [(match_dup 0)
20814                       (match_operand:SI 2 "memory_operand" "")]))
20815               (clobber (reg:CC FLAGS_REG))])]
20816   "operands[0] != operands[1]
20817    && GENERAL_REGNO_P (REGNO (operands[0]))
20818    && GENERAL_REGNO_P (REGNO (operands[1]))"
20819   [(set (match_dup 0) (match_dup 4))
20820    (parallel [(set (match_dup 0)
20821                    (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20822               (clobber (reg:CC FLAGS_REG))])]
20823   "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20825 (define_peephole2
20826   [(set (match_operand 0 "register_operand" "")
20827         (match_operand 1 "register_operand" ""))
20828    (set (match_dup 0)
20829                    (match_operator 3 "commutative_operator"
20830                      [(match_dup 0)
20831                       (match_operand 2 "memory_operand" "")]))]
20832   "operands[0] != operands[1]
20833    && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1])) 
20834        || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20835   [(set (match_dup 0) (match_dup 2))
20836    (set (match_dup 0)
20837         (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20838   "")
20840 ; Don't do logical operations with memory outputs
20842 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20843 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20844 ; the same decoder scheduling characteristics as the original.
20846 (define_peephole2
20847   [(match_scratch:SI 2 "r")
20848    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20849                    (match_operator:SI 3 "arith_or_logical_operator"
20850                      [(match_dup 0)
20851                       (match_operand:SI 1 "nonmemory_operand" "")]))
20852               (clobber (reg:CC FLAGS_REG))])]
20853   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20854   [(set (match_dup 2) (match_dup 0))
20855    (parallel [(set (match_dup 2)
20856                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20857               (clobber (reg:CC FLAGS_REG))])
20858    (set (match_dup 0) (match_dup 2))]
20859   "")
20861 (define_peephole2
20862   [(match_scratch:SI 2 "r")
20863    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20864                    (match_operator:SI 3 "arith_or_logical_operator"
20865                      [(match_operand:SI 1 "nonmemory_operand" "")
20866                       (match_dup 0)]))
20867               (clobber (reg:CC FLAGS_REG))])]
20868   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20869   [(set (match_dup 2) (match_dup 0))
20870    (parallel [(set (match_dup 2)
20871                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20872               (clobber (reg:CC FLAGS_REG))])
20873    (set (match_dup 0) (match_dup 2))]
20874   "")
20876 ;; Attempt to always use XOR for zeroing registers.
20877 (define_peephole2
20878   [(set (match_operand 0 "register_operand" "")
20879         (match_operand 1 "const0_operand" ""))]
20880   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20881    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20882    && GENERAL_REG_P (operands[0])
20883    && peep2_regno_dead_p (0, FLAGS_REG)"
20884   [(parallel [(set (match_dup 0) (const_int 0))
20885               (clobber (reg:CC FLAGS_REG))])]
20887   operands[0] = gen_lowpart (word_mode, operands[0]);
20890 (define_peephole2
20891   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20892         (const_int 0))]
20893   "(GET_MODE (operands[0]) == QImode
20894     || GET_MODE (operands[0]) == HImode)
20895    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20896    && peep2_regno_dead_p (0, FLAGS_REG)"
20897   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20898               (clobber (reg:CC FLAGS_REG))])])
20900 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20901 (define_peephole2
20902   [(set (match_operand 0 "register_operand" "")
20903         (const_int -1))]
20904   "(GET_MODE (operands[0]) == HImode
20905     || GET_MODE (operands[0]) == SImode
20906     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20907    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20908    && peep2_regno_dead_p (0, FLAGS_REG)"
20909   [(parallel [(set (match_dup 0) (const_int -1))
20910               (clobber (reg:CC FLAGS_REG))])]
20911   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20912                               operands[0]);")
20914 ;; Attempt to convert simple leas to adds. These can be created by
20915 ;; move expanders.
20916 (define_peephole2
20917   [(set (match_operand:SI 0 "register_operand" "")
20918         (plus:SI (match_dup 0)
20919                  (match_operand:SI 1 "nonmemory_operand" "")))]
20920   "peep2_regno_dead_p (0, FLAGS_REG)"
20921   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20922               (clobber (reg:CC FLAGS_REG))])]
20923   "")
20925 (define_peephole2
20926   [(set (match_operand:SI 0 "register_operand" "")
20927         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20928                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20929   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20930   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20931               (clobber (reg:CC FLAGS_REG))])]
20932   "operands[2] = gen_lowpart (SImode, operands[2]);")
20934 (define_peephole2
20935   [(set (match_operand:DI 0 "register_operand" "")
20936         (plus:DI (match_dup 0)
20937                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20938   "peep2_regno_dead_p (0, FLAGS_REG)"
20939   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20940               (clobber (reg:CC FLAGS_REG))])]
20941   "")
20943 (define_peephole2
20944   [(set (match_operand:SI 0 "register_operand" "")
20945         (mult:SI (match_dup 0)
20946                  (match_operand:SI 1 "const_int_operand" "")))]
20947   "exact_log2 (INTVAL (operands[1])) >= 0
20948    && peep2_regno_dead_p (0, FLAGS_REG)"
20949   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20950               (clobber (reg:CC FLAGS_REG))])]
20951   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20953 (define_peephole2
20954   [(set (match_operand:DI 0 "register_operand" "")
20955         (mult:DI (match_dup 0)
20956                  (match_operand:DI 1 "const_int_operand" "")))]
20957   "exact_log2 (INTVAL (operands[1])) >= 0
20958    && peep2_regno_dead_p (0, FLAGS_REG)"
20959   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20960               (clobber (reg:CC FLAGS_REG))])]
20961   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20963 (define_peephole2
20964   [(set (match_operand:SI 0 "register_operand" "")
20965         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20966                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20967   "exact_log2 (INTVAL (operands[2])) >= 0
20968    && REGNO (operands[0]) == REGNO (operands[1])
20969    && peep2_regno_dead_p (0, FLAGS_REG)"
20970   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20971               (clobber (reg:CC FLAGS_REG))])]
20972   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20974 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20975 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20976 ;; many CPUs it is also faster, since special hardware to avoid esp
20977 ;; dependencies is present.
20979 ;; While some of these conversions may be done using splitters, we use peepholes
20980 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20982 ;; Convert prologue esp subtractions to push.
20983 ;; We need register to push.  In order to keep verify_flow_info happy we have
20984 ;; two choices
20985 ;; - use scratch and clobber it in order to avoid dependencies
20986 ;; - use already live register
20987 ;; We can't use the second way right now, since there is no reliable way how to
20988 ;; verify that given register is live.  First choice will also most likely in
20989 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20990 ;; call clobbered registers are dead.  We may want to use base pointer as an
20991 ;; alternative when no register is available later.
20993 (define_peephole2
20994   [(match_scratch:SI 0 "r")
20995    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20996               (clobber (reg:CC FLAGS_REG))
20997               (clobber (mem:BLK (scratch)))])]
20998   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20999   [(clobber (match_dup 0))
21000    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21001               (clobber (mem:BLK (scratch)))])])
21003 (define_peephole2
21004   [(match_scratch:SI 0 "r")
21005    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21006               (clobber (reg:CC FLAGS_REG))
21007               (clobber (mem:BLK (scratch)))])]
21008   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21009   [(clobber (match_dup 0))
21010    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21011    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21012               (clobber (mem:BLK (scratch)))])])
21014 ;; Convert esp subtractions to push.
21015 (define_peephole2
21016   [(match_scratch:SI 0 "r")
21017    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21018               (clobber (reg:CC FLAGS_REG))])]
21019   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21020   [(clobber (match_dup 0))
21021    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21023 (define_peephole2
21024   [(match_scratch:SI 0 "r")
21025    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21026               (clobber (reg:CC FLAGS_REG))])]
21027   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21028   [(clobber (match_dup 0))
21029    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21030    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21032 ;; Convert epilogue deallocator to pop.
21033 (define_peephole2
21034   [(match_scratch:SI 0 "r")
21035    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21036               (clobber (reg:CC FLAGS_REG))
21037               (clobber (mem:BLK (scratch)))])]
21038   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21039   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21040               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21041               (clobber (mem:BLK (scratch)))])]
21042   "")
21044 ;; Two pops case is tricky, since pop causes dependency on destination register.
21045 ;; We use two registers if available.
21046 (define_peephole2
21047   [(match_scratch:SI 0 "r")
21048    (match_scratch:SI 1 "r")
21049    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21050               (clobber (reg:CC FLAGS_REG))
21051               (clobber (mem:BLK (scratch)))])]
21052   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21053   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21054               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21055               (clobber (mem:BLK (scratch)))])
21056    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21057               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21058   "")
21060 (define_peephole2
21061   [(match_scratch:SI 0 "r")
21062    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21063               (clobber (reg:CC FLAGS_REG))
21064               (clobber (mem:BLK (scratch)))])]
21065   "optimize_insn_for_size_p ()"
21066   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21067               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21068               (clobber (mem:BLK (scratch)))])
21069    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21070               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21071   "")
21073 ;; Convert esp additions to pop.
21074 (define_peephole2
21075   [(match_scratch:SI 0 "r")
21076    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21077               (clobber (reg:CC FLAGS_REG))])]
21078   ""
21079   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21080               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21081   "")
21083 ;; Two pops case is tricky, since pop causes dependency on destination register.
21084 ;; We use two registers if available.
21085 (define_peephole2
21086   [(match_scratch:SI 0 "r")
21087    (match_scratch:SI 1 "r")
21088    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21089               (clobber (reg:CC FLAGS_REG))])]
21090   ""
21091   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21092               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21093    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21094               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21095   "")
21097 (define_peephole2
21098   [(match_scratch:SI 0 "r")
21099    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21100               (clobber (reg:CC FLAGS_REG))])]
21101   "optimize_insn_for_size_p ()"
21102   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21103               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21104    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21105               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21106   "")
21108 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21109 ;; required and register dies.  Similarly for 128 to -128.
21110 (define_peephole2
21111   [(set (match_operand 0 "flags_reg_operand" "")
21112         (match_operator 1 "compare_operator"
21113           [(match_operand 2 "register_operand" "")
21114            (match_operand 3 "const_int_operand" "")]))]
21115   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
21116      && incdec_operand (operands[3], GET_MODE (operands[3])))
21117     || (!TARGET_FUSE_CMP_AND_BRANCH
21118         && INTVAL (operands[3]) == 128))
21119    && ix86_match_ccmode (insn, CCGCmode)
21120    && peep2_reg_dead_p (1, operands[2])"
21121   [(parallel [(set (match_dup 0)
21122                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21123               (clobber (match_dup 2))])]
21124   "")
21126 (define_peephole2
21127   [(match_scratch:DI 0 "r")
21128    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21129               (clobber (reg:CC FLAGS_REG))
21130               (clobber (mem:BLK (scratch)))])]
21131   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21132   [(clobber (match_dup 0))
21133    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21134               (clobber (mem:BLK (scratch)))])])
21136 (define_peephole2
21137   [(match_scratch:DI 0 "r")
21138    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21139               (clobber (reg:CC FLAGS_REG))
21140               (clobber (mem:BLK (scratch)))])]
21141   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21142   [(clobber (match_dup 0))
21143    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21144    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21145               (clobber (mem:BLK (scratch)))])])
21147 ;; Convert esp subtractions to push.
21148 (define_peephole2
21149   [(match_scratch:DI 0 "r")
21150    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21151               (clobber (reg:CC FLAGS_REG))])]
21152   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21153   [(clobber (match_dup 0))
21154    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21156 (define_peephole2
21157   [(match_scratch:DI 0 "r")
21158    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21159               (clobber (reg:CC FLAGS_REG))])]
21160   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21161   [(clobber (match_dup 0))
21162    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21163    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21165 ;; Convert epilogue deallocator to pop.
21166 (define_peephole2
21167   [(match_scratch:DI 0 "r")
21168    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21169               (clobber (reg:CC FLAGS_REG))
21170               (clobber (mem:BLK (scratch)))])]
21171   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21172   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21173               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21174               (clobber (mem:BLK (scratch)))])]
21175   "")
21177 ;; Two pops case is tricky, since pop causes dependency on destination register.
21178 ;; We use two registers if available.
21179 (define_peephole2
21180   [(match_scratch:DI 0 "r")
21181    (match_scratch:DI 1 "r")
21182    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21183               (clobber (reg:CC FLAGS_REG))
21184               (clobber (mem:BLK (scratch)))])]
21185   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21186   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21187               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21188               (clobber (mem:BLK (scratch)))])
21189    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21190               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21191   "")
21193 (define_peephole2
21194   [(match_scratch:DI 0 "r")
21195    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21196               (clobber (reg:CC FLAGS_REG))
21197               (clobber (mem:BLK (scratch)))])]
21198   "optimize_insn_for_size_p ()"
21199   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21200               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21201               (clobber (mem:BLK (scratch)))])
21202    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21203               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21204   "")
21206 ;; Convert esp additions to pop.
21207 (define_peephole2
21208   [(match_scratch:DI 0 "r")
21209    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21210               (clobber (reg:CC FLAGS_REG))])]
21211   ""
21212   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21213               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21214   "")
21216 ;; Two pops case is tricky, since pop causes dependency on destination register.
21217 ;; We use two registers if available.
21218 (define_peephole2
21219   [(match_scratch:DI 0 "r")
21220    (match_scratch:DI 1 "r")
21221    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21222               (clobber (reg:CC FLAGS_REG))])]
21223   ""
21224   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21225               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21226    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21227               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21228   "")
21230 (define_peephole2
21231   [(match_scratch:DI 0 "r")
21232    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21233               (clobber (reg:CC FLAGS_REG))])]
21234   "optimize_insn_for_size_p ()"
21235   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21236               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21237    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21238               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21239   "")
21241 ;; Convert imul by three, five and nine into lea
21242 (define_peephole2
21243   [(parallel
21244     [(set (match_operand:SI 0 "register_operand" "")
21245           (mult:SI (match_operand:SI 1 "register_operand" "")
21246                    (match_operand:SI 2 "const_int_operand" "")))
21247      (clobber (reg:CC FLAGS_REG))])]
21248   "INTVAL (operands[2]) == 3
21249    || INTVAL (operands[2]) == 5
21250    || INTVAL (operands[2]) == 9"
21251   [(set (match_dup 0)
21252         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21253                  (match_dup 1)))]
21254   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21256 (define_peephole2
21257   [(parallel
21258     [(set (match_operand:SI 0 "register_operand" "")
21259           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21260                    (match_operand:SI 2 "const_int_operand" "")))
21261      (clobber (reg:CC FLAGS_REG))])]
21262   "optimize_insn_for_speed_p ()
21263    && (INTVAL (operands[2]) == 3
21264        || INTVAL (operands[2]) == 5
21265        || INTVAL (operands[2]) == 9)"
21266   [(set (match_dup 0) (match_dup 1))
21267    (set (match_dup 0)
21268         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21269                  (match_dup 0)))]
21270   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21272 (define_peephole2
21273   [(parallel
21274     [(set (match_operand:DI 0 "register_operand" "")
21275           (mult:DI (match_operand:DI 1 "register_operand" "")
21276                    (match_operand:DI 2 "const_int_operand" "")))
21277      (clobber (reg:CC FLAGS_REG))])]
21278   "TARGET_64BIT
21279    && (INTVAL (operands[2]) == 3
21280        || INTVAL (operands[2]) == 5
21281        || INTVAL (operands[2]) == 9)"
21282   [(set (match_dup 0)
21283         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21284                  (match_dup 1)))]
21285   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21287 (define_peephole2
21288   [(parallel
21289     [(set (match_operand:DI 0 "register_operand" "")
21290           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21291                    (match_operand:DI 2 "const_int_operand" "")))
21292      (clobber (reg:CC FLAGS_REG))])]
21293   "TARGET_64BIT
21294    && optimize_insn_for_speed_p ()
21295    && (INTVAL (operands[2]) == 3
21296        || INTVAL (operands[2]) == 5
21297        || INTVAL (operands[2]) == 9)"
21298   [(set (match_dup 0) (match_dup 1))
21299    (set (match_dup 0)
21300         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21301                  (match_dup 0)))]
21302   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21304 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21305 ;; imul $32bit_imm, reg, reg is direct decoded.
21306 (define_peephole2
21307   [(match_scratch:DI 3 "r")
21308    (parallel [(set (match_operand:DI 0 "register_operand" "")
21309                    (mult:DI (match_operand:DI 1 "memory_operand" "")
21310                             (match_operand:DI 2 "immediate_operand" "")))
21311               (clobber (reg:CC FLAGS_REG))])]
21312   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21313    && !satisfies_constraint_K (operands[2])"
21314   [(set (match_dup 3) (match_dup 1))
21315    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21316               (clobber (reg:CC FLAGS_REG))])]
21319 (define_peephole2
21320   [(match_scratch:SI 3 "r")
21321    (parallel [(set (match_operand:SI 0 "register_operand" "")
21322                    (mult:SI (match_operand:SI 1 "memory_operand" "")
21323                             (match_operand:SI 2 "immediate_operand" "")))
21324               (clobber (reg:CC FLAGS_REG))])]
21325   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21326    && !satisfies_constraint_K (operands[2])"
21327   [(set (match_dup 3) (match_dup 1))
21328    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21329               (clobber (reg:CC FLAGS_REG))])]
21332 (define_peephole2
21333   [(match_scratch:SI 3 "r")
21334    (parallel [(set (match_operand:DI 0 "register_operand" "")
21335                    (zero_extend:DI
21336                      (mult:SI (match_operand:SI 1 "memory_operand" "")
21337                               (match_operand:SI 2 "immediate_operand" ""))))
21338               (clobber (reg:CC FLAGS_REG))])]
21339   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21340    && !satisfies_constraint_K (operands[2])"
21341   [(set (match_dup 3) (match_dup 1))
21342    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21343               (clobber (reg:CC FLAGS_REG))])]
21346 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21347 ;; Convert it into imul reg, reg
21348 ;; It would be better to force assembler to encode instruction using long
21349 ;; immediate, but there is apparently no way to do so.
21350 (define_peephole2
21351   [(parallel [(set (match_operand:DI 0 "register_operand" "")
21352                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21353                             (match_operand:DI 2 "const_int_operand" "")))
21354               (clobber (reg:CC FLAGS_REG))])
21355    (match_scratch:DI 3 "r")]
21356   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21357    && satisfies_constraint_K (operands[2])"
21358   [(set (match_dup 3) (match_dup 2))
21359    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21360               (clobber (reg:CC FLAGS_REG))])]
21362   if (!rtx_equal_p (operands[0], operands[1]))
21363     emit_move_insn (operands[0], operands[1]);
21366 (define_peephole2
21367   [(parallel [(set (match_operand:SI 0 "register_operand" "")
21368                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21369                             (match_operand:SI 2 "const_int_operand" "")))
21370               (clobber (reg:CC FLAGS_REG))])
21371    (match_scratch:SI 3 "r")]
21372   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21373    && satisfies_constraint_K (operands[2])"
21374   [(set (match_dup 3) (match_dup 2))
21375    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21376               (clobber (reg:CC FLAGS_REG))])]
21378   if (!rtx_equal_p (operands[0], operands[1]))
21379     emit_move_insn (operands[0], operands[1]);
21382 (define_peephole2
21383   [(parallel [(set (match_operand:HI 0 "register_operand" "")
21384                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21385                             (match_operand:HI 2 "immediate_operand" "")))
21386               (clobber (reg:CC FLAGS_REG))])
21387    (match_scratch:HI 3 "r")]
21388   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21389   [(set (match_dup 3) (match_dup 2))
21390    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21391               (clobber (reg:CC FLAGS_REG))])]
21393   if (!rtx_equal_p (operands[0], operands[1]))
21394     emit_move_insn (operands[0], operands[1]);
21397 ;; After splitting up read-modify operations, array accesses with memory
21398 ;; operands might end up in form:
21399 ;;  sall    $2, %eax
21400 ;;  movl    4(%esp), %edx
21401 ;;  addl    %edx, %eax
21402 ;; instead of pre-splitting:
21403 ;;  sall    $2, %eax
21404 ;;  addl    4(%esp), %eax
21405 ;; Turn it into:
21406 ;;  movl    4(%esp), %edx
21407 ;;  leal    (%edx,%eax,4), %eax
21409 (define_peephole2
21410   [(parallel [(set (match_operand 0 "register_operand" "")
21411                    (ashift (match_operand 1 "register_operand" "")
21412                            (match_operand 2 "const_int_operand" "")))
21413                (clobber (reg:CC FLAGS_REG))])
21414    (set (match_operand 3 "register_operand")
21415         (match_operand 4 "x86_64_general_operand" ""))
21416    (parallel [(set (match_operand 5 "register_operand" "")
21417                    (plus (match_operand 6 "register_operand" "")
21418                          (match_operand 7 "register_operand" "")))
21419                    (clobber (reg:CC FLAGS_REG))])]
21420   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21421    /* Validate MODE for lea.  */
21422    && ((!TARGET_PARTIAL_REG_STALL
21423         && (GET_MODE (operands[0]) == QImode
21424             || GET_MODE (operands[0]) == HImode))
21425        || GET_MODE (operands[0]) == SImode
21426        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21427    /* We reorder load and the shift.  */
21428    && !rtx_equal_p (operands[1], operands[3])
21429    && !reg_overlap_mentioned_p (operands[0], operands[4])
21430    /* Last PLUS must consist of operand 0 and 3.  */
21431    && !rtx_equal_p (operands[0], operands[3])
21432    && (rtx_equal_p (operands[3], operands[6])
21433        || rtx_equal_p (operands[3], operands[7]))
21434    && (rtx_equal_p (operands[0], operands[6])
21435        || rtx_equal_p (operands[0], operands[7]))
21436    /* The intermediate operand 0 must die or be same as output.  */
21437    && (rtx_equal_p (operands[0], operands[5])
21438        || peep2_reg_dead_p (3, operands[0]))"
21439   [(set (match_dup 3) (match_dup 4))
21440    (set (match_dup 0) (match_dup 1))]
21442   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21443   int scale = 1 << INTVAL (operands[2]);
21444   rtx index = gen_lowpart (Pmode, operands[1]);
21445   rtx base = gen_lowpart (Pmode, operands[3]);
21446   rtx dest = gen_lowpart (mode, operands[5]);
21448   operands[1] = gen_rtx_PLUS (Pmode, base,
21449                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21450   if (mode != Pmode)
21451     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21452   operands[0] = dest;
21455 ;; Call-value patterns last so that the wildcard operand does not
21456 ;; disrupt insn-recog's switch tables.
21458 (define_insn "*call_value_pop_0"
21459   [(set (match_operand 0 "" "")
21460         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21461               (match_operand:SI 2 "" "")))
21462    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21463                             (match_operand:SI 3 "immediate_operand" "")))]
21464   "!TARGET_64BIT"
21466   if (SIBLING_CALL_P (insn))
21467     return "jmp\t%P1";
21468   else
21469     return "call\t%P1";
21471   [(set_attr "type" "callv")])
21473 (define_insn "*call_value_pop_1"
21474   [(set (match_operand 0 "" "")
21475         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21476               (match_operand:SI 2 "" "")))
21477    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21478                             (match_operand:SI 3 "immediate_operand" "i")))]
21479   "!TARGET_64BIT"
21481   if (constant_call_address_operand (operands[1], Pmode))
21482     {
21483       if (SIBLING_CALL_P (insn))
21484         return "jmp\t%P1";
21485       else
21486         return "call\t%P1";
21487     }
21488   if (SIBLING_CALL_P (insn))
21489     return "jmp\t%A1";
21490   else
21491     return "call\t%A1";
21493   [(set_attr "type" "callv")])
21495 (define_insn "*call_value_0"
21496   [(set (match_operand 0 "" "")
21497         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21498               (match_operand:SI 2 "" "")))]
21499   "!TARGET_64BIT"
21501   if (SIBLING_CALL_P (insn))
21502     return "jmp\t%P1";
21503   else
21504     return "call\t%P1";
21506   [(set_attr "type" "callv")])
21508 (define_insn "*call_value_0_rex64"
21509   [(set (match_operand 0 "" "")
21510         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21511               (match_operand:DI 2 "const_int_operand" "")))]
21512   "TARGET_64BIT"
21514   if (SIBLING_CALL_P (insn))
21515     return "jmp\t%P1";
21516   else
21517     return "call\t%P1";
21519   [(set_attr "type" "callv")])
21521 (define_insn "*call_value_0_rex64_ms_sysv"
21522   [(set (match_operand 0 "" "")
21523         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21524               (match_operand:DI 2 "const_int_operand" "")))
21525    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21526    (clobber (reg:TI XMM6_REG))
21527    (clobber (reg:TI XMM7_REG))
21528    (clobber (reg:TI XMM8_REG))
21529    (clobber (reg:TI XMM9_REG))
21530    (clobber (reg:TI XMM10_REG))
21531    (clobber (reg:TI XMM11_REG))
21532    (clobber (reg:TI XMM12_REG))
21533    (clobber (reg:TI XMM13_REG))
21534    (clobber (reg:TI XMM14_REG))
21535    (clobber (reg:TI XMM15_REG))
21536    (clobber (reg:DI SI_REG))
21537    (clobber (reg:DI DI_REG))]
21538   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21540   if (SIBLING_CALL_P (insn))
21541     return "jmp\t%P1";
21542   else
21543     return "call\t%P1";
21545   [(set_attr "type" "callv")])
21547 (define_insn "*call_value_1"
21548   [(set (match_operand 0 "" "")
21549         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21550               (match_operand:SI 2 "" "")))]
21551   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21553   if (constant_call_address_operand (operands[1], Pmode))
21554     return "call\t%P1";
21555   return "call\t%A1";
21557   [(set_attr "type" "callv")])
21559 (define_insn "*sibcall_value_1"
21560   [(set (match_operand 0 "" "")
21561         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21562               (match_operand:SI 2 "" "")))]
21563   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21565   if (constant_call_address_operand (operands[1], Pmode))
21566     return "jmp\t%P1";
21567   return "jmp\t%A1";
21569   [(set_attr "type" "callv")])
21571 (define_insn "*call_value_1_rex64"
21572   [(set (match_operand 0 "" "")
21573         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21574               (match_operand:DI 2 "" "")))]
21575   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21576    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21578   if (constant_call_address_operand (operands[1], Pmode))
21579     return "call\t%P1";
21580   return "call\t%A1";
21582   [(set_attr "type" "callv")])
21584 (define_insn "*call_value_1_rex64_ms_sysv"
21585   [(set (match_operand 0 "" "")
21586         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21587               (match_operand:DI 2 "" "")))
21588    (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21589    (clobber (reg:TI 27))
21590    (clobber (reg:TI 28))
21591    (clobber (reg:TI 45))
21592    (clobber (reg:TI 46))
21593    (clobber (reg:TI 47))
21594    (clobber (reg:TI 48))
21595    (clobber (reg:TI 49))
21596    (clobber (reg:TI 50))
21597    (clobber (reg:TI 51))
21598    (clobber (reg:TI 52))
21599    (clobber (reg:DI SI_REG))
21600    (clobber (reg:DI DI_REG))]
21601   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21603   if (constant_call_address_operand (operands[1], Pmode))
21604     return "call\t%P1";
21605   return "call\t%A1";
21607   [(set_attr "type" "callv")])
21609 (define_insn "*call_value_1_rex64_large"
21610   [(set (match_operand 0 "" "")
21611         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21612               (match_operand:DI 2 "" "")))]
21613   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21614   "call\t%A1"
21615   [(set_attr "type" "callv")])
21617 (define_insn "*sibcall_value_1_rex64"
21618   [(set (match_operand 0 "" "")
21619         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21620               (match_operand:DI 2 "" "")))]
21621   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21622   "jmp\t%P1"
21623   [(set_attr "type" "callv")])
21625 (define_insn "*sibcall_value_1_rex64_v"
21626   [(set (match_operand 0 "" "")
21627         (call (mem:QI (reg:DI R11_REG))
21628               (match_operand:DI 1 "" "")))]
21629   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21630   "jmp\t{*%%}r11"
21631   [(set_attr "type" "callv")])
21633 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21634 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21635 ;; caught for use by garbage collectors and the like.  Using an insn that
21636 ;; maps to SIGILL makes it more likely the program will rightfully die.
21637 ;; Keeping with tradition, "6" is in honor of #UD.
21638 (define_insn "trap"
21639   [(trap_if (const_int 1) (const_int 6))]
21640   ""
21641   { return ASM_SHORT "0x0b0f"; }
21642   [(set_attr "length" "2")])
21644 (define_expand "sse_prologue_save"
21645   [(parallel [(set (match_operand:BLK 0 "" "")
21646                    (unspec:BLK [(reg:DI 21)
21647                                 (reg:DI 22)
21648                                 (reg:DI 23)
21649                                 (reg:DI 24)
21650                                 (reg:DI 25)
21651                                 (reg:DI 26)
21652                                 (reg:DI 27)
21653                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21654               (use (match_operand:DI 1 "register_operand" ""))
21655               (use (match_operand:DI 2 "immediate_operand" ""))
21656               (use (label_ref:DI (match_operand 3 "" "")))])]
21657   "TARGET_64BIT"
21658   "")
21660 (define_insn "*sse_prologue_save_insn"
21661   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21662                           (match_operand:DI 4 "const_int_operand" "n")))
21663         (unspec:BLK [(reg:DI 21)
21664                      (reg:DI 22)
21665                      (reg:DI 23)
21666                      (reg:DI 24)
21667                      (reg:DI 25)
21668                      (reg:DI 26)
21669                      (reg:DI 27)
21670                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21671    (use (match_operand:DI 1 "register_operand" "r"))
21672    (use (match_operand:DI 2 "const_int_operand" "i"))
21673    (use (label_ref:DI (match_operand 3 "" "X")))]
21674   "TARGET_64BIT
21675    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21676    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21678   int i;
21679   operands[0] = gen_rtx_MEM (Pmode,
21680                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21681   /* VEX instruction with a REX prefix will #UD.  */
21682   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21683     gcc_unreachable ();
21685   output_asm_insn ("jmp\t%A1", operands);
21686   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21687     {
21688       operands[4] = adjust_address (operands[0], DImode, i*16);
21689       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21690       PUT_MODE (operands[4], TImode);
21691       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21692         output_asm_insn ("rex", operands);
21693       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21694     }
21695   (*targetm.asm_out.internal_label) (asm_out_file, "L",
21696                                      CODE_LABEL_NUMBER (operands[3]));
21697   return "";
21699   [(set_attr "type" "other")
21700    (set_attr "length_immediate" "0")
21701    (set_attr "length_address" "0")
21702    (set (attr "length")
21703      (if_then_else
21704        (eq (symbol_ref "TARGET_AVX") (const_int 0))
21705        (const_string "34")
21706        (const_string "42")))
21707    (set_attr "memory" "store")
21708    (set_attr "modrm" "0")
21709    (set_attr "prefix" "maybe_vex")
21710    (set_attr "mode" "DI")])
21712 (define_expand "prefetch"
21713   [(prefetch (match_operand 0 "address_operand" "")
21714              (match_operand:SI 1 "const_int_operand" "")
21715              (match_operand:SI 2 "const_int_operand" ""))]
21716   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21718   int rw = INTVAL (operands[1]);
21719   int locality = INTVAL (operands[2]);
21721   gcc_assert (rw == 0 || rw == 1);
21722   gcc_assert (locality >= 0 && locality <= 3);
21723   gcc_assert (GET_MODE (operands[0]) == Pmode
21724               || GET_MODE (operands[0]) == VOIDmode);
21726   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21727      supported by SSE counterpart or the SSE prefetch is not available
21728      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21729      of locality.  */
21730   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21731     operands[2] = GEN_INT (3);
21732   else
21733     operands[1] = const0_rtx;
21736 (define_insn "*prefetch_sse"
21737   [(prefetch (match_operand:SI 0 "address_operand" "p")
21738              (const_int 0)
21739              (match_operand:SI 1 "const_int_operand" ""))]
21740   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21742   static const char * const patterns[4] = {
21743    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21744   };
21746   int locality = INTVAL (operands[1]);
21747   gcc_assert (locality >= 0 && locality <= 3);
21749   return patterns[locality];
21751   [(set_attr "type" "sse")
21752    (set_attr "memory" "none")])
21754 (define_insn "*prefetch_sse_rex"
21755   [(prefetch (match_operand:DI 0 "address_operand" "p")
21756              (const_int 0)
21757              (match_operand:SI 1 "const_int_operand" ""))]
21758   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21760   static const char * const patterns[4] = {
21761    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21762   };
21764   int locality = INTVAL (operands[1]);
21765   gcc_assert (locality >= 0 && locality <= 3);
21767   return patterns[locality];
21769   [(set_attr "type" "sse")
21770    (set_attr "memory" "none")])
21772 (define_insn "*prefetch_3dnow"
21773   [(prefetch (match_operand:SI 0 "address_operand" "p")
21774              (match_operand:SI 1 "const_int_operand" "n")
21775              (const_int 3))]
21776   "TARGET_3DNOW && !TARGET_64BIT"
21778   if (INTVAL (operands[1]) == 0)
21779     return "prefetch\t%a0";
21780   else
21781     return "prefetchw\t%a0";
21783   [(set_attr "type" "mmx")
21784    (set_attr "memory" "none")])
21786 (define_insn "*prefetch_3dnow_rex"
21787   [(prefetch (match_operand:DI 0 "address_operand" "p")
21788              (match_operand:SI 1 "const_int_operand" "n")
21789              (const_int 3))]
21790   "TARGET_3DNOW && TARGET_64BIT"
21792   if (INTVAL (operands[1]) == 0)
21793     return "prefetch\t%a0";
21794   else
21795     return "prefetchw\t%a0";
21797   [(set_attr "type" "mmx")
21798    (set_attr "memory" "none")])
21800 (define_expand "stack_protect_set"
21801   [(match_operand 0 "memory_operand" "")
21802    (match_operand 1 "memory_operand" "")]
21803   ""
21805 #ifdef TARGET_THREAD_SSP_OFFSET
21806   if (TARGET_64BIT)
21807     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21808                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21809   else
21810     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21811                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21812 #else
21813   if (TARGET_64BIT)
21814     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21815   else
21816     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21817 #endif
21818   DONE;
21821 (define_insn "stack_protect_set_si"
21822   [(set (match_operand:SI 0 "memory_operand" "=m")
21823         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21824    (set (match_scratch:SI 2 "=&r") (const_int 0))
21825    (clobber (reg:CC FLAGS_REG))]
21826   ""
21827   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21828   [(set_attr "type" "multi")])
21830 (define_insn "stack_protect_set_di"
21831   [(set (match_operand:DI 0 "memory_operand" "=m")
21832         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21833    (set (match_scratch:DI 2 "=&r") (const_int 0))
21834    (clobber (reg:CC FLAGS_REG))]
21835   "TARGET_64BIT"
21836   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21837   [(set_attr "type" "multi")])
21839 (define_insn "stack_tls_protect_set_si"
21840   [(set (match_operand:SI 0 "memory_operand" "=m")
21841         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21842    (set (match_scratch:SI 2 "=&r") (const_int 0))
21843    (clobber (reg:CC FLAGS_REG))]
21844   ""
21845   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21846   [(set_attr "type" "multi")])
21848 (define_insn "stack_tls_protect_set_di"
21849   [(set (match_operand:DI 0 "memory_operand" "=m")
21850         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21851    (set (match_scratch:DI 2 "=&r") (const_int 0))
21852    (clobber (reg:CC FLAGS_REG))]
21853   "TARGET_64BIT"
21854   {
21855      /* The kernel uses a different segment register for performance reasons; a
21856         system call would not have to trash the userspace segment register,
21857         which would be expensive */
21858      if (ix86_cmodel != CM_KERNEL)
21859         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21860      else
21861         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21862   }
21863   [(set_attr "type" "multi")])
21865 (define_expand "stack_protect_test"
21866   [(match_operand 0 "memory_operand" "")
21867    (match_operand 1 "memory_operand" "")
21868    (match_operand 2 "" "")]
21869   ""
21871   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21872   ix86_compare_op0 = operands[0];
21873   ix86_compare_op1 = operands[1];
21874   ix86_compare_emitted = flags;
21876 #ifdef TARGET_THREAD_SSP_OFFSET
21877   if (TARGET_64BIT)
21878     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21879                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21880   else
21881     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21882                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21883 #else
21884   if (TARGET_64BIT)
21885     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21886   else
21887     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21888 #endif
21889   emit_jump_insn (gen_beq (operands[2]));
21890   DONE;
21893 (define_insn "stack_protect_test_si"
21894   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21895         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21896                      (match_operand:SI 2 "memory_operand" "m")]
21897                     UNSPEC_SP_TEST))
21898    (clobber (match_scratch:SI 3 "=&r"))]
21899   ""
21900   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21901   [(set_attr "type" "multi")])
21903 (define_insn "stack_protect_test_di"
21904   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21905         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21906                      (match_operand:DI 2 "memory_operand" "m")]
21907                     UNSPEC_SP_TEST))
21908    (clobber (match_scratch:DI 3 "=&r"))]
21909   "TARGET_64BIT"
21910   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21911   [(set_attr "type" "multi")])
21913 (define_insn "stack_tls_protect_test_si"
21914   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21915         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21916                      (match_operand:SI 2 "const_int_operand" "i")]
21917                     UNSPEC_SP_TLS_TEST))
21918    (clobber (match_scratch:SI 3 "=r"))]
21919   ""
21920   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21921   [(set_attr "type" "multi")])
21923 (define_insn "stack_tls_protect_test_di"
21924   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21925         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21926                      (match_operand:DI 2 "const_int_operand" "i")]
21927                     UNSPEC_SP_TLS_TEST))
21928    (clobber (match_scratch:DI 3 "=r"))]
21929   "TARGET_64BIT"
21930   {
21931      /* The kernel uses a different segment register for performance reasons; a
21932         system call would not have to trash the userspace segment register,
21933         which would be expensive */
21934      if (ix86_cmodel != CM_KERNEL)
21935         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21936      else
21937         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21938   }
21939   [(set_attr "type" "multi")])
21941 (define_mode_iterator CRC32MODE [QI HI SI])
21942 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21943 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21945 (define_insn "sse4_2_crc32<mode>"
21946   [(set (match_operand:SI 0 "register_operand" "=r")
21947         (unspec:SI
21948           [(match_operand:SI 1 "register_operand" "0")
21949            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21950           UNSPEC_CRC32))]
21951   "TARGET_SSE4_2"
21952   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21953   [(set_attr "type" "sselog1")
21954    (set_attr "prefix_rep" "1")
21955    (set_attr "prefix_extra" "1")
21956    (set_attr "mode" "SI")])
21958 (define_insn "sse4_2_crc32di"
21959   [(set (match_operand:DI 0 "register_operand" "=r")
21960         (unspec:DI
21961           [(match_operand:DI 1 "register_operand" "0")
21962            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21963           UNSPEC_CRC32))]
21964   "TARGET_SSE4_2 && TARGET_64BIT"
21965   "crc32q\t{%2, %0|%0, %2}"
21966   [(set_attr "type" "sselog1")
21967    (set_attr "prefix_rep" "1")
21968    (set_attr "prefix_extra" "1")
21969    (set_attr "mode" "DI")])
21971 (include "mmx.md")
21972 (include "sse.md")
21973 (include "sync.md")