2008-12-02 Jakub Jelinek <jakub@redhat.com>
[official-gcc.git] / gcc / config / i386 / i386.md
blob068738d22965302ce0fb566b433370fcac4552df
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
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)
72    ; TLS support
73    (UNSPEC_TP                   18)
74    (UNSPEC_TLS_GD               19)
75    (UNSPEC_TLS_LD_BASE          20)
76    (UNSPEC_TLSDESC              21)
78    ; Other random patterns
79    (UNSPEC_SCAS                 30)
80    (UNSPEC_FNSTSW               31)
81    (UNSPEC_SAHF                 32)
82    (UNSPEC_FSTCW                33)
83    (UNSPEC_ADD_CARRY            34)
84    (UNSPEC_FLDCW                35)
85    (UNSPEC_REP                  36)
86    (UNSPEC_EH_RETURN            37)
87    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
88    (UNSPEC_TRUNC_NOOP           39)
90    ; For SSE/MMX support:
91    (UNSPEC_FIX_NOTRUNC          40)
92    (UNSPEC_MASKMOV              41)
93    (UNSPEC_MOVMSK               42)
94    (UNSPEC_MOVNT                43)
95    (UNSPEC_MOVU                 44)
96    (UNSPEC_RCP                  45)
97    (UNSPEC_RSQRT                46)
98    (UNSPEC_SFENCE               47)
99    (UNSPEC_PFRCP                49)
100    (UNSPEC_PFRCPIT1             40)
101    (UNSPEC_PFRCPIT2             41)
102    (UNSPEC_PFRSQRT              42)
103    (UNSPEC_PFRSQIT1             43)
104    (UNSPEC_MFENCE               44)
105    (UNSPEC_LFENCE               45)
106    (UNSPEC_PSADBW               46)
107    (UNSPEC_LDDQU                47)
109    ; Generic math support
110    (UNSPEC_COPYSIGN             50)
111    (UNSPEC_IEEE_MIN             51)     ; not commutative
112    (UNSPEC_IEEE_MAX             52)     ; not commutative
114    ; x87 Floating point
115    (UNSPEC_SIN                  60)
116    (UNSPEC_COS                  61)
117    (UNSPEC_FPATAN               62)
118    (UNSPEC_FYL2X                63)
119    (UNSPEC_FYL2XP1              64)
120    (UNSPEC_FRNDINT              65)
121    (UNSPEC_FIST                 66)
122    (UNSPEC_F2XM1                67)
123    (UNSPEC_TAN                  68)
124    (UNSPEC_FXAM                 69)
126    ; x87 Rounding
127    (UNSPEC_FRNDINT_FLOOR        70)
128    (UNSPEC_FRNDINT_CEIL         71)
129    (UNSPEC_FRNDINT_TRUNC        72)
130    (UNSPEC_FRNDINT_MASK_PM      73)
131    (UNSPEC_FIST_FLOOR           74)
132    (UNSPEC_FIST_CEIL            75)
134    ; x87 Double output FP
135    (UNSPEC_SINCOS_COS           80)
136    (UNSPEC_SINCOS_SIN           81)
137    (UNSPEC_XTRACT_FRACT         84)
138    (UNSPEC_XTRACT_EXP           85)
139    (UNSPEC_FSCALE_FRACT         86)
140    (UNSPEC_FSCALE_EXP           87)
141    (UNSPEC_FPREM_F              88)
142    (UNSPEC_FPREM_U              89)
143    (UNSPEC_FPREM1_F             90)
144    (UNSPEC_FPREM1_U             91)
146    (UNSPEC_C2_FLAG              95)
148    ; SSP patterns
149    (UNSPEC_SP_SET               100)
150    (UNSPEC_SP_TEST              101)
151    (UNSPEC_SP_TLS_SET           102)
152    (UNSPEC_SP_TLS_TEST          103)
154    ; SSSE3
155    (UNSPEC_PSHUFB               120)
156    (UNSPEC_PSIGN                121)
157    (UNSPEC_PALIGNR              122)
159    ; For SSE4A support
160    (UNSPEC_EXTRQI               130)
161    (UNSPEC_EXTRQ                131)
162    (UNSPEC_INSERTQI             132)
163    (UNSPEC_INSERTQ              133)
165    ; For SSE4.1 support
166    (UNSPEC_BLENDV               134)
167    (UNSPEC_INSERTPS             135)
168    (UNSPEC_DP                   136)
169    (UNSPEC_MOVNTDQA             137)
170    (UNSPEC_MPSADBW              138)
171    (UNSPEC_PHMINPOSUW           139)
172    (UNSPEC_PTEST                140)
173    (UNSPEC_ROUND                141)
175    ; For SSE4.2 support
176    (UNSPEC_CRC32                143)
177    (UNSPEC_PCMPESTR             144)
178    (UNSPEC_PCMPISTR             145)
180    ;; For SSE5
181    (UNSPEC_SSE5_INTRINSIC       150)
182    (UNSPEC_SSE5_UNSIGNED_CMP    151)
183    (UNSPEC_SSE5_TRUEFALSE       152)
184    (UNSPEC_SSE5_PERMUTE         153)
185    (UNSPEC_FRCZ                 154)
186    (UNSPEC_CVTPH2PS             155)
187    (UNSPEC_CVTPS2PH             156)
189    ; For AES support
190    (UNSPEC_AESENC               159)
191    (UNSPEC_AESENCLAST           160)
192    (UNSPEC_AESDEC               161)
193    (UNSPEC_AESDECLAST           162)
194    (UNSPEC_AESIMC               163)
195    (UNSPEC_AESKEYGENASSIST      164)
197    ; For PCLMUL support
198    (UNSPEC_PCLMUL               165)
200    ; For AVX support
201    (UNSPEC_PCMP                 166)
202    (UNSPEC_VPERMIL              167)
203    (UNSPEC_VPERMIL2             168)
204    (UNSPEC_VPERMIL2F128         169)
205    (UNSPEC_MASKLOAD             170)
206    (UNSPEC_MASKSTORE            171)
207    (UNSPEC_CAST                 172)
208    (UNSPEC_VTESTP               173)
209   ])
211 (define_constants
212   [(UNSPECV_BLOCKAGE            0)
213    (UNSPECV_STACK_PROBE         1)
214    (UNSPECV_EMMS                2)
215    (UNSPECV_LDMXCSR             3)
216    (UNSPECV_STMXCSR             4)
217    (UNSPECV_FEMMS               5)
218    (UNSPECV_CLFLUSH             6)
219    (UNSPECV_ALIGN               7)
220    (UNSPECV_MONITOR             8)
221    (UNSPECV_MWAIT               9)
222    (UNSPECV_CMPXCHG             10)
223    (UNSPECV_XCHG                12)
224    (UNSPECV_LOCK                13)
225    (UNSPECV_PROLOGUE_USE        14)
226    (UNSPECV_CLD                 15)
227    (UNSPECV_VZEROALL            16)
228    (UNSPECV_VZEROUPPER          17)
229   ])
231 ;; Constants to represent pcomtrue/pcomfalse variants
232 (define_constants
233   [(PCOM_FALSE                  0)
234    (PCOM_TRUE                   1)
235    (COM_FALSE_S                 2)
236    (COM_FALSE_P                 3)
237    (COM_TRUE_S                  4)
238    (COM_TRUE_P                  5)
239   ])
241 ;; Constants used in the SSE5 pperm instruction
242 (define_constants
243   [(PPERM_SRC                   0x00)   /* copy source */
244    (PPERM_INVERT                0x20)   /* invert source */
245    (PPERM_REVERSE               0x40)   /* bit reverse source */
246    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
247    (PPERM_ZERO                  0x80)   /* all 0's */
248    (PPERM_ONES                  0xa0)   /* all 1's */
249    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
250    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
251    (PPERM_SRC1                  0x00)   /* use first source byte */
252    (PPERM_SRC2                  0x10)   /* use second source byte */
253    ])
255 ;; Registers by name.
256 (define_constants
257   [(AX_REG                       0)
258    (DX_REG                       1)
259    (CX_REG                       2)
260    (BX_REG                       3)
261    (SI_REG                       4)
262    (DI_REG                       5)
263    (BP_REG                       6)
264    (SP_REG                       7)
265    (FLAGS_REG                   17)
266    (FPSR_REG                    18)
267    (FPCR_REG                    19)
268    (XMM0_REG                    21)
269    (XMM1_REG                    22)
270    (XMM2_REG                    23)
271    (XMM3_REG                    24)
272    (XMM4_REG                    25)
273    (XMM5_REG                    26)
274    (XMM6_REG                    27)
275    (XMM7_REG                    28)
276    (R10_REG                     39)
277    (R11_REG                     40)
278    (R13_REG                     42)
279    (XMM8_REG                    45)
280    (XMM9_REG                    46)
281    (XMM10_REG                   47)
282    (XMM11_REG                   48)
283    (XMM12_REG                   49)
284    (XMM13_REG                   50)
285    (XMM14_REG                   51)
286    (XMM15_REG                   52)
287   ])
289 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
290 ;; from i386.c.
292 ;; In C guard expressions, put expressions which may be compile-time
293 ;; constants first.  This allows for better optimization.  For
294 ;; example, write "TARGET_64BIT && reload_completed", not
295 ;; "reload_completed && TARGET_64BIT".
298 ;; Processor type.
299 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,
300                     generic64,amdfam10"
301   (const (symbol_ref "ix86_schedule")))
303 ;; A basic instruction type.  Refinements due to arguments to be
304 ;; provided in other attributes.
305 (define_attr "type"
306   "other,multi,
307    alu,alu1,negnot,imov,imovx,lea,
308    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
309    icmp,test,ibr,setcc,icmov,
310    push,pop,call,callv,leave,
311    str,bitmanip,
312    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
313    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
314    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
315    ssemuladd,sse4arg,
316    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
317   (const_string "other"))
319 ;; Main data type used by the insn
320 (define_attr "mode"
321   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
322   (const_string "unknown"))
324 ;; The CPU unit operations uses.
325 (define_attr "unit" "integer,i387,sse,mmx,unknown"
326   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
327            (const_string "i387")
328          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
329                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
330                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
331            (const_string "sse")
332          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
333            (const_string "mmx")
334          (eq_attr "type" "other")
335            (const_string "unknown")]
336          (const_string "integer")))
338 ;; The (bounding maximum) length of an instruction immediate.
339 (define_attr "length_immediate" ""
340   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
341                           bitmanip")
342            (const_int 0)
343          (eq_attr "unit" "i387,sse,mmx")
344            (const_int 0)
345          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
346                           imul,icmp,push,pop")
347            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
348          (eq_attr "type" "imov,test")
349            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
350          (eq_attr "type" "call")
351            (if_then_else (match_operand 0 "constant_call_address_operand" "")
352              (const_int 4)
353              (const_int 0))
354          (eq_attr "type" "callv")
355            (if_then_else (match_operand 1 "constant_call_address_operand" "")
356              (const_int 4)
357              (const_int 0))
358          ;; We don't know the size before shorten_branches.  Expect
359          ;; the instruction to fit for better scheduling.
360          (eq_attr "type" "ibr")
361            (const_int 1)
362          ]
363          (symbol_ref "/* Update immediate_length and other attributes! */
364                       gcc_unreachable (),1")))
366 ;; The (bounding maximum) length of an instruction address.
367 (define_attr "length_address" ""
368   (cond [(eq_attr "type" "str,other,multi,fxch")
369            (const_int 0)
370          (and (eq_attr "type" "call")
371               (match_operand 0 "constant_call_address_operand" ""))
372              (const_int 0)
373          (and (eq_attr "type" "callv")
374               (match_operand 1 "constant_call_address_operand" ""))
375              (const_int 0)
376          ]
377          (symbol_ref "ix86_attr_length_address_default (insn)")))
379 ;; Set when length prefix is used.
380 (define_attr "prefix_data16" ""
381   (if_then_else (ior (eq_attr "mode" "HI")
382                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
383     (const_int 1)
384     (const_int 0)))
386 ;; Set when string REP prefix is used.
387 (define_attr "prefix_rep" ""
388   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
389     (const_int 1)
390     (const_int 0)))
392 ;; Set when 0f opcode prefix is used.
393 (define_attr "prefix_0f" ""
394   (if_then_else
395     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
396          (eq_attr "unit" "sse,mmx"))
397     (const_int 1)
398     (const_int 0)))
400 ;; Set when REX opcode prefix is used.
401 (define_attr "prefix_rex" ""
402   (cond [(and (eq_attr "mode" "DI")
403               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
404            (const_int 1)
405          (and (eq_attr "mode" "QI")
406               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
407                   (const_int 0)))
408            (const_int 1)
409          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
410              (const_int 0))
411            (const_int 1)
412         ]
413         (const_int 0)))
415 ;; There are also additional prefixes in SSSE3.
416 (define_attr "prefix_extra" "" (const_int 0))
418 ;; Prefix used: original, VEX or maybe VEX.
419 (define_attr "prefix" "orig,vex,maybe_vex"
420   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
421     (const_string "vex")
422     (const_string "orig")))
424 ;; There is a 8bit immediate for VEX.
425 (define_attr "prefix_vex_imm8" "" (const_int 0))
427 ;; VEX W bit is used.
428 (define_attr "prefix_vex_w" "" (const_int 0))
430 ;; The length of VEX prefix
431 (define_attr "length_vex" ""
432   (if_then_else (eq_attr "prefix_0f" "1")
433     (if_then_else (eq_attr "prefix_vex_w" "1")
434       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
435       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
436     (if_then_else (eq_attr "prefix_vex_w" "1")
437       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
438       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
440 ;; Set when modrm byte is used.
441 (define_attr "modrm" ""
442   (cond [(eq_attr "type" "str,leave")
443            (const_int 0)
444          (eq_attr "unit" "i387")
445            (const_int 0)
446          (and (eq_attr "type" "incdec")
447               (ior (match_operand:SI 1 "register_operand" "")
448                    (match_operand:HI 1 "register_operand" "")))
449            (const_int 0)
450          (and (eq_attr "type" "push")
451               (not (match_operand 1 "memory_operand" "")))
452            (const_int 0)
453          (and (eq_attr "type" "pop")
454               (not (match_operand 0 "memory_operand" "")))
455            (const_int 0)
456          (and (eq_attr "type" "imov")
457               (ior (and (match_operand 0 "register_operand" "")
458                         (match_operand 1 "immediate_operand" ""))
459                    (ior (and (match_operand 0 "ax_reg_operand" "")
460                              (match_operand 1 "memory_displacement_only_operand" ""))
461                         (and (match_operand 0 "memory_displacement_only_operand" "")
462                              (match_operand 1 "ax_reg_operand" "")))))
463            (const_int 0)
464          (and (eq_attr "type" "call")
465               (match_operand 0 "constant_call_address_operand" ""))
466              (const_int 0)
467          (and (eq_attr "type" "callv")
468               (match_operand 1 "constant_call_address_operand" ""))
469              (const_int 0)
470          ]
471          (const_int 1)))
473 ;; The (bounding maximum) length of an instruction in bytes.
474 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
475 ;; Later we may want to split them and compute proper length as for
476 ;; other insns.
477 (define_attr "length" ""
478   (cond [(eq_attr "type" "other,multi,fistp,frndint")
479            (const_int 16)
480          (eq_attr "type" "fcmp")
481            (const_int 4)
482          (eq_attr "unit" "i387")
483            (plus (const_int 2)
484                  (plus (attr "prefix_data16")
485                        (attr "length_address")))
486          (ior (eq_attr "prefix" "vex")
487               (and (eq_attr "prefix" "maybe_vex")
488                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
489            (plus (attr "length_vex")
490                  (plus (attr "prefix_vex_imm8")
491                        (plus (attr "modrm")
492                              (attr "length_address"))))]
493          (plus (plus (attr "modrm")
494                      (plus (attr "prefix_0f")
495                            (plus (attr "prefix_rex")
496                                  (plus (attr "prefix_extra")
497                                        (const_int 1)))))
498                (plus (attr "prefix_rep")
499                      (plus (attr "prefix_data16")
500                            (plus (attr "length_immediate")
501                                  (attr "length_address")))))))
503 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
504 ;; `store' if there is a simple memory reference therein, or `unknown'
505 ;; if the instruction is complex.
507 (define_attr "memory" "none,load,store,both,unknown"
508   (cond [(eq_attr "type" "other,multi,str")
509            (const_string "unknown")
510          (eq_attr "type" "lea,fcmov,fpspc")
511            (const_string "none")
512          (eq_attr "type" "fistp,leave")
513            (const_string "both")
514          (eq_attr "type" "frndint")
515            (const_string "load")
516          (eq_attr "type" "push")
517            (if_then_else (match_operand 1 "memory_operand" "")
518              (const_string "both")
519              (const_string "store"))
520          (eq_attr "type" "pop")
521            (if_then_else (match_operand 0 "memory_operand" "")
522              (const_string "both")
523              (const_string "load"))
524          (eq_attr "type" "setcc")
525            (if_then_else (match_operand 0 "memory_operand" "")
526              (const_string "store")
527              (const_string "none"))
528          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
529            (if_then_else (ior (match_operand 0 "memory_operand" "")
530                               (match_operand 1 "memory_operand" ""))
531              (const_string "load")
532              (const_string "none"))
533          (eq_attr "type" "ibr")
534            (if_then_else (match_operand 0 "memory_operand" "")
535              (const_string "load")
536              (const_string "none"))
537          (eq_attr "type" "call")
538            (if_then_else (match_operand 0 "constant_call_address_operand" "")
539              (const_string "none")
540              (const_string "load"))
541          (eq_attr "type" "callv")
542            (if_then_else (match_operand 1 "constant_call_address_operand" "")
543              (const_string "none")
544              (const_string "load"))
545          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
546               (match_operand 1 "memory_operand" ""))
547            (const_string "both")
548          (and (match_operand 0 "memory_operand" "")
549               (match_operand 1 "memory_operand" ""))
550            (const_string "both")
551          (match_operand 0 "memory_operand" "")
552            (const_string "store")
553          (match_operand 1 "memory_operand" "")
554            (const_string "load")
555          (and (eq_attr "type"
556                  "!alu1,negnot,ishift1,
557                    imov,imovx,icmp,test,bitmanip,
558                    fmov,fcmp,fsgn,
559                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
560                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
561               (match_operand 2 "memory_operand" ""))
562            (const_string "load")
563          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
564               (match_operand 3 "memory_operand" ""))
565            (const_string "load")
566         ]
567         (const_string "none")))
569 ;; Indicates if an instruction has both an immediate and a displacement.
571 (define_attr "imm_disp" "false,true,unknown"
572   (cond [(eq_attr "type" "other,multi")
573            (const_string "unknown")
574          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
575               (and (match_operand 0 "memory_displacement_operand" "")
576                    (match_operand 1 "immediate_operand" "")))
577            (const_string "true")
578          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
579               (and (match_operand 0 "memory_displacement_operand" "")
580                    (match_operand 2 "immediate_operand" "")))
581            (const_string "true")
582         ]
583         (const_string "false")))
585 ;; Indicates if an FP operation has an integer source.
587 (define_attr "fp_int_src" "false,true"
588   (const_string "false"))
590 ;; Defines rounding mode of an FP operation.
592 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
593   (const_string "any"))
595 ;; Describe a user's asm statement.
596 (define_asm_attributes
597   [(set_attr "length" "128")
598    (set_attr "type" "multi")])
600 ;; All integer comparison codes.
601 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
603 ;; All floating-point comparison codes.
604 (define_code_iterator fp_cond [unordered ordered
605                                uneq unge ungt unle unlt ltgt ])
607 (define_code_iterator plusminus [plus minus])
609 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
611 ;; Base name for define_insn
612 (define_code_attr plusminus_insn
613   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
614    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
616 ;; Base name for insn mnemonic.
617 (define_code_attr plusminus_mnemonic
618   [(plus "add") (ss_plus "adds") (us_plus "addus")
619    (minus "sub") (ss_minus "subs") (us_minus "subus")])
621 ;; Mark commutative operators as such in constraints.
622 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
623                         (minus "") (ss_minus "") (us_minus "")])
625 ;; Mapping of signed max and min
626 (define_code_iterator smaxmin [smax smin])
628 ;; Mapping of unsigned max and min
629 (define_code_iterator umaxmin [umax umin])
631 ;; Mapping of signed/unsigned max and min
632 (define_code_iterator maxmin [smax smin umax umin])
634 ;; Base name for integer and FP insn mnemonic
635 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
636                                  (umax "maxu") (umin "minu")])
637 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
639 ;; Mapping of parallel logic operators
640 (define_code_iterator plogic [and ior xor])
642 ;; Base name for insn mnemonic.
643 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
645 ;; Mapping of abs neg operators
646 (define_code_iterator absneg [abs neg])
648 ;; Base name for x87 insn mnemonic.
649 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
651 ;; All single word integer modes.
652 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
654 ;; Single word integer modes without QImode.
655 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
657 ;; Instruction suffix for integer modes.
658 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
660 ;; Register class for integer modes.
661 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
663 ;; Immediate operand constraint for integer modes.
664 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
666 ;; General operand predicate for integer modes.
667 (define_mode_attr general_operand
668         [(QI "general_operand")
669          (HI "general_operand")
670          (SI "general_operand")
671          (DI "x86_64_general_operand")])
673 ;; SSE and x87 SFmode and DFmode floating point modes
674 (define_mode_iterator MODEF [SF DF])
676 ;; All x87 floating point modes
677 (define_mode_iterator X87MODEF [SF DF XF])
679 ;; All integer modes handled by x87 fisttp operator.
680 (define_mode_iterator X87MODEI [HI SI DI])
682 ;; All integer modes handled by integer x87 operators.
683 (define_mode_iterator X87MODEI12 [HI SI])
685 ;; All integer modes handled by SSE cvtts?2si* operators.
686 (define_mode_iterator SSEMODEI24 [SI DI])
688 ;; SSE asm suffix for floating point modes
689 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
691 ;; SSE vector mode corresponding to a scalar mode
692 (define_mode_attr ssevecmode
693   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
695 ;; Instruction suffix for REX 64bit operators.
696 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
698 ;; This mode iterator allows :P to be used for patterns that operate on
699 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
700 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
703 ;; Scheduling descriptions
705 (include "pentium.md")
706 (include "ppro.md")
707 (include "k6.md")
708 (include "athlon.md")
709 (include "geode.md")
712 ;; Operand and operator predicates and constraints
714 (include "predicates.md")
715 (include "constraints.md")
718 ;; Compare instructions.
720 ;; All compare insns have expanders that save the operands away without
721 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
722 ;; after the cmp) will actually emit the cmpM.
724 (define_expand "cmpti"
725   [(set (reg:CC FLAGS_REG)
726         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
727                     (match_operand:TI 1 "x86_64_general_operand" "")))]
728   "TARGET_64BIT"
730   if (MEM_P (operands[0]) && MEM_P (operands[1]))
731     operands[0] = force_reg (TImode, operands[0]);
732   ix86_compare_op0 = operands[0];
733   ix86_compare_op1 = operands[1];
734   DONE;
737 (define_expand "cmpdi"
738   [(set (reg:CC FLAGS_REG)
739         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
740                     (match_operand:DI 1 "x86_64_general_operand" "")))]
741   ""
743   if (MEM_P (operands[0]) && MEM_P (operands[1]))
744     operands[0] = force_reg (DImode, operands[0]);
745   ix86_compare_op0 = operands[0];
746   ix86_compare_op1 = operands[1];
747   DONE;
750 (define_expand "cmpsi"
751   [(set (reg:CC FLAGS_REG)
752         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
753                     (match_operand:SI 1 "general_operand" "")))]
754   ""
756   if (MEM_P (operands[0]) && MEM_P (operands[1]))
757     operands[0] = force_reg (SImode, operands[0]);
758   ix86_compare_op0 = operands[0];
759   ix86_compare_op1 = operands[1];
760   DONE;
763 (define_expand "cmphi"
764   [(set (reg:CC FLAGS_REG)
765         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
766                     (match_operand:HI 1 "general_operand" "")))]
767   ""
769   if (MEM_P (operands[0]) && MEM_P (operands[1]))
770     operands[0] = force_reg (HImode, operands[0]);
771   ix86_compare_op0 = operands[0];
772   ix86_compare_op1 = operands[1];
773   DONE;
776 (define_expand "cmpqi"
777   [(set (reg:CC FLAGS_REG)
778         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
779                     (match_operand:QI 1 "general_operand" "")))]
780   "TARGET_QIMODE_MATH"
782   if (MEM_P (operands[0]) && MEM_P (operands[1]))
783     operands[0] = force_reg (QImode, operands[0]);
784   ix86_compare_op0 = operands[0];
785   ix86_compare_op1 = operands[1];
786   DONE;
789 (define_insn "cmpdi_ccno_1_rex64"
790   [(set (reg FLAGS_REG)
791         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
792                  (match_operand:DI 1 "const0_operand" "")))]
793   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
794   "@
795    test{q}\t%0, %0
796    cmp{q}\t{%1, %0|%0, %1}"
797   [(set_attr "type" "test,icmp")
798    (set_attr "length_immediate" "0,1")
799    (set_attr "mode" "DI")])
801 (define_insn "*cmpdi_minus_1_rex64"
802   [(set (reg FLAGS_REG)
803         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
804                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
805                  (const_int 0)))]
806   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
807   "cmp{q}\t{%1, %0|%0, %1}"
808   [(set_attr "type" "icmp")
809    (set_attr "mode" "DI")])
811 (define_expand "cmpdi_1_rex64"
812   [(set (reg:CC FLAGS_REG)
813         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
814                     (match_operand:DI 1 "general_operand" "")))]
815   "TARGET_64BIT"
816   "")
818 (define_insn "cmpdi_1_insn_rex64"
819   [(set (reg FLAGS_REG)
820         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
821                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
822   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
823   "cmp{q}\t{%1, %0|%0, %1}"
824   [(set_attr "type" "icmp")
825    (set_attr "mode" "DI")])
828 (define_insn "*cmpsi_ccno_1"
829   [(set (reg FLAGS_REG)
830         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
831                  (match_operand:SI 1 "const0_operand" "")))]
832   "ix86_match_ccmode (insn, CCNOmode)"
833   "@
834    test{l}\t%0, %0
835    cmp{l}\t{%1, %0|%0, %1}"
836   [(set_attr "type" "test,icmp")
837    (set_attr "length_immediate" "0,1")
838    (set_attr "mode" "SI")])
840 (define_insn "*cmpsi_minus_1"
841   [(set (reg FLAGS_REG)
842         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
843                            (match_operand:SI 1 "general_operand" "ri,mr"))
844                  (const_int 0)))]
845   "ix86_match_ccmode (insn, CCGOCmode)"
846   "cmp{l}\t{%1, %0|%0, %1}"
847   [(set_attr "type" "icmp")
848    (set_attr "mode" "SI")])
850 (define_expand "cmpsi_1"
851   [(set (reg:CC FLAGS_REG)
852         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
853                     (match_operand:SI 1 "general_operand" "")))]
854   ""
855   "")
857 (define_insn "*cmpsi_1_insn"
858   [(set (reg FLAGS_REG)
859         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
860                  (match_operand:SI 1 "general_operand" "ri,mr")))]
861   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
862     && ix86_match_ccmode (insn, CCmode)"
863   "cmp{l}\t{%1, %0|%0, %1}"
864   [(set_attr "type" "icmp")
865    (set_attr "mode" "SI")])
867 (define_insn "*cmphi_ccno_1"
868   [(set (reg FLAGS_REG)
869         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
870                  (match_operand:HI 1 "const0_operand" "")))]
871   "ix86_match_ccmode (insn, CCNOmode)"
872   "@
873    test{w}\t%0, %0
874    cmp{w}\t{%1, %0|%0, %1}"
875   [(set_attr "type" "test,icmp")
876    (set_attr "length_immediate" "0,1")
877    (set_attr "mode" "HI")])
879 (define_insn "*cmphi_minus_1"
880   [(set (reg FLAGS_REG)
881         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
882                            (match_operand:HI 1 "general_operand" "rn,mr"))
883                  (const_int 0)))]
884   "ix86_match_ccmode (insn, CCGOCmode)"
885   "cmp{w}\t{%1, %0|%0, %1}"
886   [(set_attr "type" "icmp")
887    (set_attr "mode" "HI")])
889 (define_insn "*cmphi_1"
890   [(set (reg FLAGS_REG)
891         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
892                  (match_operand:HI 1 "general_operand" "rn,mr")))]
893   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
894    && ix86_match_ccmode (insn, CCmode)"
895   "cmp{w}\t{%1, %0|%0, %1}"
896   [(set_attr "type" "icmp")
897    (set_attr "mode" "HI")])
899 (define_insn "*cmpqi_ccno_1"
900   [(set (reg FLAGS_REG)
901         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
902                  (match_operand:QI 1 "const0_operand" "")))]
903   "ix86_match_ccmode (insn, CCNOmode)"
904   "@
905    test{b}\t%0, %0
906    cmp{b}\t{$0, %0|%0, 0}"
907   [(set_attr "type" "test,icmp")
908    (set_attr "length_immediate" "0,1")
909    (set_attr "mode" "QI")])
911 (define_insn "*cmpqi_1"
912   [(set (reg FLAGS_REG)
913         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
914                  (match_operand:QI 1 "general_operand" "qn,mq")))]
915   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
916     && ix86_match_ccmode (insn, CCmode)"
917   "cmp{b}\t{%1, %0|%0, %1}"
918   [(set_attr "type" "icmp")
919    (set_attr "mode" "QI")])
921 (define_insn "*cmpqi_minus_1"
922   [(set (reg FLAGS_REG)
923         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
924                            (match_operand:QI 1 "general_operand" "qn,mq"))
925                  (const_int 0)))]
926   "ix86_match_ccmode (insn, CCGOCmode)"
927   "cmp{b}\t{%1, %0|%0, %1}"
928   [(set_attr "type" "icmp")
929    (set_attr "mode" "QI")])
931 (define_insn "*cmpqi_ext_1"
932   [(set (reg FLAGS_REG)
933         (compare
934           (match_operand:QI 0 "general_operand" "Qm")
935           (subreg:QI
936             (zero_extract:SI
937               (match_operand 1 "ext_register_operand" "Q")
938               (const_int 8)
939               (const_int 8)) 0)))]
940   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
941   "cmp{b}\t{%h1, %0|%0, %h1}"
942   [(set_attr "type" "icmp")
943    (set_attr "mode" "QI")])
945 (define_insn "*cmpqi_ext_1_rex64"
946   [(set (reg FLAGS_REG)
947         (compare
948           (match_operand:QI 0 "register_operand" "Q")
949           (subreg:QI
950             (zero_extract:SI
951               (match_operand 1 "ext_register_operand" "Q")
952               (const_int 8)
953               (const_int 8)) 0)))]
954   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
955   "cmp{b}\t{%h1, %0|%0, %h1}"
956   [(set_attr "type" "icmp")
957    (set_attr "mode" "QI")])
959 (define_insn "*cmpqi_ext_2"
960   [(set (reg FLAGS_REG)
961         (compare
962           (subreg:QI
963             (zero_extract:SI
964               (match_operand 0 "ext_register_operand" "Q")
965               (const_int 8)
966               (const_int 8)) 0)
967           (match_operand:QI 1 "const0_operand" "")))]
968   "ix86_match_ccmode (insn, CCNOmode)"
969   "test{b}\t%h0, %h0"
970   [(set_attr "type" "test")
971    (set_attr "length_immediate" "0")
972    (set_attr "mode" "QI")])
974 (define_expand "cmpqi_ext_3"
975   [(set (reg:CC FLAGS_REG)
976         (compare:CC
977           (subreg:QI
978             (zero_extract:SI
979               (match_operand 0 "ext_register_operand" "")
980               (const_int 8)
981               (const_int 8)) 0)
982           (match_operand:QI 1 "general_operand" "")))]
983   ""
984   "")
986 (define_insn "cmpqi_ext_3_insn"
987   [(set (reg FLAGS_REG)
988         (compare
989           (subreg:QI
990             (zero_extract:SI
991               (match_operand 0 "ext_register_operand" "Q")
992               (const_int 8)
993               (const_int 8)) 0)
994           (match_operand:QI 1 "general_operand" "Qmn")))]
995   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
996   "cmp{b}\t{%1, %h0|%h0, %1}"
997   [(set_attr "type" "icmp")
998    (set_attr "mode" "QI")])
1000 (define_insn "cmpqi_ext_3_insn_rex64"
1001   [(set (reg FLAGS_REG)
1002         (compare
1003           (subreg:QI
1004             (zero_extract:SI
1005               (match_operand 0 "ext_register_operand" "Q")
1006               (const_int 8)
1007               (const_int 8)) 0)
1008           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1009   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1010   "cmp{b}\t{%1, %h0|%h0, %1}"
1011   [(set_attr "type" "icmp")
1012    (set_attr "mode" "QI")])
1014 (define_insn "*cmpqi_ext_4"
1015   [(set (reg FLAGS_REG)
1016         (compare
1017           (subreg:QI
1018             (zero_extract:SI
1019               (match_operand 0 "ext_register_operand" "Q")
1020               (const_int 8)
1021               (const_int 8)) 0)
1022           (subreg:QI
1023             (zero_extract:SI
1024               (match_operand 1 "ext_register_operand" "Q")
1025               (const_int 8)
1026               (const_int 8)) 0)))]
1027   "ix86_match_ccmode (insn, CCmode)"
1028   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1029   [(set_attr "type" "icmp")
1030    (set_attr "mode" "QI")])
1032 ;; These implement float point compares.
1033 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1034 ;; which would allow mix and match FP modes on the compares.  Which is what
1035 ;; the old patterns did, but with many more of them.
1037 (define_expand "cmpxf"
1038   [(set (reg:CC FLAGS_REG)
1039         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1040                     (match_operand:XF 1 "nonmemory_operand" "")))]
1041   "TARGET_80387"
1043   ix86_compare_op0 = operands[0];
1044   ix86_compare_op1 = operands[1];
1045   DONE;
1048 (define_expand "cmp<mode>"
1049   [(set (reg:CC FLAGS_REG)
1050         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1051                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1052   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1054   ix86_compare_op0 = operands[0];
1055   ix86_compare_op1 = operands[1];
1056   DONE;
1059 ;; FP compares, step 1:
1060 ;; Set the FP condition codes.
1062 ;; CCFPmode     compare with exceptions
1063 ;; CCFPUmode    compare with no exceptions
1065 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1066 ;; used to manage the reg stack popping would not be preserved.
1068 (define_insn "*cmpfp_0"
1069   [(set (match_operand:HI 0 "register_operand" "=a")
1070         (unspec:HI
1071           [(compare:CCFP
1072              (match_operand 1 "register_operand" "f")
1073              (match_operand 2 "const0_operand" ""))]
1074         UNSPEC_FNSTSW))]
1075   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1076    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1077   "* return output_fp_compare (insn, operands, 0, 0);"
1078   [(set_attr "type" "multi")
1079    (set_attr "unit" "i387")
1080    (set (attr "mode")
1081      (cond [(match_operand:SF 1 "" "")
1082               (const_string "SF")
1083             (match_operand:DF 1 "" "")
1084               (const_string "DF")
1085            ]
1086            (const_string "XF")))])
1088 (define_insn_and_split "*cmpfp_0_cc"
1089   [(set (reg:CCFP FLAGS_REG)
1090         (compare:CCFP
1091           (match_operand 1 "register_operand" "f")
1092           (match_operand 2 "const0_operand" "")))
1093    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1094   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1095    && TARGET_SAHF && !TARGET_CMOVE
1096    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1097   "#"
1098   "&& reload_completed"
1099   [(set (match_dup 0)
1100         (unspec:HI
1101           [(compare:CCFP (match_dup 1)(match_dup 2))]
1102         UNSPEC_FNSTSW))
1103    (set (reg:CC FLAGS_REG)
1104         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1105   ""
1106   [(set_attr "type" "multi")
1107    (set_attr "unit" "i387")
1108    (set (attr "mode")
1109      (cond [(match_operand:SF 1 "" "")
1110               (const_string "SF")
1111             (match_operand:DF 1 "" "")
1112               (const_string "DF")
1113            ]
1114            (const_string "XF")))])
1116 (define_insn "*cmpfp_xf"
1117   [(set (match_operand:HI 0 "register_operand" "=a")
1118         (unspec:HI
1119           [(compare:CCFP
1120              (match_operand:XF 1 "register_operand" "f")
1121              (match_operand:XF 2 "register_operand" "f"))]
1122           UNSPEC_FNSTSW))]
1123   "TARGET_80387"
1124   "* return output_fp_compare (insn, operands, 0, 0);"
1125   [(set_attr "type" "multi")
1126    (set_attr "unit" "i387")
1127    (set_attr "mode" "XF")])
1129 (define_insn_and_split "*cmpfp_xf_cc"
1130   [(set (reg:CCFP FLAGS_REG)
1131         (compare:CCFP
1132           (match_operand:XF 1 "register_operand" "f")
1133           (match_operand:XF 2 "register_operand" "f")))
1134    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1135   "TARGET_80387
1136    && TARGET_SAHF && !TARGET_CMOVE"
1137   "#"
1138   "&& reload_completed"
1139   [(set (match_dup 0)
1140         (unspec:HI
1141           [(compare:CCFP (match_dup 1)(match_dup 2))]
1142         UNSPEC_FNSTSW))
1143    (set (reg:CC FLAGS_REG)
1144         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1145   ""
1146   [(set_attr "type" "multi")
1147    (set_attr "unit" "i387")
1148    (set_attr "mode" "XF")])
1150 (define_insn "*cmpfp_<mode>"
1151   [(set (match_operand:HI 0 "register_operand" "=a")
1152         (unspec:HI
1153           [(compare:CCFP
1154              (match_operand:MODEF 1 "register_operand" "f")
1155              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1156           UNSPEC_FNSTSW))]
1157   "TARGET_80387"
1158   "* return output_fp_compare (insn, operands, 0, 0);"
1159   [(set_attr "type" "multi")
1160    (set_attr "unit" "i387")
1161    (set_attr "mode" "<MODE>")])
1163 (define_insn_and_split "*cmpfp_<mode>_cc"
1164   [(set (reg:CCFP FLAGS_REG)
1165         (compare:CCFP
1166           (match_operand:MODEF 1 "register_operand" "f")
1167           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1168    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1169   "TARGET_80387
1170    && TARGET_SAHF && !TARGET_CMOVE"
1171   "#"
1172   "&& reload_completed"
1173   [(set (match_dup 0)
1174         (unspec:HI
1175           [(compare:CCFP (match_dup 1)(match_dup 2))]
1176         UNSPEC_FNSTSW))
1177    (set (reg:CC FLAGS_REG)
1178         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1179   ""
1180   [(set_attr "type" "multi")
1181    (set_attr "unit" "i387")
1182    (set_attr "mode" "<MODE>")])
1184 (define_insn "*cmpfp_u"
1185   [(set (match_operand:HI 0 "register_operand" "=a")
1186         (unspec:HI
1187           [(compare:CCFPU
1188              (match_operand 1 "register_operand" "f")
1189              (match_operand 2 "register_operand" "f"))]
1190           UNSPEC_FNSTSW))]
1191   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1192    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1193   "* return output_fp_compare (insn, operands, 0, 1);"
1194   [(set_attr "type" "multi")
1195    (set_attr "unit" "i387")
1196    (set (attr "mode")
1197      (cond [(match_operand:SF 1 "" "")
1198               (const_string "SF")
1199             (match_operand:DF 1 "" "")
1200               (const_string "DF")
1201            ]
1202            (const_string "XF")))])
1204 (define_insn_and_split "*cmpfp_u_cc"
1205   [(set (reg:CCFPU FLAGS_REG)
1206         (compare:CCFPU
1207           (match_operand 1 "register_operand" "f")
1208           (match_operand 2 "register_operand" "f")))
1209    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1210   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1211    && TARGET_SAHF && !TARGET_CMOVE
1212    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1213   "#"
1214   "&& reload_completed"
1215   [(set (match_dup 0)
1216         (unspec:HI
1217           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1218         UNSPEC_FNSTSW))
1219    (set (reg:CC FLAGS_REG)
1220         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1221   ""
1222   [(set_attr "type" "multi")
1223    (set_attr "unit" "i387")
1224    (set (attr "mode")
1225      (cond [(match_operand:SF 1 "" "")
1226               (const_string "SF")
1227             (match_operand:DF 1 "" "")
1228               (const_string "DF")
1229            ]
1230            (const_string "XF")))])
1232 (define_insn "*cmpfp_<mode>"
1233   [(set (match_operand:HI 0 "register_operand" "=a")
1234         (unspec:HI
1235           [(compare:CCFP
1236              (match_operand 1 "register_operand" "f")
1237              (match_operator 3 "float_operator"
1238                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1239           UNSPEC_FNSTSW))]
1240   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1241    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1242    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1243   "* return output_fp_compare (insn, operands, 0, 0);"
1244   [(set_attr "type" "multi")
1245    (set_attr "unit" "i387")
1246    (set_attr "fp_int_src" "true")
1247    (set_attr "mode" "<MODE>")])
1249 (define_insn_and_split "*cmpfp_<mode>_cc"
1250   [(set (reg:CCFP FLAGS_REG)
1251         (compare:CCFP
1252           (match_operand 1 "register_operand" "f")
1253           (match_operator 3 "float_operator"
1254             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1255    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1256   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1257    && TARGET_SAHF && !TARGET_CMOVE
1258    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1259    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1260   "#"
1261   "&& reload_completed"
1262   [(set (match_dup 0)
1263         (unspec:HI
1264           [(compare:CCFP
1265              (match_dup 1)
1266              (match_op_dup 3 [(match_dup 2)]))]
1267         UNSPEC_FNSTSW))
1268    (set (reg:CC FLAGS_REG)
1269         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1270   ""
1271   [(set_attr "type" "multi")
1272    (set_attr "unit" "i387")
1273    (set_attr "fp_int_src" "true")
1274    (set_attr "mode" "<MODE>")])
1276 ;; FP compares, step 2
1277 ;; Move the fpsw to ax.
1279 (define_insn "x86_fnstsw_1"
1280   [(set (match_operand:HI 0 "register_operand" "=a")
1281         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1282   "TARGET_80387"
1283   "fnstsw\t%0"
1284   [(set_attr "length" "2")
1285    (set_attr "mode" "SI")
1286    (set_attr "unit" "i387")])
1288 ;; FP compares, step 3
1289 ;; Get ax into flags, general case.
1291 (define_insn "x86_sahf_1"
1292   [(set (reg:CC FLAGS_REG)
1293         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1294                    UNSPEC_SAHF))]
1295   "TARGET_SAHF"
1297 #ifdef HAVE_AS_IX86_SAHF
1298   return "sahf";
1299 #else
1300   return ".byte\t0x9e";
1301 #endif
1303   [(set_attr "length" "1")
1304    (set_attr "athlon_decode" "vector")
1305    (set_attr "amdfam10_decode" "direct")
1306    (set_attr "mode" "SI")])
1308 ;; Pentium Pro can do steps 1 through 3 in one go.
1309 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1310 (define_insn "*cmpfp_i_mixed"
1311   [(set (reg:CCFP FLAGS_REG)
1312         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1313                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1314   "TARGET_MIX_SSE_I387
1315    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1316    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1317   "* return output_fp_compare (insn, operands, 1, 0);"
1318   [(set_attr "type" "fcmp,ssecomi")
1319    (set_attr "prefix" "orig,maybe_vex")
1320    (set (attr "mode")
1321      (if_then_else (match_operand:SF 1 "" "")
1322         (const_string "SF")
1323         (const_string "DF")))
1324    (set_attr "athlon_decode" "vector")
1325    (set_attr "amdfam10_decode" "direct")])
1327 (define_insn "*cmpfp_i_sse"
1328   [(set (reg:CCFP FLAGS_REG)
1329         (compare:CCFP (match_operand 0 "register_operand" "x")
1330                       (match_operand 1 "nonimmediate_operand" "xm")))]
1331   "TARGET_SSE_MATH
1332    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1333    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1334   "* return output_fp_compare (insn, operands, 1, 0);"
1335   [(set_attr "type" "ssecomi")
1336    (set_attr "prefix" "maybe_vex")
1337    (set (attr "mode")
1338      (if_then_else (match_operand:SF 1 "" "")
1339         (const_string "SF")
1340         (const_string "DF")))
1341    (set_attr "athlon_decode" "vector")
1342    (set_attr "amdfam10_decode" "direct")])
1344 (define_insn "*cmpfp_i_i387"
1345   [(set (reg:CCFP FLAGS_REG)
1346         (compare:CCFP (match_operand 0 "register_operand" "f")
1347                       (match_operand 1 "register_operand" "f")))]
1348   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1349    && TARGET_CMOVE
1350    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1351    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1352   "* return output_fp_compare (insn, operands, 1, 0);"
1353   [(set_attr "type" "fcmp")
1354    (set (attr "mode")
1355      (cond [(match_operand:SF 1 "" "")
1356               (const_string "SF")
1357             (match_operand:DF 1 "" "")
1358               (const_string "DF")
1359            ]
1360            (const_string "XF")))
1361    (set_attr "athlon_decode" "vector")
1362    (set_attr "amdfam10_decode" "direct")])
1364 (define_insn "*cmpfp_iu_mixed"
1365   [(set (reg:CCFPU FLAGS_REG)
1366         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1367                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1368   "TARGET_MIX_SSE_I387
1369    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1370    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1371   "* return output_fp_compare (insn, operands, 1, 1);"
1372   [(set_attr "type" "fcmp,ssecomi")
1373    (set_attr "prefix" "orig,maybe_vex")
1374    (set (attr "mode")
1375      (if_then_else (match_operand:SF 1 "" "")
1376         (const_string "SF")
1377         (const_string "DF")))
1378    (set_attr "athlon_decode" "vector")
1379    (set_attr "amdfam10_decode" "direct")])
1381 (define_insn "*cmpfp_iu_sse"
1382   [(set (reg:CCFPU FLAGS_REG)
1383         (compare:CCFPU (match_operand 0 "register_operand" "x")
1384                        (match_operand 1 "nonimmediate_operand" "xm")))]
1385   "TARGET_SSE_MATH
1386    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1387    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1388   "* return output_fp_compare (insn, operands, 1, 1);"
1389   [(set_attr "type" "ssecomi")
1390    (set_attr "prefix" "maybe_vex")
1391    (set (attr "mode")
1392      (if_then_else (match_operand:SF 1 "" "")
1393         (const_string "SF")
1394         (const_string "DF")))
1395    (set_attr "athlon_decode" "vector")
1396    (set_attr "amdfam10_decode" "direct")])
1398 (define_insn "*cmpfp_iu_387"
1399   [(set (reg:CCFPU FLAGS_REG)
1400         (compare:CCFPU (match_operand 0 "register_operand" "f")
1401                        (match_operand 1 "register_operand" "f")))]
1402   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1403    && TARGET_CMOVE
1404    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1405    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1406   "* return output_fp_compare (insn, operands, 1, 1);"
1407   [(set_attr "type" "fcmp")
1408    (set (attr "mode")
1409      (cond [(match_operand:SF 1 "" "")
1410               (const_string "SF")
1411             (match_operand:DF 1 "" "")
1412               (const_string "DF")
1413            ]
1414            (const_string "XF")))
1415    (set_attr "athlon_decode" "vector")
1416    (set_attr "amdfam10_decode" "direct")])
1418 ;; Move instructions.
1420 ;; General case of fullword move.
1422 (define_expand "movsi"
1423   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1424         (match_operand:SI 1 "general_operand" ""))]
1425   ""
1426   "ix86_expand_move (SImode, operands); DONE;")
1428 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1429 ;; general_operand.
1431 ;; %%% We don't use a post-inc memory reference because x86 is not a
1432 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1433 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1434 ;; targets without our curiosities, and it is just as easy to represent
1435 ;; this differently.
1437 (define_insn "*pushsi2"
1438   [(set (match_operand:SI 0 "push_operand" "=<")
1439         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1440   "!TARGET_64BIT"
1441   "push{l}\t%1"
1442   [(set_attr "type" "push")
1443    (set_attr "mode" "SI")])
1445 ;; For 64BIT abi we always round up to 8 bytes.
1446 (define_insn "*pushsi2_rex64"
1447   [(set (match_operand:SI 0 "push_operand" "=X")
1448         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1449   "TARGET_64BIT"
1450   "push{q}\t%q1"
1451   [(set_attr "type" "push")
1452    (set_attr "mode" "SI")])
1454 (define_insn "*pushsi2_prologue"
1455   [(set (match_operand:SI 0 "push_operand" "=<")
1456         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1457    (clobber (mem:BLK (scratch)))]
1458   "!TARGET_64BIT"
1459   "push{l}\t%1"
1460   [(set_attr "type" "push")
1461    (set_attr "mode" "SI")])
1463 (define_insn "*popsi1_epilogue"
1464   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1465         (mem:SI (reg:SI SP_REG)))
1466    (set (reg:SI SP_REG)
1467         (plus:SI (reg:SI SP_REG) (const_int 4)))
1468    (clobber (mem:BLK (scratch)))]
1469   "!TARGET_64BIT"
1470   "pop{l}\t%0"
1471   [(set_attr "type" "pop")
1472    (set_attr "mode" "SI")])
1474 (define_insn "popsi1"
1475   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1476         (mem:SI (reg:SI SP_REG)))
1477    (set (reg:SI SP_REG)
1478         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1479   "!TARGET_64BIT"
1480   "pop{l}\t%0"
1481   [(set_attr "type" "pop")
1482    (set_attr "mode" "SI")])
1484 (define_insn "*movsi_xor"
1485   [(set (match_operand:SI 0 "register_operand" "=r")
1486         (match_operand:SI 1 "const0_operand" ""))
1487    (clobber (reg:CC FLAGS_REG))]
1488   "reload_completed"
1489   "xor{l}\t%0, %0"
1490   [(set_attr "type" "alu1")
1491    (set_attr "mode" "SI")
1492    (set_attr "length_immediate" "0")])
1494 (define_insn "*movsi_or"
1495   [(set (match_operand:SI 0 "register_operand" "=r")
1496         (match_operand:SI 1 "immediate_operand" "i"))
1497    (clobber (reg:CC FLAGS_REG))]
1498   "reload_completed
1499    && operands[1] == constm1_rtx"
1501   operands[1] = constm1_rtx;
1502   return "or{l}\t{%1, %0|%0, %1}";
1504   [(set_attr "type" "alu1")
1505    (set_attr "mode" "SI")
1506    (set_attr "length_immediate" "1")])
1508 (define_insn "*movsi_1"
1509   [(set (match_operand:SI 0 "nonimmediate_operand"
1510                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1511         (match_operand:SI 1 "general_operand"
1512                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1513   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1515   switch (get_attr_type (insn))
1516     {
1517     case TYPE_SSELOG1:
1518       if (get_attr_mode (insn) == MODE_TI)
1519         return "%vpxor\t%0, %d0";
1520       return "%vxorps\t%0, %d0";
1522     case TYPE_SSEMOV:
1523       switch (get_attr_mode (insn))
1524         {
1525         case MODE_TI:
1526           return "%vmovdqa\t{%1, %0|%0, %1}";
1527         case MODE_V4SF:
1528           return "%vmovaps\t{%1, %0|%0, %1}";
1529         case MODE_SI:
1530           return "%vmovd\t{%1, %0|%0, %1}";
1531         case MODE_SF:
1532           return "%vmovss\t{%1, %0|%0, %1}";
1533         default:
1534           gcc_unreachable ();
1535         }
1537     case TYPE_MMXADD:
1538       return "pxor\t%0, %0";
1540     case TYPE_MMXMOV:
1541       if (get_attr_mode (insn) == MODE_DI)
1542         return "movq\t{%1, %0|%0, %1}";
1543       return "movd\t{%1, %0|%0, %1}";
1545     case TYPE_LEA:
1546       return "lea{l}\t{%1, %0|%0, %1}";
1548     default:
1549       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1550       return "mov{l}\t{%1, %0|%0, %1}";
1551     }
1553   [(set (attr "type")
1554      (cond [(eq_attr "alternative" "2")
1555               (const_string "mmxadd")
1556             (eq_attr "alternative" "3,4,5")
1557               (const_string "mmxmov")
1558             (eq_attr "alternative" "6")
1559               (const_string "sselog1")
1560             (eq_attr "alternative" "7,8,9,10,11")
1561               (const_string "ssemov")
1562             (match_operand:DI 1 "pic_32bit_operand" "")
1563               (const_string "lea")
1564            ]
1565            (const_string "imov")))
1566    (set (attr "prefix")
1567      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1568        (const_string "orig")
1569        (const_string "maybe_vex")))
1570    (set (attr "mode")
1571      (cond [(eq_attr "alternative" "2,3")
1572               (const_string "DI")
1573             (eq_attr "alternative" "6,7")
1574               (if_then_else
1575                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1576                 (const_string "V4SF")
1577                 (const_string "TI"))
1578             (and (eq_attr "alternative" "8,9,10,11")
1579                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1580               (const_string "SF")
1581            ]
1582            (const_string "SI")))])
1584 ;; Stores and loads of ax to arbitrary constant address.
1585 ;; We fake an second form of instruction to force reload to load address
1586 ;; into register when rax is not available
1587 (define_insn "*movabssi_1_rex64"
1588   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1589         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1590   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1591   "@
1592    movabs{l}\t{%1, %P0|%P0, %1}
1593    mov{l}\t{%1, %a0|%a0, %1}"
1594   [(set_attr "type" "imov")
1595    (set_attr "modrm" "0,*")
1596    (set_attr "length_address" "8,0")
1597    (set_attr "length_immediate" "0,*")
1598    (set_attr "memory" "store")
1599    (set_attr "mode" "SI")])
1601 (define_insn "*movabssi_2_rex64"
1602   [(set (match_operand:SI 0 "register_operand" "=a,r")
1603         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1604   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1605   "@
1606    movabs{l}\t{%P1, %0|%0, %P1}
1607    mov{l}\t{%a1, %0|%0, %a1}"
1608   [(set_attr "type" "imov")
1609    (set_attr "modrm" "0,*")
1610    (set_attr "length_address" "8,0")
1611    (set_attr "length_immediate" "0")
1612    (set_attr "memory" "load")
1613    (set_attr "mode" "SI")])
1615 (define_insn "*swapsi"
1616   [(set (match_operand:SI 0 "register_operand" "+r")
1617         (match_operand:SI 1 "register_operand" "+r"))
1618    (set (match_dup 1)
1619         (match_dup 0))]
1620   ""
1621   "xchg{l}\t%1, %0"
1622   [(set_attr "type" "imov")
1623    (set_attr "mode" "SI")
1624    (set_attr "pent_pair" "np")
1625    (set_attr "athlon_decode" "vector")
1626    (set_attr "amdfam10_decode" "double")])
1628 (define_expand "movhi"
1629   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1630         (match_operand:HI 1 "general_operand" ""))]
1631   ""
1632   "ix86_expand_move (HImode, operands); DONE;")
1634 (define_insn "*pushhi2"
1635   [(set (match_operand:HI 0 "push_operand" "=X")
1636         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1637   "!TARGET_64BIT"
1638   "push{l}\t%k1"
1639   [(set_attr "type" "push")
1640    (set_attr "mode" "SI")])
1642 ;; For 64BIT abi we always round up to 8 bytes.
1643 (define_insn "*pushhi2_rex64"
1644   [(set (match_operand:HI 0 "push_operand" "=X")
1645         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1646   "TARGET_64BIT"
1647   "push{q}\t%q1"
1648   [(set_attr "type" "push")
1649    (set_attr "mode" "DI")])
1651 (define_insn "*movhi_1"
1652   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1653         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1654   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1656   switch (get_attr_type (insn))
1657     {
1658     case TYPE_IMOVX:
1659       /* movzwl is faster than movw on p2 due to partial word stalls,
1660          though not as fast as an aligned movl.  */
1661       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1662     default:
1663       if (get_attr_mode (insn) == MODE_SI)
1664         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1665       else
1666         return "mov{w}\t{%1, %0|%0, %1}";
1667     }
1669   [(set (attr "type")
1670      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1671               (const_string "imov")
1672             (and (eq_attr "alternative" "0")
1673                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1674                           (const_int 0))
1675                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1676                           (const_int 0))))
1677               (const_string "imov")
1678             (and (eq_attr "alternative" "1,2")
1679                  (match_operand:HI 1 "aligned_operand" ""))
1680               (const_string "imov")
1681             (and (ne (symbol_ref "TARGET_MOVX")
1682                      (const_int 0))
1683                  (eq_attr "alternative" "0,2"))
1684               (const_string "imovx")
1685            ]
1686            (const_string "imov")))
1687     (set (attr "mode")
1688       (cond [(eq_attr "type" "imovx")
1689                (const_string "SI")
1690              (and (eq_attr "alternative" "1,2")
1691                   (match_operand:HI 1 "aligned_operand" ""))
1692                (const_string "SI")
1693              (and (eq_attr "alternative" "0")
1694                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1695                            (const_int 0))
1696                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1697                            (const_int 0))))
1698                (const_string "SI")
1699             ]
1700             (const_string "HI")))])
1702 ;; Stores and loads of ax to arbitrary constant address.
1703 ;; We fake an second form of instruction to force reload to load address
1704 ;; into register when rax is not available
1705 (define_insn "*movabshi_1_rex64"
1706   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1707         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1708   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1709   "@
1710    movabs{w}\t{%1, %P0|%P0, %1}
1711    mov{w}\t{%1, %a0|%a0, %1}"
1712   [(set_attr "type" "imov")
1713    (set_attr "modrm" "0,*")
1714    (set_attr "length_address" "8,0")
1715    (set_attr "length_immediate" "0,*")
1716    (set_attr "memory" "store")
1717    (set_attr "mode" "HI")])
1719 (define_insn "*movabshi_2_rex64"
1720   [(set (match_operand:HI 0 "register_operand" "=a,r")
1721         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1722   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1723   "@
1724    movabs{w}\t{%P1, %0|%0, %P1}
1725    mov{w}\t{%a1, %0|%0, %a1}"
1726   [(set_attr "type" "imov")
1727    (set_attr "modrm" "0,*")
1728    (set_attr "length_address" "8,0")
1729    (set_attr "length_immediate" "0")
1730    (set_attr "memory" "load")
1731    (set_attr "mode" "HI")])
1733 (define_insn "*swaphi_1"
1734   [(set (match_operand:HI 0 "register_operand" "+r")
1735         (match_operand:HI 1 "register_operand" "+r"))
1736    (set (match_dup 1)
1737         (match_dup 0))]
1738   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1739   "xchg{l}\t%k1, %k0"
1740   [(set_attr "type" "imov")
1741    (set_attr "mode" "SI")
1742    (set_attr "pent_pair" "np")
1743    (set_attr "athlon_decode" "vector")
1744    (set_attr "amdfam10_decode" "double")])
1746 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1747 (define_insn "*swaphi_2"
1748   [(set (match_operand:HI 0 "register_operand" "+r")
1749         (match_operand:HI 1 "register_operand" "+r"))
1750    (set (match_dup 1)
1751         (match_dup 0))]
1752   "TARGET_PARTIAL_REG_STALL"
1753   "xchg{w}\t%1, %0"
1754   [(set_attr "type" "imov")
1755    (set_attr "mode" "HI")
1756    (set_attr "pent_pair" "np")
1757    (set_attr "athlon_decode" "vector")])
1759 (define_expand "movstricthi"
1760   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1761         (match_operand:HI 1 "general_operand" ""))]
1762   ""
1764   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1765     FAIL;
1766   /* Don't generate memory->memory moves, go through a register */
1767   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1768     operands[1] = force_reg (HImode, operands[1]);
1771 (define_insn "*movstricthi_1"
1772   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1773         (match_operand:HI 1 "general_operand" "rn,m"))]
1774   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1775    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1776   "mov{w}\t{%1, %0|%0, %1}"
1777   [(set_attr "type" "imov")
1778    (set_attr "mode" "HI")])
1780 (define_insn "*movstricthi_xor"
1781   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1782         (match_operand:HI 1 "const0_operand" ""))
1783    (clobber (reg:CC FLAGS_REG))]
1784   "reload_completed"
1785   "xor{w}\t%0, %0"
1786   [(set_attr "type" "alu1")
1787    (set_attr "mode" "HI")
1788    (set_attr "length_immediate" "0")])
1790 (define_expand "movqi"
1791   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1792         (match_operand:QI 1 "general_operand" ""))]
1793   ""
1794   "ix86_expand_move (QImode, operands); DONE;")
1796 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1797 ;; "push a byte".  But actually we use pushl, which has the effect
1798 ;; of rounding the amount pushed up to a word.
1800 (define_insn "*pushqi2"
1801   [(set (match_operand:QI 0 "push_operand" "=X")
1802         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1803   "!TARGET_64BIT"
1804   "push{l}\t%k1"
1805   [(set_attr "type" "push")
1806    (set_attr "mode" "SI")])
1808 ;; For 64BIT abi we always round up to 8 bytes.
1809 (define_insn "*pushqi2_rex64"
1810   [(set (match_operand:QI 0 "push_operand" "=X")
1811         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1812   "TARGET_64BIT"
1813   "push{q}\t%q1"
1814   [(set_attr "type" "push")
1815    (set_attr "mode" "DI")])
1817 ;; Situation is quite tricky about when to choose full sized (SImode) move
1818 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1819 ;; partial register dependency machines (such as AMD Athlon), where QImode
1820 ;; moves issue extra dependency and for partial register stalls machines
1821 ;; that don't use QImode patterns (and QImode move cause stall on the next
1822 ;; instruction).
1824 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1825 ;; register stall machines with, where we use QImode instructions, since
1826 ;; partial register stall can be caused there.  Then we use movzx.
1827 (define_insn "*movqi_1"
1828   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1829         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1830   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1832   switch (get_attr_type (insn))
1833     {
1834     case TYPE_IMOVX:
1835       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1836       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1837     default:
1838       if (get_attr_mode (insn) == MODE_SI)
1839         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1840       else
1841         return "mov{b}\t{%1, %0|%0, %1}";
1842     }
1844   [(set (attr "type")
1845      (cond [(and (eq_attr "alternative" "5")
1846                  (not (match_operand:QI 1 "aligned_operand" "")))
1847               (const_string "imovx")
1848             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1849               (const_string "imov")
1850             (and (eq_attr "alternative" "3")
1851                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1852                           (const_int 0))
1853                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1854                           (const_int 0))))
1855               (const_string "imov")
1856             (eq_attr "alternative" "3,5")
1857               (const_string "imovx")
1858             (and (ne (symbol_ref "TARGET_MOVX")
1859                      (const_int 0))
1860                  (eq_attr "alternative" "2"))
1861               (const_string "imovx")
1862            ]
1863            (const_string "imov")))
1864    (set (attr "mode")
1865       (cond [(eq_attr "alternative" "3,4,5")
1866                (const_string "SI")
1867              (eq_attr "alternative" "6")
1868                (const_string "QI")
1869              (eq_attr "type" "imovx")
1870                (const_string "SI")
1871              (and (eq_attr "type" "imov")
1872                   (and (eq_attr "alternative" "0,1")
1873                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1874                                 (const_int 0))
1875                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1876                                      (const_int 0))
1877                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1878                                      (const_int 0))))))
1879                (const_string "SI")
1880              ;; Avoid partial register stalls when not using QImode arithmetic
1881              (and (eq_attr "type" "imov")
1882                   (and (eq_attr "alternative" "0,1")
1883                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1884                                 (const_int 0))
1885                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1886                                 (const_int 0)))))
1887                (const_string "SI")
1888            ]
1889            (const_string "QI")))])
1891 (define_insn "*swapqi_1"
1892   [(set (match_operand:QI 0 "register_operand" "+r")
1893         (match_operand:QI 1 "register_operand" "+r"))
1894    (set (match_dup 1)
1895         (match_dup 0))]
1896   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1897   "xchg{l}\t%k1, %k0"
1898   [(set_attr "type" "imov")
1899    (set_attr "mode" "SI")
1900    (set_attr "pent_pair" "np")
1901    (set_attr "athlon_decode" "vector")
1902    (set_attr "amdfam10_decode" "vector")])
1904 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1905 (define_insn "*swapqi_2"
1906   [(set (match_operand:QI 0 "register_operand" "+q")
1907         (match_operand:QI 1 "register_operand" "+q"))
1908    (set (match_dup 1)
1909         (match_dup 0))]
1910   "TARGET_PARTIAL_REG_STALL"
1911   "xchg{b}\t%1, %0"
1912   [(set_attr "type" "imov")
1913    (set_attr "mode" "QI")
1914    (set_attr "pent_pair" "np")
1915    (set_attr "athlon_decode" "vector")])
1917 (define_expand "movstrictqi"
1918   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1919         (match_operand:QI 1 "general_operand" ""))]
1920   ""
1922   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1923     FAIL;
1924   /* Don't generate memory->memory moves, go through a register.  */
1925   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1926     operands[1] = force_reg (QImode, operands[1]);
1929 (define_insn "*movstrictqi_1"
1930   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1931         (match_operand:QI 1 "general_operand" "*qn,m"))]
1932   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1933    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1934   "mov{b}\t{%1, %0|%0, %1}"
1935   [(set_attr "type" "imov")
1936    (set_attr "mode" "QI")])
1938 (define_insn "*movstrictqi_xor"
1939   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1940         (match_operand:QI 1 "const0_operand" ""))
1941    (clobber (reg:CC FLAGS_REG))]
1942   "reload_completed"
1943   "xor{b}\t%0, %0"
1944   [(set_attr "type" "alu1")
1945    (set_attr "mode" "QI")
1946    (set_attr "length_immediate" "0")])
1948 (define_insn "*movsi_extv_1"
1949   [(set (match_operand:SI 0 "register_operand" "=R")
1950         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1951                          (const_int 8)
1952                          (const_int 8)))]
1953   ""
1954   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1955   [(set_attr "type" "imovx")
1956    (set_attr "mode" "SI")])
1958 (define_insn "*movhi_extv_1"
1959   [(set (match_operand:HI 0 "register_operand" "=R")
1960         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1961                          (const_int 8)
1962                          (const_int 8)))]
1963   ""
1964   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1965   [(set_attr "type" "imovx")
1966    (set_attr "mode" "SI")])
1968 (define_insn "*movqi_extv_1"
1969   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1970         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1971                          (const_int 8)
1972                          (const_int 8)))]
1973   "!TARGET_64BIT"
1975   switch (get_attr_type (insn))
1976     {
1977     case TYPE_IMOVX:
1978       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1979     default:
1980       return "mov{b}\t{%h1, %0|%0, %h1}";
1981     }
1983   [(set (attr "type")
1984      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1985                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1986                              (ne (symbol_ref "TARGET_MOVX")
1987                                  (const_int 0))))
1988         (const_string "imovx")
1989         (const_string "imov")))
1990    (set (attr "mode")
1991      (if_then_else (eq_attr "type" "imovx")
1992         (const_string "SI")
1993         (const_string "QI")))])
1995 (define_insn "*movqi_extv_1_rex64"
1996   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1997         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1998                          (const_int 8)
1999                          (const_int 8)))]
2000   "TARGET_64BIT"
2002   switch (get_attr_type (insn))
2003     {
2004     case TYPE_IMOVX:
2005       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2006     default:
2007       return "mov{b}\t{%h1, %0|%0, %h1}";
2008     }
2010   [(set (attr "type")
2011      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2012                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2013                              (ne (symbol_ref "TARGET_MOVX")
2014                                  (const_int 0))))
2015         (const_string "imovx")
2016         (const_string "imov")))
2017    (set (attr "mode")
2018      (if_then_else (eq_attr "type" "imovx")
2019         (const_string "SI")
2020         (const_string "QI")))])
2022 ;; Stores and loads of ax to arbitrary constant address.
2023 ;; We fake an second form of instruction to force reload to load address
2024 ;; into register when rax is not available
2025 (define_insn "*movabsqi_1_rex64"
2026   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2027         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2028   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2029   "@
2030    movabs{b}\t{%1, %P0|%P0, %1}
2031    mov{b}\t{%1, %a0|%a0, %1}"
2032   [(set_attr "type" "imov")
2033    (set_attr "modrm" "0,*")
2034    (set_attr "length_address" "8,0")
2035    (set_attr "length_immediate" "0,*")
2036    (set_attr "memory" "store")
2037    (set_attr "mode" "QI")])
2039 (define_insn "*movabsqi_2_rex64"
2040   [(set (match_operand:QI 0 "register_operand" "=a,r")
2041         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2042   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2043   "@
2044    movabs{b}\t{%P1, %0|%0, %P1}
2045    mov{b}\t{%a1, %0|%0, %a1}"
2046   [(set_attr "type" "imov")
2047    (set_attr "modrm" "0,*")
2048    (set_attr "length_address" "8,0")
2049    (set_attr "length_immediate" "0")
2050    (set_attr "memory" "load")
2051    (set_attr "mode" "QI")])
2053 (define_insn "*movdi_extzv_1"
2054   [(set (match_operand:DI 0 "register_operand" "=R")
2055         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2056                          (const_int 8)
2057                          (const_int 8)))]
2058   "TARGET_64BIT"
2059   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2060   [(set_attr "type" "imovx")
2061    (set_attr "mode" "DI")])
2063 (define_insn "*movsi_extzv_1"
2064   [(set (match_operand:SI 0 "register_operand" "=R")
2065         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2066                          (const_int 8)
2067                          (const_int 8)))]
2068   ""
2069   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2070   [(set_attr "type" "imovx")
2071    (set_attr "mode" "SI")])
2073 (define_insn "*movqi_extzv_2"
2074   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2075         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2076                                     (const_int 8)
2077                                     (const_int 8)) 0))]
2078   "!TARGET_64BIT"
2080   switch (get_attr_type (insn))
2081     {
2082     case TYPE_IMOVX:
2083       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2084     default:
2085       return "mov{b}\t{%h1, %0|%0, %h1}";
2086     }
2088   [(set (attr "type")
2089      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2090                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2091                              (ne (symbol_ref "TARGET_MOVX")
2092                                  (const_int 0))))
2093         (const_string "imovx")
2094         (const_string "imov")))
2095    (set (attr "mode")
2096      (if_then_else (eq_attr "type" "imovx")
2097         (const_string "SI")
2098         (const_string "QI")))])
2100 (define_insn "*movqi_extzv_2_rex64"
2101   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2102         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2103                                     (const_int 8)
2104                                     (const_int 8)) 0))]
2105   "TARGET_64BIT"
2107   switch (get_attr_type (insn))
2108     {
2109     case TYPE_IMOVX:
2110       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2111     default:
2112       return "mov{b}\t{%h1, %0|%0, %h1}";
2113     }
2115   [(set (attr "type")
2116      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2117                         (ne (symbol_ref "TARGET_MOVX")
2118                             (const_int 0)))
2119         (const_string "imovx")
2120         (const_string "imov")))
2121    (set (attr "mode")
2122      (if_then_else (eq_attr "type" "imovx")
2123         (const_string "SI")
2124         (const_string "QI")))])
2126 (define_insn "movsi_insv_1"
2127   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2128                          (const_int 8)
2129                          (const_int 8))
2130         (match_operand:SI 1 "general_operand" "Qmn"))]
2131   "!TARGET_64BIT"
2132   "mov{b}\t{%b1, %h0|%h0, %b1}"
2133   [(set_attr "type" "imov")
2134    (set_attr "mode" "QI")])
2136 (define_insn "*movsi_insv_1_rex64"
2137   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2138                          (const_int 8)
2139                          (const_int 8))
2140         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2141   "TARGET_64BIT"
2142   "mov{b}\t{%b1, %h0|%h0, %b1}"
2143   [(set_attr "type" "imov")
2144    (set_attr "mode" "QI")])
2146 (define_insn "movdi_insv_1_rex64"
2147   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2148                          (const_int 8)
2149                          (const_int 8))
2150         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2151   "TARGET_64BIT"
2152   "mov{b}\t{%b1, %h0|%h0, %b1}"
2153   [(set_attr "type" "imov")
2154    (set_attr "mode" "QI")])
2156 (define_insn "*movqi_insv_2"
2157   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2158                          (const_int 8)
2159                          (const_int 8))
2160         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2161                      (const_int 8)))]
2162   ""
2163   "mov{b}\t{%h1, %h0|%h0, %h1}"
2164   [(set_attr "type" "imov")
2165    (set_attr "mode" "QI")])
2167 (define_expand "movdi"
2168   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2169         (match_operand:DI 1 "general_operand" ""))]
2170   ""
2171   "ix86_expand_move (DImode, operands); DONE;")
2173 (define_insn "*pushdi"
2174   [(set (match_operand:DI 0 "push_operand" "=<")
2175         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2176   "!TARGET_64BIT"
2177   "#")
2179 (define_insn "*pushdi2_rex64"
2180   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2181         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2182   "TARGET_64BIT"
2183   "@
2184    push{q}\t%1
2185    #"
2186   [(set_attr "type" "push,multi")
2187    (set_attr "mode" "DI")])
2189 ;; Convert impossible pushes of immediate to existing instructions.
2190 ;; First try to get scratch register and go through it.  In case this
2191 ;; fails, push sign extended lower part first and then overwrite
2192 ;; upper part by 32bit move.
2193 (define_peephole2
2194   [(match_scratch:DI 2 "r")
2195    (set (match_operand:DI 0 "push_operand" "")
2196         (match_operand:DI 1 "immediate_operand" ""))]
2197   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2198    && !x86_64_immediate_operand (operands[1], DImode)"
2199   [(set (match_dup 2) (match_dup 1))
2200    (set (match_dup 0) (match_dup 2))]
2201   "")
2203 ;; We need to define this as both peepholer and splitter for case
2204 ;; peephole2 pass is not run.
2205 ;; "&& 1" is needed to keep it from matching the previous pattern.
2206 (define_peephole2
2207   [(set (match_operand:DI 0 "push_operand" "")
2208         (match_operand:DI 1 "immediate_operand" ""))]
2209   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2210    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2211   [(set (match_dup 0) (match_dup 1))
2212    (set (match_dup 2) (match_dup 3))]
2213   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2214    operands[1] = gen_lowpart (DImode, operands[2]);
2215    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2216                                                     GEN_INT (4)));
2217   ")
2219 (define_split
2220   [(set (match_operand:DI 0 "push_operand" "")
2221         (match_operand:DI 1 "immediate_operand" ""))]
2222   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2223                     ? epilogue_completed : reload_completed)
2224    && !symbolic_operand (operands[1], DImode)
2225    && !x86_64_immediate_operand (operands[1], DImode)"
2226   [(set (match_dup 0) (match_dup 1))
2227    (set (match_dup 2) (match_dup 3))]
2228   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2229    operands[1] = gen_lowpart (DImode, operands[2]);
2230    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2231                                                     GEN_INT (4)));
2232   ")
2234 (define_insn "*pushdi2_prologue_rex64"
2235   [(set (match_operand:DI 0 "push_operand" "=<")
2236         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2237    (clobber (mem:BLK (scratch)))]
2238   "TARGET_64BIT"
2239   "push{q}\t%1"
2240   [(set_attr "type" "push")
2241    (set_attr "mode" "DI")])
2243 (define_insn "*popdi1_epilogue_rex64"
2244   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2245         (mem:DI (reg:DI SP_REG)))
2246    (set (reg:DI SP_REG)
2247         (plus:DI (reg:DI SP_REG) (const_int 8)))
2248    (clobber (mem:BLK (scratch)))]
2249   "TARGET_64BIT"
2250   "pop{q}\t%0"
2251   [(set_attr "type" "pop")
2252    (set_attr "mode" "DI")])
2254 (define_insn "popdi1"
2255   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2256         (mem:DI (reg:DI SP_REG)))
2257    (set (reg:DI SP_REG)
2258         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2259   "TARGET_64BIT"
2260   "pop{q}\t%0"
2261   [(set_attr "type" "pop")
2262    (set_attr "mode" "DI")])
2264 (define_insn "*movdi_xor_rex64"
2265   [(set (match_operand:DI 0 "register_operand" "=r")
2266         (match_operand:DI 1 "const0_operand" ""))
2267    (clobber (reg:CC FLAGS_REG))]
2268   "TARGET_64BIT
2269    && reload_completed"
2270   "xor{l}\t%k0, %k0";
2271   [(set_attr "type" "alu1")
2272    (set_attr "mode" "SI")
2273    (set_attr "length_immediate" "0")])
2275 (define_insn "*movdi_or_rex64"
2276   [(set (match_operand:DI 0 "register_operand" "=r")
2277         (match_operand:DI 1 "const_int_operand" "i"))
2278    (clobber (reg:CC FLAGS_REG))]
2279   "TARGET_64BIT
2280    && reload_completed
2281    && operands[1] == constm1_rtx"
2283   operands[1] = constm1_rtx;
2284   return "or{q}\t{%1, %0|%0, %1}";
2286   [(set_attr "type" "alu1")
2287    (set_attr "mode" "DI")
2288    (set_attr "length_immediate" "1")])
2290 (define_insn "*movdi_2"
2291   [(set (match_operand:DI 0 "nonimmediate_operand"
2292                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2293         (match_operand:DI 1 "general_operand"
2294                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2295   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2296   "@
2297    #
2298    #
2299    pxor\t%0, %0
2300    movq\t{%1, %0|%0, %1}
2301    movq\t{%1, %0|%0, %1}
2302    %vpxor\t%0, %d0
2303    %vmovq\t{%1, %0|%0, %1}
2304    %vmovdqa\t{%1, %0|%0, %1}
2305    %vmovq\t{%1, %0|%0, %1}
2306    xorps\t%0, %0
2307    movlps\t{%1, %0|%0, %1}
2308    movaps\t{%1, %0|%0, %1}
2309    movlps\t{%1, %0|%0, %1}"
2310   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2311    (set (attr "prefix")
2312      (if_then_else (eq_attr "alternative" "5,6,7,8")
2313        (const_string "vex")
2314        (const_string "orig")))
2315    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2317 (define_split
2318   [(set (match_operand:DI 0 "push_operand" "")
2319         (match_operand:DI 1 "general_operand" ""))]
2320   "!TARGET_64BIT && reload_completed
2321    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2322   [(const_int 0)]
2323   "ix86_split_long_move (operands); DONE;")
2325 ;; %%% This multiword shite has got to go.
2326 (define_split
2327   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2328         (match_operand:DI 1 "general_operand" ""))]
2329   "!TARGET_64BIT && reload_completed
2330    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2331    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2332   [(const_int 0)]
2333   "ix86_split_long_move (operands); DONE;")
2335 (define_insn "*movdi_1_rex64"
2336   [(set (match_operand:DI 0 "nonimmediate_operand"
2337           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2338         (match_operand:DI 1 "general_operand"
2339           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2340   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2342   switch (get_attr_type (insn))
2343     {
2344     case TYPE_SSECVT:
2345       if (SSE_REG_P (operands[0]))
2346         return "movq2dq\t{%1, %0|%0, %1}";
2347       else
2348         return "movdq2q\t{%1, %0|%0, %1}";
2350     case TYPE_SSEMOV:
2351       if (TARGET_AVX)
2352         {
2353           if (get_attr_mode (insn) == MODE_TI)
2354             return "vmovdqa\t{%1, %0|%0, %1}";
2355           else
2356             return "vmovq\t{%1, %0|%0, %1}";
2357         }
2359       if (get_attr_mode (insn) == MODE_TI)
2360         return "movdqa\t{%1, %0|%0, %1}";
2361       /* FALLTHRU */
2363     case TYPE_MMXMOV:
2364       /* Moves from and into integer register is done using movd
2365          opcode with REX prefix.  */
2366       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2367         return "movd\t{%1, %0|%0, %1}";
2368       return "movq\t{%1, %0|%0, %1}";
2370     case TYPE_SSELOG1:
2371       return "%vpxor\t%0, %d0";
2373     case TYPE_MMXADD:
2374       return "pxor\t%0, %0";
2376     case TYPE_MULTI:
2377       return "#";
2379     case TYPE_LEA:
2380       return "lea{q}\t{%a1, %0|%0, %a1}";
2382     default:
2383       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2384       if (get_attr_mode (insn) == MODE_SI)
2385         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2386       else if (which_alternative == 2)
2387         return "movabs{q}\t{%1, %0|%0, %1}";
2388       else
2389         return "mov{q}\t{%1, %0|%0, %1}";
2390     }
2392   [(set (attr "type")
2393      (cond [(eq_attr "alternative" "5")
2394               (const_string "mmxadd")
2395             (eq_attr "alternative" "6,7,8,9,10")
2396               (const_string "mmxmov")
2397             (eq_attr "alternative" "11")
2398               (const_string "sselog1")
2399             (eq_attr "alternative" "12,13,14,15,16")
2400               (const_string "ssemov")
2401             (eq_attr "alternative" "17,18")
2402               (const_string "ssecvt")
2403             (eq_attr "alternative" "4")
2404               (const_string "multi")
2405             (match_operand:DI 1 "pic_32bit_operand" "")
2406               (const_string "lea")
2407            ]
2408            (const_string "imov")))
2409    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2410    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2411    (set (attr "prefix")
2412      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2413        (const_string "maybe_vex")
2414        (const_string "orig")))
2415    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2417 ;; Stores and loads of ax to arbitrary constant address.
2418 ;; We fake an second form of instruction to force reload to load address
2419 ;; into register when rax is not available
2420 (define_insn "*movabsdi_1_rex64"
2421   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2422         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2423   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2424   "@
2425    movabs{q}\t{%1, %P0|%P0, %1}
2426    mov{q}\t{%1, %a0|%a0, %1}"
2427   [(set_attr "type" "imov")
2428    (set_attr "modrm" "0,*")
2429    (set_attr "length_address" "8,0")
2430    (set_attr "length_immediate" "0,*")
2431    (set_attr "memory" "store")
2432    (set_attr "mode" "DI")])
2434 (define_insn "*movabsdi_2_rex64"
2435   [(set (match_operand:DI 0 "register_operand" "=a,r")
2436         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2437   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2438   "@
2439    movabs{q}\t{%P1, %0|%0, %P1}
2440    mov{q}\t{%a1, %0|%0, %a1}"
2441   [(set_attr "type" "imov")
2442    (set_attr "modrm" "0,*")
2443    (set_attr "length_address" "8,0")
2444    (set_attr "length_immediate" "0")
2445    (set_attr "memory" "load")
2446    (set_attr "mode" "DI")])
2448 ;; Convert impossible stores of immediate to existing instructions.
2449 ;; First try to get scratch register and go through it.  In case this
2450 ;; fails, move by 32bit parts.
2451 (define_peephole2
2452   [(match_scratch:DI 2 "r")
2453    (set (match_operand:DI 0 "memory_operand" "")
2454         (match_operand:DI 1 "immediate_operand" ""))]
2455   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2456    && !x86_64_immediate_operand (operands[1], DImode)"
2457   [(set (match_dup 2) (match_dup 1))
2458    (set (match_dup 0) (match_dup 2))]
2459   "")
2461 ;; We need to define this as both peepholer and splitter for case
2462 ;; peephole2 pass is not run.
2463 ;; "&& 1" is needed to keep it from matching the previous pattern.
2464 (define_peephole2
2465   [(set (match_operand:DI 0 "memory_operand" "")
2466         (match_operand:DI 1 "immediate_operand" ""))]
2467   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2468    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2469   [(set (match_dup 2) (match_dup 3))
2470    (set (match_dup 4) (match_dup 5))]
2471   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2473 (define_split
2474   [(set (match_operand:DI 0 "memory_operand" "")
2475         (match_operand:DI 1 "immediate_operand" ""))]
2476   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2477                     ? epilogue_completed : reload_completed)
2478    && !symbolic_operand (operands[1], DImode)
2479    && !x86_64_immediate_operand (operands[1], DImode)"
2480   [(set (match_dup 2) (match_dup 3))
2481    (set (match_dup 4) (match_dup 5))]
2482   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2484 (define_insn "*swapdi_rex64"
2485   [(set (match_operand:DI 0 "register_operand" "+r")
2486         (match_operand:DI 1 "register_operand" "+r"))
2487    (set (match_dup 1)
2488         (match_dup 0))]
2489   "TARGET_64BIT"
2490   "xchg{q}\t%1, %0"
2491   [(set_attr "type" "imov")
2492    (set_attr "mode" "DI")
2493    (set_attr "pent_pair" "np")
2494    (set_attr "athlon_decode" "vector")
2495    (set_attr "amdfam10_decode" "double")])
2497 (define_expand "movoi"
2498   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2499         (match_operand:OI 1 "general_operand" ""))]
2500   "TARGET_AVX"
2501   "ix86_expand_move (OImode, operands); DONE;")
2503 (define_insn "*movoi_internal"
2504   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2505         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2506   "TARGET_AVX
2507    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2509   switch (which_alternative)
2510     {
2511     case 0:
2512       return "vxorps\t%0, %0, %0";
2513     case 1:
2514     case 2:
2515       if (misaligned_operand (operands[0], OImode)
2516           || misaligned_operand (operands[1], OImode))
2517         return "vmovdqu\t{%1, %0|%0, %1}";
2518       else
2519         return "vmovdqa\t{%1, %0|%0, %1}";
2520     default:
2521       gcc_unreachable ();
2522     }
2524   [(set_attr "type" "sselog1,ssemov,ssemov")
2525    (set_attr "prefix" "vex")
2526    (set_attr "mode" "OI")])
2528 (define_expand "movti"
2529   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2530         (match_operand:TI 1 "nonimmediate_operand" ""))]
2531   "TARGET_SSE || TARGET_64BIT"
2533   if (TARGET_64BIT)
2534     ix86_expand_move (TImode, operands);
2535   else if (push_operand (operands[0], TImode))
2536     ix86_expand_push (TImode, operands[1]);
2537   else
2538     ix86_expand_vector_move (TImode, operands);
2539   DONE;
2542 (define_insn "*movti_internal"
2543   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2544         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2545   "TARGET_SSE && !TARGET_64BIT
2546    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2548   switch (which_alternative)
2549     {
2550     case 0:
2551       if (get_attr_mode (insn) == MODE_V4SF)
2552         return "%vxorps\t%0, %d0";
2553       else
2554         return "%vpxor\t%0, %d0";
2555     case 1:
2556     case 2:
2557       /* TDmode values are passed as TImode on the stack.  Moving them
2558          to stack may result in unaligned memory access.  */
2559       if (misaligned_operand (operands[0], TImode)
2560           || misaligned_operand (operands[1], TImode))
2561         {
2562           if (get_attr_mode (insn) == MODE_V4SF)
2563             return "%vmovups\t{%1, %0|%0, %1}";
2564          else
2565            return "%vmovdqu\t{%1, %0|%0, %1}";
2566         }
2567       else
2568         {
2569           if (get_attr_mode (insn) == MODE_V4SF)
2570             return "%vmovaps\t{%1, %0|%0, %1}";
2571          else
2572            return "%vmovdqa\t{%1, %0|%0, %1}";
2573         }
2574     default:
2575       gcc_unreachable ();
2576     }
2578   [(set_attr "type" "sselog1,ssemov,ssemov")
2579    (set_attr "prefix" "maybe_vex")
2580    (set (attr "mode")
2581         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2582                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2583                  (const_string "V4SF")
2584                (and (eq_attr "alternative" "2")
2585                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2586                         (const_int 0)))
2587                  (const_string "V4SF")]
2588               (const_string "TI")))])
2590 (define_insn "*movti_rex64"
2591   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2592         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2593   "TARGET_64BIT
2594    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2596   switch (which_alternative)
2597     {
2598     case 0:
2599     case 1:
2600       return "#";
2601     case 2:
2602       if (get_attr_mode (insn) == MODE_V4SF)
2603         return "%vxorps\t%0, %d0";
2604       else
2605         return "%vpxor\t%0, %d0";
2606     case 3:
2607     case 4:
2608       /* TDmode values are passed as TImode on the stack.  Moving them
2609          to stack may result in unaligned memory access.  */
2610       if (misaligned_operand (operands[0], TImode)
2611           || misaligned_operand (operands[1], TImode))
2612         {
2613           if (get_attr_mode (insn) == MODE_V4SF)
2614             return "%vmovups\t{%1, %0|%0, %1}";
2615          else
2616            return "%vmovdqu\t{%1, %0|%0, %1}";
2617         }
2618       else
2619         {
2620           if (get_attr_mode (insn) == MODE_V4SF)
2621             return "%vmovaps\t{%1, %0|%0, %1}";
2622          else
2623            return "%vmovdqa\t{%1, %0|%0, %1}";
2624         }
2625     default:
2626       gcc_unreachable ();
2627     }
2629   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2630    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2631    (set (attr "mode")
2632         (cond [(eq_attr "alternative" "2,3")
2633                  (if_then_else
2634                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2635                        (const_int 0))
2636                    (const_string "V4SF")
2637                    (const_string "TI"))
2638                (eq_attr "alternative" "4")
2639                  (if_then_else
2640                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2641                             (const_int 0))
2642                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2643                             (const_int 0)))
2644                    (const_string "V4SF")
2645                    (const_string "TI"))]
2646                (const_string "DI")))])
2648 (define_split
2649   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2650         (match_operand:TI 1 "general_operand" ""))]
2651   "reload_completed && !SSE_REG_P (operands[0])
2652    && !SSE_REG_P (operands[1])"
2653   [(const_int 0)]
2654   "ix86_split_long_move (operands); DONE;")
2656 ;; This expands to what emit_move_complex would generate if we didn't
2657 ;; have a movti pattern.  Having this avoids problems with reload on
2658 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2659 ;; to have around all the time.
2660 (define_expand "movcdi"
2661   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2662         (match_operand:CDI 1 "general_operand" ""))]
2663   ""
2665   if (push_operand (operands[0], CDImode))
2666     emit_move_complex_push (CDImode, operands[0], operands[1]);
2667   else
2668     emit_move_complex_parts (operands[0], operands[1]);
2669   DONE;
2672 (define_expand "movsf"
2673   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2674         (match_operand:SF 1 "general_operand" ""))]
2675   ""
2676   "ix86_expand_move (SFmode, operands); DONE;")
2678 (define_insn "*pushsf"
2679   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2680         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2681   "!TARGET_64BIT"
2683   /* Anything else should be already split before reg-stack.  */
2684   gcc_assert (which_alternative == 1);
2685   return "push{l}\t%1";
2687   [(set_attr "type" "multi,push,multi")
2688    (set_attr "unit" "i387,*,*")
2689    (set_attr "mode" "SF,SI,SF")])
2691 (define_insn "*pushsf_rex64"
2692   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2693         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2694   "TARGET_64BIT"
2696   /* Anything else should be already split before reg-stack.  */
2697   gcc_assert (which_alternative == 1);
2698   return "push{q}\t%q1";
2700   [(set_attr "type" "multi,push,multi")
2701    (set_attr "unit" "i387,*,*")
2702    (set_attr "mode" "SF,DI,SF")])
2704 (define_split
2705   [(set (match_operand:SF 0 "push_operand" "")
2706         (match_operand:SF 1 "memory_operand" ""))]
2707   "reload_completed
2708    && MEM_P (operands[1])
2709    && (operands[2] = find_constant_src (insn))"
2710   [(set (match_dup 0)
2711         (match_dup 2))])
2714 ;; %%% Kill this when call knows how to work this out.
2715 (define_split
2716   [(set (match_operand:SF 0 "push_operand" "")
2717         (match_operand:SF 1 "any_fp_register_operand" ""))]
2718   "!TARGET_64BIT"
2719   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2720    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2722 (define_split
2723   [(set (match_operand:SF 0 "push_operand" "")
2724         (match_operand:SF 1 "any_fp_register_operand" ""))]
2725   "TARGET_64BIT"
2726   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2727    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2729 (define_insn "*movsf_1"
2730   [(set (match_operand:SF 0 "nonimmediate_operand"
2731           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2732         (match_operand:SF 1 "general_operand"
2733           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2734   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2735    && (reload_in_progress || reload_completed
2736        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2737        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2738            && standard_80387_constant_p (operands[1]))
2739        || GET_CODE (operands[1]) != CONST_DOUBLE
2740        || memory_operand (operands[0], SFmode))"
2742   switch (which_alternative)
2743     {
2744     case 0:
2745     case 1:
2746       return output_387_reg_move (insn, operands);
2748     case 2:
2749       return standard_80387_constant_opcode (operands[1]);
2751     case 3:
2752     case 4:
2753       return "mov{l}\t{%1, %0|%0, %1}";
2754     case 5:
2755       if (get_attr_mode (insn) == MODE_TI)
2756         return "%vpxor\t%0, %d0";
2757       else
2758         return "%vxorps\t%0, %d0";
2759     case 6:
2760       if (get_attr_mode (insn) == MODE_V4SF)
2761         return "%vmovaps\t{%1, %0|%0, %1}";
2762       else
2763         return "%vmovss\t{%1, %d0|%d0, %1}";
2764     case 7:
2765       if (TARGET_AVX)
2766         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2767                                    : "vmovss\t{%1, %0|%0, %1}";
2768       else
2769         return "movss\t{%1, %0|%0, %1}";
2770     case 8:
2771       return "%vmovss\t{%1, %0|%0, %1}";
2773     case 9: case 10: case 14: case 15:
2774       return "movd\t{%1, %0|%0, %1}";
2775     case 12: case 13:
2776       return "%vmovd\t{%1, %0|%0, %1}";
2778     case 11:
2779       return "movq\t{%1, %0|%0, %1}";
2781     default:
2782       gcc_unreachable ();
2783     }
2785   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2786    (set (attr "prefix")
2787      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2788        (const_string "maybe_vex")
2789        (const_string "orig")))
2790    (set (attr "mode")
2791         (cond [(eq_attr "alternative" "3,4,9,10")
2792                  (const_string "SI")
2793                (eq_attr "alternative" "5")
2794                  (if_then_else
2795                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2796                                  (const_int 0))
2797                              (ne (symbol_ref "TARGET_SSE2")
2798                                  (const_int 0)))
2799                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2800                             (const_int 0)))
2801                    (const_string "TI")
2802                    (const_string "V4SF"))
2803                /* For architectures resolving dependencies on
2804                   whole SSE registers use APS move to break dependency
2805                   chains, otherwise use short move to avoid extra work.
2807                   Do the same for architectures resolving dependencies on
2808                   the parts.  While in DF mode it is better to always handle
2809                   just register parts, the SF mode is different due to lack
2810                   of instructions to load just part of the register.  It is
2811                   better to maintain the whole registers in single format
2812                   to avoid problems on using packed logical operations.  */
2813                (eq_attr "alternative" "6")
2814                  (if_then_else
2815                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2816                             (const_int 0))
2817                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2818                             (const_int 0)))
2819                    (const_string "V4SF")
2820                    (const_string "SF"))
2821                (eq_attr "alternative" "11")
2822                  (const_string "DI")]
2823                (const_string "SF")))])
2825 (define_insn "*swapsf"
2826   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2827         (match_operand:SF 1 "fp_register_operand" "+f"))
2828    (set (match_dup 1)
2829         (match_dup 0))]
2830   "reload_completed || TARGET_80387"
2832   if (STACK_TOP_P (operands[0]))
2833     return "fxch\t%1";
2834   else
2835     return "fxch\t%0";
2837   [(set_attr "type" "fxch")
2838    (set_attr "mode" "SF")])
2840 (define_expand "movdf"
2841   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2842         (match_operand:DF 1 "general_operand" ""))]
2843   ""
2844   "ix86_expand_move (DFmode, operands); DONE;")
2846 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2847 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2848 ;; On the average, pushdf using integers can be still shorter.  Allow this
2849 ;; pattern for optimize_size too.
2851 (define_insn "*pushdf_nointeger"
2852   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2853         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2854   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2856   /* This insn should be already split before reg-stack.  */
2857   gcc_unreachable ();
2859   [(set_attr "type" "multi")
2860    (set_attr "unit" "i387,*,*,*")
2861    (set_attr "mode" "DF,SI,SI,DF")])
2863 (define_insn "*pushdf_integer"
2864   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2865         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2866   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2868   /* This insn should be already split before reg-stack.  */
2869   gcc_unreachable ();
2871   [(set_attr "type" "multi")
2872    (set_attr "unit" "i387,*,*")
2873    (set_attr "mode" "DF,SI,DF")])
2875 ;; %%% Kill this when call knows how to work this out.
2876 (define_split
2877   [(set (match_operand:DF 0 "push_operand" "")
2878         (match_operand:DF 1 "any_fp_register_operand" ""))]
2879   "reload_completed"
2880   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2881    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2882   "")
2884 (define_split
2885   [(set (match_operand:DF 0 "push_operand" "")
2886         (match_operand:DF 1 "general_operand" ""))]
2887   "reload_completed"
2888   [(const_int 0)]
2889   "ix86_split_long_move (operands); DONE;")
2891 ;; Moving is usually shorter when only FP registers are used. This separate
2892 ;; movdf pattern avoids the use of integer registers for FP operations
2893 ;; when optimizing for size.
2895 (define_insn "*movdf_nointeger"
2896   [(set (match_operand:DF 0 "nonimmediate_operand"
2897                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2898         (match_operand:DF 1 "general_operand"
2899                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2900   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2901    && ((optimize_function_for_size_p (cfun)
2902        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2903    && (reload_in_progress || reload_completed
2904        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2905        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2906            && optimize_function_for_size_p (cfun)
2907            && !memory_operand (operands[0], DFmode)
2908            && standard_80387_constant_p (operands[1]))
2909        || GET_CODE (operands[1]) != CONST_DOUBLE
2910        || ((optimize_function_for_size_p (cfun)
2911             || !TARGET_MEMORY_MISMATCH_STALL
2912             || reload_in_progress || reload_completed)
2913            && memory_operand (operands[0], DFmode)))"
2915   switch (which_alternative)
2916     {
2917     case 0:
2918     case 1:
2919       return output_387_reg_move (insn, operands);
2921     case 2:
2922       return standard_80387_constant_opcode (operands[1]);
2924     case 3:
2925     case 4:
2926       return "#";
2927     case 5:
2928       switch (get_attr_mode (insn))
2929         {
2930         case MODE_V4SF:
2931           return "%vxorps\t%0, %d0";
2932         case MODE_V2DF:
2933           return "%vxorpd\t%0, %d0";
2934         case MODE_TI:
2935           return "%vpxor\t%0, %d0";
2936         default:
2937           gcc_unreachable ();
2938         }
2939     case 6:
2940     case 7:
2941     case 8:
2942       switch (get_attr_mode (insn))
2943         {
2944         case MODE_V4SF:
2945           return "%vmovaps\t{%1, %0|%0, %1}";
2946         case MODE_V2DF:
2947           return "%vmovapd\t{%1, %0|%0, %1}";
2948         case MODE_TI:
2949           return "%vmovdqa\t{%1, %0|%0, %1}";
2950         case MODE_DI:
2951           return "%vmovq\t{%1, %0|%0, %1}";
2952         case MODE_DF:
2953           if (TARGET_AVX)
2954             {
2955               if (REG_P (operands[0]) && REG_P (operands[1]))
2956                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2957               else
2958                 return "vmovsd\t{%1, %0|%0, %1}";
2959             }
2960           else
2961             return "movsd\t{%1, %0|%0, %1}";
2962         case MODE_V1DF:
2963           if (TARGET_AVX)
2964             {
2965               if (REG_P (operands[0]))
2966                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
2967               else
2968                 return "vmovlpd\t{%1, %0|%0, %1}";
2969             }
2970           else
2971             return "movlpd\t{%1, %0|%0, %1}";
2972         case MODE_V2SF:
2973           if (TARGET_AVX)
2974             {
2975               if (REG_P (operands[0]))
2976                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
2977               else
2978                 return "vmovlps\t{%1, %0|%0, %1}";
2979             }
2980           else
2981             return "movlps\t{%1, %0|%0, %1}";
2982         default:
2983           gcc_unreachable ();
2984         }
2986     default:
2987       gcc_unreachable ();
2988     }
2990   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2991    (set (attr "prefix")
2992      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2993        (const_string "orig")
2994        (const_string "maybe_vex")))
2995    (set (attr "mode")
2996         (cond [(eq_attr "alternative" "0,1,2")
2997                  (const_string "DF")
2998                (eq_attr "alternative" "3,4")
2999                  (const_string "SI")
3001                /* For SSE1, we have many fewer alternatives.  */
3002                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3003                  (cond [(eq_attr "alternative" "5,6")
3004                           (const_string "V4SF")
3005                        ]
3006                    (const_string "V2SF"))
3008                /* xorps is one byte shorter.  */
3009                (eq_attr "alternative" "5")
3010                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3011                             (const_int 0))
3012                           (const_string "V4SF")
3013                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3014                             (const_int 0))
3015                           (const_string "TI")
3016                        ]
3017                        (const_string "V2DF"))
3019                /* For architectures resolving dependencies on
3020                   whole SSE registers use APD move to break dependency
3021                   chains, otherwise use short move to avoid extra work.
3023                   movaps encodes one byte shorter.  */
3024                (eq_attr "alternative" "6")
3025                  (cond
3026                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3027                         (const_int 0))
3028                       (const_string "V4SF")
3029                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3030                         (const_int 0))
3031                       (const_string "V2DF")
3032                    ]
3033                    (const_string "DF"))
3034                /* For architectures resolving dependencies on register
3035                   parts we may avoid extra work to zero out upper part
3036                   of register.  */
3037                (eq_attr "alternative" "7")
3038                  (if_then_else
3039                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3040                        (const_int 0))
3041                    (const_string "V1DF")
3042                    (const_string "DF"))
3043               ]
3044               (const_string "DF")))])
3046 (define_insn "*movdf_integer_rex64"
3047   [(set (match_operand:DF 0 "nonimmediate_operand"
3048                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3049         (match_operand:DF 1 "general_operand"
3050                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3051   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3052    && (reload_in_progress || reload_completed
3053        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3054        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3055            && optimize_function_for_size_p (cfun)
3056            && standard_80387_constant_p (operands[1]))
3057        || GET_CODE (operands[1]) != CONST_DOUBLE
3058        || memory_operand (operands[0], DFmode))"
3060   switch (which_alternative)
3061     {
3062     case 0:
3063     case 1:
3064       return output_387_reg_move (insn, operands);
3066     case 2:
3067       return standard_80387_constant_opcode (operands[1]);
3069     case 3:
3070     case 4:
3071       return "#";
3073     case 5:
3074       switch (get_attr_mode (insn))
3075         {
3076         case MODE_V4SF:
3077           return "%vxorps\t%0, %d0";
3078         case MODE_V2DF:
3079           return "%vxorpd\t%0, %d0";
3080         case MODE_TI:
3081           return "%vpxor\t%0, %d0";
3082         default:
3083           gcc_unreachable ();
3084         }
3085     case 6:
3086     case 7:
3087     case 8:
3088       switch (get_attr_mode (insn))
3089         {
3090         case MODE_V4SF:
3091           return "%vmovaps\t{%1, %0|%0, %1}";
3092         case MODE_V2DF:
3093           return "%vmovapd\t{%1, %0|%0, %1}";
3094         case MODE_TI:
3095           return "%vmovdqa\t{%1, %0|%0, %1}";
3096         case MODE_DI:
3097           return "%vmovq\t{%1, %0|%0, %1}";
3098         case MODE_DF:
3099           if (TARGET_AVX)
3100             {
3101               if (REG_P (operands[0]) && REG_P (operands[1]))
3102                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3103               else
3104                 return "vmovsd\t{%1, %0|%0, %1}";
3105             }
3106           else
3107             return "movsd\t{%1, %0|%0, %1}";
3108         case MODE_V1DF:
3109           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3110         case MODE_V2SF:
3111           return "%vmovlps\t{%1, %d0|%d0, %1}";
3112         default:
3113           gcc_unreachable ();
3114         }
3116     case 9:
3117     case 10:
3118     return "%vmovd\t{%1, %0|%0, %1}";
3120     default:
3121       gcc_unreachable();
3122     }
3124   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3125    (set (attr "prefix")
3126      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3127        (const_string "orig")
3128        (const_string "maybe_vex")))
3129    (set (attr "mode")
3130         (cond [(eq_attr "alternative" "0,1,2")
3131                  (const_string "DF")
3132                (eq_attr "alternative" "3,4,9,10")
3133                  (const_string "DI")
3135                /* For SSE1, we have many fewer alternatives.  */
3136                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3137                  (cond [(eq_attr "alternative" "5,6")
3138                           (const_string "V4SF")
3139                        ]
3140                    (const_string "V2SF"))
3142                /* xorps is one byte shorter.  */
3143                (eq_attr "alternative" "5")
3144                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3145                             (const_int 0))
3146                           (const_string "V4SF")
3147                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3148                             (const_int 0))
3149                           (const_string "TI")
3150                        ]
3151                        (const_string "V2DF"))
3153                /* For architectures resolving dependencies on
3154                   whole SSE registers use APD move to break dependency
3155                   chains, otherwise use short move to avoid extra work.
3157                   movaps encodes one byte shorter.  */
3158                (eq_attr "alternative" "6")
3159                  (cond
3160                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3161                         (const_int 0))
3162                       (const_string "V4SF")
3163                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3164                         (const_int 0))
3165                       (const_string "V2DF")
3166                    ]
3167                    (const_string "DF"))
3168                /* For architectures resolving dependencies on register
3169                   parts we may avoid extra work to zero out upper part
3170                   of register.  */
3171                (eq_attr "alternative" "7")
3172                  (if_then_else
3173                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3174                        (const_int 0))
3175                    (const_string "V1DF")
3176                    (const_string "DF"))
3177               ]
3178               (const_string "DF")))])
3180 (define_insn "*movdf_integer"
3181   [(set (match_operand:DF 0 "nonimmediate_operand"
3182                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3183         (match_operand:DF 1 "general_operand"
3184                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3185   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3186    && optimize_function_for_speed_p (cfun)
3187    && TARGET_INTEGER_DFMODE_MOVES
3188    && (reload_in_progress || reload_completed
3189        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3190        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3191            && optimize_function_for_size_p (cfun)
3192            && standard_80387_constant_p (operands[1]))
3193        || GET_CODE (operands[1]) != CONST_DOUBLE
3194        || memory_operand (operands[0], DFmode))"
3196   switch (which_alternative)
3197     {
3198     case 0:
3199     case 1:
3200       return output_387_reg_move (insn, operands);
3202     case 2:
3203       return standard_80387_constant_opcode (operands[1]);
3205     case 3:
3206     case 4:
3207       return "#";
3209     case 5:
3210       switch (get_attr_mode (insn))
3211         {
3212         case MODE_V4SF:
3213           return "xorps\t%0, %0";
3214         case MODE_V2DF:
3215           return "xorpd\t%0, %0";
3216         case MODE_TI:
3217           return "pxor\t%0, %0";
3218         default:
3219           gcc_unreachable ();
3220         }
3221     case 6:
3222     case 7:
3223     case 8:
3224       switch (get_attr_mode (insn))
3225         {
3226         case MODE_V4SF:
3227           return "movaps\t{%1, %0|%0, %1}";
3228         case MODE_V2DF:
3229           return "movapd\t{%1, %0|%0, %1}";
3230         case MODE_TI:
3231           return "movdqa\t{%1, %0|%0, %1}";
3232         case MODE_DI:
3233           return "movq\t{%1, %0|%0, %1}";
3234         case MODE_DF:
3235           return "movsd\t{%1, %0|%0, %1}";
3236         case MODE_V1DF:
3237           return "movlpd\t{%1, %0|%0, %1}";
3238         case MODE_V2SF:
3239           return "movlps\t{%1, %0|%0, %1}";
3240         default:
3241           gcc_unreachable ();
3242         }
3244     default:
3245       gcc_unreachable();
3246     }
3248   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3249    (set (attr "mode")
3250         (cond [(eq_attr "alternative" "0,1,2")
3251                  (const_string "DF")
3252                (eq_attr "alternative" "3,4")
3253                  (const_string "SI")
3255                /* For SSE1, we have many fewer alternatives.  */
3256                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3257                  (cond [(eq_attr "alternative" "5,6")
3258                           (const_string "V4SF")
3259                        ]
3260                    (const_string "V2SF"))
3262                /* xorps is one byte shorter.  */
3263                (eq_attr "alternative" "5")
3264                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3265                             (const_int 0))
3266                           (const_string "V4SF")
3267                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3268                             (const_int 0))
3269                           (const_string "TI")
3270                        ]
3271                        (const_string "V2DF"))
3273                /* For architectures resolving dependencies on
3274                   whole SSE registers use APD move to break dependency
3275                   chains, otherwise use short move to avoid extra work.
3277                   movaps encodes one byte shorter.  */
3278                (eq_attr "alternative" "6")
3279                  (cond
3280                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3281                         (const_int 0))
3282                       (const_string "V4SF")
3283                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3284                         (const_int 0))
3285                       (const_string "V2DF")
3286                    ]
3287                    (const_string "DF"))
3288                /* For architectures resolving dependencies on register
3289                   parts we may avoid extra work to zero out upper part
3290                   of register.  */
3291                (eq_attr "alternative" "7")
3292                  (if_then_else
3293                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3294                        (const_int 0))
3295                    (const_string "V1DF")
3296                    (const_string "DF"))
3297               ]
3298               (const_string "DF")))])
3300 (define_split
3301   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3302         (match_operand:DF 1 "general_operand" ""))]
3303   "reload_completed
3304    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3305    && ! (ANY_FP_REG_P (operands[0]) ||
3306          (GET_CODE (operands[0]) == SUBREG
3307           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3308    && ! (ANY_FP_REG_P (operands[1]) ||
3309          (GET_CODE (operands[1]) == SUBREG
3310           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3311   [(const_int 0)]
3312   "ix86_split_long_move (operands); DONE;")
3314 (define_insn "*swapdf"
3315   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3316         (match_operand:DF 1 "fp_register_operand" "+f"))
3317    (set (match_dup 1)
3318         (match_dup 0))]
3319   "reload_completed || TARGET_80387"
3321   if (STACK_TOP_P (operands[0]))
3322     return "fxch\t%1";
3323   else
3324     return "fxch\t%0";
3326   [(set_attr "type" "fxch")
3327    (set_attr "mode" "DF")])
3329 (define_expand "movxf"
3330   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3331         (match_operand:XF 1 "general_operand" ""))]
3332   ""
3333   "ix86_expand_move (XFmode, operands); DONE;")
3335 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3336 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3337 ;; Pushing using integer instructions is longer except for constants
3338 ;; and direct memory references.
3339 ;; (assuming that any given constant is pushed only once, but this ought to be
3340 ;;  handled elsewhere).
3342 (define_insn "*pushxf_nointeger"
3343   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3344         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3345   "optimize_function_for_size_p (cfun)"
3347   /* This insn should be already split before reg-stack.  */
3348   gcc_unreachable ();
3350   [(set_attr "type" "multi")
3351    (set_attr "unit" "i387,*,*")
3352    (set_attr "mode" "XF,SI,SI")])
3354 (define_insn "*pushxf_integer"
3355   [(set (match_operand:XF 0 "push_operand" "=<,<")
3356         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3357   "optimize_function_for_speed_p (cfun)"
3359   /* This insn should be already split before reg-stack.  */
3360   gcc_unreachable ();
3362   [(set_attr "type" "multi")
3363    (set_attr "unit" "i387,*")
3364    (set_attr "mode" "XF,SI")])
3366 (define_split
3367   [(set (match_operand 0 "push_operand" "")
3368         (match_operand 1 "general_operand" ""))]
3369   "reload_completed
3370    && (GET_MODE (operands[0]) == XFmode
3371        || GET_MODE (operands[0]) == DFmode)
3372    && !ANY_FP_REG_P (operands[1])"
3373   [(const_int 0)]
3374   "ix86_split_long_move (operands); DONE;")
3376 (define_split
3377   [(set (match_operand:XF 0 "push_operand" "")
3378         (match_operand:XF 1 "any_fp_register_operand" ""))]
3379   ""
3380   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3381    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3382   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3384 ;; Do not use integer registers when optimizing for size
3385 (define_insn "*movxf_nointeger"
3386   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3387         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3388   "optimize_function_for_size_p (cfun)
3389    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3390    && (reload_in_progress || reload_completed
3391        || standard_80387_constant_p (operands[1])
3392        || GET_CODE (operands[1]) != CONST_DOUBLE
3393        || memory_operand (operands[0], XFmode))"
3395   switch (which_alternative)
3396     {
3397     case 0:
3398     case 1:
3399       return output_387_reg_move (insn, operands);
3401     case 2:
3402       return standard_80387_constant_opcode (operands[1]);
3404     case 3: case 4:
3405       return "#";
3406     default:
3407       gcc_unreachable ();
3408     }
3410   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3411    (set_attr "mode" "XF,XF,XF,SI,SI")])
3413 (define_insn "*movxf_integer"
3414   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3415         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3416   "optimize_function_for_speed_p (cfun)
3417    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3418    && (reload_in_progress || reload_completed
3419        || GET_CODE (operands[1]) != CONST_DOUBLE
3420        || memory_operand (operands[0], XFmode))"
3422   switch (which_alternative)
3423     {
3424     case 0:
3425     case 1:
3426       return output_387_reg_move (insn, operands);
3428     case 2:
3429       return standard_80387_constant_opcode (operands[1]);
3431     case 3: case 4:
3432       return "#";
3434     default:
3435       gcc_unreachable ();
3436     }
3438   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3439    (set_attr "mode" "XF,XF,XF,SI,SI")])
3441 (define_expand "movtf"
3442   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3443         (match_operand:TF 1 "nonimmediate_operand" ""))]
3444   "TARGET_SSE2"
3446   ix86_expand_move (TFmode, operands);
3447   DONE;
3450 (define_insn "*movtf_internal"
3451   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3452         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3453   "TARGET_SSE2
3454    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3456   switch (which_alternative)
3457     {
3458     case 0:
3459     case 1:
3460       if (get_attr_mode (insn) == MODE_V4SF)
3461         return "%vmovaps\t{%1, %0|%0, %1}";
3462       else
3463         return "%vmovdqa\t{%1, %0|%0, %1}";
3464     case 2:
3465       if (get_attr_mode (insn) == MODE_V4SF)
3466         return "%vxorps\t%0, %d0";
3467       else
3468         return "%vpxor\t%0, %d0";
3469     case 3:
3470     case 4:
3471         return "#";
3472     default:
3473       gcc_unreachable ();
3474     }
3476   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3477    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3478    (set (attr "mode")
3479         (cond [(eq_attr "alternative" "0,2")
3480                  (if_then_else
3481                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3482                        (const_int 0))
3483                    (const_string "V4SF")
3484                    (const_string "TI"))
3485                (eq_attr "alternative" "1")
3486                  (if_then_else
3487                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3488                             (const_int 0))
3489                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3490                             (const_int 0)))
3491                    (const_string "V4SF")
3492                    (const_string "TI"))]
3493                (const_string "DI")))])
3495 (define_insn "*pushtf_sse"
3496   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3497         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3498   "TARGET_SSE2"
3500   /* This insn should be already split before reg-stack.  */
3501   gcc_unreachable ();
3503   [(set_attr "type" "multi")
3504    (set_attr "unit" "sse,*,*")
3505    (set_attr "mode" "TF,SI,SI")])
3507 (define_split
3508   [(set (match_operand:TF 0 "push_operand" "")
3509         (match_operand:TF 1 "general_operand" ""))]
3510   "TARGET_SSE2 && reload_completed
3511    && !SSE_REG_P (operands[1])"
3512   [(const_int 0)]
3513   "ix86_split_long_move (operands); DONE;")
3515 (define_split
3516   [(set (match_operand:TF 0 "push_operand" "")
3517         (match_operand:TF 1 "any_fp_register_operand" ""))]
3518   "TARGET_SSE2"
3519   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3520    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3521   "")
3523 (define_split
3524   [(set (match_operand 0 "nonimmediate_operand" "")
3525         (match_operand 1 "general_operand" ""))]
3526   "reload_completed
3527    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3528    && GET_MODE (operands[0]) == XFmode
3529    && ! (ANY_FP_REG_P (operands[0]) ||
3530          (GET_CODE (operands[0]) == SUBREG
3531           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3532    && ! (ANY_FP_REG_P (operands[1]) ||
3533          (GET_CODE (operands[1]) == SUBREG
3534           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3535   [(const_int 0)]
3536   "ix86_split_long_move (operands); DONE;")
3538 (define_split
3539   [(set (match_operand 0 "register_operand" "")
3540         (match_operand 1 "memory_operand" ""))]
3541   "reload_completed
3542    && MEM_P (operands[1])
3543    && (GET_MODE (operands[0]) == TFmode
3544        || GET_MODE (operands[0]) == XFmode
3545        || GET_MODE (operands[0]) == SFmode
3546        || GET_MODE (operands[0]) == DFmode)
3547    && (operands[2] = find_constant_src (insn))"
3548   [(set (match_dup 0) (match_dup 2))]
3550   rtx c = operands[2];
3551   rtx r = operands[0];
3553   if (GET_CODE (r) == SUBREG)
3554     r = SUBREG_REG (r);
3556   if (SSE_REG_P (r))
3557     {
3558       if (!standard_sse_constant_p (c))
3559         FAIL;
3560     }
3561   else if (FP_REG_P (r))
3562     {
3563       if (!standard_80387_constant_p (c))
3564         FAIL;
3565     }
3566   else if (MMX_REG_P (r))
3567     FAIL;
3570 (define_split
3571   [(set (match_operand 0 "register_operand" "")
3572         (float_extend (match_operand 1 "memory_operand" "")))]
3573   "reload_completed
3574    && MEM_P (operands[1])
3575    && (GET_MODE (operands[0]) == TFmode
3576        || GET_MODE (operands[0]) == XFmode
3577        || GET_MODE (operands[0]) == SFmode
3578        || GET_MODE (operands[0]) == DFmode)
3579    && (operands[2] = find_constant_src (insn))"
3580   [(set (match_dup 0) (match_dup 2))]
3582   rtx c = operands[2];
3583   rtx r = operands[0];
3585   if (GET_CODE (r) == SUBREG)
3586     r = SUBREG_REG (r);
3588   if (SSE_REG_P (r))
3589     {
3590       if (!standard_sse_constant_p (c))
3591         FAIL;
3592     }
3593   else if (FP_REG_P (r))
3594     {
3595       if (!standard_80387_constant_p (c))
3596         FAIL;
3597     }
3598   else if (MMX_REG_P (r))
3599     FAIL;
3602 (define_insn "swapxf"
3603   [(set (match_operand:XF 0 "register_operand" "+f")
3604         (match_operand:XF 1 "register_operand" "+f"))
3605    (set (match_dup 1)
3606         (match_dup 0))]
3607   "TARGET_80387"
3609   if (STACK_TOP_P (operands[0]))
3610     return "fxch\t%1";
3611   else
3612     return "fxch\t%0";
3614   [(set_attr "type" "fxch")
3615    (set_attr "mode" "XF")])
3617 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3618 (define_split
3619   [(set (match_operand:X87MODEF 0 "register_operand" "")
3620         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3621   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3622    && (standard_80387_constant_p (operands[1]) == 8
3623        || standard_80387_constant_p (operands[1]) == 9)"
3624   [(set (match_dup 0)(match_dup 1))
3625    (set (match_dup 0)
3626         (neg:X87MODEF (match_dup 0)))]
3628   REAL_VALUE_TYPE r;
3630   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3631   if (real_isnegzero (&r))
3632     operands[1] = CONST0_RTX (<MODE>mode);
3633   else
3634     operands[1] = CONST1_RTX (<MODE>mode);
3637 (define_split
3638   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3639         (match_operand:TF 1 "general_operand" ""))]
3640   "reload_completed
3641    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3642   [(const_int 0)]
3643   "ix86_split_long_move (operands); DONE;")
3645 ;; Zero extension instructions
3647 (define_expand "zero_extendhisi2"
3648   [(set (match_operand:SI 0 "register_operand" "")
3649      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3650   ""
3652   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3653     {
3654       operands[1] = force_reg (HImode, operands[1]);
3655       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3656       DONE;
3657     }
3660 (define_insn "zero_extendhisi2_and"
3661   [(set (match_operand:SI 0 "register_operand" "=r")
3662      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3663    (clobber (reg:CC FLAGS_REG))]
3664   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3665   "#"
3666   [(set_attr "type" "alu1")
3667    (set_attr "mode" "SI")])
3669 (define_split
3670   [(set (match_operand:SI 0 "register_operand" "")
3671         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3672    (clobber (reg:CC FLAGS_REG))]
3673   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3674    && optimize_function_for_speed_p (cfun)"
3675   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3676               (clobber (reg:CC FLAGS_REG))])]
3677   "")
3679 (define_insn "*zero_extendhisi2_movzwl"
3680   [(set (match_operand:SI 0 "register_operand" "=r")
3681      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3682   "!TARGET_ZERO_EXTEND_WITH_AND
3683    || optimize_function_for_size_p (cfun)"
3684   "movz{wl|x}\t{%1, %0|%0, %1}"
3685   [(set_attr "type" "imovx")
3686    (set_attr "mode" "SI")])
3688 (define_expand "zero_extendqihi2"
3689   [(parallel
3690     [(set (match_operand:HI 0 "register_operand" "")
3691        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3692      (clobber (reg:CC FLAGS_REG))])]
3693   ""
3694   "")
3696 (define_insn "*zero_extendqihi2_and"
3697   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3698      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3699    (clobber (reg:CC FLAGS_REG))]
3700   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3701   "#"
3702   [(set_attr "type" "alu1")
3703    (set_attr "mode" "HI")])
3705 (define_insn "*zero_extendqihi2_movzbw_and"
3706   [(set (match_operand:HI 0 "register_operand" "=r,r")
3707      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3708    (clobber (reg:CC FLAGS_REG))]
3709   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3710   "#"
3711   [(set_attr "type" "imovx,alu1")
3712    (set_attr "mode" "HI")])
3714 ; zero extend to SImode here to avoid partial register stalls
3715 (define_insn "*zero_extendqihi2_movzbl"
3716   [(set (match_operand:HI 0 "register_operand" "=r")
3717      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3718   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3719    && reload_completed"
3720   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3721   [(set_attr "type" "imovx")
3722    (set_attr "mode" "SI")])
3724 ;; For the movzbw case strip only the clobber
3725 (define_split
3726   [(set (match_operand:HI 0 "register_operand" "")
3727         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3728    (clobber (reg:CC FLAGS_REG))]
3729   "reload_completed
3730    && (!TARGET_ZERO_EXTEND_WITH_AND
3731        || optimize_function_for_size_p (cfun))
3732    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3733   [(set (match_operand:HI 0 "register_operand" "")
3734         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3736 ;; When source and destination does not overlap, clear destination
3737 ;; first and then do the movb
3738 (define_split
3739   [(set (match_operand:HI 0 "register_operand" "")
3740         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3741    (clobber (reg:CC FLAGS_REG))]
3742   "reload_completed
3743    && ANY_QI_REG_P (operands[0])
3744    && (TARGET_ZERO_EXTEND_WITH_AND
3745        && optimize_function_for_speed_p (cfun))
3746    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3747   [(set (match_dup 0) (const_int 0))
3748    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3749   "operands[2] = gen_lowpart (QImode, operands[0]);")
3751 ;; Rest is handled by single and.
3752 (define_split
3753   [(set (match_operand:HI 0 "register_operand" "")
3754         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3755    (clobber (reg:CC FLAGS_REG))]
3756   "reload_completed
3757    && true_regnum (operands[0]) == true_regnum (operands[1])"
3758   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3759               (clobber (reg:CC FLAGS_REG))])]
3760   "")
3762 (define_expand "zero_extendqisi2"
3763   [(parallel
3764     [(set (match_operand:SI 0 "register_operand" "")
3765        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3766      (clobber (reg:CC FLAGS_REG))])]
3767   ""
3768   "")
3770 (define_insn "*zero_extendqisi2_and"
3771   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3772      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3773    (clobber (reg:CC FLAGS_REG))]
3774   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3775   "#"
3776   [(set_attr "type" "alu1")
3777    (set_attr "mode" "SI")])
3779 (define_insn "*zero_extendqisi2_movzbw_and"
3780   [(set (match_operand:SI 0 "register_operand" "=r,r")
3781      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3782    (clobber (reg:CC FLAGS_REG))]
3783   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3784   "#"
3785   [(set_attr "type" "imovx,alu1")
3786    (set_attr "mode" "SI")])
3788 (define_insn "*zero_extendqisi2_movzbw"
3789   [(set (match_operand:SI 0 "register_operand" "=r")
3790      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3791   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3792    && reload_completed"
3793   "movz{bl|x}\t{%1, %0|%0, %1}"
3794   [(set_attr "type" "imovx")
3795    (set_attr "mode" "SI")])
3797 ;; For the movzbl case strip only the clobber
3798 (define_split
3799   [(set (match_operand:SI 0 "register_operand" "")
3800         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3801    (clobber (reg:CC FLAGS_REG))]
3802   "reload_completed
3803    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3804    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3805   [(set (match_dup 0)
3806         (zero_extend:SI (match_dup 1)))])
3808 ;; When source and destination does not overlap, clear destination
3809 ;; first and then do the movb
3810 (define_split
3811   [(set (match_operand:SI 0 "register_operand" "")
3812         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3813    (clobber (reg:CC FLAGS_REG))]
3814   "reload_completed
3815    && ANY_QI_REG_P (operands[0])
3816    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3817    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3818    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3819   [(set (match_dup 0) (const_int 0))
3820    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3821   "operands[2] = gen_lowpart (QImode, operands[0]);")
3823 ;; Rest is handled by single and.
3824 (define_split
3825   [(set (match_operand:SI 0 "register_operand" "")
3826         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3827    (clobber (reg:CC FLAGS_REG))]
3828   "reload_completed
3829    && true_regnum (operands[0]) == true_regnum (operands[1])"
3830   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3831               (clobber (reg:CC FLAGS_REG))])]
3832   "")
3834 ;; %%% Kill me once multi-word ops are sane.
3835 (define_expand "zero_extendsidi2"
3836   [(set (match_operand:DI 0 "register_operand" "")
3837      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3838   ""
3840   if (!TARGET_64BIT)
3841     {
3842       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3843       DONE;
3844     }
3847 (define_insn "zero_extendsidi2_32"
3848   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3849         (zero_extend:DI
3850          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3851    (clobber (reg:CC FLAGS_REG))]
3852   "!TARGET_64BIT"
3853   "@
3854    #
3855    #
3856    #
3857    movd\t{%1, %0|%0, %1}
3858    movd\t{%1, %0|%0, %1}
3859    %vmovd\t{%1, %0|%0, %1}
3860    %vmovd\t{%1, %0|%0, %1}"
3861   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3862    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3863    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3865 (define_insn "zero_extendsidi2_rex64"
3866   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3867      (zero_extend:DI
3868        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3869   "TARGET_64BIT"
3870   "@
3871    mov\t{%k1, %k0|%k0, %k1}
3872    #
3873    movd\t{%1, %0|%0, %1}
3874    movd\t{%1, %0|%0, %1}
3875    %vmovd\t{%1, %0|%0, %1}
3876    %vmovd\t{%1, %0|%0, %1}"
3877   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3878    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3879    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3881 (define_split
3882   [(set (match_operand:DI 0 "memory_operand" "")
3883      (zero_extend:DI (match_dup 0)))]
3884   "TARGET_64BIT"
3885   [(set (match_dup 4) (const_int 0))]
3886   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3888 (define_split
3889   [(set (match_operand:DI 0 "register_operand" "")
3890         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3891    (clobber (reg:CC FLAGS_REG))]
3892   "!TARGET_64BIT && reload_completed
3893    && true_regnum (operands[0]) == true_regnum (operands[1])"
3894   [(set (match_dup 4) (const_int 0))]
3895   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3897 (define_split
3898   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3899         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3900    (clobber (reg:CC FLAGS_REG))]
3901   "!TARGET_64BIT && reload_completed
3902    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3903   [(set (match_dup 3) (match_dup 1))
3904    (set (match_dup 4) (const_int 0))]
3905   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3907 (define_insn "zero_extendhidi2"
3908   [(set (match_operand:DI 0 "register_operand" "=r")
3909      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3910   "TARGET_64BIT"
3911   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3912   [(set_attr "type" "imovx")
3913    (set_attr "mode" "DI")])
3915 (define_insn "zero_extendqidi2"
3916   [(set (match_operand:DI 0 "register_operand" "=r")
3917      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3918   "TARGET_64BIT"
3919   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3920   [(set_attr "type" "imovx")
3921    (set_attr "mode" "DI")])
3923 ;; Sign extension instructions
3925 (define_expand "extendsidi2"
3926   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3927                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3928               (clobber (reg:CC FLAGS_REG))
3929               (clobber (match_scratch:SI 2 ""))])]
3930   ""
3932   if (TARGET_64BIT)
3933     {
3934       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3935       DONE;
3936     }
3939 (define_insn "*extendsidi2_1"
3940   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3941         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3942    (clobber (reg:CC FLAGS_REG))
3943    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3944   "!TARGET_64BIT"
3945   "#")
3947 (define_insn "extendsidi2_rex64"
3948   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3949         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3950   "TARGET_64BIT"
3951   "@
3952    {cltq|cdqe}
3953    movs{lq|x}\t{%1,%0|%0, %1}"
3954   [(set_attr "type" "imovx")
3955    (set_attr "mode" "DI")
3956    (set_attr "prefix_0f" "0")
3957    (set_attr "modrm" "0,1")])
3959 (define_insn "extendhidi2"
3960   [(set (match_operand:DI 0 "register_operand" "=r")
3961         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3962   "TARGET_64BIT"
3963   "movs{wq|x}\t{%1,%0|%0, %1}"
3964   [(set_attr "type" "imovx")
3965    (set_attr "mode" "DI")])
3967 (define_insn "extendqidi2"
3968   [(set (match_operand:DI 0 "register_operand" "=r")
3969         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3970   "TARGET_64BIT"
3971   "movs{bq|x}\t{%1,%0|%0, %1}"
3972    [(set_attr "type" "imovx")
3973     (set_attr "mode" "DI")])
3975 ;; Extend to memory case when source register does die.
3976 (define_split
3977   [(set (match_operand:DI 0 "memory_operand" "")
3978         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3979    (clobber (reg:CC FLAGS_REG))
3980    (clobber (match_operand:SI 2 "register_operand" ""))]
3981   "(reload_completed
3982     && dead_or_set_p (insn, operands[1])
3983     && !reg_mentioned_p (operands[1], operands[0]))"
3984   [(set (match_dup 3) (match_dup 1))
3985    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3986               (clobber (reg:CC FLAGS_REG))])
3987    (set (match_dup 4) (match_dup 1))]
3988   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3990 ;; Extend to memory case when source register does not die.
3991 (define_split
3992   [(set (match_operand:DI 0 "memory_operand" "")
3993         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3994    (clobber (reg:CC FLAGS_REG))
3995    (clobber (match_operand:SI 2 "register_operand" ""))]
3996   "reload_completed"
3997   [(const_int 0)]
3999   split_di (&operands[0], 1, &operands[3], &operands[4]);
4001   emit_move_insn (operands[3], operands[1]);
4003   /* Generate a cltd if possible and doing so it profitable.  */
4004   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4005       && true_regnum (operands[1]) == AX_REG
4006       && true_regnum (operands[2]) == DX_REG)
4007     {
4008       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4009     }
4010   else
4011     {
4012       emit_move_insn (operands[2], operands[1]);
4013       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4014     }
4015   emit_move_insn (operands[4], operands[2]);
4016   DONE;
4019 ;; Extend to register case.  Optimize case where source and destination
4020 ;; registers match and cases where we can use cltd.
4021 (define_split
4022   [(set (match_operand:DI 0 "register_operand" "")
4023         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4024    (clobber (reg:CC FLAGS_REG))
4025    (clobber (match_scratch:SI 2 ""))]
4026   "reload_completed"
4027   [(const_int 0)]
4029   split_di (&operands[0], 1, &operands[3], &operands[4]);
4031   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4032     emit_move_insn (operands[3], operands[1]);
4034   /* Generate a cltd if possible and doing so it profitable.  */
4035   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4036       && true_regnum (operands[3]) == AX_REG)
4037     {
4038       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4039       DONE;
4040     }
4042   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4043     emit_move_insn (operands[4], operands[1]);
4045   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4046   DONE;
4049 (define_insn "extendhisi2"
4050   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4051         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4052   ""
4054   switch (get_attr_prefix_0f (insn))
4055     {
4056     case 0:
4057       return "{cwtl|cwde}";
4058     default:
4059       return "movs{wl|x}\t{%1,%0|%0, %1}";
4060     }
4062   [(set_attr "type" "imovx")
4063    (set_attr "mode" "SI")
4064    (set (attr "prefix_0f")
4065      ;; movsx is short decodable while cwtl is vector decoded.
4066      (if_then_else (and (eq_attr "cpu" "!k6")
4067                         (eq_attr "alternative" "0"))
4068         (const_string "0")
4069         (const_string "1")))
4070    (set (attr "modrm")
4071      (if_then_else (eq_attr "prefix_0f" "0")
4072         (const_string "0")
4073         (const_string "1")))])
4075 (define_insn "*extendhisi2_zext"
4076   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4077         (zero_extend:DI
4078           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4079   "TARGET_64BIT"
4081   switch (get_attr_prefix_0f (insn))
4082     {
4083     case 0:
4084       return "{cwtl|cwde}";
4085     default:
4086       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4087     }
4089   [(set_attr "type" "imovx")
4090    (set_attr "mode" "SI")
4091    (set (attr "prefix_0f")
4092      ;; movsx is short decodable while cwtl is vector decoded.
4093      (if_then_else (and (eq_attr "cpu" "!k6")
4094                         (eq_attr "alternative" "0"))
4095         (const_string "0")
4096         (const_string "1")))
4097    (set (attr "modrm")
4098      (if_then_else (eq_attr "prefix_0f" "0")
4099         (const_string "0")
4100         (const_string "1")))])
4102 (define_insn "extendqihi2"
4103   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4104         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4105   ""
4107   switch (get_attr_prefix_0f (insn))
4108     {
4109     case 0:
4110       return "{cbtw|cbw}";
4111     default:
4112       return "movs{bw|x}\t{%1,%0|%0, %1}";
4113     }
4115   [(set_attr "type" "imovx")
4116    (set_attr "mode" "HI")
4117    (set (attr "prefix_0f")
4118      ;; movsx is short decodable while cwtl is vector decoded.
4119      (if_then_else (and (eq_attr "cpu" "!k6")
4120                         (eq_attr "alternative" "0"))
4121         (const_string "0")
4122         (const_string "1")))
4123    (set (attr "modrm")
4124      (if_then_else (eq_attr "prefix_0f" "0")
4125         (const_string "0")
4126         (const_string "1")))])
4128 (define_insn "extendqisi2"
4129   [(set (match_operand:SI 0 "register_operand" "=r")
4130         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4131   ""
4132   "movs{bl|x}\t{%1,%0|%0, %1}"
4133    [(set_attr "type" "imovx")
4134     (set_attr "mode" "SI")])
4136 (define_insn "*extendqisi2_zext"
4137   [(set (match_operand:DI 0 "register_operand" "=r")
4138         (zero_extend:DI
4139           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4140   "TARGET_64BIT"
4141   "movs{bl|x}\t{%1,%k0|%k0, %1}"
4142    [(set_attr "type" "imovx")
4143     (set_attr "mode" "SI")])
4145 ;; Conversions between float and double.
4147 ;; These are all no-ops in the model used for the 80387.  So just
4148 ;; emit moves.
4150 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4151 (define_insn "*dummy_extendsfdf2"
4152   [(set (match_operand:DF 0 "push_operand" "=<")
4153         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4154   "0"
4155   "#")
4157 (define_split
4158   [(set (match_operand:DF 0 "push_operand" "")
4159         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4160   ""
4161   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4162    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4164 (define_insn "*dummy_extendsfxf2"
4165   [(set (match_operand:XF 0 "push_operand" "=<")
4166         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4167   "0"
4168   "#")
4170 (define_split
4171   [(set (match_operand:XF 0 "push_operand" "")
4172         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4173   ""
4174   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4175    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4176   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4178 (define_split
4179   [(set (match_operand:XF 0 "push_operand" "")
4180         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4181   ""
4182   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4183    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4184   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4186 (define_expand "extendsfdf2"
4187   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4188         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4189   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4191   /* ??? Needed for compress_float_constant since all fp constants
4192      are LEGITIMATE_CONSTANT_P.  */
4193   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4194     {
4195       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4196           && standard_80387_constant_p (operands[1]) > 0)
4197         {
4198           operands[1] = simplify_const_unary_operation
4199             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4200           emit_move_insn_1 (operands[0], operands[1]);
4201           DONE;
4202         }
4203       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4204     }
4207 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4208    cvtss2sd:
4209       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4210       cvtps2pd xmm2,xmm1
4211    We do the conversion post reload to avoid producing of 128bit spills
4212    that might lead to ICE on 32bit target.  The sequence unlikely combine
4213    anyway.  */
4214 (define_split
4215   [(set (match_operand:DF 0 "register_operand" "")
4216         (float_extend:DF
4217           (match_operand:SF 1 "nonimmediate_operand" "")))]
4218   "TARGET_USE_VECTOR_FP_CONVERTS
4219    && optimize_insn_for_speed_p ()
4220    && reload_completed && SSE_REG_P (operands[0])"
4221    [(set (match_dup 2)
4222          (float_extend:V2DF
4223            (vec_select:V2SF
4224              (match_dup 3)
4225              (parallel [(const_int 0) (const_int 1)]))))]
4227   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4228   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4229   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4230      Try to avoid move when unpacking can be done in source.  */
4231   if (REG_P (operands[1]))
4232     {
4233       /* If it is unsafe to overwrite upper half of source, we need
4234          to move to destination and unpack there.  */
4235       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4236            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4237           && true_regnum (operands[0]) != true_regnum (operands[1]))
4238         {
4239           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4240           emit_move_insn (tmp, operands[1]);
4241         }
4242       else
4243         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4244       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4245     }
4246   else
4247     emit_insn (gen_vec_setv4sf_0 (operands[3],
4248                                   CONST0_RTX (V4SFmode), operands[1]));
4251 (define_insn "*extendsfdf2_mixed"
4252   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4253         (float_extend:DF
4254           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4255   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4257   switch (which_alternative)
4258     {
4259     case 0:
4260     case 1:
4261       return output_387_reg_move (insn, operands);
4263     case 2:
4264       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4266     default:
4267       gcc_unreachable ();
4268     }
4270   [(set_attr "type" "fmov,fmov,ssecvt")
4271    (set_attr "prefix" "orig,orig,maybe_vex")
4272    (set_attr "mode" "SF,XF,DF")])
4274 (define_insn "*extendsfdf2_sse"
4275   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4276         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4277   "TARGET_SSE2 && TARGET_SSE_MATH"
4278   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4279   [(set_attr "type" "ssecvt")
4280    (set_attr "prefix" "maybe_vex")
4281    (set_attr "mode" "DF")])
4283 (define_insn "*extendsfdf2_i387"
4284   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4285         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4286   "TARGET_80387"
4287   "* return output_387_reg_move (insn, operands);"
4288   [(set_attr "type" "fmov")
4289    (set_attr "mode" "SF,XF")])
4291 (define_expand "extend<mode>xf2"
4292   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4293         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4294   "TARGET_80387"
4296   /* ??? Needed for compress_float_constant since all fp constants
4297      are LEGITIMATE_CONSTANT_P.  */
4298   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4299     {
4300       if (standard_80387_constant_p (operands[1]) > 0)
4301         {
4302           operands[1] = simplify_const_unary_operation
4303             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4304           emit_move_insn_1 (operands[0], operands[1]);
4305           DONE;
4306         }
4307       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4308     }
4311 (define_insn "*extend<mode>xf2_i387"
4312   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4313         (float_extend:XF
4314           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4315   "TARGET_80387"
4316   "* return output_387_reg_move (insn, operands);"
4317   [(set_attr "type" "fmov")
4318    (set_attr "mode" "<MODE>,XF")])
4320 ;; %%% This seems bad bad news.
4321 ;; This cannot output into an f-reg because there is no way to be sure
4322 ;; of truncating in that case.  Otherwise this is just like a simple move
4323 ;; insn.  So we pretend we can output to a reg in order to get better
4324 ;; register preferencing, but we really use a stack slot.
4326 ;; Conversion from DFmode to SFmode.
4328 (define_expand "truncdfsf2"
4329   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4330         (float_truncate:SF
4331           (match_operand:DF 1 "nonimmediate_operand" "")))]
4332   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4334   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4335     ;
4336   else if (flag_unsafe_math_optimizations)
4337     ;
4338   else
4339     {
4340       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4341       rtx temp = assign_386_stack_local (SFmode, slot);
4342       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4343       DONE;
4344     }
4347 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4348    cvtsd2ss:
4349       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4350       cvtpd2ps xmm2,xmm1
4351    We do the conversion post reload to avoid producing of 128bit spills
4352    that might lead to ICE on 32bit target.  The sequence unlikely combine
4353    anyway.  */
4354 (define_split
4355   [(set (match_operand:SF 0 "register_operand" "")
4356         (float_truncate:SF
4357           (match_operand:DF 1 "nonimmediate_operand" "")))]
4358   "TARGET_USE_VECTOR_FP_CONVERTS
4359    && optimize_insn_for_speed_p ()
4360    && reload_completed && SSE_REG_P (operands[0])"
4361    [(set (match_dup 2)
4362          (vec_concat:V4SF
4363            (float_truncate:V2SF
4364              (match_dup 4))
4365            (match_dup 3)))]
4367   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4368   operands[3] = CONST0_RTX (V2SFmode);
4369   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4370   /* Use movsd for loading from memory, unpcklpd for registers.
4371      Try to avoid move when unpacking can be done in source, or SSE3
4372      movddup is available.  */
4373   if (REG_P (operands[1]))
4374     {
4375       if (!TARGET_SSE3
4376           && true_regnum (operands[0]) != true_regnum (operands[1])
4377           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4378               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4379         {
4380           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4381           emit_move_insn (tmp, operands[1]);
4382           operands[1] = tmp;
4383         }
4384       else if (!TARGET_SSE3)
4385         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4386       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4387     }
4388   else
4389     emit_insn (gen_sse2_loadlpd (operands[4],
4390                                  CONST0_RTX (V2DFmode), operands[1]));
4393 (define_expand "truncdfsf2_with_temp"
4394   [(parallel [(set (match_operand:SF 0 "" "")
4395                    (float_truncate:SF (match_operand:DF 1 "" "")))
4396               (clobber (match_operand:SF 2 "" ""))])]
4397   "")
4399 (define_insn "*truncdfsf_fast_mixed"
4400   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4401         (float_truncate:SF
4402           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4403   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4405   switch (which_alternative)
4406     {
4407     case 0:
4408       return output_387_reg_move (insn, operands);
4409     case 1:
4410       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4411     default:
4412       gcc_unreachable ();
4413     }
4415   [(set_attr "type" "fmov,ssecvt")
4416    (set_attr "prefix" "orig,maybe_vex")
4417    (set_attr "mode" "SF")])
4419 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4420 ;; because nothing we do here is unsafe.
4421 (define_insn "*truncdfsf_fast_sse"
4422   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4423         (float_truncate:SF
4424           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4425   "TARGET_SSE2 && TARGET_SSE_MATH"
4426   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4427   [(set_attr "type" "ssecvt")
4428    (set_attr "prefix" "maybe_vex")
4429    (set_attr "mode" "SF")])
4431 (define_insn "*truncdfsf_fast_i387"
4432   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4433         (float_truncate:SF
4434           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4435   "TARGET_80387 && flag_unsafe_math_optimizations"
4436   "* return output_387_reg_move (insn, operands);"
4437   [(set_attr "type" "fmov")
4438    (set_attr "mode" "SF")])
4440 (define_insn "*truncdfsf_mixed"
4441   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4442         (float_truncate:SF
4443           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4444    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4445   "TARGET_MIX_SSE_I387"
4447   switch (which_alternative)
4448     {
4449     case 0:
4450       return output_387_reg_move (insn, operands);
4452     case 1:
4453       return "#";
4454     case 2:
4455       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4456     default:
4457       gcc_unreachable ();
4458     }
4460   [(set_attr "type" "fmov,multi,ssecvt")
4461    (set_attr "unit" "*,i387,*")
4462    (set_attr "prefix" "orig,orig,maybe_vex")
4463    (set_attr "mode" "SF")])
4465 (define_insn "*truncdfsf_i387"
4466   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4467         (float_truncate:SF
4468           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4469    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4470   "TARGET_80387"
4472   switch (which_alternative)
4473     {
4474     case 0:
4475       return output_387_reg_move (insn, operands);
4477     case 1:
4478       return "#";
4479     default:
4480       gcc_unreachable ();
4481     }
4483   [(set_attr "type" "fmov,multi")
4484    (set_attr "unit" "*,i387")
4485    (set_attr "mode" "SF")])
4487 (define_insn "*truncdfsf2_i387_1"
4488   [(set (match_operand:SF 0 "memory_operand" "=m")
4489         (float_truncate:SF
4490           (match_operand:DF 1 "register_operand" "f")))]
4491   "TARGET_80387
4492    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4493    && !TARGET_MIX_SSE_I387"
4494   "* return output_387_reg_move (insn, operands);"
4495   [(set_attr "type" "fmov")
4496    (set_attr "mode" "SF")])
4498 (define_split
4499   [(set (match_operand:SF 0 "register_operand" "")
4500         (float_truncate:SF
4501          (match_operand:DF 1 "fp_register_operand" "")))
4502    (clobber (match_operand 2 "" ""))]
4503   "reload_completed"
4504   [(set (match_dup 2) (match_dup 1))
4505    (set (match_dup 0) (match_dup 2))]
4507   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4510 ;; Conversion from XFmode to {SF,DF}mode
4512 (define_expand "truncxf<mode>2"
4513   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4514                    (float_truncate:MODEF
4515                      (match_operand:XF 1 "register_operand" "")))
4516               (clobber (match_dup 2))])]
4517   "TARGET_80387"
4519   if (flag_unsafe_math_optimizations)
4520     {
4521       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4522       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4523       if (reg != operands[0])
4524         emit_move_insn (operands[0], reg);
4525       DONE;
4526     }
4527   else
4528     {
4529       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4530       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4531     }
4534 (define_insn "*truncxfsf2_mixed"
4535   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4536         (float_truncate:SF
4537           (match_operand:XF 1 "register_operand" "f,f")))
4538    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4539   "TARGET_80387"
4541   gcc_assert (!which_alternative);
4542   return output_387_reg_move (insn, operands);
4544   [(set_attr "type" "fmov,multi")
4545    (set_attr "unit" "*,i387")
4546    (set_attr "mode" "SF")])
4548 (define_insn "*truncxfdf2_mixed"
4549   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4550         (float_truncate:DF
4551           (match_operand:XF 1 "register_operand" "f,f")))
4552    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4553   "TARGET_80387"
4555   gcc_assert (!which_alternative);
4556   return output_387_reg_move (insn, operands);
4558   [(set_attr "type" "fmov,multi")
4559    (set_attr "unit" "*,i387")
4560    (set_attr "mode" "DF")])
4562 (define_insn "truncxf<mode>2_i387_noop"
4563   [(set (match_operand:MODEF 0 "register_operand" "=f")
4564         (float_truncate:MODEF
4565           (match_operand:XF 1 "register_operand" "f")))]
4566   "TARGET_80387 && flag_unsafe_math_optimizations"
4567   "* return output_387_reg_move (insn, operands);"
4568   [(set_attr "type" "fmov")
4569    (set_attr "mode" "<MODE>")])
4571 (define_insn "*truncxf<mode>2_i387"
4572   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4573         (float_truncate:MODEF
4574           (match_operand:XF 1 "register_operand" "f")))]
4575   "TARGET_80387"
4576   "* return output_387_reg_move (insn, operands);"
4577   [(set_attr "type" "fmov")
4578    (set_attr "mode" "<MODE>")])
4580 (define_split
4581   [(set (match_operand:MODEF 0 "register_operand" "")
4582         (float_truncate:MODEF
4583           (match_operand:XF 1 "register_operand" "")))
4584    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4585   "TARGET_80387 && reload_completed"
4586   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4587    (set (match_dup 0) (match_dup 2))]
4588   "")
4590 (define_split
4591   [(set (match_operand:MODEF 0 "memory_operand" "")
4592         (float_truncate:MODEF
4593           (match_operand:XF 1 "register_operand" "")))
4594    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4595   "TARGET_80387"
4596   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4597   "")
4599 ;; Signed conversion to DImode.
4601 (define_expand "fix_truncxfdi2"
4602   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4603                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4604               (clobber (reg:CC FLAGS_REG))])]
4605   "TARGET_80387"
4607   if (TARGET_FISTTP)
4608    {
4609      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4610      DONE;
4611    }
4614 (define_expand "fix_trunc<mode>di2"
4615   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4616                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4617               (clobber (reg:CC FLAGS_REG))])]
4618   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4620   if (TARGET_FISTTP
4621       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4622    {
4623      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4624      DONE;
4625    }
4626   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4627    {
4628      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4629      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4630      if (out != operands[0])
4631         emit_move_insn (operands[0], out);
4632      DONE;
4633    }
4636 ;; Signed conversion to SImode.
4638 (define_expand "fix_truncxfsi2"
4639   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4640                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4641               (clobber (reg:CC FLAGS_REG))])]
4642   "TARGET_80387"
4644   if (TARGET_FISTTP)
4645    {
4646      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4647      DONE;
4648    }
4651 (define_expand "fix_trunc<mode>si2"
4652   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4653                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4654               (clobber (reg:CC FLAGS_REG))])]
4655   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4657   if (TARGET_FISTTP
4658       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4659    {
4660      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4661      DONE;
4662    }
4663   if (SSE_FLOAT_MODE_P (<MODE>mode))
4664    {
4665      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4666      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4667      if (out != operands[0])
4668         emit_move_insn (operands[0], out);
4669      DONE;
4670    }
4673 ;; Signed conversion to HImode.
4675 (define_expand "fix_trunc<mode>hi2"
4676   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4677                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4678               (clobber (reg:CC FLAGS_REG))])]
4679   "TARGET_80387
4680    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4682   if (TARGET_FISTTP)
4683    {
4684      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4685      DONE;
4686    }
4689 ;; Unsigned conversion to SImode.
4691 (define_expand "fixuns_trunc<mode>si2"
4692   [(parallel
4693     [(set (match_operand:SI 0 "register_operand" "")
4694           (unsigned_fix:SI
4695             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4696      (use (match_dup 2))
4697      (clobber (match_scratch:<ssevecmode> 3 ""))
4698      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4699   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4701   enum machine_mode mode = <MODE>mode;
4702   enum machine_mode vecmode = <ssevecmode>mode;
4703   REAL_VALUE_TYPE TWO31r;
4704   rtx two31;
4706   if (optimize_insn_for_size_p ())
4707     FAIL;
4709   real_ldexp (&TWO31r, &dconst1, 31);
4710   two31 = const_double_from_real_value (TWO31r, mode);
4711   two31 = ix86_build_const_vector (mode, true, two31);
4712   operands[2] = force_reg (vecmode, two31);
4715 (define_insn_and_split "*fixuns_trunc<mode>_1"
4716   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4717         (unsigned_fix:SI
4718           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4719    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4720    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4721    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4722   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4723    && optimize_function_for_speed_p (cfun)"
4724   "#"
4725   "&& reload_completed"
4726   [(const_int 0)]
4728   ix86_split_convert_uns_si_sse (operands);
4729   DONE;
4732 ;; Unsigned conversion to HImode.
4733 ;; Without these patterns, we'll try the unsigned SI conversion which
4734 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4736 (define_expand "fixuns_trunc<mode>hi2"
4737   [(set (match_dup 2)
4738         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4739    (set (match_operand:HI 0 "nonimmediate_operand" "")
4740         (subreg:HI (match_dup 2) 0))]
4741   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4742   "operands[2] = gen_reg_rtx (SImode);")
4744 ;; When SSE is available, it is always faster to use it!
4745 (define_insn "fix_trunc<mode>di_sse"
4746   [(set (match_operand:DI 0 "register_operand" "=r,r")
4747         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4748   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4749    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4750   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4751   [(set_attr "type" "sseicvt")
4752    (set_attr "prefix" "maybe_vex")
4753    (set_attr "mode" "<MODE>")
4754    (set_attr "athlon_decode" "double,vector")
4755    (set_attr "amdfam10_decode" "double,double")])
4757 (define_insn "fix_trunc<mode>si_sse"
4758   [(set (match_operand:SI 0 "register_operand" "=r,r")
4759         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4760   "SSE_FLOAT_MODE_P (<MODE>mode)
4761    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4762   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4763   [(set_attr "type" "sseicvt")
4764    (set_attr "prefix" "maybe_vex")
4765    (set_attr "mode" "<MODE>")
4766    (set_attr "athlon_decode" "double,vector")
4767    (set_attr "amdfam10_decode" "double,double")])
4769 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4770 (define_peephole2
4771   [(set (match_operand:MODEF 0 "register_operand" "")
4772         (match_operand:MODEF 1 "memory_operand" ""))
4773    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4774         (fix:SSEMODEI24 (match_dup 0)))]
4775   "TARGET_SHORTEN_X87_SSE
4776    && peep2_reg_dead_p (2, operands[0])"
4777   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4778   "")
4780 ;; Avoid vector decoded forms of the instruction.
4781 (define_peephole2
4782   [(match_scratch:DF 2 "Y2")
4783    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4784         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4785   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4786   [(set (match_dup 2) (match_dup 1))
4787    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4788   "")
4790 (define_peephole2
4791   [(match_scratch:SF 2 "x")
4792    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4793         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4794   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4795   [(set (match_dup 2) (match_dup 1))
4796    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4797   "")
4799 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4800   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4801         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4802   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4803    && TARGET_FISTTP
4804    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4805          && (TARGET_64BIT || <MODE>mode != DImode))
4806         && TARGET_SSE_MATH)
4807    && !(reload_completed || reload_in_progress)"
4808   "#"
4809   "&& 1"
4810   [(const_int 0)]
4812   if (memory_operand (operands[0], VOIDmode))
4813     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4814   else
4815     {
4816       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4817       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4818                                                             operands[1],
4819                                                             operands[2]));
4820     }
4821   DONE;
4823   [(set_attr "type" "fisttp")
4824    (set_attr "mode" "<MODE>")])
4826 (define_insn "fix_trunc<mode>_i387_fisttp"
4827   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4828         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4829    (clobber (match_scratch:XF 2 "=&1f"))]
4830   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4831    && TARGET_FISTTP
4832    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4833          && (TARGET_64BIT || <MODE>mode != DImode))
4834         && TARGET_SSE_MATH)"
4835   "* return output_fix_trunc (insn, operands, 1);"
4836   [(set_attr "type" "fisttp")
4837    (set_attr "mode" "<MODE>")])
4839 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4840   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4841         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4842    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4843    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4844   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4845    && TARGET_FISTTP
4846    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4847         && (TARGET_64BIT || <MODE>mode != DImode))
4848         && TARGET_SSE_MATH)"
4849   "#"
4850   [(set_attr "type" "fisttp")
4851    (set_attr "mode" "<MODE>")])
4853 (define_split
4854   [(set (match_operand:X87MODEI 0 "register_operand" "")
4855         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4856    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4857    (clobber (match_scratch 3 ""))]
4858   "reload_completed"
4859   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4860               (clobber (match_dup 3))])
4861    (set (match_dup 0) (match_dup 2))]
4862   "")
4864 (define_split
4865   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4866         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4867    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4868    (clobber (match_scratch 3 ""))]
4869   "reload_completed"
4870   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4871               (clobber (match_dup 3))])]
4872   "")
4874 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4875 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4876 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4877 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4878 ;; function in i386.c.
4879 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4880   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4881         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4882    (clobber (reg:CC FLAGS_REG))]
4883   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4884    && !TARGET_FISTTP
4885    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4886          && (TARGET_64BIT || <MODE>mode != DImode))
4887    && !(reload_completed || reload_in_progress)"
4888   "#"
4889   "&& 1"
4890   [(const_int 0)]
4892   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4894   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4895   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4896   if (memory_operand (operands[0], VOIDmode))
4897     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4898                                          operands[2], operands[3]));
4899   else
4900     {
4901       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4902       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4903                                                      operands[2], operands[3],
4904                                                      operands[4]));
4905     }
4906   DONE;
4908   [(set_attr "type" "fistp")
4909    (set_attr "i387_cw" "trunc")
4910    (set_attr "mode" "<MODE>")])
4912 (define_insn "fix_truncdi_i387"
4913   [(set (match_operand:DI 0 "memory_operand" "=m")
4914         (fix:DI (match_operand 1 "register_operand" "f")))
4915    (use (match_operand:HI 2 "memory_operand" "m"))
4916    (use (match_operand:HI 3 "memory_operand" "m"))
4917    (clobber (match_scratch:XF 4 "=&1f"))]
4918   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4919    && !TARGET_FISTTP
4920    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4921   "* return output_fix_trunc (insn, operands, 0);"
4922   [(set_attr "type" "fistp")
4923    (set_attr "i387_cw" "trunc")
4924    (set_attr "mode" "DI")])
4926 (define_insn "fix_truncdi_i387_with_temp"
4927   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4928         (fix:DI (match_operand 1 "register_operand" "f,f")))
4929    (use (match_operand:HI 2 "memory_operand" "m,m"))
4930    (use (match_operand:HI 3 "memory_operand" "m,m"))
4931    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4932    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4933   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4934    && !TARGET_FISTTP
4935    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4936   "#"
4937   [(set_attr "type" "fistp")
4938    (set_attr "i387_cw" "trunc")
4939    (set_attr "mode" "DI")])
4941 (define_split
4942   [(set (match_operand:DI 0 "register_operand" "")
4943         (fix:DI (match_operand 1 "register_operand" "")))
4944    (use (match_operand:HI 2 "memory_operand" ""))
4945    (use (match_operand:HI 3 "memory_operand" ""))
4946    (clobber (match_operand:DI 4 "memory_operand" ""))
4947    (clobber (match_scratch 5 ""))]
4948   "reload_completed"
4949   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4950               (use (match_dup 2))
4951               (use (match_dup 3))
4952               (clobber (match_dup 5))])
4953    (set (match_dup 0) (match_dup 4))]
4954   "")
4956 (define_split
4957   [(set (match_operand:DI 0 "memory_operand" "")
4958         (fix:DI (match_operand 1 "register_operand" "")))
4959    (use (match_operand:HI 2 "memory_operand" ""))
4960    (use (match_operand:HI 3 "memory_operand" ""))
4961    (clobber (match_operand:DI 4 "memory_operand" ""))
4962    (clobber (match_scratch 5 ""))]
4963   "reload_completed"
4964   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4965               (use (match_dup 2))
4966               (use (match_dup 3))
4967               (clobber (match_dup 5))])]
4968   "")
4970 (define_insn "fix_trunc<mode>_i387"
4971   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4972         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4973    (use (match_operand:HI 2 "memory_operand" "m"))
4974    (use (match_operand:HI 3 "memory_operand" "m"))]
4975   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4976    && !TARGET_FISTTP
4977    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4978   "* return output_fix_trunc (insn, operands, 0);"
4979   [(set_attr "type" "fistp")
4980    (set_attr "i387_cw" "trunc")
4981    (set_attr "mode" "<MODE>")])
4983 (define_insn "fix_trunc<mode>_i387_with_temp"
4984   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4985         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4986    (use (match_operand:HI 2 "memory_operand" "m,m"))
4987    (use (match_operand:HI 3 "memory_operand" "m,m"))
4988    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4989   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4990    && !TARGET_FISTTP
4991    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4992   "#"
4993   [(set_attr "type" "fistp")
4994    (set_attr "i387_cw" "trunc")
4995    (set_attr "mode" "<MODE>")])
4997 (define_split
4998   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4999         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5000    (use (match_operand:HI 2 "memory_operand" ""))
5001    (use (match_operand:HI 3 "memory_operand" ""))
5002    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5003   "reload_completed"
5004   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5005               (use (match_dup 2))
5006               (use (match_dup 3))])
5007    (set (match_dup 0) (match_dup 4))]
5008   "")
5010 (define_split
5011   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5012         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5013    (use (match_operand:HI 2 "memory_operand" ""))
5014    (use (match_operand:HI 3 "memory_operand" ""))
5015    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5016   "reload_completed"
5017   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5018               (use (match_dup 2))
5019               (use (match_dup 3))])]
5020   "")
5022 (define_insn "x86_fnstcw_1"
5023   [(set (match_operand:HI 0 "memory_operand" "=m")
5024         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5025   "TARGET_80387"
5026   "fnstcw\t%0"
5027   [(set_attr "length" "2")
5028    (set_attr "mode" "HI")
5029    (set_attr "unit" "i387")])
5031 (define_insn "x86_fldcw_1"
5032   [(set (reg:HI FPCR_REG)
5033         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5034   "TARGET_80387"
5035   "fldcw\t%0"
5036   [(set_attr "length" "2")
5037    (set_attr "mode" "HI")
5038    (set_attr "unit" "i387")
5039    (set_attr "athlon_decode" "vector")
5040    (set_attr "amdfam10_decode" "vector")])
5042 ;; Conversion between fixed point and floating point.
5044 ;; Even though we only accept memory inputs, the backend _really_
5045 ;; wants to be able to do this between registers.
5047 (define_expand "floathi<mode>2"
5048   [(set (match_operand:X87MODEF 0 "register_operand" "")
5049         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5050   "TARGET_80387
5051    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5052        || TARGET_MIX_SSE_I387)"
5053   "")
5055 ;; Pre-reload splitter to add memory clobber to the pattern.
5056 (define_insn_and_split "*floathi<mode>2_1"
5057   [(set (match_operand:X87MODEF 0 "register_operand" "")
5058         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5059   "TARGET_80387
5060    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5061        || TARGET_MIX_SSE_I387)
5062    && !(reload_completed || reload_in_progress)"
5063   "#"
5064   "&& 1"
5065   [(parallel [(set (match_dup 0)
5066               (float:X87MODEF (match_dup 1)))
5067    (clobber (match_dup 2))])]
5068   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5070 (define_insn "*floathi<mode>2_i387_with_temp"
5071   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5072         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5073   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5074   "TARGET_80387
5075    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5076        || TARGET_MIX_SSE_I387)"
5077   "#"
5078   [(set_attr "type" "fmov,multi")
5079    (set_attr "mode" "<MODE>")
5080    (set_attr "unit" "*,i387")
5081    (set_attr "fp_int_src" "true")])
5083 (define_insn "*floathi<mode>2_i387"
5084   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5085         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5086   "TARGET_80387
5087    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5088        || TARGET_MIX_SSE_I387)"
5089   "fild%z1\t%1"
5090   [(set_attr "type" "fmov")
5091    (set_attr "mode" "<MODE>")
5092    (set_attr "fp_int_src" "true")])
5094 (define_split
5095   [(set (match_operand:X87MODEF 0 "register_operand" "")
5096         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5097    (clobber (match_operand:HI 2 "memory_operand" ""))]
5098   "TARGET_80387
5099    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5100        || TARGET_MIX_SSE_I387)
5101    && reload_completed"
5102   [(set (match_dup 2) (match_dup 1))
5103    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5104   "")
5106 (define_split
5107   [(set (match_operand:X87MODEF 0 "register_operand" "")
5108         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5109    (clobber (match_operand:HI 2 "memory_operand" ""))]
5110    "TARGET_80387
5111     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5112         || TARGET_MIX_SSE_I387)
5113     && reload_completed"
5114   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5115   "")
5117 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5118   [(set (match_operand:X87MODEF 0 "register_operand" "")
5119         (float:X87MODEF
5120           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5121   "TARGET_80387
5122    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5123        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5124   "")
5126 ;; Pre-reload splitter to add memory clobber to the pattern.
5127 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5128   [(set (match_operand:X87MODEF 0 "register_operand" "")
5129         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5130   "((TARGET_80387
5131      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5132            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5133          || TARGET_MIX_SSE_I387))
5134     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5135         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5136         && ((<SSEMODEI24:MODE>mode == SImode
5137              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5138              && optimize_function_for_speed_p (cfun)
5139              && flag_trapping_math)
5140             || !(TARGET_INTER_UNIT_CONVERSIONS
5141                  || optimize_function_for_size_p (cfun)))))
5142    && !(reload_completed || reload_in_progress)"
5143   "#"
5144   "&& 1"
5145   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5146               (clobber (match_dup 2))])]
5148   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5150   /* Avoid store forwarding (partial memory) stall penalty
5151      by passing DImode value through XMM registers.  */
5152   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5153       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5154       && optimize_function_for_speed_p (cfun))
5155     {
5156       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5157                                                             operands[1],
5158                                                             operands[2]));
5159       DONE;
5160     }
5163 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5164   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5165         (float:MODEF
5166           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5167    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5168   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5169    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5170   "#"
5171   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5172    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5173    (set_attr "unit" "*,i387,*,*,*")
5174    (set_attr "athlon_decode" "*,*,double,direct,double")
5175    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5176    (set_attr "fp_int_src" "true")])
5178 (define_insn "*floatsi<mode>2_vector_mixed"
5179   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5180         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5181   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5182    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5183   "@
5184    fild%z1\t%1
5185    #"
5186   [(set_attr "type" "fmov,sseicvt")
5187    (set_attr "mode" "<MODE>,<ssevecmode>")
5188    (set_attr "unit" "i387,*")
5189    (set_attr "athlon_decode" "*,direct")
5190    (set_attr "amdfam10_decode" "*,double")
5191    (set_attr "fp_int_src" "true")])
5193 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5194   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5195         (float:MODEF
5196           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5197   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5198   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5199    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5200   "#"
5201   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5202    (set_attr "mode" "<MODEF:MODE>")
5203    (set_attr "unit" "*,i387,*,*")
5204    (set_attr "athlon_decode" "*,*,double,direct")
5205    (set_attr "amdfam10_decode" "*,*,vector,double")
5206    (set_attr "fp_int_src" "true")])
5208 (define_split
5209   [(set (match_operand:MODEF 0 "register_operand" "")
5210         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5211    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5212   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5213    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5214    && TARGET_INTER_UNIT_CONVERSIONS
5215    && reload_completed
5216    && (SSE_REG_P (operands[0])
5217        || (GET_CODE (operands[0]) == SUBREG
5218            && SSE_REG_P (operands[0])))"
5219   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5220   "")
5222 (define_split
5223   [(set (match_operand:MODEF 0 "register_operand" "")
5224         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5225    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5226   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5227    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5228    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5229    && reload_completed
5230    && (SSE_REG_P (operands[0])
5231        || (GET_CODE (operands[0]) == SUBREG
5232            && SSE_REG_P (operands[0])))"
5233   [(set (match_dup 2) (match_dup 1))
5234    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5235   "")
5237 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5238   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5239         (float:MODEF
5240           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5241   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5242    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5243    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5244   "@
5245    fild%z1\t%1
5246    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5247    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5248   [(set_attr "type" "fmov,sseicvt,sseicvt")
5249    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5250    (set_attr "mode" "<MODEF:MODE>")
5251    (set_attr "unit" "i387,*,*")
5252    (set_attr "athlon_decode" "*,double,direct")
5253    (set_attr "amdfam10_decode" "*,vector,double")
5254    (set_attr "fp_int_src" "true")])
5256 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5257   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5258         (float:MODEF
5259           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5260   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5261    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5262    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5263   "@
5264    fild%z1\t%1
5265    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5266   [(set_attr "type" "fmov,sseicvt")
5267    (set_attr "prefix" "orig,maybe_vex")
5268    (set_attr "mode" "<MODEF:MODE>")
5269    (set_attr "athlon_decode" "*,direct")
5270    (set_attr "amdfam10_decode" "*,double")
5271    (set_attr "fp_int_src" "true")])
5273 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5274   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5275         (float:MODEF
5276           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5277    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5278   "TARGET_SSE2 && TARGET_SSE_MATH
5279    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5280   "#"
5281   [(set_attr "type" "sseicvt")
5282    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5283    (set_attr "athlon_decode" "double,direct,double")
5284    (set_attr "amdfam10_decode" "vector,double,double")
5285    (set_attr "fp_int_src" "true")])
5287 (define_insn "*floatsi<mode>2_vector_sse"
5288   [(set (match_operand:MODEF 0 "register_operand" "=x")
5289         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5290   "TARGET_SSE2 && TARGET_SSE_MATH
5291    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5292   "#"
5293   [(set_attr "type" "sseicvt")
5294    (set_attr "mode" "<MODE>")
5295    (set_attr "athlon_decode" "direct")
5296    (set_attr "amdfam10_decode" "double")
5297    (set_attr "fp_int_src" "true")])
5299 (define_split
5300   [(set (match_operand:MODEF 0 "register_operand" "")
5301         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5302    (clobber (match_operand:SI 2 "memory_operand" ""))]
5303   "TARGET_SSE2 && TARGET_SSE_MATH
5304    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5305    && reload_completed
5306    && (SSE_REG_P (operands[0])
5307        || (GET_CODE (operands[0]) == SUBREG
5308            && SSE_REG_P (operands[0])))"
5309   [(const_int 0)]
5311   rtx op1 = operands[1];
5313   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5314                                      <MODE>mode, 0);
5315   if (GET_CODE (op1) == SUBREG)
5316     op1 = SUBREG_REG (op1);
5318   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5319     {
5320       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5321       emit_insn (gen_sse2_loadld (operands[4],
5322                                   CONST0_RTX (V4SImode), operands[1]));
5323     }
5324   /* We can ignore possible trapping value in the
5325      high part of SSE register for non-trapping math. */
5326   else if (SSE_REG_P (op1) && !flag_trapping_math)
5327     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5328   else
5329     {
5330       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5331       emit_move_insn (operands[2], operands[1]);
5332       emit_insn (gen_sse2_loadld (operands[4],
5333                                   CONST0_RTX (V4SImode), operands[2]));
5334     }
5335   emit_insn
5336     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5337   DONE;
5340 (define_split
5341   [(set (match_operand:MODEF 0 "register_operand" "")
5342         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5343    (clobber (match_operand:SI 2 "memory_operand" ""))]
5344   "TARGET_SSE2 && TARGET_SSE_MATH
5345    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5346    && reload_completed
5347    && (SSE_REG_P (operands[0])
5348        || (GET_CODE (operands[0]) == SUBREG
5349            && SSE_REG_P (operands[0])))"
5350   [(const_int 0)]
5352   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5353                                      <MODE>mode, 0);
5354   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5356   emit_insn (gen_sse2_loadld (operands[4],
5357                               CONST0_RTX (V4SImode), operands[1]));
5358   emit_insn
5359     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5360   DONE;
5363 (define_split
5364   [(set (match_operand:MODEF 0 "register_operand" "")
5365         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5366   "TARGET_SSE2 && TARGET_SSE_MATH
5367    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5368    && reload_completed
5369    && (SSE_REG_P (operands[0])
5370        || (GET_CODE (operands[0]) == SUBREG
5371            && SSE_REG_P (operands[0])))"
5372   [(const_int 0)]
5374   rtx op1 = operands[1];
5376   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5377                                      <MODE>mode, 0);
5378   if (GET_CODE (op1) == SUBREG)
5379     op1 = SUBREG_REG (op1);
5381   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5382     {
5383       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5384       emit_insn (gen_sse2_loadld (operands[4],
5385                                   CONST0_RTX (V4SImode), operands[1]));
5386     }
5387   /* We can ignore possible trapping value in the
5388      high part of SSE register for non-trapping math. */
5389   else if (SSE_REG_P (op1) && !flag_trapping_math)
5390     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5391   else
5392     gcc_unreachable ();
5393   emit_insn
5394     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5395   DONE;
5398 (define_split
5399   [(set (match_operand:MODEF 0 "register_operand" "")
5400         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5401   "TARGET_SSE2 && TARGET_SSE_MATH
5402    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5403    && reload_completed
5404    && (SSE_REG_P (operands[0])
5405        || (GET_CODE (operands[0]) == SUBREG
5406            && SSE_REG_P (operands[0])))"
5407   [(const_int 0)]
5409   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5410                                      <MODE>mode, 0);
5411   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5413   emit_insn (gen_sse2_loadld (operands[4],
5414                               CONST0_RTX (V4SImode), operands[1]));
5415   emit_insn
5416     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5417   DONE;
5420 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5421   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5422         (float:MODEF
5423           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5424   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5425   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5426    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5427   "#"
5428   [(set_attr "type" "sseicvt")
5429    (set_attr "mode" "<MODEF:MODE>")
5430    (set_attr "athlon_decode" "double,direct")
5431    (set_attr "amdfam10_decode" "vector,double")
5432    (set_attr "fp_int_src" "true")])
5434 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5435   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5436         (float:MODEF
5437           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5438   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5439    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5440    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5441   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5442   [(set_attr "type" "sseicvt")
5443    (set_attr "prefix" "maybe_vex")
5444    (set_attr "mode" "<MODEF:MODE>")
5445    (set_attr "athlon_decode" "double,direct")
5446    (set_attr "amdfam10_decode" "vector,double")
5447    (set_attr "fp_int_src" "true")])
5449 (define_split
5450   [(set (match_operand:MODEF 0 "register_operand" "")
5451         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5452    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5453   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5454    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5455    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5456    && reload_completed
5457    && (SSE_REG_P (operands[0])
5458        || (GET_CODE (operands[0]) == SUBREG
5459            && SSE_REG_P (operands[0])))"
5460   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5461   "")
5463 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5464   [(set (match_operand:MODEF 0 "register_operand" "=x")
5465         (float:MODEF
5466           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5467   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5468    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5469    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5470   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5471   [(set_attr "type" "sseicvt")
5472    (set_attr "prefix" "maybe_vex")
5473    (set_attr "mode" "<MODEF:MODE>")
5474    (set_attr "athlon_decode" "direct")
5475    (set_attr "amdfam10_decode" "double")
5476    (set_attr "fp_int_src" "true")])
5478 (define_split
5479   [(set (match_operand:MODEF 0 "register_operand" "")
5480         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5481    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5482   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5483    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5484    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5485    && reload_completed
5486    && (SSE_REG_P (operands[0])
5487        || (GET_CODE (operands[0]) == SUBREG
5488            && SSE_REG_P (operands[0])))"
5489   [(set (match_dup 2) (match_dup 1))
5490    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5491   "")
5493 (define_split
5494   [(set (match_operand:MODEF 0 "register_operand" "")
5495         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5496    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5497   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5498    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5499    && reload_completed
5500    && (SSE_REG_P (operands[0])
5501        || (GET_CODE (operands[0]) == SUBREG
5502            && SSE_REG_P (operands[0])))"
5503   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5504   "")
5506 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5507   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5508         (float:X87MODEF
5509           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5510   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5511   "TARGET_80387"
5512   "@
5513    fild%z1\t%1
5514    #"
5515   [(set_attr "type" "fmov,multi")
5516    (set_attr "mode" "<X87MODEF:MODE>")
5517    (set_attr "unit" "*,i387")
5518    (set_attr "fp_int_src" "true")])
5520 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5521   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5522         (float:X87MODEF
5523           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5524   "TARGET_80387"
5525   "fild%z1\t%1"
5526   [(set_attr "type" "fmov")
5527    (set_attr "mode" "<X87MODEF:MODE>")
5528    (set_attr "fp_int_src" "true")])
5530 (define_split
5531   [(set (match_operand:X87MODEF 0 "register_operand" "")
5532         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5533    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5534   "TARGET_80387
5535    && reload_completed
5536    && FP_REG_P (operands[0])"
5537   [(set (match_dup 2) (match_dup 1))
5538    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5539   "")
5541 (define_split
5542   [(set (match_operand:X87MODEF 0 "register_operand" "")
5543         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5544    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5545   "TARGET_80387
5546    && reload_completed
5547    && FP_REG_P (operands[0])"
5548   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5549   "")
5551 ;; Avoid store forwarding (partial memory) stall penalty
5552 ;; by passing DImode value through XMM registers.  */
5554 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5555   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5556         (float:X87MODEF
5557           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5558    (clobber (match_scratch:V4SI 3 "=X,x"))
5559    (clobber (match_scratch:V4SI 4 "=X,x"))
5560    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5561   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5562    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5563   "#"
5564   [(set_attr "type" "multi")
5565    (set_attr "mode" "<X87MODEF:MODE>")
5566    (set_attr "unit" "i387")
5567    (set_attr "fp_int_src" "true")])
5569 (define_split
5570   [(set (match_operand:X87MODEF 0 "register_operand" "")
5571         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5572    (clobber (match_scratch:V4SI 3 ""))
5573    (clobber (match_scratch:V4SI 4 ""))
5574    (clobber (match_operand:DI 2 "memory_operand" ""))]
5575   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5576    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5577    && reload_completed
5578    && FP_REG_P (operands[0])"
5579   [(set (match_dup 2) (match_dup 3))
5580    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5582   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5583      Assemble the 64-bit DImode value in an xmm register.  */
5584   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5585                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5586   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5587                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5588   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5590   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5593 (define_split
5594   [(set (match_operand:X87MODEF 0 "register_operand" "")
5595         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5596    (clobber (match_scratch:V4SI 3 ""))
5597    (clobber (match_scratch:V4SI 4 ""))
5598    (clobber (match_operand:DI 2 "memory_operand" ""))]
5599   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5600    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5601    && reload_completed
5602    && FP_REG_P (operands[0])"
5603   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5604   "")
5606 ;; Avoid store forwarding (partial memory) stall penalty by extending
5607 ;; SImode value to DImode through XMM register instead of pushing two
5608 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5609 ;; targets benefit from this optimization. Also note that fild
5610 ;; loads from memory only.
5612 (define_insn "*floatunssi<mode>2_1"
5613   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5614         (unsigned_float:X87MODEF
5615           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5616    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5617    (clobber (match_scratch:SI 3 "=X,x"))]
5618   "!TARGET_64BIT
5619    && TARGET_80387 && TARGET_SSE"
5620   "#"
5621   [(set_attr "type" "multi")
5622    (set_attr "mode" "<MODE>")])
5624 (define_split
5625   [(set (match_operand:X87MODEF 0 "register_operand" "")
5626         (unsigned_float:X87MODEF
5627           (match_operand:SI 1 "register_operand" "")))
5628    (clobber (match_operand:DI 2 "memory_operand" ""))
5629    (clobber (match_scratch:SI 3 ""))]
5630   "!TARGET_64BIT
5631    && TARGET_80387 && TARGET_SSE
5632    && reload_completed"
5633   [(set (match_dup 2) (match_dup 1))
5634    (set (match_dup 0)
5635         (float:X87MODEF (match_dup 2)))]
5636   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5638 (define_split
5639   [(set (match_operand:X87MODEF 0 "register_operand" "")
5640         (unsigned_float:X87MODEF
5641           (match_operand:SI 1 "memory_operand" "")))
5642    (clobber (match_operand:DI 2 "memory_operand" ""))
5643    (clobber (match_scratch:SI 3 ""))]
5644   "!TARGET_64BIT
5645    && TARGET_80387 && TARGET_SSE
5646    && reload_completed"
5647   [(set (match_dup 2) (match_dup 3))
5648    (set (match_dup 0)
5649         (float:X87MODEF (match_dup 2)))]
5651   emit_move_insn (operands[3], operands[1]);
5652   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5655 (define_expand "floatunssi<mode>2"
5656   [(parallel
5657      [(set (match_operand:X87MODEF 0 "register_operand" "")
5658            (unsigned_float:X87MODEF
5659              (match_operand:SI 1 "nonimmediate_operand" "")))
5660       (clobber (match_dup 2))
5661       (clobber (match_scratch:SI 3 ""))])]
5662   "!TARGET_64BIT
5663    && ((TARGET_80387 && TARGET_SSE)
5664        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5666   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5667     {
5668       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5669       DONE;
5670     }
5671   else
5672     {
5673       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5674       operands[2] = assign_386_stack_local (DImode, slot);
5675     }
5678 (define_expand "floatunsdisf2"
5679   [(use (match_operand:SF 0 "register_operand" ""))
5680    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5681   "TARGET_64BIT && TARGET_SSE_MATH"
5682   "x86_emit_floatuns (operands); DONE;")
5684 (define_expand "floatunsdidf2"
5685   [(use (match_operand:DF 0 "register_operand" ""))
5686    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5687   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5688    && TARGET_SSE2 && TARGET_SSE_MATH"
5690   if (TARGET_64BIT)
5691     x86_emit_floatuns (operands);
5692   else
5693     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5694   DONE;
5697 ;; Add instructions
5699 ;; %%% splits for addditi3
5701 (define_expand "addti3"
5702   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5703         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5704                  (match_operand:TI 2 "x86_64_general_operand" "")))]
5705   "TARGET_64BIT"
5706   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5708 (define_insn "*addti3_1"
5709   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5710         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5711                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5712    (clobber (reg:CC FLAGS_REG))]
5713   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5714   "#")
5716 (define_split
5717   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5718         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5719                  (match_operand:TI 2 "x86_64_general_operand" "")))
5720    (clobber (reg:CC FLAGS_REG))]
5721   "TARGET_64BIT && reload_completed"
5722   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5723                                           UNSPEC_ADD_CARRY))
5724               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5725    (parallel [(set (match_dup 3)
5726                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5727                                      (match_dup 4))
5728                             (match_dup 5)))
5729               (clobber (reg:CC FLAGS_REG))])]
5730   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5732 ;; %%% splits for addsidi3
5733 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5734 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5735 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5737 (define_expand "adddi3"
5738   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5739         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5740                  (match_operand:DI 2 "x86_64_general_operand" "")))]
5741   ""
5742   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5744 (define_insn "*adddi3_1"
5745   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5746         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5747                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5748    (clobber (reg:CC FLAGS_REG))]
5749   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5750   "#")
5752 (define_split
5753   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5754         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5755                  (match_operand:DI 2 "general_operand" "")))
5756    (clobber (reg:CC FLAGS_REG))]
5757   "!TARGET_64BIT && reload_completed"
5758   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5759                                           UNSPEC_ADD_CARRY))
5760               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5761    (parallel [(set (match_dup 3)
5762                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5763                                      (match_dup 4))
5764                             (match_dup 5)))
5765               (clobber (reg:CC FLAGS_REG))])]
5766   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5768 (define_insn "adddi3_carry_rex64"
5769   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5770           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5771                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5772                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5773    (clobber (reg:CC FLAGS_REG))]
5774   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5775   "adc{q}\t{%2, %0|%0, %2}"
5776   [(set_attr "type" "alu")
5777    (set_attr "pent_pair" "pu")
5778    (set_attr "mode" "DI")])
5780 (define_insn "*adddi3_cc_rex64"
5781   [(set (reg:CC FLAGS_REG)
5782         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5783                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5784                    UNSPEC_ADD_CARRY))
5785    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5786         (plus:DI (match_dup 1) (match_dup 2)))]
5787   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5788   "add{q}\t{%2, %0|%0, %2}"
5789   [(set_attr "type" "alu")
5790    (set_attr "mode" "DI")])
5792 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5793   [(set (reg:CCC FLAGS_REG)
5794         (compare:CCC
5795             (plusminus:SWI
5796                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5797                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5798             (match_dup 1)))
5799    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5800         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5801   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5802   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5803   [(set_attr "type" "alu")
5804    (set_attr "mode" "<MODE>")])
5806 (define_insn "*add<mode>3_cconly_overflow"
5807   [(set (reg:CCC FLAGS_REG)
5808         (compare:CCC
5809                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5810                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5811                 (match_dup 1)))
5812    (clobber (match_scratch:SWI 0 "=<r>"))]
5813   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5814   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5815   [(set_attr "type" "alu")
5816    (set_attr "mode" "<MODE>")])
5818 (define_insn "*sub<mode>3_cconly_overflow"
5819   [(set (reg:CCC FLAGS_REG)
5820         (compare:CCC
5821              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5822                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5823              (match_dup 0)))]
5824   ""
5825   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5826   [(set_attr "type" "icmp")
5827    (set_attr "mode" "<MODE>")])
5829 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5830   [(set (reg:CCC FLAGS_REG)
5831         (compare:CCC
5832             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5833                           (match_operand:SI 2 "general_operand" "g"))
5834             (match_dup 1)))
5835    (set (match_operand:DI 0 "register_operand" "=r")
5836         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5837   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5838   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5839   [(set_attr "type" "alu")
5840    (set_attr "mode" "SI")])
5842 (define_insn "addqi3_carry"
5843   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5844           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5845                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5846                    (match_operand:QI 2 "general_operand" "qn,qm")))
5847    (clobber (reg:CC FLAGS_REG))]
5848   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5849   "adc{b}\t{%2, %0|%0, %2}"
5850   [(set_attr "type" "alu")
5851    (set_attr "pent_pair" "pu")
5852    (set_attr "mode" "QI")])
5854 (define_insn "addhi3_carry"
5855   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5856           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5857                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5858                    (match_operand:HI 2 "general_operand" "rn,rm")))
5859    (clobber (reg:CC FLAGS_REG))]
5860   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5861   "adc{w}\t{%2, %0|%0, %2}"
5862   [(set_attr "type" "alu")
5863    (set_attr "pent_pair" "pu")
5864    (set_attr "mode" "HI")])
5866 (define_insn "addsi3_carry"
5867   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5868           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5869                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5870                    (match_operand:SI 2 "general_operand" "ri,rm")))
5871    (clobber (reg:CC FLAGS_REG))]
5872   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5873   "adc{l}\t{%2, %0|%0, %2}"
5874   [(set_attr "type" "alu")
5875    (set_attr "pent_pair" "pu")
5876    (set_attr "mode" "SI")])
5878 (define_insn "*addsi3_carry_zext"
5879   [(set (match_operand:DI 0 "register_operand" "=r")
5880           (zero_extend:DI
5881             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5882                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5883                      (match_operand:SI 2 "general_operand" "g"))))
5884    (clobber (reg:CC FLAGS_REG))]
5885   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5886   "adc{l}\t{%2, %k0|%k0, %2}"
5887   [(set_attr "type" "alu")
5888    (set_attr "pent_pair" "pu")
5889    (set_attr "mode" "SI")])
5891 (define_insn "*addsi3_cc"
5892   [(set (reg:CC FLAGS_REG)
5893         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5894                     (match_operand:SI 2 "general_operand" "ri,rm")]
5895                    UNSPEC_ADD_CARRY))
5896    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5897         (plus:SI (match_dup 1) (match_dup 2)))]
5898   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5899   "add{l}\t{%2, %0|%0, %2}"
5900   [(set_attr "type" "alu")
5901    (set_attr "mode" "SI")])
5903 (define_insn "addqi3_cc"
5904   [(set (reg:CC FLAGS_REG)
5905         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5906                     (match_operand:QI 2 "general_operand" "qn,qm")]
5907                    UNSPEC_ADD_CARRY))
5908    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5909         (plus:QI (match_dup 1) (match_dup 2)))]
5910   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5911   "add{b}\t{%2, %0|%0, %2}"
5912   [(set_attr "type" "alu")
5913    (set_attr "mode" "QI")])
5915 (define_expand "addsi3"
5916   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5917         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5918                  (match_operand:SI 2 "general_operand" "")))]
5919   ""
5920   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5922 (define_insn "*lea_1"
5923   [(set (match_operand:SI 0 "register_operand" "=r")
5924         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5925   "!TARGET_64BIT"
5926   "lea{l}\t{%a1, %0|%0, %a1}"
5927   [(set_attr "type" "lea")
5928    (set_attr "mode" "SI")])
5930 (define_insn "*lea_1_rex64"
5931   [(set (match_operand:SI 0 "register_operand" "=r")
5932         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5933   "TARGET_64BIT"
5934   "lea{l}\t{%a1, %0|%0, %a1}"
5935   [(set_attr "type" "lea")
5936    (set_attr "mode" "SI")])
5938 (define_insn "*lea_1_zext"
5939   [(set (match_operand:DI 0 "register_operand" "=r")
5940         (zero_extend:DI
5941          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5942   "TARGET_64BIT"
5943   "lea{l}\t{%a1, %k0|%k0, %a1}"
5944   [(set_attr "type" "lea")
5945    (set_attr "mode" "SI")])
5947 (define_insn "*lea_2_rex64"
5948   [(set (match_operand:DI 0 "register_operand" "=r")
5949         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5950   "TARGET_64BIT"
5951   "lea{q}\t{%a1, %0|%0, %a1}"
5952   [(set_attr "type" "lea")
5953    (set_attr "mode" "DI")])
5955 ;; The lea patterns for non-Pmodes needs to be matched by several
5956 ;; insns converted to real lea by splitters.
5958 (define_insn_and_split "*lea_general_1"
5959   [(set (match_operand 0 "register_operand" "=r")
5960         (plus (plus (match_operand 1 "index_register_operand" "l")
5961                     (match_operand 2 "register_operand" "r"))
5962               (match_operand 3 "immediate_operand" "i")))]
5963   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5964     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5965    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5966    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5967    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5968    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5969        || GET_MODE (operands[3]) == VOIDmode)"
5970   "#"
5971   "&& reload_completed"
5972   [(const_int 0)]
5974   rtx pat;
5975   operands[0] = gen_lowpart (SImode, operands[0]);
5976   operands[1] = gen_lowpart (Pmode, operands[1]);
5977   operands[2] = gen_lowpart (Pmode, operands[2]);
5978   operands[3] = gen_lowpart (Pmode, operands[3]);
5979   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5980                       operands[3]);
5981   if (Pmode != SImode)
5982     pat = gen_rtx_SUBREG (SImode, pat, 0);
5983   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5984   DONE;
5986   [(set_attr "type" "lea")
5987    (set_attr "mode" "SI")])
5989 (define_insn_and_split "*lea_general_1_zext"
5990   [(set (match_operand:DI 0 "register_operand" "=r")
5991         (zero_extend:DI
5992           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5993                             (match_operand:SI 2 "register_operand" "r"))
5994                    (match_operand:SI 3 "immediate_operand" "i"))))]
5995   "TARGET_64BIT"
5996   "#"
5997   "&& reload_completed"
5998   [(set (match_dup 0)
5999         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6000                                                      (match_dup 2))
6001                                             (match_dup 3)) 0)))]
6003   operands[1] = gen_lowpart (Pmode, operands[1]);
6004   operands[2] = gen_lowpart (Pmode, operands[2]);
6005   operands[3] = gen_lowpart (Pmode, operands[3]);
6007   [(set_attr "type" "lea")
6008    (set_attr "mode" "SI")])
6010 (define_insn_and_split "*lea_general_2"
6011   [(set (match_operand 0 "register_operand" "=r")
6012         (plus (mult (match_operand 1 "index_register_operand" "l")
6013                     (match_operand 2 "const248_operand" "i"))
6014               (match_operand 3 "nonmemory_operand" "ri")))]
6015   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6016     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6017    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6018    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6019    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6020        || GET_MODE (operands[3]) == VOIDmode)"
6021   "#"
6022   "&& reload_completed"
6023   [(const_int 0)]
6025   rtx pat;
6026   operands[0] = gen_lowpart (SImode, operands[0]);
6027   operands[1] = gen_lowpart (Pmode, operands[1]);
6028   operands[3] = gen_lowpart (Pmode, operands[3]);
6029   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6030                       operands[3]);
6031   if (Pmode != SImode)
6032     pat = gen_rtx_SUBREG (SImode, pat, 0);
6033   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6034   DONE;
6036   [(set_attr "type" "lea")
6037    (set_attr "mode" "SI")])
6039 (define_insn_and_split "*lea_general_2_zext"
6040   [(set (match_operand:DI 0 "register_operand" "=r")
6041         (zero_extend:DI
6042           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6043                             (match_operand:SI 2 "const248_operand" "n"))
6044                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6045   "TARGET_64BIT"
6046   "#"
6047   "&& reload_completed"
6048   [(set (match_dup 0)
6049         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6050                                                      (match_dup 2))
6051                                             (match_dup 3)) 0)))]
6053   operands[1] = gen_lowpart (Pmode, operands[1]);
6054   operands[3] = gen_lowpart (Pmode, operands[3]);
6056   [(set_attr "type" "lea")
6057    (set_attr "mode" "SI")])
6059 (define_insn_and_split "*lea_general_3"
6060   [(set (match_operand 0 "register_operand" "=r")
6061         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6062                           (match_operand 2 "const248_operand" "i"))
6063                     (match_operand 3 "register_operand" "r"))
6064               (match_operand 4 "immediate_operand" "i")))]
6065   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6066     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6067    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6068    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6069    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6070   "#"
6071   "&& reload_completed"
6072   [(const_int 0)]
6074   rtx pat;
6075   operands[0] = gen_lowpart (SImode, operands[0]);
6076   operands[1] = gen_lowpart (Pmode, operands[1]);
6077   operands[3] = gen_lowpart (Pmode, operands[3]);
6078   operands[4] = gen_lowpart (Pmode, operands[4]);
6079   pat = gen_rtx_PLUS (Pmode,
6080                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6081                                                          operands[2]),
6082                                     operands[3]),
6083                       operands[4]);
6084   if (Pmode != SImode)
6085     pat = gen_rtx_SUBREG (SImode, pat, 0);
6086   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6087   DONE;
6089   [(set_attr "type" "lea")
6090    (set_attr "mode" "SI")])
6092 (define_insn_and_split "*lea_general_3_zext"
6093   [(set (match_operand:DI 0 "register_operand" "=r")
6094         (zero_extend:DI
6095           (plus:SI (plus:SI (mult:SI
6096                               (match_operand:SI 1 "index_register_operand" "l")
6097                               (match_operand:SI 2 "const248_operand" "n"))
6098                             (match_operand:SI 3 "register_operand" "r"))
6099                    (match_operand:SI 4 "immediate_operand" "i"))))]
6100   "TARGET_64BIT"
6101   "#"
6102   "&& reload_completed"
6103   [(set (match_dup 0)
6104         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6105                                                               (match_dup 2))
6106                                                      (match_dup 3))
6107                                             (match_dup 4)) 0)))]
6109   operands[1] = gen_lowpart (Pmode, operands[1]);
6110   operands[3] = gen_lowpart (Pmode, operands[3]);
6111   operands[4] = gen_lowpart (Pmode, operands[4]);
6113   [(set_attr "type" "lea")
6114    (set_attr "mode" "SI")])
6116 (define_insn "*adddi_1_rex64"
6117   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
6118         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
6119                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
6120    (clobber (reg:CC FLAGS_REG))]
6121   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6123   switch (get_attr_type (insn))
6124     {
6125     case TYPE_LEA:
6126       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6127       return "lea{q}\t{%a2, %0|%0, %a2}";
6129     case TYPE_INCDEC:
6130       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6131       if (operands[2] == const1_rtx)
6132         return "inc{q}\t%0";
6133       else
6134         {
6135           gcc_assert (operands[2] == constm1_rtx);
6136           return "dec{q}\t%0";
6137         }
6139     default:
6140       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6142       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6143          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6144       if (CONST_INT_P (operands[2])
6145           /* Avoid overflows.  */
6146           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6147           && (INTVAL (operands[2]) == 128
6148               || (INTVAL (operands[2]) < 0
6149                   && INTVAL (operands[2]) != -128)))
6150         {
6151           operands[2] = GEN_INT (-INTVAL (operands[2]));
6152           return "sub{q}\t{%2, %0|%0, %2}";
6153         }
6154       return "add{q}\t{%2, %0|%0, %2}";
6155     }
6157   [(set (attr "type")
6158      (cond [(eq_attr "alternative" "2")
6159               (const_string "lea")
6160             ; Current assemblers are broken and do not allow @GOTOFF in
6161             ; ought but a memory context.
6162             (match_operand:DI 2 "pic_symbolic_operand" "")
6163               (const_string "lea")
6164             (match_operand:DI 2 "incdec_operand" "")
6165               (const_string "incdec")
6166            ]
6167            (const_string "alu")))
6168    (set_attr "mode" "DI")])
6170 ;; Convert lea to the lea pattern to avoid flags dependency.
6171 (define_split
6172   [(set (match_operand:DI 0 "register_operand" "")
6173         (plus:DI (match_operand:DI 1 "register_operand" "")
6174                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6175    (clobber (reg:CC FLAGS_REG))]
6176   "TARGET_64BIT && reload_completed
6177    && true_regnum (operands[0]) != true_regnum (operands[1])"
6178   [(set (match_dup 0)
6179         (plus:DI (match_dup 1)
6180                  (match_dup 2)))]
6181   "")
6183 (define_insn "*adddi_2_rex64"
6184   [(set (reg FLAGS_REG)
6185         (compare
6186           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6187                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6188           (const_int 0)))
6189    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6190         (plus:DI (match_dup 1) (match_dup 2)))]
6191   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6192    && ix86_binary_operator_ok (PLUS, DImode, operands)
6193    /* Current assemblers are broken and do not allow @GOTOFF in
6194       ought but a memory context.  */
6195    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6197   switch (get_attr_type (insn))
6198     {
6199     case TYPE_INCDEC:
6200       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6201       if (operands[2] == const1_rtx)
6202         return "inc{q}\t%0";
6203       else
6204         {
6205           gcc_assert (operands[2] == constm1_rtx);
6206           return "dec{q}\t%0";
6207         }
6209     default:
6210       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6211       /* ???? We ought to handle there the 32bit case too
6212          - do we need new constraint?  */
6213       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6214          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6215       if (CONST_INT_P (operands[2])
6216           /* Avoid overflows.  */
6217           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6218           && (INTVAL (operands[2]) == 128
6219               || (INTVAL (operands[2]) < 0
6220                   && INTVAL (operands[2]) != -128)))
6221         {
6222           operands[2] = GEN_INT (-INTVAL (operands[2]));
6223           return "sub{q}\t{%2, %0|%0, %2}";
6224         }
6225       return "add{q}\t{%2, %0|%0, %2}";
6226     }
6228   [(set (attr "type")
6229      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6230         (const_string "incdec")
6231         (const_string "alu")))
6232    (set_attr "mode" "DI")])
6234 (define_insn "*adddi_3_rex64"
6235   [(set (reg FLAGS_REG)
6236         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6237                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6238    (clobber (match_scratch:DI 0 "=r"))]
6239   "TARGET_64BIT
6240    && ix86_match_ccmode (insn, CCZmode)
6241    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6242    /* Current assemblers are broken and do not allow @GOTOFF in
6243       ought but a memory context.  */
6244    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6246   switch (get_attr_type (insn))
6247     {
6248     case TYPE_INCDEC:
6249       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6250       if (operands[2] == const1_rtx)
6251         return "inc{q}\t%0";
6252       else
6253         {
6254           gcc_assert (operands[2] == constm1_rtx);
6255           return "dec{q}\t%0";
6256         }
6258     default:
6259       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6260       /* ???? We ought to handle there the 32bit case too
6261          - do we need new constraint?  */
6262       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6263          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6264       if (CONST_INT_P (operands[2])
6265           /* Avoid overflows.  */
6266           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6267           && (INTVAL (operands[2]) == 128
6268               || (INTVAL (operands[2]) < 0
6269                   && INTVAL (operands[2]) != -128)))
6270         {
6271           operands[2] = GEN_INT (-INTVAL (operands[2]));
6272           return "sub{q}\t{%2, %0|%0, %2}";
6273         }
6274       return "add{q}\t{%2, %0|%0, %2}";
6275     }
6277   [(set (attr "type")
6278      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6279         (const_string "incdec")
6280         (const_string "alu")))
6281    (set_attr "mode" "DI")])
6283 ; For comparisons against 1, -1 and 128, we may generate better code
6284 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6285 ; is matched then.  We can't accept general immediate, because for
6286 ; case of overflows,  the result is messed up.
6287 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6288 ; when negated.
6289 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6290 ; only for comparisons not depending on it.
6291 (define_insn "*adddi_4_rex64"
6292   [(set (reg FLAGS_REG)
6293         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6294                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6295    (clobber (match_scratch:DI 0 "=rm"))]
6296   "TARGET_64BIT
6297    &&  ix86_match_ccmode (insn, CCGCmode)"
6299   switch (get_attr_type (insn))
6300     {
6301     case TYPE_INCDEC:
6302       if (operands[2] == constm1_rtx)
6303         return "inc{q}\t%0";
6304       else
6305         {
6306           gcc_assert (operands[2] == const1_rtx);
6307           return "dec{q}\t%0";
6308         }
6310     default:
6311       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6312       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6313          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6314       if ((INTVAL (operands[2]) == -128
6315            || (INTVAL (operands[2]) > 0
6316                && INTVAL (operands[2]) != 128))
6317           /* Avoid overflows.  */
6318           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6319         return "sub{q}\t{%2, %0|%0, %2}";
6320       operands[2] = GEN_INT (-INTVAL (operands[2]));
6321       return "add{q}\t{%2, %0|%0, %2}";
6322     }
6324   [(set (attr "type")
6325      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6326         (const_string "incdec")
6327         (const_string "alu")))
6328    (set_attr "mode" "DI")])
6330 (define_insn "*adddi_5_rex64"
6331   [(set (reg FLAGS_REG)
6332         (compare
6333           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6334                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6335           (const_int 0)))
6336    (clobber (match_scratch:DI 0 "=r"))]
6337   "TARGET_64BIT
6338    && ix86_match_ccmode (insn, CCGOCmode)
6339    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6340    /* Current assemblers are broken and do not allow @GOTOFF in
6341       ought but a memory context.  */
6342    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6344   switch (get_attr_type (insn))
6345     {
6346     case TYPE_INCDEC:
6347       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6348       if (operands[2] == const1_rtx)
6349         return "inc{q}\t%0";
6350       else
6351         {
6352           gcc_assert (operands[2] == constm1_rtx);
6353           return "dec{q}\t%0";
6354         }
6356     default:
6357       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6358       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6359          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6360       if (CONST_INT_P (operands[2])
6361           /* Avoid overflows.  */
6362           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6363           && (INTVAL (operands[2]) == 128
6364               || (INTVAL (operands[2]) < 0
6365                   && INTVAL (operands[2]) != -128)))
6366         {
6367           operands[2] = GEN_INT (-INTVAL (operands[2]));
6368           return "sub{q}\t{%2, %0|%0, %2}";
6369         }
6370       return "add{q}\t{%2, %0|%0, %2}";
6371     }
6373   [(set (attr "type")
6374      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6375         (const_string "incdec")
6376         (const_string "alu")))
6377    (set_attr "mode" "DI")])
6380 (define_insn "*addsi_1"
6381   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6382         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6383                  (match_operand:SI 2 "general_operand" "g,ri,li")))
6384    (clobber (reg:CC FLAGS_REG))]
6385   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6387   switch (get_attr_type (insn))
6388     {
6389     case TYPE_LEA:
6390       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6391       return "lea{l}\t{%a2, %0|%0, %a2}";
6393     case TYPE_INCDEC:
6394       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6395       if (operands[2] == const1_rtx)
6396         return "inc{l}\t%0";
6397       else
6398         {
6399           gcc_assert (operands[2] == constm1_rtx);
6400           return "dec{l}\t%0";
6401         }
6403     default:
6404       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6406       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6407          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6408       if (CONST_INT_P (operands[2])
6409           && (INTVAL (operands[2]) == 128
6410               || (INTVAL (operands[2]) < 0
6411                   && INTVAL (operands[2]) != -128)))
6412         {
6413           operands[2] = GEN_INT (-INTVAL (operands[2]));
6414           return "sub{l}\t{%2, %0|%0, %2}";
6415         }
6416       return "add{l}\t{%2, %0|%0, %2}";
6417     }
6419   [(set (attr "type")
6420      (cond [(eq_attr "alternative" "2")
6421               (const_string "lea")
6422             ; Current assemblers are broken and do not allow @GOTOFF in
6423             ; ought but a memory context.
6424             (match_operand:SI 2 "pic_symbolic_operand" "")
6425               (const_string "lea")
6426             (match_operand:SI 2 "incdec_operand" "")
6427               (const_string "incdec")
6428            ]
6429            (const_string "alu")))
6430    (set_attr "mode" "SI")])
6432 ;; Convert lea to the lea pattern to avoid flags dependency.
6433 (define_split
6434   [(set (match_operand 0 "register_operand" "")
6435         (plus (match_operand 1 "register_operand" "")
6436               (match_operand 2 "nonmemory_operand" "")))
6437    (clobber (reg:CC FLAGS_REG))]
6438   "reload_completed
6439    && true_regnum (operands[0]) != true_regnum (operands[1])"
6440   [(const_int 0)]
6442   rtx pat;
6443   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6444      may confuse gen_lowpart.  */
6445   if (GET_MODE (operands[0]) != Pmode)
6446     {
6447       operands[1] = gen_lowpart (Pmode, operands[1]);
6448       operands[2] = gen_lowpart (Pmode, operands[2]);
6449     }
6450   operands[0] = gen_lowpart (SImode, operands[0]);
6451   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6452   if (Pmode != SImode)
6453     pat = gen_rtx_SUBREG (SImode, pat, 0);
6454   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6455   DONE;
6458 ;; It may seem that nonimmediate operand is proper one for operand 1.
6459 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6460 ;; we take care in ix86_binary_operator_ok to not allow two memory
6461 ;; operands so proper swapping will be done in reload.  This allow
6462 ;; patterns constructed from addsi_1 to match.
6463 (define_insn "addsi_1_zext"
6464   [(set (match_operand:DI 0 "register_operand" "=r,r")
6465         (zero_extend:DI
6466           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6467                    (match_operand:SI 2 "general_operand" "g,li"))))
6468    (clobber (reg:CC FLAGS_REG))]
6469   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6471   switch (get_attr_type (insn))
6472     {
6473     case TYPE_LEA:
6474       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6475       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6477     case TYPE_INCDEC:
6478       if (operands[2] == const1_rtx)
6479         return "inc{l}\t%k0";
6480       else
6481         {
6482           gcc_assert (operands[2] == constm1_rtx);
6483           return "dec{l}\t%k0";
6484         }
6486     default:
6487       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6488          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6489       if (CONST_INT_P (operands[2])
6490           && (INTVAL (operands[2]) == 128
6491               || (INTVAL (operands[2]) < 0
6492                   && INTVAL (operands[2]) != -128)))
6493         {
6494           operands[2] = GEN_INT (-INTVAL (operands[2]));
6495           return "sub{l}\t{%2, %k0|%k0, %2}";
6496         }
6497       return "add{l}\t{%2, %k0|%k0, %2}";
6498     }
6500   [(set (attr "type")
6501      (cond [(eq_attr "alternative" "1")
6502               (const_string "lea")
6503             ; Current assemblers are broken and do not allow @GOTOFF in
6504             ; ought but a memory context.
6505             (match_operand:SI 2 "pic_symbolic_operand" "")
6506               (const_string "lea")
6507             (match_operand:SI 2 "incdec_operand" "")
6508               (const_string "incdec")
6509            ]
6510            (const_string "alu")))
6511    (set_attr "mode" "SI")])
6513 ;; Convert lea to the lea pattern to avoid flags dependency.
6514 (define_split
6515   [(set (match_operand:DI 0 "register_operand" "")
6516         (zero_extend:DI
6517           (plus:SI (match_operand:SI 1 "register_operand" "")
6518                    (match_operand:SI 2 "nonmemory_operand" ""))))
6519    (clobber (reg:CC FLAGS_REG))]
6520   "TARGET_64BIT && reload_completed
6521    && true_regnum (operands[0]) != true_regnum (operands[1])"
6522   [(set (match_dup 0)
6523         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6525   operands[1] = gen_lowpart (Pmode, operands[1]);
6526   operands[2] = gen_lowpart (Pmode, operands[2]);
6529 (define_insn "*addsi_2"
6530   [(set (reg FLAGS_REG)
6531         (compare
6532           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6533                    (match_operand:SI 2 "general_operand" "g,ri"))
6534           (const_int 0)))
6535    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6536         (plus:SI (match_dup 1) (match_dup 2)))]
6537   "ix86_match_ccmode (insn, CCGOCmode)
6538    && ix86_binary_operator_ok (PLUS, SImode, operands)
6539    /* Current assemblers are broken and do not allow @GOTOFF in
6540       ought but a memory context.  */
6541    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6543   switch (get_attr_type (insn))
6544     {
6545     case TYPE_INCDEC:
6546       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6547       if (operands[2] == const1_rtx)
6548         return "inc{l}\t%0";
6549       else
6550         {
6551           gcc_assert (operands[2] == constm1_rtx);
6552           return "dec{l}\t%0";
6553         }
6555     default:
6556       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6557       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6558          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6559       if (CONST_INT_P (operands[2])
6560           && (INTVAL (operands[2]) == 128
6561               || (INTVAL (operands[2]) < 0
6562                   && INTVAL (operands[2]) != -128)))
6563         {
6564           operands[2] = GEN_INT (-INTVAL (operands[2]));
6565           return "sub{l}\t{%2, %0|%0, %2}";
6566         }
6567       return "add{l}\t{%2, %0|%0, %2}";
6568     }
6570   [(set (attr "type")
6571      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6572         (const_string "incdec")
6573         (const_string "alu")))
6574    (set_attr "mode" "SI")])
6576 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6577 (define_insn "*addsi_2_zext"
6578   [(set (reg FLAGS_REG)
6579         (compare
6580           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6581                    (match_operand:SI 2 "general_operand" "g"))
6582           (const_int 0)))
6583    (set (match_operand:DI 0 "register_operand" "=r")
6584         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6585   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6586    && ix86_binary_operator_ok (PLUS, SImode, operands)
6587    /* Current assemblers are broken and do not allow @GOTOFF in
6588       ought but a memory context.  */
6589    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6591   switch (get_attr_type (insn))
6592     {
6593     case TYPE_INCDEC:
6594       if (operands[2] == const1_rtx)
6595         return "inc{l}\t%k0";
6596       else
6597         {
6598           gcc_assert (operands[2] == constm1_rtx);
6599           return "dec{l}\t%k0";
6600         }
6602     default:
6603       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6604          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6605       if (CONST_INT_P (operands[2])
6606           && (INTVAL (operands[2]) == 128
6607               || (INTVAL (operands[2]) < 0
6608                   && INTVAL (operands[2]) != -128)))
6609         {
6610           operands[2] = GEN_INT (-INTVAL (operands[2]));
6611           return "sub{l}\t{%2, %k0|%k0, %2}";
6612         }
6613       return "add{l}\t{%2, %k0|%k0, %2}";
6614     }
6616   [(set (attr "type")
6617      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6618         (const_string "incdec")
6619         (const_string "alu")))
6620    (set_attr "mode" "SI")])
6622 (define_insn "*addsi_3"
6623   [(set (reg FLAGS_REG)
6624         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6625                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6626    (clobber (match_scratch:SI 0 "=r"))]
6627   "ix86_match_ccmode (insn, CCZmode)
6628    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6629    /* Current assemblers are broken and do not allow @GOTOFF in
6630       ought but a memory context.  */
6631    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6633   switch (get_attr_type (insn))
6634     {
6635     case TYPE_INCDEC:
6636       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6637       if (operands[2] == const1_rtx)
6638         return "inc{l}\t%0";
6639       else
6640         {
6641           gcc_assert (operands[2] == constm1_rtx);
6642           return "dec{l}\t%0";
6643         }
6645     default:
6646       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6647       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6648          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6649       if (CONST_INT_P (operands[2])
6650           && (INTVAL (operands[2]) == 128
6651               || (INTVAL (operands[2]) < 0
6652                   && INTVAL (operands[2]) != -128)))
6653         {
6654           operands[2] = GEN_INT (-INTVAL (operands[2]));
6655           return "sub{l}\t{%2, %0|%0, %2}";
6656         }
6657       return "add{l}\t{%2, %0|%0, %2}";
6658     }
6660   [(set (attr "type")
6661      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6662         (const_string "incdec")
6663         (const_string "alu")))
6664    (set_attr "mode" "SI")])
6666 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6667 (define_insn "*addsi_3_zext"
6668   [(set (reg FLAGS_REG)
6669         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6670                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6671    (set (match_operand:DI 0 "register_operand" "=r")
6672         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6673   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6674    && ix86_binary_operator_ok (PLUS, SImode, operands)
6675    /* Current assemblers are broken and do not allow @GOTOFF in
6676       ought but a memory context.  */
6677    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6679   switch (get_attr_type (insn))
6680     {
6681     case TYPE_INCDEC:
6682       if (operands[2] == const1_rtx)
6683         return "inc{l}\t%k0";
6684       else
6685         {
6686           gcc_assert (operands[2] == constm1_rtx);
6687           return "dec{l}\t%k0";
6688         }
6690     default:
6691       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6692          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6693       if (CONST_INT_P (operands[2])
6694           && (INTVAL (operands[2]) == 128
6695               || (INTVAL (operands[2]) < 0
6696                   && INTVAL (operands[2]) != -128)))
6697         {
6698           operands[2] = GEN_INT (-INTVAL (operands[2]));
6699           return "sub{l}\t{%2, %k0|%k0, %2}";
6700         }
6701       return "add{l}\t{%2, %k0|%k0, %2}";
6702     }
6704   [(set (attr "type")
6705      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6706         (const_string "incdec")
6707         (const_string "alu")))
6708    (set_attr "mode" "SI")])
6710 ; For comparisons against 1, -1 and 128, we may generate better code
6711 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6712 ; is matched then.  We can't accept general immediate, because for
6713 ; case of overflows,  the result is messed up.
6714 ; This pattern also don't hold of 0x80000000, since the value overflows
6715 ; when negated.
6716 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6717 ; only for comparisons not depending on it.
6718 (define_insn "*addsi_4"
6719   [(set (reg FLAGS_REG)
6720         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6721                  (match_operand:SI 2 "const_int_operand" "n")))
6722    (clobber (match_scratch:SI 0 "=rm"))]
6723   "ix86_match_ccmode (insn, CCGCmode)
6724    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6726   switch (get_attr_type (insn))
6727     {
6728     case TYPE_INCDEC:
6729       if (operands[2] == constm1_rtx)
6730         return "inc{l}\t%0";
6731       else
6732         {
6733           gcc_assert (operands[2] == const1_rtx);
6734           return "dec{l}\t%0";
6735         }
6737     default:
6738       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6739       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6740          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6741       if ((INTVAL (operands[2]) == -128
6742            || (INTVAL (operands[2]) > 0
6743                && INTVAL (operands[2]) != 128)))
6744         return "sub{l}\t{%2, %0|%0, %2}";
6745       operands[2] = GEN_INT (-INTVAL (operands[2]));
6746       return "add{l}\t{%2, %0|%0, %2}";
6747     }
6749   [(set (attr "type")
6750      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6751         (const_string "incdec")
6752         (const_string "alu")))
6753    (set_attr "mode" "SI")])
6755 (define_insn "*addsi_5"
6756   [(set (reg FLAGS_REG)
6757         (compare
6758           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6759                    (match_operand:SI 2 "general_operand" "g"))
6760           (const_int 0)))
6761    (clobber (match_scratch:SI 0 "=r"))]
6762   "ix86_match_ccmode (insn, CCGOCmode)
6763    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6764    /* Current assemblers are broken and do not allow @GOTOFF in
6765       ought but a memory context.  */
6766    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6768   switch (get_attr_type (insn))
6769     {
6770     case TYPE_INCDEC:
6771       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6772       if (operands[2] == const1_rtx)
6773         return "inc{l}\t%0";
6774       else
6775         {
6776           gcc_assert (operands[2] == constm1_rtx);
6777           return "dec{l}\t%0";
6778         }
6780     default:
6781       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6782       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6783          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6784       if (CONST_INT_P (operands[2])
6785           && (INTVAL (operands[2]) == 128
6786               || (INTVAL (operands[2]) < 0
6787                   && INTVAL (operands[2]) != -128)))
6788         {
6789           operands[2] = GEN_INT (-INTVAL (operands[2]));
6790           return "sub{l}\t{%2, %0|%0, %2}";
6791         }
6792       return "add{l}\t{%2, %0|%0, %2}";
6793     }
6795   [(set (attr "type")
6796      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6797         (const_string "incdec")
6798         (const_string "alu")))
6799    (set_attr "mode" "SI")])
6801 (define_expand "addhi3"
6802   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6803         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6804                  (match_operand:HI 2 "general_operand" "")))]
6805   "TARGET_HIMODE_MATH"
6806   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6808 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6809 ;; type optimizations enabled by define-splits.  This is not important
6810 ;; for PII, and in fact harmful because of partial register stalls.
6812 (define_insn "*addhi_1_lea"
6813   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6814         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6815                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6816    (clobber (reg:CC FLAGS_REG))]
6817   "!TARGET_PARTIAL_REG_STALL
6818    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6820   switch (get_attr_type (insn))
6821     {
6822     case TYPE_LEA:
6823       return "#";
6824     case TYPE_INCDEC:
6825       if (operands[2] == const1_rtx)
6826         return "inc{w}\t%0";
6827       else
6828         {
6829           gcc_assert (operands[2] == constm1_rtx);
6830           return "dec{w}\t%0";
6831         }
6833     default:
6834       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6835          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6836       if (CONST_INT_P (operands[2])
6837           && (INTVAL (operands[2]) == 128
6838               || (INTVAL (operands[2]) < 0
6839                   && INTVAL (operands[2]) != -128)))
6840         {
6841           operands[2] = GEN_INT (-INTVAL (operands[2]));
6842           return "sub{w}\t{%2, %0|%0, %2}";
6843         }
6844       return "add{w}\t{%2, %0|%0, %2}";
6845     }
6847   [(set (attr "type")
6848      (if_then_else (eq_attr "alternative" "2")
6849         (const_string "lea")
6850         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6851            (const_string "incdec")
6852            (const_string "alu"))))
6853    (set_attr "mode" "HI,HI,SI")])
6855 (define_insn "*addhi_1"
6856   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6857         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6858                  (match_operand:HI 2 "general_operand" "rn,rm")))
6859    (clobber (reg:CC FLAGS_REG))]
6860   "TARGET_PARTIAL_REG_STALL
6861    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6863   switch (get_attr_type (insn))
6864     {
6865     case TYPE_INCDEC:
6866       if (operands[2] == const1_rtx)
6867         return "inc{w}\t%0";
6868       else
6869         {
6870           gcc_assert (operands[2] == constm1_rtx);
6871           return "dec{w}\t%0";
6872         }
6874     default:
6875       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6876          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6877       if (CONST_INT_P (operands[2])
6878           && (INTVAL (operands[2]) == 128
6879               || (INTVAL (operands[2]) < 0
6880                   && INTVAL (operands[2]) != -128)))
6881         {
6882           operands[2] = GEN_INT (-INTVAL (operands[2]));
6883           return "sub{w}\t{%2, %0|%0, %2}";
6884         }
6885       return "add{w}\t{%2, %0|%0, %2}";
6886     }
6888   [(set (attr "type")
6889      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6890         (const_string "incdec")
6891         (const_string "alu")))
6892    (set_attr "mode" "HI")])
6894 (define_insn "*addhi_2"
6895   [(set (reg FLAGS_REG)
6896         (compare
6897           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6898                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6899           (const_int 0)))
6900    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6901         (plus:HI (match_dup 1) (match_dup 2)))]
6902   "ix86_match_ccmode (insn, CCGOCmode)
6903    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6905   switch (get_attr_type (insn))
6906     {
6907     case TYPE_INCDEC:
6908       if (operands[2] == const1_rtx)
6909         return "inc{w}\t%0";
6910       else
6911         {
6912           gcc_assert (operands[2] == constm1_rtx);
6913           return "dec{w}\t%0";
6914         }
6916     default:
6917       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6918          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6919       if (CONST_INT_P (operands[2])
6920           && (INTVAL (operands[2]) == 128
6921               || (INTVAL (operands[2]) < 0
6922                   && INTVAL (operands[2]) != -128)))
6923         {
6924           operands[2] = GEN_INT (-INTVAL (operands[2]));
6925           return "sub{w}\t{%2, %0|%0, %2}";
6926         }
6927       return "add{w}\t{%2, %0|%0, %2}";
6928     }
6930   [(set (attr "type")
6931      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6932         (const_string "incdec")
6933         (const_string "alu")))
6934    (set_attr "mode" "HI")])
6936 (define_insn "*addhi_3"
6937   [(set (reg FLAGS_REG)
6938         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6939                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6940    (clobber (match_scratch:HI 0 "=r"))]
6941   "ix86_match_ccmode (insn, CCZmode)
6942    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6944   switch (get_attr_type (insn))
6945     {
6946     case TYPE_INCDEC:
6947       if (operands[2] == const1_rtx)
6948         return "inc{w}\t%0";
6949       else
6950         {
6951           gcc_assert (operands[2] == constm1_rtx);
6952           return "dec{w}\t%0";
6953         }
6955     default:
6956       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6957          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6958       if (CONST_INT_P (operands[2])
6959           && (INTVAL (operands[2]) == 128
6960               || (INTVAL (operands[2]) < 0
6961                   && INTVAL (operands[2]) != -128)))
6962         {
6963           operands[2] = GEN_INT (-INTVAL (operands[2]));
6964           return "sub{w}\t{%2, %0|%0, %2}";
6965         }
6966       return "add{w}\t{%2, %0|%0, %2}";
6967     }
6969   [(set (attr "type")
6970      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6971         (const_string "incdec")
6972         (const_string "alu")))
6973    (set_attr "mode" "HI")])
6975 ; See comments above addsi_4 for details.
6976 (define_insn "*addhi_4"
6977   [(set (reg FLAGS_REG)
6978         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6979                  (match_operand:HI 2 "const_int_operand" "n")))
6980    (clobber (match_scratch:HI 0 "=rm"))]
6981   "ix86_match_ccmode (insn, CCGCmode)
6982    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6984   switch (get_attr_type (insn))
6985     {
6986     case TYPE_INCDEC:
6987       if (operands[2] == constm1_rtx)
6988         return "inc{w}\t%0";
6989       else
6990         {
6991           gcc_assert (operands[2] == const1_rtx);
6992           return "dec{w}\t%0";
6993         }
6995     default:
6996       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6997       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6998          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6999       if ((INTVAL (operands[2]) == -128
7000            || (INTVAL (operands[2]) > 0
7001                && INTVAL (operands[2]) != 128)))
7002         return "sub{w}\t{%2, %0|%0, %2}";
7003       operands[2] = GEN_INT (-INTVAL (operands[2]));
7004       return "add{w}\t{%2, %0|%0, %2}";
7005     }
7007   [(set (attr "type")
7008      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7009         (const_string "incdec")
7010         (const_string "alu")))
7011    (set_attr "mode" "SI")])
7014 (define_insn "*addhi_5"
7015   [(set (reg FLAGS_REG)
7016         (compare
7017           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7018                    (match_operand:HI 2 "general_operand" "rmn"))
7019           (const_int 0)))
7020    (clobber (match_scratch:HI 0 "=r"))]
7021   "ix86_match_ccmode (insn, CCGOCmode)
7022    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7024   switch (get_attr_type (insn))
7025     {
7026     case TYPE_INCDEC:
7027       if (operands[2] == const1_rtx)
7028         return "inc{w}\t%0";
7029       else
7030         {
7031           gcc_assert (operands[2] == constm1_rtx);
7032           return "dec{w}\t%0";
7033         }
7035     default:
7036       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7037          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7038       if (CONST_INT_P (operands[2])
7039           && (INTVAL (operands[2]) == 128
7040               || (INTVAL (operands[2]) < 0
7041                   && INTVAL (operands[2]) != -128)))
7042         {
7043           operands[2] = GEN_INT (-INTVAL (operands[2]));
7044           return "sub{w}\t{%2, %0|%0, %2}";
7045         }
7046       return "add{w}\t{%2, %0|%0, %2}";
7047     }
7049   [(set (attr "type")
7050      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7051         (const_string "incdec")
7052         (const_string "alu")))
7053    (set_attr "mode" "HI")])
7055 (define_expand "addqi3"
7056   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7057         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7058                  (match_operand:QI 2 "general_operand" "")))]
7059   "TARGET_QIMODE_MATH"
7060   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7062 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7063 (define_insn "*addqi_1_lea"
7064   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7065         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7066                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7067    (clobber (reg:CC FLAGS_REG))]
7068   "!TARGET_PARTIAL_REG_STALL
7069    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7071   int widen = (which_alternative == 2);
7072   switch (get_attr_type (insn))
7073     {
7074     case TYPE_LEA:
7075       return "#";
7076     case TYPE_INCDEC:
7077       if (operands[2] == const1_rtx)
7078         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7079       else
7080         {
7081           gcc_assert (operands[2] == constm1_rtx);
7082           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7083         }
7085     default:
7086       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7087          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7088       if (CONST_INT_P (operands[2])
7089           && (INTVAL (operands[2]) == 128
7090               || (INTVAL (operands[2]) < 0
7091                   && INTVAL (operands[2]) != -128)))
7092         {
7093           operands[2] = GEN_INT (-INTVAL (operands[2]));
7094           if (widen)
7095             return "sub{l}\t{%2, %k0|%k0, %2}";
7096           else
7097             return "sub{b}\t{%2, %0|%0, %2}";
7098         }
7099       if (widen)
7100         return "add{l}\t{%k2, %k0|%k0, %k2}";
7101       else
7102         return "add{b}\t{%2, %0|%0, %2}";
7103     }
7105   [(set (attr "type")
7106      (if_then_else (eq_attr "alternative" "3")
7107         (const_string "lea")
7108         (if_then_else (match_operand:QI 2 "incdec_operand" "")
7109            (const_string "incdec")
7110            (const_string "alu"))))
7111    (set_attr "mode" "QI,QI,SI,SI")])
7113 (define_insn "*addqi_1"
7114   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7115         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7116                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7117    (clobber (reg:CC FLAGS_REG))]
7118   "TARGET_PARTIAL_REG_STALL
7119    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7121   int widen = (which_alternative == 2);
7122   switch (get_attr_type (insn))
7123     {
7124     case TYPE_INCDEC:
7125       if (operands[2] == const1_rtx)
7126         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7127       else
7128         {
7129           gcc_assert (operands[2] == constm1_rtx);
7130           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7131         }
7133     default:
7134       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7135          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7136       if (CONST_INT_P (operands[2])
7137           && (INTVAL (operands[2]) == 128
7138               || (INTVAL (operands[2]) < 0
7139                   && INTVAL (operands[2]) != -128)))
7140         {
7141           operands[2] = GEN_INT (-INTVAL (operands[2]));
7142           if (widen)
7143             return "sub{l}\t{%2, %k0|%k0, %2}";
7144           else
7145             return "sub{b}\t{%2, %0|%0, %2}";
7146         }
7147       if (widen)
7148         return "add{l}\t{%k2, %k0|%k0, %k2}";
7149       else
7150         return "add{b}\t{%2, %0|%0, %2}";
7151     }
7153   [(set (attr "type")
7154      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7155         (const_string "incdec")
7156         (const_string "alu")))
7157    (set_attr "mode" "QI,QI,SI")])
7159 (define_insn "*addqi_1_slp"
7160   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7161         (plus:QI (match_dup 0)
7162                  (match_operand:QI 1 "general_operand" "qn,qnm")))
7163    (clobber (reg:CC FLAGS_REG))]
7164   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7165    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7167   switch (get_attr_type (insn))
7168     {
7169     case TYPE_INCDEC:
7170       if (operands[1] == const1_rtx)
7171         return "inc{b}\t%0";
7172       else
7173         {
7174           gcc_assert (operands[1] == constm1_rtx);
7175           return "dec{b}\t%0";
7176         }
7178     default:
7179       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
7180       if (CONST_INT_P (operands[1])
7181           && INTVAL (operands[1]) < 0)
7182         {
7183           operands[1] = GEN_INT (-INTVAL (operands[1]));
7184           return "sub{b}\t{%1, %0|%0, %1}";
7185         }
7186       return "add{b}\t{%1, %0|%0, %1}";
7187     }
7189   [(set (attr "type")
7190      (if_then_else (match_operand:QI 1 "incdec_operand" "")
7191         (const_string "incdec")
7192         (const_string "alu1")))
7193    (set (attr "memory")
7194      (if_then_else (match_operand 1 "memory_operand" "")
7195         (const_string "load")
7196         (const_string "none")))
7197    (set_attr "mode" "QI")])
7199 (define_insn "*addqi_2"
7200   [(set (reg FLAGS_REG)
7201         (compare
7202           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7203                    (match_operand:QI 2 "general_operand" "qmn,qn"))
7204           (const_int 0)))
7205    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7206         (plus:QI (match_dup 1) (match_dup 2)))]
7207   "ix86_match_ccmode (insn, CCGOCmode)
7208    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7210   switch (get_attr_type (insn))
7211     {
7212     case TYPE_INCDEC:
7213       if (operands[2] == const1_rtx)
7214         return "inc{b}\t%0";
7215       else
7216         {
7217           gcc_assert (operands[2] == constm1_rtx
7218                       || (CONST_INT_P (operands[2])
7219                           && INTVAL (operands[2]) == 255));
7220           return "dec{b}\t%0";
7221         }
7223     default:
7224       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7225       if (CONST_INT_P (operands[2])
7226           && INTVAL (operands[2]) < 0)
7227         {
7228           operands[2] = GEN_INT (-INTVAL (operands[2]));
7229           return "sub{b}\t{%2, %0|%0, %2}";
7230         }
7231       return "add{b}\t{%2, %0|%0, %2}";
7232     }
7234   [(set (attr "type")
7235      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7236         (const_string "incdec")
7237         (const_string "alu")))
7238    (set_attr "mode" "QI")])
7240 (define_insn "*addqi_3"
7241   [(set (reg FLAGS_REG)
7242         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7243                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7244    (clobber (match_scratch:QI 0 "=q"))]
7245   "ix86_match_ccmode (insn, CCZmode)
7246    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7248   switch (get_attr_type (insn))
7249     {
7250     case TYPE_INCDEC:
7251       if (operands[2] == const1_rtx)
7252         return "inc{b}\t%0";
7253       else
7254         {
7255           gcc_assert (operands[2] == constm1_rtx
7256                       || (CONST_INT_P (operands[2])
7257                           && INTVAL (operands[2]) == 255));
7258           return "dec{b}\t%0";
7259         }
7261     default:
7262       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7263       if (CONST_INT_P (operands[2])
7264           && INTVAL (operands[2]) < 0)
7265         {
7266           operands[2] = GEN_INT (-INTVAL (operands[2]));
7267           return "sub{b}\t{%2, %0|%0, %2}";
7268         }
7269       return "add{b}\t{%2, %0|%0, %2}";
7270     }
7272   [(set (attr "type")
7273      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7274         (const_string "incdec")
7275         (const_string "alu")))
7276    (set_attr "mode" "QI")])
7278 ; See comments above addsi_4 for details.
7279 (define_insn "*addqi_4"
7280   [(set (reg FLAGS_REG)
7281         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7282                  (match_operand:QI 2 "const_int_operand" "n")))
7283    (clobber (match_scratch:QI 0 "=qm"))]
7284   "ix86_match_ccmode (insn, CCGCmode)
7285    && (INTVAL (operands[2]) & 0xff) != 0x80"
7287   switch (get_attr_type (insn))
7288     {
7289     case TYPE_INCDEC:
7290       if (operands[2] == constm1_rtx
7291           || (CONST_INT_P (operands[2])
7292               && INTVAL (operands[2]) == 255))
7293         return "inc{b}\t%0";
7294       else
7295         {
7296           gcc_assert (operands[2] == const1_rtx);
7297           return "dec{b}\t%0";
7298         }
7300     default:
7301       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7302       if (INTVAL (operands[2]) < 0)
7303         {
7304           operands[2] = GEN_INT (-INTVAL (operands[2]));
7305           return "add{b}\t{%2, %0|%0, %2}";
7306         }
7307       return "sub{b}\t{%2, %0|%0, %2}";
7308     }
7310   [(set (attr "type")
7311      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7312         (const_string "incdec")
7313         (const_string "alu")))
7314    (set_attr "mode" "QI")])
7317 (define_insn "*addqi_5"
7318   [(set (reg FLAGS_REG)
7319         (compare
7320           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7321                    (match_operand:QI 2 "general_operand" "qmn"))
7322           (const_int 0)))
7323    (clobber (match_scratch:QI 0 "=q"))]
7324   "ix86_match_ccmode (insn, CCGOCmode)
7325    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7327   switch (get_attr_type (insn))
7328     {
7329     case TYPE_INCDEC:
7330       if (operands[2] == const1_rtx)
7331         return "inc{b}\t%0";
7332       else
7333         {
7334           gcc_assert (operands[2] == constm1_rtx
7335                       || (CONST_INT_P (operands[2])
7336                           && INTVAL (operands[2]) == 255));
7337           return "dec{b}\t%0";
7338         }
7340     default:
7341       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7342       if (CONST_INT_P (operands[2])
7343           && INTVAL (operands[2]) < 0)
7344         {
7345           operands[2] = GEN_INT (-INTVAL (operands[2]));
7346           return "sub{b}\t{%2, %0|%0, %2}";
7347         }
7348       return "add{b}\t{%2, %0|%0, %2}";
7349     }
7351   [(set (attr "type")
7352      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7353         (const_string "incdec")
7354         (const_string "alu")))
7355    (set_attr "mode" "QI")])
7358 (define_insn "addqi_ext_1"
7359   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7360                          (const_int 8)
7361                          (const_int 8))
7362         (plus:SI
7363           (zero_extract:SI
7364             (match_operand 1 "ext_register_operand" "0")
7365             (const_int 8)
7366             (const_int 8))
7367           (match_operand:QI 2 "general_operand" "Qmn")))
7368    (clobber (reg:CC FLAGS_REG))]
7369   "!TARGET_64BIT"
7371   switch (get_attr_type (insn))
7372     {
7373     case TYPE_INCDEC:
7374       if (operands[2] == const1_rtx)
7375         return "inc{b}\t%h0";
7376       else
7377         {
7378           gcc_assert (operands[2] == constm1_rtx
7379                       || (CONST_INT_P (operands[2])
7380                           && INTVAL (operands[2]) == 255));
7381           return "dec{b}\t%h0";
7382         }
7384     default:
7385       return "add{b}\t{%2, %h0|%h0, %2}";
7386     }
7388   [(set (attr "type")
7389      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7390         (const_string "incdec")
7391         (const_string "alu")))
7392    (set_attr "mode" "QI")])
7394 (define_insn "*addqi_ext_1_rex64"
7395   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7396                          (const_int 8)
7397                          (const_int 8))
7398         (plus:SI
7399           (zero_extract:SI
7400             (match_operand 1 "ext_register_operand" "0")
7401             (const_int 8)
7402             (const_int 8))
7403           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7404    (clobber (reg:CC FLAGS_REG))]
7405   "TARGET_64BIT"
7407   switch (get_attr_type (insn))
7408     {
7409     case TYPE_INCDEC:
7410       if (operands[2] == const1_rtx)
7411         return "inc{b}\t%h0";
7412       else
7413         {
7414           gcc_assert (operands[2] == constm1_rtx
7415                       || (CONST_INT_P (operands[2])
7416                           && INTVAL (operands[2]) == 255));
7417           return "dec{b}\t%h0";
7418         }
7420     default:
7421       return "add{b}\t{%2, %h0|%h0, %2}";
7422     }
7424   [(set (attr "type")
7425      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7426         (const_string "incdec")
7427         (const_string "alu")))
7428    (set_attr "mode" "QI")])
7430 (define_insn "*addqi_ext_2"
7431   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7432                          (const_int 8)
7433                          (const_int 8))
7434         (plus:SI
7435           (zero_extract:SI
7436             (match_operand 1 "ext_register_operand" "%0")
7437             (const_int 8)
7438             (const_int 8))
7439           (zero_extract:SI
7440             (match_operand 2 "ext_register_operand" "Q")
7441             (const_int 8)
7442             (const_int 8))))
7443    (clobber (reg:CC FLAGS_REG))]
7444   ""
7445   "add{b}\t{%h2, %h0|%h0, %h2}"
7446   [(set_attr "type" "alu")
7447    (set_attr "mode" "QI")])
7449 ;; The patterns that match these are at the end of this file.
7451 (define_expand "addxf3"
7452   [(set (match_operand:XF 0 "register_operand" "")
7453         (plus:XF (match_operand:XF 1 "register_operand" "")
7454                  (match_operand:XF 2 "register_operand" "")))]
7455   "TARGET_80387"
7456   "")
7458 (define_expand "add<mode>3"
7459   [(set (match_operand:MODEF 0 "register_operand" "")
7460         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7461                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7462   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7463   "")
7465 ;; Subtract instructions
7467 ;; %%% splits for subditi3
7469 (define_expand "subti3"
7470   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7471         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7472                   (match_operand:TI 2 "x86_64_general_operand" "")))]
7473   "TARGET_64BIT"
7474   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7476 (define_insn "*subti3_1"
7477   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7478         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7479                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7480    (clobber (reg:CC FLAGS_REG))]
7481   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7482   "#")
7484 (define_split
7485   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7486         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7487                   (match_operand:TI 2 "x86_64_general_operand" "")))
7488    (clobber (reg:CC FLAGS_REG))]
7489   "TARGET_64BIT && reload_completed"
7490   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7491               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7492    (parallel [(set (match_dup 3)
7493                    (minus:DI (match_dup 4)
7494                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7495                                       (match_dup 5))))
7496               (clobber (reg:CC FLAGS_REG))])]
7497   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7499 ;; %%% splits for subsidi3
7501 (define_expand "subdi3"
7502   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7503         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7504                   (match_operand:DI 2 "x86_64_general_operand" "")))]
7505   ""
7506   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7508 (define_insn "*subdi3_1"
7509   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7510         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7511                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7512    (clobber (reg:CC FLAGS_REG))]
7513   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7514   "#")
7516 (define_split
7517   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7518         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7519                   (match_operand:DI 2 "general_operand" "")))
7520    (clobber (reg:CC FLAGS_REG))]
7521   "!TARGET_64BIT && reload_completed"
7522   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7523               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7524    (parallel [(set (match_dup 3)
7525                    (minus:SI (match_dup 4)
7526                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7527                                       (match_dup 5))))
7528               (clobber (reg:CC FLAGS_REG))])]
7529   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7531 (define_insn "subdi3_carry_rex64"
7532   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7533           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7534             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7535                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7536    (clobber (reg:CC FLAGS_REG))]
7537   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7538   "sbb{q}\t{%2, %0|%0, %2}"
7539   [(set_attr "type" "alu")
7540    (set_attr "pent_pair" "pu")
7541    (set_attr "mode" "DI")])
7543 (define_insn "*subdi_1_rex64"
7544   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7545         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7546                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7547    (clobber (reg:CC FLAGS_REG))]
7548   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7549   "sub{q}\t{%2, %0|%0, %2}"
7550   [(set_attr "type" "alu")
7551    (set_attr "mode" "DI")])
7553 (define_insn "*subdi_2_rex64"
7554   [(set (reg FLAGS_REG)
7555         (compare
7556           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7557                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7558           (const_int 0)))
7559    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7560         (minus:DI (match_dup 1) (match_dup 2)))]
7561   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7562    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7563   "sub{q}\t{%2, %0|%0, %2}"
7564   [(set_attr "type" "alu")
7565    (set_attr "mode" "DI")])
7567 (define_insn "*subdi_3_rex63"
7568   [(set (reg FLAGS_REG)
7569         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7570                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7571    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7572         (minus:DI (match_dup 1) (match_dup 2)))]
7573   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7574    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7575   "sub{q}\t{%2, %0|%0, %2}"
7576   [(set_attr "type" "alu")
7577    (set_attr "mode" "DI")])
7579 (define_insn "subqi3_carry"
7580   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7581           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7582             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7583                (match_operand:QI 2 "general_operand" "qn,qm"))))
7584    (clobber (reg:CC FLAGS_REG))]
7585   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7586   "sbb{b}\t{%2, %0|%0, %2}"
7587   [(set_attr "type" "alu")
7588    (set_attr "pent_pair" "pu")
7589    (set_attr "mode" "QI")])
7591 (define_insn "subhi3_carry"
7592   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7593           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7594             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7595                (match_operand:HI 2 "general_operand" "rn,rm"))))
7596    (clobber (reg:CC FLAGS_REG))]
7597   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7598   "sbb{w}\t{%2, %0|%0, %2}"
7599   [(set_attr "type" "alu")
7600    (set_attr "pent_pair" "pu")
7601    (set_attr "mode" "HI")])
7603 (define_insn "subsi3_carry"
7604   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7605           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7606             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7607                (match_operand:SI 2 "general_operand" "ri,rm"))))
7608    (clobber (reg:CC FLAGS_REG))]
7609   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7610   "sbb{l}\t{%2, %0|%0, %2}"
7611   [(set_attr "type" "alu")
7612    (set_attr "pent_pair" "pu")
7613    (set_attr "mode" "SI")])
7615 (define_insn "subsi3_carry_zext"
7616   [(set (match_operand:DI 0 "register_operand" "=r")
7617           (zero_extend:DI
7618             (minus:SI (match_operand:SI 1 "register_operand" "0")
7619               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7620                  (match_operand:SI 2 "general_operand" "g")))))
7621    (clobber (reg:CC FLAGS_REG))]
7622   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7623   "sbb{l}\t{%2, %k0|%k0, %2}"
7624   [(set_attr "type" "alu")
7625    (set_attr "pent_pair" "pu")
7626    (set_attr "mode" "SI")])
7628 (define_expand "subsi3"
7629   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7630         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7631                   (match_operand:SI 2 "general_operand" "")))]
7632   ""
7633   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7635 (define_insn "*subsi_1"
7636   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7637         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7638                   (match_operand:SI 2 "general_operand" "ri,rm")))
7639    (clobber (reg:CC FLAGS_REG))]
7640   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7641   "sub{l}\t{%2, %0|%0, %2}"
7642   [(set_attr "type" "alu")
7643    (set_attr "mode" "SI")])
7645 (define_insn "*subsi_1_zext"
7646   [(set (match_operand:DI 0 "register_operand" "=r")
7647         (zero_extend:DI
7648           (minus:SI (match_operand:SI 1 "register_operand" "0")
7649                     (match_operand:SI 2 "general_operand" "g"))))
7650    (clobber (reg:CC FLAGS_REG))]
7651   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7652   "sub{l}\t{%2, %k0|%k0, %2}"
7653   [(set_attr "type" "alu")
7654    (set_attr "mode" "SI")])
7656 (define_insn "*subsi_2"
7657   [(set (reg FLAGS_REG)
7658         (compare
7659           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7660                     (match_operand:SI 2 "general_operand" "ri,rm"))
7661           (const_int 0)))
7662    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7663         (minus:SI (match_dup 1) (match_dup 2)))]
7664   "ix86_match_ccmode (insn, CCGOCmode)
7665    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7666   "sub{l}\t{%2, %0|%0, %2}"
7667   [(set_attr "type" "alu")
7668    (set_attr "mode" "SI")])
7670 (define_insn "*subsi_2_zext"
7671   [(set (reg FLAGS_REG)
7672         (compare
7673           (minus:SI (match_operand:SI 1 "register_operand" "0")
7674                     (match_operand:SI 2 "general_operand" "g"))
7675           (const_int 0)))
7676    (set (match_operand:DI 0 "register_operand" "=r")
7677         (zero_extend:DI
7678           (minus:SI (match_dup 1)
7679                     (match_dup 2))))]
7680   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7681    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7682   "sub{l}\t{%2, %k0|%k0, %2}"
7683   [(set_attr "type" "alu")
7684    (set_attr "mode" "SI")])
7686 (define_insn "*subsi_3"
7687   [(set (reg FLAGS_REG)
7688         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7689                  (match_operand:SI 2 "general_operand" "ri,rm")))
7690    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7691         (minus:SI (match_dup 1) (match_dup 2)))]
7692   "ix86_match_ccmode (insn, CCmode)
7693    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7694   "sub{l}\t{%2, %0|%0, %2}"
7695   [(set_attr "type" "alu")
7696    (set_attr "mode" "SI")])
7698 (define_insn "*subsi_3_zext"
7699   [(set (reg FLAGS_REG)
7700         (compare (match_operand:SI 1 "register_operand" "0")
7701                  (match_operand:SI 2 "general_operand" "g")))
7702    (set (match_operand:DI 0 "register_operand" "=r")
7703         (zero_extend:DI
7704           (minus:SI (match_dup 1)
7705                     (match_dup 2))))]
7706   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7707    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7708   "sub{l}\t{%2, %1|%1, %2}"
7709   [(set_attr "type" "alu")
7710    (set_attr "mode" "DI")])
7712 (define_expand "subhi3"
7713   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7714         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7715                   (match_operand:HI 2 "general_operand" "")))]
7716   "TARGET_HIMODE_MATH"
7717   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7719 (define_insn "*subhi_1"
7720   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7721         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7722                   (match_operand:HI 2 "general_operand" "rn,rm")))
7723    (clobber (reg:CC FLAGS_REG))]
7724   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7725   "sub{w}\t{%2, %0|%0, %2}"
7726   [(set_attr "type" "alu")
7727    (set_attr "mode" "HI")])
7729 (define_insn "*subhi_2"
7730   [(set (reg FLAGS_REG)
7731         (compare
7732           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7733                     (match_operand:HI 2 "general_operand" "rn,rm"))
7734           (const_int 0)))
7735    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7736         (minus:HI (match_dup 1) (match_dup 2)))]
7737   "ix86_match_ccmode (insn, CCGOCmode)
7738    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7739   "sub{w}\t{%2, %0|%0, %2}"
7740   [(set_attr "type" "alu")
7741    (set_attr "mode" "HI")])
7743 (define_insn "*subhi_3"
7744   [(set (reg FLAGS_REG)
7745         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7746                  (match_operand:HI 2 "general_operand" "rn,rm")))
7747    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7748         (minus:HI (match_dup 1) (match_dup 2)))]
7749   "ix86_match_ccmode (insn, CCmode)
7750    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7751   "sub{w}\t{%2, %0|%0, %2}"
7752   [(set_attr "type" "alu")
7753    (set_attr "mode" "HI")])
7755 (define_expand "subqi3"
7756   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7757         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7758                   (match_operand:QI 2 "general_operand" "")))]
7759   "TARGET_QIMODE_MATH"
7760   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7762 (define_insn "*subqi_1"
7763   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7764         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7765                   (match_operand:QI 2 "general_operand" "qn,qm")))
7766    (clobber (reg:CC FLAGS_REG))]
7767   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7768   "sub{b}\t{%2, %0|%0, %2}"
7769   [(set_attr "type" "alu")
7770    (set_attr "mode" "QI")])
7772 (define_insn "*subqi_1_slp"
7773   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7774         (minus:QI (match_dup 0)
7775                   (match_operand:QI 1 "general_operand" "qn,qm")))
7776    (clobber (reg:CC FLAGS_REG))]
7777   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7778    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7779   "sub{b}\t{%1, %0|%0, %1}"
7780   [(set_attr "type" "alu1")
7781    (set_attr "mode" "QI")])
7783 (define_insn "*subqi_2"
7784   [(set (reg FLAGS_REG)
7785         (compare
7786           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7787                     (match_operand:QI 2 "general_operand" "qn,qm"))
7788           (const_int 0)))
7789    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7790         (minus:QI (match_dup 1) (match_dup 2)))]
7791   "ix86_match_ccmode (insn, CCGOCmode)
7792    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7793   "sub{b}\t{%2, %0|%0, %2}"
7794   [(set_attr "type" "alu")
7795    (set_attr "mode" "QI")])
7797 (define_insn "*subqi_3"
7798   [(set (reg FLAGS_REG)
7799         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7800                  (match_operand:QI 2 "general_operand" "qn,qm")))
7801    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7802         (minus:QI (match_dup 1) (match_dup 2)))]
7803   "ix86_match_ccmode (insn, CCmode)
7804    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7805   "sub{b}\t{%2, %0|%0, %2}"
7806   [(set_attr "type" "alu")
7807    (set_attr "mode" "QI")])
7809 ;; The patterns that match these are at the end of this file.
7811 (define_expand "subxf3"
7812   [(set (match_operand:XF 0 "register_operand" "")
7813         (minus:XF (match_operand:XF 1 "register_operand" "")
7814                   (match_operand:XF 2 "register_operand" "")))]
7815   "TARGET_80387"
7816   "")
7818 (define_expand "sub<mode>3"
7819   [(set (match_operand:MODEF 0 "register_operand" "")
7820         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7821                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7822   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7823   "")
7825 ;; Multiply instructions
7827 (define_expand "muldi3"
7828   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7829                    (mult:DI (match_operand:DI 1 "register_operand" "")
7830                             (match_operand:DI 2 "x86_64_general_operand" "")))
7831               (clobber (reg:CC FLAGS_REG))])]
7832   "TARGET_64BIT"
7833   "")
7835 ;; On AMDFAM10
7836 ;; IMUL reg64, reg64, imm8      Direct
7837 ;; IMUL reg64, mem64, imm8      VectorPath
7838 ;; IMUL reg64, reg64, imm32     Direct
7839 ;; IMUL reg64, mem64, imm32     VectorPath
7840 ;; IMUL reg64, reg64            Direct
7841 ;; IMUL reg64, mem64            Direct
7843 (define_insn "*muldi3_1_rex64"
7844   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7845         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7846                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7847    (clobber (reg:CC FLAGS_REG))]
7848   "TARGET_64BIT
7849    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7850   "@
7851    imul{q}\t{%2, %1, %0|%0, %1, %2}
7852    imul{q}\t{%2, %1, %0|%0, %1, %2}
7853    imul{q}\t{%2, %0|%0, %2}"
7854   [(set_attr "type" "imul")
7855    (set_attr "prefix_0f" "0,0,1")
7856    (set (attr "athlon_decode")
7857         (cond [(eq_attr "cpu" "athlon")
7858                   (const_string "vector")
7859                (eq_attr "alternative" "1")
7860                   (const_string "vector")
7861                (and (eq_attr "alternative" "2")
7862                     (match_operand 1 "memory_operand" ""))
7863                   (const_string "vector")]
7864               (const_string "direct")))
7865    (set (attr "amdfam10_decode")
7866         (cond [(and (eq_attr "alternative" "0,1")
7867                     (match_operand 1 "memory_operand" ""))
7868                   (const_string "vector")]
7869               (const_string "direct")))
7870    (set_attr "mode" "DI")])
7872 (define_expand "mulsi3"
7873   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7874                    (mult:SI (match_operand:SI 1 "register_operand" "")
7875                             (match_operand:SI 2 "general_operand" "")))
7876               (clobber (reg:CC FLAGS_REG))])]
7877   ""
7878   "")
7880 ;; On AMDFAM10
7881 ;; IMUL reg32, reg32, imm8      Direct
7882 ;; IMUL reg32, mem32, imm8      VectorPath
7883 ;; IMUL reg32, reg32, imm32     Direct
7884 ;; IMUL reg32, mem32, imm32     VectorPath
7885 ;; IMUL reg32, reg32            Direct
7886 ;; IMUL reg32, mem32            Direct
7888 (define_insn "*mulsi3_1"
7889   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7890         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7891                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7892    (clobber (reg:CC FLAGS_REG))]
7893   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7894   "@
7895    imul{l}\t{%2, %1, %0|%0, %1, %2}
7896    imul{l}\t{%2, %1, %0|%0, %1, %2}
7897    imul{l}\t{%2, %0|%0, %2}"
7898   [(set_attr "type" "imul")
7899    (set_attr "prefix_0f" "0,0,1")
7900    (set (attr "athlon_decode")
7901         (cond [(eq_attr "cpu" "athlon")
7902                   (const_string "vector")
7903                (eq_attr "alternative" "1")
7904                   (const_string "vector")
7905                (and (eq_attr "alternative" "2")
7906                     (match_operand 1 "memory_operand" ""))
7907                   (const_string "vector")]
7908               (const_string "direct")))
7909    (set (attr "amdfam10_decode")
7910         (cond [(and (eq_attr "alternative" "0,1")
7911                     (match_operand 1 "memory_operand" ""))
7912                   (const_string "vector")]
7913               (const_string "direct")))
7914    (set_attr "mode" "SI")])
7916 (define_insn "*mulsi3_1_zext"
7917   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7918         (zero_extend:DI
7919           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7920                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7921    (clobber (reg:CC FLAGS_REG))]
7922   "TARGET_64BIT
7923    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7924   "@
7925    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7926    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7927    imul{l}\t{%2, %k0|%k0, %2}"
7928   [(set_attr "type" "imul")
7929    (set_attr "prefix_0f" "0,0,1")
7930    (set (attr "athlon_decode")
7931         (cond [(eq_attr "cpu" "athlon")
7932                   (const_string "vector")
7933                (eq_attr "alternative" "1")
7934                   (const_string "vector")
7935                (and (eq_attr "alternative" "2")
7936                     (match_operand 1 "memory_operand" ""))
7937                   (const_string "vector")]
7938               (const_string "direct")))
7939    (set (attr "amdfam10_decode")
7940         (cond [(and (eq_attr "alternative" "0,1")
7941                     (match_operand 1 "memory_operand" ""))
7942                   (const_string "vector")]
7943               (const_string "direct")))
7944    (set_attr "mode" "SI")])
7946 (define_expand "mulhi3"
7947   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7948                    (mult:HI (match_operand:HI 1 "register_operand" "")
7949                             (match_operand:HI 2 "general_operand" "")))
7950               (clobber (reg:CC FLAGS_REG))])]
7951   "TARGET_HIMODE_MATH"
7952   "")
7954 ;; On AMDFAM10
7955 ;; IMUL reg16, reg16, imm8      VectorPath
7956 ;; IMUL reg16, mem16, imm8      VectorPath
7957 ;; IMUL reg16, reg16, imm16     VectorPath
7958 ;; IMUL reg16, mem16, imm16     VectorPath
7959 ;; IMUL reg16, reg16            Direct
7960 ;; IMUL reg16, mem16            Direct
7961 (define_insn "*mulhi3_1"
7962   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7963         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7964                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7965    (clobber (reg:CC FLAGS_REG))]
7966   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7967   "@
7968    imul{w}\t{%2, %1, %0|%0, %1, %2}
7969    imul{w}\t{%2, %1, %0|%0, %1, %2}
7970    imul{w}\t{%2, %0|%0, %2}"
7971   [(set_attr "type" "imul")
7972    (set_attr "prefix_0f" "0,0,1")
7973    (set (attr "athlon_decode")
7974         (cond [(eq_attr "cpu" "athlon")
7975                   (const_string "vector")
7976                (eq_attr "alternative" "1,2")
7977                   (const_string "vector")]
7978               (const_string "direct")))
7979    (set (attr "amdfam10_decode")
7980         (cond [(eq_attr "alternative" "0,1")
7981                   (const_string "vector")]
7982               (const_string "direct")))
7983    (set_attr "mode" "HI")])
7985 (define_expand "mulqi3"
7986   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7987                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7988                             (match_operand:QI 2 "register_operand" "")))
7989               (clobber (reg:CC FLAGS_REG))])]
7990   "TARGET_QIMODE_MATH"
7991   "")
7993 ;;On AMDFAM10
7994 ;; MUL reg8     Direct
7995 ;; MUL mem8     Direct
7997 (define_insn "*mulqi3_1"
7998   [(set (match_operand:QI 0 "register_operand" "=a")
7999         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8000                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8001    (clobber (reg:CC FLAGS_REG))]
8002   "TARGET_QIMODE_MATH
8003    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8004   "mul{b}\t%2"
8005   [(set_attr "type" "imul")
8006    (set_attr "length_immediate" "0")
8007    (set (attr "athlon_decode")
8008      (if_then_else (eq_attr "cpu" "athlon")
8009         (const_string "vector")
8010         (const_string "direct")))
8011    (set_attr "amdfam10_decode" "direct")
8012    (set_attr "mode" "QI")])
8014 (define_expand "umulqihi3"
8015   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8016                    (mult:HI (zero_extend:HI
8017                               (match_operand:QI 1 "nonimmediate_operand" ""))
8018                             (zero_extend:HI
8019                               (match_operand:QI 2 "register_operand" ""))))
8020               (clobber (reg:CC FLAGS_REG))])]
8021   "TARGET_QIMODE_MATH"
8022   "")
8024 (define_insn "*umulqihi3_1"
8025   [(set (match_operand:HI 0 "register_operand" "=a")
8026         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8027                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8028    (clobber (reg:CC FLAGS_REG))]
8029   "TARGET_QIMODE_MATH
8030    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8031   "mul{b}\t%2"
8032   [(set_attr "type" "imul")
8033    (set_attr "length_immediate" "0")
8034    (set (attr "athlon_decode")
8035      (if_then_else (eq_attr "cpu" "athlon")
8036         (const_string "vector")
8037         (const_string "direct")))
8038    (set_attr "amdfam10_decode" "direct")
8039    (set_attr "mode" "QI")])
8041 (define_expand "mulqihi3"
8042   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8043                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8044                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8045               (clobber (reg:CC FLAGS_REG))])]
8046   "TARGET_QIMODE_MATH"
8047   "")
8049 (define_insn "*mulqihi3_insn"
8050   [(set (match_operand:HI 0 "register_operand" "=a")
8051         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8052                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8053    (clobber (reg:CC FLAGS_REG))]
8054   "TARGET_QIMODE_MATH
8055    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8056   "imul{b}\t%2"
8057   [(set_attr "type" "imul")
8058    (set_attr "length_immediate" "0")
8059    (set (attr "athlon_decode")
8060      (if_then_else (eq_attr "cpu" "athlon")
8061         (const_string "vector")
8062         (const_string "direct")))
8063    (set_attr "amdfam10_decode" "direct")
8064    (set_attr "mode" "QI")])
8066 (define_expand "umulditi3"
8067   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8068                    (mult:TI (zero_extend:TI
8069                               (match_operand:DI 1 "nonimmediate_operand" ""))
8070                             (zero_extend:TI
8071                               (match_operand:DI 2 "register_operand" ""))))
8072               (clobber (reg:CC FLAGS_REG))])]
8073   "TARGET_64BIT"
8074   "")
8076 (define_insn "*umulditi3_insn"
8077   [(set (match_operand:TI 0 "register_operand" "=A")
8078         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8079                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8080    (clobber (reg:CC FLAGS_REG))]
8081   "TARGET_64BIT
8082    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8083   "mul{q}\t%2"
8084   [(set_attr "type" "imul")
8085    (set_attr "length_immediate" "0")
8086    (set (attr "athlon_decode")
8087      (if_then_else (eq_attr "cpu" "athlon")
8088         (const_string "vector")
8089         (const_string "double")))
8090    (set_attr "amdfam10_decode" "double")
8091    (set_attr "mode" "DI")])
8093 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8094 (define_expand "umulsidi3"
8095   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8096                    (mult:DI (zero_extend:DI
8097                               (match_operand:SI 1 "nonimmediate_operand" ""))
8098                             (zero_extend:DI
8099                               (match_operand:SI 2 "register_operand" ""))))
8100               (clobber (reg:CC FLAGS_REG))])]
8101   "!TARGET_64BIT"
8102   "")
8104 (define_insn "*umulsidi3_insn"
8105   [(set (match_operand:DI 0 "register_operand" "=A")
8106         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8107                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8108    (clobber (reg:CC FLAGS_REG))]
8109   "!TARGET_64BIT
8110    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8111   "mul{l}\t%2"
8112   [(set_attr "type" "imul")
8113    (set_attr "length_immediate" "0")
8114    (set (attr "athlon_decode")
8115      (if_then_else (eq_attr "cpu" "athlon")
8116         (const_string "vector")
8117         (const_string "double")))
8118    (set_attr "amdfam10_decode" "double")
8119    (set_attr "mode" "SI")])
8121 (define_expand "mulditi3"
8122   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8123                    (mult:TI (sign_extend:TI
8124                               (match_operand:DI 1 "nonimmediate_operand" ""))
8125                             (sign_extend:TI
8126                               (match_operand:DI 2 "register_operand" ""))))
8127               (clobber (reg:CC FLAGS_REG))])]
8128   "TARGET_64BIT"
8129   "")
8131 (define_insn "*mulditi3_insn"
8132   [(set (match_operand:TI 0 "register_operand" "=A")
8133         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8134                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8135    (clobber (reg:CC FLAGS_REG))]
8136   "TARGET_64BIT
8137    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8138   "imul{q}\t%2"
8139   [(set_attr "type" "imul")
8140    (set_attr "length_immediate" "0")
8141    (set (attr "athlon_decode")
8142      (if_then_else (eq_attr "cpu" "athlon")
8143         (const_string "vector")
8144         (const_string "double")))
8145    (set_attr "amdfam10_decode" "double")
8146    (set_attr "mode" "DI")])
8148 (define_expand "mulsidi3"
8149   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8150                    (mult:DI (sign_extend:DI
8151                               (match_operand:SI 1 "nonimmediate_operand" ""))
8152                             (sign_extend:DI
8153                               (match_operand:SI 2 "register_operand" ""))))
8154               (clobber (reg:CC FLAGS_REG))])]
8155   "!TARGET_64BIT"
8156   "")
8158 (define_insn "*mulsidi3_insn"
8159   [(set (match_operand:DI 0 "register_operand" "=A")
8160         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8161                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8162    (clobber (reg:CC FLAGS_REG))]
8163   "!TARGET_64BIT
8164    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8165   "imul{l}\t%2"
8166   [(set_attr "type" "imul")
8167    (set_attr "length_immediate" "0")
8168    (set (attr "athlon_decode")
8169      (if_then_else (eq_attr "cpu" "athlon")
8170         (const_string "vector")
8171         (const_string "double")))
8172    (set_attr "amdfam10_decode" "double")
8173    (set_attr "mode" "SI")])
8175 (define_expand "umuldi3_highpart"
8176   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8177                    (truncate:DI
8178                      (lshiftrt:TI
8179                        (mult:TI (zero_extend:TI
8180                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8181                                 (zero_extend:TI
8182                                   (match_operand:DI 2 "register_operand" "")))
8183                        (const_int 64))))
8184               (clobber (match_scratch:DI 3 ""))
8185               (clobber (reg:CC FLAGS_REG))])]
8186   "TARGET_64BIT"
8187   "")
8189 (define_insn "*umuldi3_highpart_rex64"
8190   [(set (match_operand:DI 0 "register_operand" "=d")
8191         (truncate:DI
8192           (lshiftrt:TI
8193             (mult:TI (zero_extend:TI
8194                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8195                      (zero_extend:TI
8196                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8197             (const_int 64))))
8198    (clobber (match_scratch:DI 3 "=1"))
8199    (clobber (reg:CC FLAGS_REG))]
8200   "TARGET_64BIT
8201    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8202   "mul{q}\t%2"
8203   [(set_attr "type" "imul")
8204    (set_attr "length_immediate" "0")
8205    (set (attr "athlon_decode")
8206      (if_then_else (eq_attr "cpu" "athlon")
8207         (const_string "vector")
8208         (const_string "double")))
8209    (set_attr "amdfam10_decode" "double")
8210    (set_attr "mode" "DI")])
8212 (define_expand "umulsi3_highpart"
8213   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8214                    (truncate:SI
8215                      (lshiftrt:DI
8216                        (mult:DI (zero_extend:DI
8217                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8218                                 (zero_extend:DI
8219                                   (match_operand:SI 2 "register_operand" "")))
8220                        (const_int 32))))
8221               (clobber (match_scratch:SI 3 ""))
8222               (clobber (reg:CC FLAGS_REG))])]
8223   ""
8224   "")
8226 (define_insn "*umulsi3_highpart_insn"
8227   [(set (match_operand:SI 0 "register_operand" "=d")
8228         (truncate:SI
8229           (lshiftrt:DI
8230             (mult:DI (zero_extend:DI
8231                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8232                      (zero_extend:DI
8233                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8234             (const_int 32))))
8235    (clobber (match_scratch:SI 3 "=1"))
8236    (clobber (reg:CC FLAGS_REG))]
8237   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8238   "mul{l}\t%2"
8239   [(set_attr "type" "imul")
8240    (set_attr "length_immediate" "0")
8241    (set (attr "athlon_decode")
8242      (if_then_else (eq_attr "cpu" "athlon")
8243         (const_string "vector")
8244         (const_string "double")))
8245    (set_attr "amdfam10_decode" "double")
8246    (set_attr "mode" "SI")])
8248 (define_insn "*umulsi3_highpart_zext"
8249   [(set (match_operand:DI 0 "register_operand" "=d")
8250         (zero_extend:DI (truncate:SI
8251           (lshiftrt:DI
8252             (mult:DI (zero_extend:DI
8253                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8254                      (zero_extend:DI
8255                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8256             (const_int 32)))))
8257    (clobber (match_scratch:SI 3 "=1"))
8258    (clobber (reg:CC FLAGS_REG))]
8259   "TARGET_64BIT
8260    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8261   "mul{l}\t%2"
8262   [(set_attr "type" "imul")
8263    (set_attr "length_immediate" "0")
8264    (set (attr "athlon_decode")
8265      (if_then_else (eq_attr "cpu" "athlon")
8266         (const_string "vector")
8267         (const_string "double")))
8268    (set_attr "amdfam10_decode" "double")
8269    (set_attr "mode" "SI")])
8271 (define_expand "smuldi3_highpart"
8272   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8273                    (truncate:DI
8274                      (lshiftrt:TI
8275                        (mult:TI (sign_extend:TI
8276                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8277                                 (sign_extend:TI
8278                                   (match_operand:DI 2 "register_operand" "")))
8279                        (const_int 64))))
8280               (clobber (match_scratch:DI 3 ""))
8281               (clobber (reg:CC FLAGS_REG))])]
8282   "TARGET_64BIT"
8283   "")
8285 (define_insn "*smuldi3_highpart_rex64"
8286   [(set (match_operand:DI 0 "register_operand" "=d")
8287         (truncate:DI
8288           (lshiftrt:TI
8289             (mult:TI (sign_extend:TI
8290                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8291                      (sign_extend:TI
8292                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8293             (const_int 64))))
8294    (clobber (match_scratch:DI 3 "=1"))
8295    (clobber (reg:CC FLAGS_REG))]
8296   "TARGET_64BIT
8297    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8298   "imul{q}\t%2"
8299   [(set_attr "type" "imul")
8300    (set (attr "athlon_decode")
8301      (if_then_else (eq_attr "cpu" "athlon")
8302         (const_string "vector")
8303         (const_string "double")))
8304    (set_attr "amdfam10_decode" "double")
8305    (set_attr "mode" "DI")])
8307 (define_expand "smulsi3_highpart"
8308   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8309                    (truncate:SI
8310                      (lshiftrt:DI
8311                        (mult:DI (sign_extend:DI
8312                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8313                                 (sign_extend:DI
8314                                   (match_operand:SI 2 "register_operand" "")))
8315                        (const_int 32))))
8316               (clobber (match_scratch:SI 3 ""))
8317               (clobber (reg:CC FLAGS_REG))])]
8318   ""
8319   "")
8321 (define_insn "*smulsi3_highpart_insn"
8322   [(set (match_operand:SI 0 "register_operand" "=d")
8323         (truncate:SI
8324           (lshiftrt:DI
8325             (mult:DI (sign_extend:DI
8326                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8327                      (sign_extend:DI
8328                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8329             (const_int 32))))
8330    (clobber (match_scratch:SI 3 "=1"))
8331    (clobber (reg:CC FLAGS_REG))]
8332   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8333   "imul{l}\t%2"
8334   [(set_attr "type" "imul")
8335    (set (attr "athlon_decode")
8336      (if_then_else (eq_attr "cpu" "athlon")
8337         (const_string "vector")
8338         (const_string "double")))
8339    (set_attr "amdfam10_decode" "double")
8340    (set_attr "mode" "SI")])
8342 (define_insn "*smulsi3_highpart_zext"
8343   [(set (match_operand:DI 0 "register_operand" "=d")
8344         (zero_extend:DI (truncate:SI
8345           (lshiftrt:DI
8346             (mult:DI (sign_extend:DI
8347                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8348                      (sign_extend:DI
8349                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8350             (const_int 32)))))
8351    (clobber (match_scratch:SI 3 "=1"))
8352    (clobber (reg:CC FLAGS_REG))]
8353   "TARGET_64BIT
8354    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8355   "imul{l}\t%2"
8356   [(set_attr "type" "imul")
8357    (set (attr "athlon_decode")
8358      (if_then_else (eq_attr "cpu" "athlon")
8359         (const_string "vector")
8360         (const_string "double")))
8361    (set_attr "amdfam10_decode" "double")
8362    (set_attr "mode" "SI")])
8364 ;; The patterns that match these are at the end of this file.
8366 (define_expand "mulxf3"
8367   [(set (match_operand:XF 0 "register_operand" "")
8368         (mult:XF (match_operand:XF 1 "register_operand" "")
8369                  (match_operand:XF 2 "register_operand" "")))]
8370   "TARGET_80387"
8371   "")
8373 (define_expand "mul<mode>3"
8374   [(set (match_operand:MODEF 0 "register_operand" "")
8375         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8376                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8377   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8378   "")
8380 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8383 ;; Divide instructions
8385 (define_insn "divqi3"
8386   [(set (match_operand:QI 0 "register_operand" "=a")
8387         (div:QI (match_operand:HI 1 "register_operand" "0")
8388                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8389    (clobber (reg:CC FLAGS_REG))]
8390   "TARGET_QIMODE_MATH"
8391   "idiv{b}\t%2"
8392   [(set_attr "type" "idiv")
8393    (set_attr "mode" "QI")])
8395 (define_insn "udivqi3"
8396   [(set (match_operand:QI 0 "register_operand" "=a")
8397         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8398                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8399    (clobber (reg:CC FLAGS_REG))]
8400   "TARGET_QIMODE_MATH"
8401   "div{b}\t%2"
8402   [(set_attr "type" "idiv")
8403    (set_attr "mode" "QI")])
8405 ;; The patterns that match these are at the end of this file.
8407 (define_expand "divxf3"
8408   [(set (match_operand:XF 0 "register_operand" "")
8409         (div:XF (match_operand:XF 1 "register_operand" "")
8410                 (match_operand:XF 2 "register_operand" "")))]
8411   "TARGET_80387"
8412   "")
8414 (define_expand "divdf3"
8415   [(set (match_operand:DF 0 "register_operand" "")
8416         (div:DF (match_operand:DF 1 "register_operand" "")
8417                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8418    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8419    "")
8421 (define_expand "divsf3"
8422   [(set (match_operand:SF 0 "register_operand" "")
8423         (div:SF (match_operand:SF 1 "register_operand" "")
8424                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8425   "TARGET_80387 || TARGET_SSE_MATH"
8427   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8428       && flag_finite_math_only && !flag_trapping_math
8429       && flag_unsafe_math_optimizations)
8430     {
8431       ix86_emit_swdivsf (operands[0], operands[1],
8432                          operands[2], SFmode);
8433       DONE;
8434     }
8437 ;; Remainder instructions.
8439 (define_expand "divmoddi4"
8440   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8441                    (div:DI (match_operand:DI 1 "register_operand" "")
8442                            (match_operand:DI 2 "nonimmediate_operand" "")))
8443               (set (match_operand:DI 3 "register_operand" "")
8444                    (mod:DI (match_dup 1) (match_dup 2)))
8445               (clobber (reg:CC FLAGS_REG))])]
8446   "TARGET_64BIT"
8447   "")
8449 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8450 ;; Penalize eax case slightly because it results in worse scheduling
8451 ;; of code.
8452 (define_insn "*divmoddi4_nocltd_rex64"
8453   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8454         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8455                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8456    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8457         (mod:DI (match_dup 2) (match_dup 3)))
8458    (clobber (reg:CC FLAGS_REG))]
8459   "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8460   "#"
8461   [(set_attr "type" "multi")])
8463 (define_insn "*divmoddi4_cltd_rex64"
8464   [(set (match_operand:DI 0 "register_operand" "=a")
8465         (div:DI (match_operand:DI 2 "register_operand" "a")
8466                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8467    (set (match_operand:DI 1 "register_operand" "=&d")
8468         (mod:DI (match_dup 2) (match_dup 3)))
8469    (clobber (reg:CC FLAGS_REG))]
8470   "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8471   "#"
8472   [(set_attr "type" "multi")])
8474 (define_insn "*divmoddi_noext_rex64"
8475   [(set (match_operand:DI 0 "register_operand" "=a")
8476         (div:DI (match_operand:DI 1 "register_operand" "0")
8477                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8478    (set (match_operand:DI 3 "register_operand" "=d")
8479         (mod:DI (match_dup 1) (match_dup 2)))
8480    (use (match_operand:DI 4 "register_operand" "3"))
8481    (clobber (reg:CC FLAGS_REG))]
8482   "TARGET_64BIT"
8483   "idiv{q}\t%2"
8484   [(set_attr "type" "idiv")
8485    (set_attr "mode" "DI")])
8487 (define_split
8488   [(set (match_operand:DI 0 "register_operand" "")
8489         (div:DI (match_operand:DI 1 "register_operand" "")
8490                 (match_operand:DI 2 "nonimmediate_operand" "")))
8491    (set (match_operand:DI 3 "register_operand" "")
8492         (mod:DI (match_dup 1) (match_dup 2)))
8493    (clobber (reg:CC FLAGS_REG))]
8494   "TARGET_64BIT && reload_completed"
8495   [(parallel [(set (match_dup 3)
8496                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8497               (clobber (reg:CC FLAGS_REG))])
8498    (parallel [(set (match_dup 0)
8499                    (div:DI (reg:DI 0) (match_dup 2)))
8500               (set (match_dup 3)
8501                    (mod:DI (reg:DI 0) (match_dup 2)))
8502               (use (match_dup 3))
8503               (clobber (reg:CC FLAGS_REG))])]
8505   /* Avoid use of cltd in favor of a mov+shift.  */
8506   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8507     {
8508       if (true_regnum (operands[1]))
8509         emit_move_insn (operands[0], operands[1]);
8510       else
8511         emit_move_insn (operands[3], operands[1]);
8512       operands[4] = operands[3];
8513     }
8514   else
8515     {
8516       gcc_assert (!true_regnum (operands[1]));
8517       operands[4] = operands[1];
8518     }
8522 (define_expand "divmodsi4"
8523   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8524                    (div:SI (match_operand:SI 1 "register_operand" "")
8525                            (match_operand:SI 2 "nonimmediate_operand" "")))
8526               (set (match_operand:SI 3 "register_operand" "")
8527                    (mod:SI (match_dup 1) (match_dup 2)))
8528               (clobber (reg:CC FLAGS_REG))])]
8529   ""
8530   "")
8532 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8533 ;; Penalize eax case slightly because it results in worse scheduling
8534 ;; of code.
8535 (define_insn "*divmodsi4_nocltd"
8536   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8537         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8538                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8539    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8540         (mod:SI (match_dup 2) (match_dup 3)))
8541    (clobber (reg:CC FLAGS_REG))]
8542   "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8543   "#"
8544   [(set_attr "type" "multi")])
8546 (define_insn "*divmodsi4_cltd"
8547   [(set (match_operand:SI 0 "register_operand" "=a")
8548         (div:SI (match_operand:SI 2 "register_operand" "a")
8549                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8550    (set (match_operand:SI 1 "register_operand" "=&d")
8551         (mod:SI (match_dup 2) (match_dup 3)))
8552    (clobber (reg:CC FLAGS_REG))]
8553   "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8554   "#"
8555   [(set_attr "type" "multi")])
8557 (define_insn "*divmodsi_noext"
8558   [(set (match_operand:SI 0 "register_operand" "=a")
8559         (div:SI (match_operand:SI 1 "register_operand" "0")
8560                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8561    (set (match_operand:SI 3 "register_operand" "=d")
8562         (mod:SI (match_dup 1) (match_dup 2)))
8563    (use (match_operand:SI 4 "register_operand" "3"))
8564    (clobber (reg:CC FLAGS_REG))]
8565   ""
8566   "idiv{l}\t%2"
8567   [(set_attr "type" "idiv")
8568    (set_attr "mode" "SI")])
8570 (define_split
8571   [(set (match_operand:SI 0 "register_operand" "")
8572         (div:SI (match_operand:SI 1 "register_operand" "")
8573                 (match_operand:SI 2 "nonimmediate_operand" "")))
8574    (set (match_operand:SI 3 "register_operand" "")
8575         (mod:SI (match_dup 1) (match_dup 2)))
8576    (clobber (reg:CC FLAGS_REG))]
8577   "reload_completed"
8578   [(parallel [(set (match_dup 3)
8579                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8580               (clobber (reg:CC FLAGS_REG))])
8581    (parallel [(set (match_dup 0)
8582                    (div:SI (reg:SI 0) (match_dup 2)))
8583               (set (match_dup 3)
8584                    (mod:SI (reg:SI 0) (match_dup 2)))
8585               (use (match_dup 3))
8586               (clobber (reg:CC FLAGS_REG))])]
8588   /* Avoid use of cltd in favor of a mov+shift.  */
8589   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8590     {
8591       if (true_regnum (operands[1]))
8592         emit_move_insn (operands[0], operands[1]);
8593       else
8594         emit_move_insn (operands[3], operands[1]);
8595       operands[4] = operands[3];
8596     }
8597   else
8598     {
8599       gcc_assert (!true_regnum (operands[1]));
8600       operands[4] = operands[1];
8601     }
8603 ;; %%% Split me.
8604 (define_insn "divmodhi4"
8605   [(set (match_operand:HI 0 "register_operand" "=a")
8606         (div:HI (match_operand:HI 1 "register_operand" "0")
8607                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8608    (set (match_operand:HI 3 "register_operand" "=&d")
8609         (mod:HI (match_dup 1) (match_dup 2)))
8610    (clobber (reg:CC FLAGS_REG))]
8611   "TARGET_HIMODE_MATH"
8612   "cwtd\;idiv{w}\t%2"
8613   [(set_attr "type" "multi")
8614    (set_attr "length_immediate" "0")
8615    (set_attr "mode" "SI")])
8617 (define_insn "udivmoddi4"
8618   [(set (match_operand:DI 0 "register_operand" "=a")
8619         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8620                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8621    (set (match_operand:DI 3 "register_operand" "=&d")
8622         (umod:DI (match_dup 1) (match_dup 2)))
8623    (clobber (reg:CC FLAGS_REG))]
8624   "TARGET_64BIT"
8625   "xor{q}\t%3, %3\;div{q}\t%2"
8626   [(set_attr "type" "multi")
8627    (set_attr "length_immediate" "0")
8628    (set_attr "mode" "DI")])
8630 (define_insn "*udivmoddi4_noext"
8631   [(set (match_operand:DI 0 "register_operand" "=a")
8632         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8633                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8634    (set (match_operand:DI 3 "register_operand" "=d")
8635         (umod:DI (match_dup 1) (match_dup 2)))
8636    (use (match_dup 3))
8637    (clobber (reg:CC FLAGS_REG))]
8638   "TARGET_64BIT"
8639   "div{q}\t%2"
8640   [(set_attr "type" "idiv")
8641    (set_attr "mode" "DI")])
8643 (define_split
8644   [(set (match_operand:DI 0 "register_operand" "")
8645         (udiv:DI (match_operand:DI 1 "register_operand" "")
8646                  (match_operand:DI 2 "nonimmediate_operand" "")))
8647    (set (match_operand:DI 3 "register_operand" "")
8648         (umod:DI (match_dup 1) (match_dup 2)))
8649    (clobber (reg:CC FLAGS_REG))]
8650   "TARGET_64BIT && reload_completed"
8651   [(set (match_dup 3) (const_int 0))
8652    (parallel [(set (match_dup 0)
8653                    (udiv:DI (match_dup 1) (match_dup 2)))
8654               (set (match_dup 3)
8655                    (umod:DI (match_dup 1) (match_dup 2)))
8656               (use (match_dup 3))
8657               (clobber (reg:CC FLAGS_REG))])]
8658   "")
8660 (define_insn "udivmodsi4"
8661   [(set (match_operand:SI 0 "register_operand" "=a")
8662         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8663                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8664    (set (match_operand:SI 3 "register_operand" "=&d")
8665         (umod:SI (match_dup 1) (match_dup 2)))
8666    (clobber (reg:CC FLAGS_REG))]
8667   ""
8668   "xor{l}\t%3, %3\;div{l}\t%2"
8669   [(set_attr "type" "multi")
8670    (set_attr "length_immediate" "0")
8671    (set_attr "mode" "SI")])
8673 (define_insn "*udivmodsi4_noext"
8674   [(set (match_operand:SI 0 "register_operand" "=a")
8675         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8676                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8677    (set (match_operand:SI 3 "register_operand" "=d")
8678         (umod:SI (match_dup 1) (match_dup 2)))
8679    (use (match_dup 3))
8680    (clobber (reg:CC FLAGS_REG))]
8681   ""
8682   "div{l}\t%2"
8683   [(set_attr "type" "idiv")
8684    (set_attr "mode" "SI")])
8686 (define_split
8687   [(set (match_operand:SI 0 "register_operand" "")
8688         (udiv:SI (match_operand:SI 1 "register_operand" "")
8689                  (match_operand:SI 2 "nonimmediate_operand" "")))
8690    (set (match_operand:SI 3 "register_operand" "")
8691         (umod:SI (match_dup 1) (match_dup 2)))
8692    (clobber (reg:CC FLAGS_REG))]
8693   "reload_completed"
8694   [(set (match_dup 3) (const_int 0))
8695    (parallel [(set (match_dup 0)
8696                    (udiv:SI (match_dup 1) (match_dup 2)))
8697               (set (match_dup 3)
8698                    (umod:SI (match_dup 1) (match_dup 2)))
8699               (use (match_dup 3))
8700               (clobber (reg:CC FLAGS_REG))])]
8701   "")
8703 (define_expand "udivmodhi4"
8704   [(set (match_dup 4) (const_int 0))
8705    (parallel [(set (match_operand:HI 0 "register_operand" "")
8706                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8707                             (match_operand:HI 2 "nonimmediate_operand" "")))
8708               (set (match_operand:HI 3 "register_operand" "")
8709                    (umod:HI (match_dup 1) (match_dup 2)))
8710               (use (match_dup 4))
8711               (clobber (reg:CC FLAGS_REG))])]
8712   "TARGET_HIMODE_MATH"
8713   "operands[4] = gen_reg_rtx (HImode);")
8715 (define_insn "*udivmodhi_noext"
8716   [(set (match_operand:HI 0 "register_operand" "=a")
8717         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8718                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8719    (set (match_operand:HI 3 "register_operand" "=d")
8720         (umod:HI (match_dup 1) (match_dup 2)))
8721    (use (match_operand:HI 4 "register_operand" "3"))
8722    (clobber (reg:CC FLAGS_REG))]
8723   ""
8724   "div{w}\t%2"
8725   [(set_attr "type" "idiv")
8726    (set_attr "mode" "HI")])
8728 ;; We cannot use div/idiv for double division, because it causes
8729 ;; "division by zero" on the overflow and that's not what we expect
8730 ;; from truncate.  Because true (non truncating) double division is
8731 ;; never generated, we can't create this insn anyway.
8733 ;(define_insn ""
8734 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8735 ;       (truncate:SI
8736 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8737 ;                  (zero_extend:DI
8738 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8739 ;   (set (match_operand:SI 3 "register_operand" "=d")
8740 ;       (truncate:SI
8741 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8742 ;   (clobber (reg:CC FLAGS_REG))]
8743 ;  ""
8744 ;  "div{l}\t{%2, %0|%0, %2}"
8745 ;  [(set_attr "type" "idiv")])
8747 ;;- Logical AND instructions
8749 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8750 ;; Note that this excludes ah.
8752 (define_insn "*testdi_1_rex64"
8753   [(set (reg FLAGS_REG)
8754         (compare
8755           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8756                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8757           (const_int 0)))]
8758   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8759    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8760   "@
8761    test{l}\t{%k1, %k0|%k0, %k1}
8762    test{l}\t{%k1, %k0|%k0, %k1}
8763    test{q}\t{%1, %0|%0, %1}
8764    test{q}\t{%1, %0|%0, %1}
8765    test{q}\t{%1, %0|%0, %1}"
8766   [(set_attr "type" "test")
8767    (set_attr "modrm" "0,1,0,1,1")
8768    (set_attr "mode" "SI,SI,DI,DI,DI")
8769    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8771 (define_insn "testsi_1"
8772   [(set (reg FLAGS_REG)
8773         (compare
8774           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8775                   (match_operand:SI 1 "general_operand" "i,i,ri"))
8776           (const_int 0)))]
8777   "ix86_match_ccmode (insn, CCNOmode)
8778    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8779   "test{l}\t{%1, %0|%0, %1}"
8780   [(set_attr "type" "test")
8781    (set_attr "modrm" "0,1,1")
8782    (set_attr "mode" "SI")
8783    (set_attr "pent_pair" "uv,np,uv")])
8785 (define_expand "testsi_ccno_1"
8786   [(set (reg:CCNO FLAGS_REG)
8787         (compare:CCNO
8788           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8789                   (match_operand:SI 1 "nonmemory_operand" ""))
8790           (const_int 0)))]
8791   ""
8792   "")
8794 (define_insn "*testhi_1"
8795   [(set (reg FLAGS_REG)
8796         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8797                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8798                  (const_int 0)))]
8799   "ix86_match_ccmode (insn, CCNOmode)
8800    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8801   "test{w}\t{%1, %0|%0, %1}"
8802   [(set_attr "type" "test")
8803    (set_attr "modrm" "0,1,1")
8804    (set_attr "mode" "HI")
8805    (set_attr "pent_pair" "uv,np,uv")])
8807 (define_expand "testqi_ccz_1"
8808   [(set (reg:CCZ FLAGS_REG)
8809         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8810                              (match_operand:QI 1 "nonmemory_operand" ""))
8811                  (const_int 0)))]
8812   ""
8813   "")
8815 (define_insn "*testqi_1_maybe_si"
8816   [(set (reg FLAGS_REG)
8817         (compare
8818           (and:QI
8819             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8820             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8821           (const_int 0)))]
8822    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8823     && ix86_match_ccmode (insn,
8824                          CONST_INT_P (operands[1])
8825                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8827   if (which_alternative == 3)
8828     {
8829       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8830         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8831       return "test{l}\t{%1, %k0|%k0, %1}";
8832     }
8833   return "test{b}\t{%1, %0|%0, %1}";
8835   [(set_attr "type" "test")
8836    (set_attr "modrm" "0,1,1,1")
8837    (set_attr "mode" "QI,QI,QI,SI")
8838    (set_attr "pent_pair" "uv,np,uv,np")])
8840 (define_insn "*testqi_1"
8841   [(set (reg FLAGS_REG)
8842         (compare
8843           (and:QI
8844             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8845             (match_operand:QI 1 "general_operand" "n,n,qn"))
8846           (const_int 0)))]
8847   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8848    && ix86_match_ccmode (insn, CCNOmode)"
8849   "test{b}\t{%1, %0|%0, %1}"
8850   [(set_attr "type" "test")
8851    (set_attr "modrm" "0,1,1")
8852    (set_attr "mode" "QI")
8853    (set_attr "pent_pair" "uv,np,uv")])
8855 (define_expand "testqi_ext_ccno_0"
8856   [(set (reg:CCNO FLAGS_REG)
8857         (compare:CCNO
8858           (and:SI
8859             (zero_extract:SI
8860               (match_operand 0 "ext_register_operand" "")
8861               (const_int 8)
8862               (const_int 8))
8863             (match_operand 1 "const_int_operand" ""))
8864           (const_int 0)))]
8865   ""
8866   "")
8868 (define_insn "*testqi_ext_0"
8869   [(set (reg FLAGS_REG)
8870         (compare
8871           (and:SI
8872             (zero_extract:SI
8873               (match_operand 0 "ext_register_operand" "Q")
8874               (const_int 8)
8875               (const_int 8))
8876             (match_operand 1 "const_int_operand" "n"))
8877           (const_int 0)))]
8878   "ix86_match_ccmode (insn, CCNOmode)"
8879   "test{b}\t{%1, %h0|%h0, %1}"
8880   [(set_attr "type" "test")
8881    (set_attr "mode" "QI")
8882    (set_attr "length_immediate" "1")
8883    (set_attr "pent_pair" "np")])
8885 (define_insn "*testqi_ext_1"
8886   [(set (reg FLAGS_REG)
8887         (compare
8888           (and:SI
8889             (zero_extract:SI
8890               (match_operand 0 "ext_register_operand" "Q")
8891               (const_int 8)
8892               (const_int 8))
8893             (zero_extend:SI
8894               (match_operand:QI 1 "general_operand" "Qm")))
8895           (const_int 0)))]
8896   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8897    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8898   "test{b}\t{%1, %h0|%h0, %1}"
8899   [(set_attr "type" "test")
8900    (set_attr "mode" "QI")])
8902 (define_insn "*testqi_ext_1_rex64"
8903   [(set (reg FLAGS_REG)
8904         (compare
8905           (and:SI
8906             (zero_extract:SI
8907               (match_operand 0 "ext_register_operand" "Q")
8908               (const_int 8)
8909               (const_int 8))
8910             (zero_extend:SI
8911               (match_operand:QI 1 "register_operand" "Q")))
8912           (const_int 0)))]
8913   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8914   "test{b}\t{%1, %h0|%h0, %1}"
8915   [(set_attr "type" "test")
8916    (set_attr "mode" "QI")])
8918 (define_insn "*testqi_ext_2"
8919   [(set (reg FLAGS_REG)
8920         (compare
8921           (and:SI
8922             (zero_extract:SI
8923               (match_operand 0 "ext_register_operand" "Q")
8924               (const_int 8)
8925               (const_int 8))
8926             (zero_extract:SI
8927               (match_operand 1 "ext_register_operand" "Q")
8928               (const_int 8)
8929               (const_int 8)))
8930           (const_int 0)))]
8931   "ix86_match_ccmode (insn, CCNOmode)"
8932   "test{b}\t{%h1, %h0|%h0, %h1}"
8933   [(set_attr "type" "test")
8934    (set_attr "mode" "QI")])
8936 ;; Combine likes to form bit extractions for some tests.  Humor it.
8937 (define_insn "*testqi_ext_3"
8938   [(set (reg FLAGS_REG)
8939         (compare (zero_extract:SI
8940                    (match_operand 0 "nonimmediate_operand" "rm")
8941                    (match_operand:SI 1 "const_int_operand" "")
8942                    (match_operand:SI 2 "const_int_operand" ""))
8943                  (const_int 0)))]
8944   "ix86_match_ccmode (insn, CCNOmode)
8945    && INTVAL (operands[1]) > 0
8946    && INTVAL (operands[2]) >= 0
8947    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8948    && (GET_MODE (operands[0]) == SImode
8949        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8950        || GET_MODE (operands[0]) == HImode
8951        || GET_MODE (operands[0]) == QImode)"
8952   "#")
8954 (define_insn "*testqi_ext_3_rex64"
8955   [(set (reg FLAGS_REG)
8956         (compare (zero_extract:DI
8957                    (match_operand 0 "nonimmediate_operand" "rm")
8958                    (match_operand:DI 1 "const_int_operand" "")
8959                    (match_operand:DI 2 "const_int_operand" ""))
8960                  (const_int 0)))]
8961   "TARGET_64BIT
8962    && ix86_match_ccmode (insn, CCNOmode)
8963    && INTVAL (operands[1]) > 0
8964    && INTVAL (operands[2]) >= 0
8965    /* Ensure that resulting mask is zero or sign extended operand.  */
8966    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8967        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8968            && INTVAL (operands[1]) > 32))
8969    && (GET_MODE (operands[0]) == SImode
8970        || GET_MODE (operands[0]) == DImode
8971        || GET_MODE (operands[0]) == HImode
8972        || GET_MODE (operands[0]) == QImode)"
8973   "#")
8975 (define_split
8976   [(set (match_operand 0 "flags_reg_operand" "")
8977         (match_operator 1 "compare_operator"
8978           [(zero_extract
8979              (match_operand 2 "nonimmediate_operand" "")
8980              (match_operand 3 "const_int_operand" "")
8981              (match_operand 4 "const_int_operand" ""))
8982            (const_int 0)]))]
8983   "ix86_match_ccmode (insn, CCNOmode)"
8984   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8986   rtx val = operands[2];
8987   HOST_WIDE_INT len = INTVAL (operands[3]);
8988   HOST_WIDE_INT pos = INTVAL (operands[4]);
8989   HOST_WIDE_INT mask;
8990   enum machine_mode mode, submode;
8992   mode = GET_MODE (val);
8993   if (MEM_P (val))
8994     {
8995       /* ??? Combine likes to put non-volatile mem extractions in QImode
8996          no matter the size of the test.  So find a mode that works.  */
8997       if (! MEM_VOLATILE_P (val))
8998         {
8999           mode = smallest_mode_for_size (pos + len, MODE_INT);
9000           val = adjust_address (val, mode, 0);
9001         }
9002     }
9003   else if (GET_CODE (val) == SUBREG
9004            && (submode = GET_MODE (SUBREG_REG (val)),
9005                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9006            && pos + len <= GET_MODE_BITSIZE (submode))
9007     {
9008       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
9009       mode = submode;
9010       val = SUBREG_REG (val);
9011     }
9012   else if (mode == HImode && pos + len <= 8)
9013     {
9014       /* Small HImode tests can be converted to QImode.  */
9015       mode = QImode;
9016       val = gen_lowpart (QImode, val);
9017     }
9019   if (len == HOST_BITS_PER_WIDE_INT)
9020     mask = -1;
9021   else
9022     mask = ((HOST_WIDE_INT)1 << len) - 1;
9023   mask <<= pos;
9025   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9028 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9029 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9030 ;; this is relatively important trick.
9031 ;; Do the conversion only post-reload to avoid limiting of the register class
9032 ;; to QI regs.
9033 (define_split
9034   [(set (match_operand 0 "flags_reg_operand" "")
9035         (match_operator 1 "compare_operator"
9036           [(and (match_operand 2 "register_operand" "")
9037                 (match_operand 3 "const_int_operand" ""))
9038            (const_int 0)]))]
9039    "reload_completed
9040     && QI_REG_P (operands[2])
9041     && GET_MODE (operands[2]) != QImode
9042     && ((ix86_match_ccmode (insn, CCZmode)
9043          && !(INTVAL (operands[3]) & ~(255 << 8)))
9044         || (ix86_match_ccmode (insn, CCNOmode)
9045             && !(INTVAL (operands[3]) & ~(127 << 8))))"
9046   [(set (match_dup 0)
9047         (match_op_dup 1
9048           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9049                    (match_dup 3))
9050            (const_int 0)]))]
9051   "operands[2] = gen_lowpart (SImode, operands[2]);
9052    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9054 (define_split
9055   [(set (match_operand 0 "flags_reg_operand" "")
9056         (match_operator 1 "compare_operator"
9057           [(and (match_operand 2 "nonimmediate_operand" "")
9058                 (match_operand 3 "const_int_operand" ""))
9059            (const_int 0)]))]
9060    "reload_completed
9061     && GET_MODE (operands[2]) != QImode
9062     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9063     && ((ix86_match_ccmode (insn, CCZmode)
9064          && !(INTVAL (operands[3]) & ~255))
9065         || (ix86_match_ccmode (insn, CCNOmode)
9066             && !(INTVAL (operands[3]) & ~127)))"
9067   [(set (match_dup 0)
9068         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9069                          (const_int 0)]))]
9070   "operands[2] = gen_lowpart (QImode, operands[2]);
9071    operands[3] = gen_lowpart (QImode, operands[3]);")
9074 ;; %%% This used to optimize known byte-wide and operations to memory,
9075 ;; and sometimes to QImode registers.  If this is considered useful,
9076 ;; it should be done with splitters.
9078 (define_expand "anddi3"
9079   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9080         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9081                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9082   "TARGET_64BIT"
9083   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9085 (define_insn "*anddi_1_rex64"
9086   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9087         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9088                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9089    (clobber (reg:CC FLAGS_REG))]
9090   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9092   switch (get_attr_type (insn))
9093     {
9094     case TYPE_IMOVX:
9095       {
9096         enum machine_mode mode;
9098         gcc_assert (CONST_INT_P (operands[2]));
9099         if (INTVAL (operands[2]) == 0xff)
9100           mode = QImode;
9101         else
9102           {
9103             gcc_assert (INTVAL (operands[2]) == 0xffff);
9104             mode = HImode;
9105           }
9107         operands[1] = gen_lowpart (mode, operands[1]);
9108         if (mode == QImode)
9109           return "movz{bq|x}\t{%1,%0|%0, %1}";
9110         else
9111           return "movz{wq|x}\t{%1,%0|%0, %1}";
9112       }
9114     default:
9115       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9116       if (get_attr_mode (insn) == MODE_SI)
9117         return "and{l}\t{%k2, %k0|%k0, %k2}";
9118       else
9119         return "and{q}\t{%2, %0|%0, %2}";
9120     }
9122   [(set_attr "type" "alu,alu,alu,imovx")
9123    (set_attr "length_immediate" "*,*,*,0")
9124    (set_attr "mode" "SI,DI,DI,DI")])
9126 (define_insn "*anddi_2"
9127   [(set (reg FLAGS_REG)
9128         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9129                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9130                  (const_int 0)))
9131    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9132         (and:DI (match_dup 1) (match_dup 2)))]
9133   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9134    && ix86_binary_operator_ok (AND, DImode, operands)"
9135   "@
9136    and{l}\t{%k2, %k0|%k0, %k2}
9137    and{q}\t{%2, %0|%0, %2}
9138    and{q}\t{%2, %0|%0, %2}"
9139   [(set_attr "type" "alu")
9140    (set_attr "mode" "SI,DI,DI")])
9142 (define_expand "andsi3"
9143   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9144         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9145                 (match_operand:SI 2 "general_operand" "")))]
9146   ""
9147   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9149 (define_insn "*andsi_1"
9150   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9151         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9152                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9153    (clobber (reg:CC FLAGS_REG))]
9154   "ix86_binary_operator_ok (AND, SImode, operands)"
9156   switch (get_attr_type (insn))
9157     {
9158     case TYPE_IMOVX:
9159       {
9160         enum machine_mode mode;
9162         gcc_assert (CONST_INT_P (operands[2]));
9163         if (INTVAL (operands[2]) == 0xff)
9164           mode = QImode;
9165         else
9166           {
9167             gcc_assert (INTVAL (operands[2]) == 0xffff);
9168             mode = HImode;
9169           }
9171         operands[1] = gen_lowpart (mode, operands[1]);
9172         if (mode == QImode)
9173           return "movz{bl|x}\t{%1,%0|%0, %1}";
9174         else
9175           return "movz{wl|x}\t{%1,%0|%0, %1}";
9176       }
9178     default:
9179       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9180       return "and{l}\t{%2, %0|%0, %2}";
9181     }
9183   [(set_attr "type" "alu,alu,imovx")
9184    (set_attr "length_immediate" "*,*,0")
9185    (set_attr "mode" "SI")])
9187 (define_split
9188   [(set (match_operand 0 "register_operand" "")
9189         (and (match_dup 0)
9190              (const_int -65536)))
9191    (clobber (reg:CC FLAGS_REG))]
9192   "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9193   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9194   "operands[1] = gen_lowpart (HImode, operands[0]);")
9196 (define_split
9197   [(set (match_operand 0 "ext_register_operand" "")
9198         (and (match_dup 0)
9199              (const_int -256)))
9200    (clobber (reg:CC FLAGS_REG))]
9201   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9202   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9203   "operands[1] = gen_lowpart (QImode, operands[0]);")
9205 (define_split
9206   [(set (match_operand 0 "ext_register_operand" "")
9207         (and (match_dup 0)
9208              (const_int -65281)))
9209    (clobber (reg:CC FLAGS_REG))]
9210   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9211   [(parallel [(set (zero_extract:SI (match_dup 0)
9212                                     (const_int 8)
9213                                     (const_int 8))
9214                    (xor:SI
9215                      (zero_extract:SI (match_dup 0)
9216                                       (const_int 8)
9217                                       (const_int 8))
9218                      (zero_extract:SI (match_dup 0)
9219                                       (const_int 8)
9220                                       (const_int 8))))
9221               (clobber (reg:CC FLAGS_REG))])]
9222   "operands[0] = gen_lowpart (SImode, operands[0]);")
9224 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9225 (define_insn "*andsi_1_zext"
9226   [(set (match_operand:DI 0 "register_operand" "=r")
9227         (zero_extend:DI
9228           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9229                   (match_operand:SI 2 "general_operand" "g"))))
9230    (clobber (reg:CC FLAGS_REG))]
9231   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9232   "and{l}\t{%2, %k0|%k0, %2}"
9233   [(set_attr "type" "alu")
9234    (set_attr "mode" "SI")])
9236 (define_insn "*andsi_2"
9237   [(set (reg FLAGS_REG)
9238         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9239                          (match_operand:SI 2 "general_operand" "g,ri"))
9240                  (const_int 0)))
9241    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9242         (and:SI (match_dup 1) (match_dup 2)))]
9243   "ix86_match_ccmode (insn, CCNOmode)
9244    && ix86_binary_operator_ok (AND, SImode, operands)"
9245   "and{l}\t{%2, %0|%0, %2}"
9246   [(set_attr "type" "alu")
9247    (set_attr "mode" "SI")])
9249 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9250 (define_insn "*andsi_2_zext"
9251   [(set (reg FLAGS_REG)
9252         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9253                          (match_operand:SI 2 "general_operand" "g"))
9254                  (const_int 0)))
9255    (set (match_operand:DI 0 "register_operand" "=r")
9256         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9257   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9258    && ix86_binary_operator_ok (AND, SImode, operands)"
9259   "and{l}\t{%2, %k0|%k0, %2}"
9260   [(set_attr "type" "alu")
9261    (set_attr "mode" "SI")])
9263 (define_expand "andhi3"
9264   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9265         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9266                 (match_operand:HI 2 "general_operand" "")))]
9267   "TARGET_HIMODE_MATH"
9268   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9270 (define_insn "*andhi_1"
9271   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9272         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9273                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9274    (clobber (reg:CC FLAGS_REG))]
9275   "ix86_binary_operator_ok (AND, HImode, operands)"
9277   switch (get_attr_type (insn))
9278     {
9279     case TYPE_IMOVX:
9280       gcc_assert (CONST_INT_P (operands[2]));
9281       gcc_assert (INTVAL (operands[2]) == 0xff);
9282       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9284     default:
9285       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9287       return "and{w}\t{%2, %0|%0, %2}";
9288     }
9290   [(set_attr "type" "alu,alu,imovx")
9291    (set_attr "length_immediate" "*,*,0")
9292    (set_attr "mode" "HI,HI,SI")])
9294 (define_insn "*andhi_2"
9295   [(set (reg FLAGS_REG)
9296         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9297                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9298                  (const_int 0)))
9299    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9300         (and:HI (match_dup 1) (match_dup 2)))]
9301   "ix86_match_ccmode (insn, CCNOmode)
9302    && ix86_binary_operator_ok (AND, HImode, operands)"
9303   "and{w}\t{%2, %0|%0, %2}"
9304   [(set_attr "type" "alu")
9305    (set_attr "mode" "HI")])
9307 (define_expand "andqi3"
9308   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9309         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9310                 (match_operand:QI 2 "general_operand" "")))]
9311   "TARGET_QIMODE_MATH"
9312   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9314 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9315 (define_insn "*andqi_1"
9316   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9317         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9318                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9319    (clobber (reg:CC FLAGS_REG))]
9320   "ix86_binary_operator_ok (AND, QImode, operands)"
9321   "@
9322    and{b}\t{%2, %0|%0, %2}
9323    and{b}\t{%2, %0|%0, %2}
9324    and{l}\t{%k2, %k0|%k0, %k2}"
9325   [(set_attr "type" "alu")
9326    (set_attr "mode" "QI,QI,SI")])
9328 (define_insn "*andqi_1_slp"
9329   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9330         (and:QI (match_dup 0)
9331                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9332    (clobber (reg:CC FLAGS_REG))]
9333   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9334    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9335   "and{b}\t{%1, %0|%0, %1}"
9336   [(set_attr "type" "alu1")
9337    (set_attr "mode" "QI")])
9339 (define_insn "*andqi_2_maybe_si"
9340   [(set (reg FLAGS_REG)
9341         (compare (and:QI
9342                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9343                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9344                  (const_int 0)))
9345    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9346         (and:QI (match_dup 1) (match_dup 2)))]
9347   "ix86_binary_operator_ok (AND, QImode, operands)
9348    && ix86_match_ccmode (insn,
9349                          CONST_INT_P (operands[2])
9350                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9352   if (which_alternative == 2)
9353     {
9354       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9355         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9356       return "and{l}\t{%2, %k0|%k0, %2}";
9357     }
9358   return "and{b}\t{%2, %0|%0, %2}";
9360   [(set_attr "type" "alu")
9361    (set_attr "mode" "QI,QI,SI")])
9363 (define_insn "*andqi_2"
9364   [(set (reg FLAGS_REG)
9365         (compare (and:QI
9366                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9367                    (match_operand:QI 2 "general_operand" "qmn,qn"))
9368                  (const_int 0)))
9369    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9370         (and:QI (match_dup 1) (match_dup 2)))]
9371   "ix86_match_ccmode (insn, CCNOmode)
9372    && ix86_binary_operator_ok (AND, QImode, operands)"
9373   "and{b}\t{%2, %0|%0, %2}"
9374   [(set_attr "type" "alu")
9375    (set_attr "mode" "QI")])
9377 (define_insn "*andqi_2_slp"
9378   [(set (reg FLAGS_REG)
9379         (compare (and:QI
9380                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9381                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9382                  (const_int 0)))
9383    (set (strict_low_part (match_dup 0))
9384         (and:QI (match_dup 0) (match_dup 1)))]
9385   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9386    && ix86_match_ccmode (insn, CCNOmode)
9387    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9388   "and{b}\t{%1, %0|%0, %1}"
9389   [(set_attr "type" "alu1")
9390    (set_attr "mode" "QI")])
9392 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9393 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9394 ;; for a QImode operand, which of course failed.
9396 (define_insn "andqi_ext_0"
9397   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9398                          (const_int 8)
9399                          (const_int 8))
9400         (and:SI
9401           (zero_extract:SI
9402             (match_operand 1 "ext_register_operand" "0")
9403             (const_int 8)
9404             (const_int 8))
9405           (match_operand 2 "const_int_operand" "n")))
9406    (clobber (reg:CC FLAGS_REG))]
9407   ""
9408   "and{b}\t{%2, %h0|%h0, %2}"
9409   [(set_attr "type" "alu")
9410    (set_attr "length_immediate" "1")
9411    (set_attr "mode" "QI")])
9413 ;; Generated by peephole translating test to and.  This shows up
9414 ;; often in fp comparisons.
9416 (define_insn "*andqi_ext_0_cc"
9417   [(set (reg FLAGS_REG)
9418         (compare
9419           (and:SI
9420             (zero_extract:SI
9421               (match_operand 1 "ext_register_operand" "0")
9422               (const_int 8)
9423               (const_int 8))
9424             (match_operand 2 "const_int_operand" "n"))
9425           (const_int 0)))
9426    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9427                          (const_int 8)
9428                          (const_int 8))
9429         (and:SI
9430           (zero_extract:SI
9431             (match_dup 1)
9432             (const_int 8)
9433             (const_int 8))
9434           (match_dup 2)))]
9435   "ix86_match_ccmode (insn, CCNOmode)"
9436   "and{b}\t{%2, %h0|%h0, %2}"
9437   [(set_attr "type" "alu")
9438    (set_attr "length_immediate" "1")
9439    (set_attr "mode" "QI")])
9441 (define_insn "*andqi_ext_1"
9442   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9443                          (const_int 8)
9444                          (const_int 8))
9445         (and:SI
9446           (zero_extract:SI
9447             (match_operand 1 "ext_register_operand" "0")
9448             (const_int 8)
9449             (const_int 8))
9450           (zero_extend:SI
9451             (match_operand:QI 2 "general_operand" "Qm"))))
9452    (clobber (reg:CC FLAGS_REG))]
9453   "!TARGET_64BIT"
9454   "and{b}\t{%2, %h0|%h0, %2}"
9455   [(set_attr "type" "alu")
9456    (set_attr "length_immediate" "0")
9457    (set_attr "mode" "QI")])
9459 (define_insn "*andqi_ext_1_rex64"
9460   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9461                          (const_int 8)
9462                          (const_int 8))
9463         (and:SI
9464           (zero_extract:SI
9465             (match_operand 1 "ext_register_operand" "0")
9466             (const_int 8)
9467             (const_int 8))
9468           (zero_extend:SI
9469             (match_operand 2 "ext_register_operand" "Q"))))
9470    (clobber (reg:CC FLAGS_REG))]
9471   "TARGET_64BIT"
9472   "and{b}\t{%2, %h0|%h0, %2}"
9473   [(set_attr "type" "alu")
9474    (set_attr "length_immediate" "0")
9475    (set_attr "mode" "QI")])
9477 (define_insn "*andqi_ext_2"
9478   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9479                          (const_int 8)
9480                          (const_int 8))
9481         (and:SI
9482           (zero_extract:SI
9483             (match_operand 1 "ext_register_operand" "%0")
9484             (const_int 8)
9485             (const_int 8))
9486           (zero_extract:SI
9487             (match_operand 2 "ext_register_operand" "Q")
9488             (const_int 8)
9489             (const_int 8))))
9490    (clobber (reg:CC FLAGS_REG))]
9491   ""
9492   "and{b}\t{%h2, %h0|%h0, %h2}"
9493   [(set_attr "type" "alu")
9494    (set_attr "length_immediate" "0")
9495    (set_attr "mode" "QI")])
9497 ;; Convert wide AND instructions with immediate operand to shorter QImode
9498 ;; equivalents when possible.
9499 ;; Don't do the splitting with memory operands, since it introduces risk
9500 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9501 ;; for size, but that can (should?) be handled by generic code instead.
9502 (define_split
9503   [(set (match_operand 0 "register_operand" "")
9504         (and (match_operand 1 "register_operand" "")
9505              (match_operand 2 "const_int_operand" "")))
9506    (clobber (reg:CC FLAGS_REG))]
9507    "reload_completed
9508     && QI_REG_P (operands[0])
9509     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9510     && !(~INTVAL (operands[2]) & ~(255 << 8))
9511     && GET_MODE (operands[0]) != QImode"
9512   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9513                    (and:SI (zero_extract:SI (match_dup 1)
9514                                             (const_int 8) (const_int 8))
9515                            (match_dup 2)))
9516               (clobber (reg:CC FLAGS_REG))])]
9517   "operands[0] = gen_lowpart (SImode, operands[0]);
9518    operands[1] = gen_lowpart (SImode, operands[1]);
9519    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9521 ;; Since AND can be encoded with sign extended immediate, this is only
9522 ;; profitable when 7th bit is not set.
9523 (define_split
9524   [(set (match_operand 0 "register_operand" "")
9525         (and (match_operand 1 "general_operand" "")
9526              (match_operand 2 "const_int_operand" "")))
9527    (clobber (reg:CC FLAGS_REG))]
9528    "reload_completed
9529     && ANY_QI_REG_P (operands[0])
9530     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9531     && !(~INTVAL (operands[2]) & ~255)
9532     && !(INTVAL (operands[2]) & 128)
9533     && GET_MODE (operands[0]) != QImode"
9534   [(parallel [(set (strict_low_part (match_dup 0))
9535                    (and:QI (match_dup 1)
9536                            (match_dup 2)))
9537               (clobber (reg:CC FLAGS_REG))])]
9538   "operands[0] = gen_lowpart (QImode, operands[0]);
9539    operands[1] = gen_lowpart (QImode, operands[1]);
9540    operands[2] = gen_lowpart (QImode, operands[2]);")
9542 ;; Logical inclusive OR instructions
9544 ;; %%% This used to optimize known byte-wide and operations to memory.
9545 ;; If this is considered useful, it should be done with splitters.
9547 (define_expand "iordi3"
9548   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9549         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9550                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9551   "TARGET_64BIT"
9552   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9554 (define_insn "*iordi_1_rex64"
9555   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9556         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9557                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9558    (clobber (reg:CC FLAGS_REG))]
9559   "TARGET_64BIT
9560    && ix86_binary_operator_ok (IOR, DImode, operands)"
9561   "or{q}\t{%2, %0|%0, %2}"
9562   [(set_attr "type" "alu")
9563    (set_attr "mode" "DI")])
9565 (define_insn "*iordi_2_rex64"
9566   [(set (reg FLAGS_REG)
9567         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9568                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9569                  (const_int 0)))
9570    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9571         (ior:DI (match_dup 1) (match_dup 2)))]
9572   "TARGET_64BIT
9573    && ix86_match_ccmode (insn, CCNOmode)
9574    && ix86_binary_operator_ok (IOR, DImode, operands)"
9575   "or{q}\t{%2, %0|%0, %2}"
9576   [(set_attr "type" "alu")
9577    (set_attr "mode" "DI")])
9579 (define_insn "*iordi_3_rex64"
9580   [(set (reg FLAGS_REG)
9581         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9582                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9583                  (const_int 0)))
9584    (clobber (match_scratch:DI 0 "=r"))]
9585   "TARGET_64BIT
9586    && ix86_match_ccmode (insn, CCNOmode)
9587    && ix86_binary_operator_ok (IOR, DImode, operands)"
9588   "or{q}\t{%2, %0|%0, %2}"
9589   [(set_attr "type" "alu")
9590    (set_attr "mode" "DI")])
9593 (define_expand "iorsi3"
9594   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9595         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9596                 (match_operand:SI 2 "general_operand" "")))]
9597   ""
9598   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9600 (define_insn "*iorsi_1"
9601   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9602         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9603                 (match_operand:SI 2 "general_operand" "ri,g")))
9604    (clobber (reg:CC FLAGS_REG))]
9605   "ix86_binary_operator_ok (IOR, SImode, operands)"
9606   "or{l}\t{%2, %0|%0, %2}"
9607   [(set_attr "type" "alu")
9608    (set_attr "mode" "SI")])
9610 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9611 (define_insn "*iorsi_1_zext"
9612   [(set (match_operand:DI 0 "register_operand" "=r")
9613         (zero_extend:DI
9614           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9615                   (match_operand:SI 2 "general_operand" "g"))))
9616    (clobber (reg:CC FLAGS_REG))]
9617   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9618   "or{l}\t{%2, %k0|%k0, %2}"
9619   [(set_attr "type" "alu")
9620    (set_attr "mode" "SI")])
9622 (define_insn "*iorsi_1_zext_imm"
9623   [(set (match_operand:DI 0 "register_operand" "=r")
9624         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9625                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9626    (clobber (reg:CC FLAGS_REG))]
9627   "TARGET_64BIT"
9628   "or{l}\t{%2, %k0|%k0, %2}"
9629   [(set_attr "type" "alu")
9630    (set_attr "mode" "SI")])
9632 (define_insn "*iorsi_2"
9633   [(set (reg FLAGS_REG)
9634         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9635                          (match_operand:SI 2 "general_operand" "g,ri"))
9636                  (const_int 0)))
9637    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9638         (ior:SI (match_dup 1) (match_dup 2)))]
9639   "ix86_match_ccmode (insn, CCNOmode)
9640    && ix86_binary_operator_ok (IOR, SImode, operands)"
9641   "or{l}\t{%2, %0|%0, %2}"
9642   [(set_attr "type" "alu")
9643    (set_attr "mode" "SI")])
9645 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9646 ;; ??? Special case for immediate operand is missing - it is tricky.
9647 (define_insn "*iorsi_2_zext"
9648   [(set (reg FLAGS_REG)
9649         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9650                          (match_operand:SI 2 "general_operand" "g"))
9651                  (const_int 0)))
9652    (set (match_operand:DI 0 "register_operand" "=r")
9653         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9654   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9655    && ix86_binary_operator_ok (IOR, SImode, operands)"
9656   "or{l}\t{%2, %k0|%k0, %2}"
9657   [(set_attr "type" "alu")
9658    (set_attr "mode" "SI")])
9660 (define_insn "*iorsi_2_zext_imm"
9661   [(set (reg FLAGS_REG)
9662         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9663                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9664                  (const_int 0)))
9665    (set (match_operand:DI 0 "register_operand" "=r")
9666         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9667   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9668    && ix86_binary_operator_ok (IOR, SImode, operands)"
9669   "or{l}\t{%2, %k0|%k0, %2}"
9670   [(set_attr "type" "alu")
9671    (set_attr "mode" "SI")])
9673 (define_insn "*iorsi_3"
9674   [(set (reg FLAGS_REG)
9675         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9676                          (match_operand:SI 2 "general_operand" "g"))
9677                  (const_int 0)))
9678    (clobber (match_scratch:SI 0 "=r"))]
9679   "ix86_match_ccmode (insn, CCNOmode)
9680    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9681   "or{l}\t{%2, %0|%0, %2}"
9682   [(set_attr "type" "alu")
9683    (set_attr "mode" "SI")])
9685 (define_expand "iorhi3"
9686   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9687         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9688                 (match_operand:HI 2 "general_operand" "")))]
9689   "TARGET_HIMODE_MATH"
9690   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9692 (define_insn "*iorhi_1"
9693   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9694         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9695                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9696    (clobber (reg:CC FLAGS_REG))]
9697   "ix86_binary_operator_ok (IOR, HImode, operands)"
9698   "or{w}\t{%2, %0|%0, %2}"
9699   [(set_attr "type" "alu")
9700    (set_attr "mode" "HI")])
9702 (define_insn "*iorhi_2"
9703   [(set (reg FLAGS_REG)
9704         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9705                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9706                  (const_int 0)))
9707    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9708         (ior:HI (match_dup 1) (match_dup 2)))]
9709   "ix86_match_ccmode (insn, CCNOmode)
9710    && ix86_binary_operator_ok (IOR, HImode, operands)"
9711   "or{w}\t{%2, %0|%0, %2}"
9712   [(set_attr "type" "alu")
9713    (set_attr "mode" "HI")])
9715 (define_insn "*iorhi_3"
9716   [(set (reg FLAGS_REG)
9717         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9718                          (match_operand:HI 2 "general_operand" "rmn"))
9719                  (const_int 0)))
9720    (clobber (match_scratch:HI 0 "=r"))]
9721   "ix86_match_ccmode (insn, CCNOmode)
9722    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9723   "or{w}\t{%2, %0|%0, %2}"
9724   [(set_attr "type" "alu")
9725    (set_attr "mode" "HI")])
9727 (define_expand "iorqi3"
9728   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9729         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9730                 (match_operand:QI 2 "general_operand" "")))]
9731   "TARGET_QIMODE_MATH"
9732   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9734 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9735 (define_insn "*iorqi_1"
9736   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9737         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9738                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9739    (clobber (reg:CC FLAGS_REG))]
9740   "ix86_binary_operator_ok (IOR, QImode, operands)"
9741   "@
9742    or{b}\t{%2, %0|%0, %2}
9743    or{b}\t{%2, %0|%0, %2}
9744    or{l}\t{%k2, %k0|%k0, %k2}"
9745   [(set_attr "type" "alu")
9746    (set_attr "mode" "QI,QI,SI")])
9748 (define_insn "*iorqi_1_slp"
9749   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9750         (ior:QI (match_dup 0)
9751                 (match_operand:QI 1 "general_operand" "qmn,qn")))
9752    (clobber (reg:CC FLAGS_REG))]
9753   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9754    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9755   "or{b}\t{%1, %0|%0, %1}"
9756   [(set_attr "type" "alu1")
9757    (set_attr "mode" "QI")])
9759 (define_insn "*iorqi_2"
9760   [(set (reg FLAGS_REG)
9761         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9762                          (match_operand:QI 2 "general_operand" "qmn,qn"))
9763                  (const_int 0)))
9764    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9765         (ior:QI (match_dup 1) (match_dup 2)))]
9766   "ix86_match_ccmode (insn, CCNOmode)
9767    && ix86_binary_operator_ok (IOR, QImode, operands)"
9768   "or{b}\t{%2, %0|%0, %2}"
9769   [(set_attr "type" "alu")
9770    (set_attr "mode" "QI")])
9772 (define_insn "*iorqi_2_slp"
9773   [(set (reg FLAGS_REG)
9774         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9775                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9776                  (const_int 0)))
9777    (set (strict_low_part (match_dup 0))
9778         (ior:QI (match_dup 0) (match_dup 1)))]
9779   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9780    && ix86_match_ccmode (insn, CCNOmode)
9781    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9782   "or{b}\t{%1, %0|%0, %1}"
9783   [(set_attr "type" "alu1")
9784    (set_attr "mode" "QI")])
9786 (define_insn "*iorqi_3"
9787   [(set (reg FLAGS_REG)
9788         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9789                          (match_operand:QI 2 "general_operand" "qmn"))
9790                  (const_int 0)))
9791    (clobber (match_scratch:QI 0 "=q"))]
9792   "ix86_match_ccmode (insn, CCNOmode)
9793    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9794   "or{b}\t{%2, %0|%0, %2}"
9795   [(set_attr "type" "alu")
9796    (set_attr "mode" "QI")])
9798 (define_insn "*iorqi_ext_0"
9799   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9800                          (const_int 8)
9801                          (const_int 8))
9802         (ior:SI
9803           (zero_extract:SI
9804             (match_operand 1 "ext_register_operand" "0")
9805             (const_int 8)
9806             (const_int 8))
9807           (match_operand 2 "const_int_operand" "n")))
9808    (clobber (reg:CC FLAGS_REG))]
9809   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9810   "or{b}\t{%2, %h0|%h0, %2}"
9811   [(set_attr "type" "alu")
9812    (set_attr "length_immediate" "1")
9813    (set_attr "mode" "QI")])
9815 (define_insn "*iorqi_ext_1"
9816   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9817                          (const_int 8)
9818                          (const_int 8))
9819         (ior:SI
9820           (zero_extract:SI
9821             (match_operand 1 "ext_register_operand" "0")
9822             (const_int 8)
9823             (const_int 8))
9824           (zero_extend:SI
9825             (match_operand:QI 2 "general_operand" "Qm"))))
9826    (clobber (reg:CC FLAGS_REG))]
9827   "!TARGET_64BIT
9828    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9829   "or{b}\t{%2, %h0|%h0, %2}"
9830   [(set_attr "type" "alu")
9831    (set_attr "length_immediate" "0")
9832    (set_attr "mode" "QI")])
9834 (define_insn "*iorqi_ext_1_rex64"
9835   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9836                          (const_int 8)
9837                          (const_int 8))
9838         (ior:SI
9839           (zero_extract:SI
9840             (match_operand 1 "ext_register_operand" "0")
9841             (const_int 8)
9842             (const_int 8))
9843           (zero_extend:SI
9844             (match_operand 2 "ext_register_operand" "Q"))))
9845    (clobber (reg:CC FLAGS_REG))]
9846   "TARGET_64BIT
9847    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9848   "or{b}\t{%2, %h0|%h0, %2}"
9849   [(set_attr "type" "alu")
9850    (set_attr "length_immediate" "0")
9851    (set_attr "mode" "QI")])
9853 (define_insn "*iorqi_ext_2"
9854   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9855                          (const_int 8)
9856                          (const_int 8))
9857         (ior:SI
9858           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9859                            (const_int 8)
9860                            (const_int 8))
9861           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9862                            (const_int 8)
9863                            (const_int 8))))
9864    (clobber (reg:CC FLAGS_REG))]
9865   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9866   "ior{b}\t{%h2, %h0|%h0, %h2}"
9867   [(set_attr "type" "alu")
9868    (set_attr "length_immediate" "0")
9869    (set_attr "mode" "QI")])
9871 (define_split
9872   [(set (match_operand 0 "register_operand" "")
9873         (ior (match_operand 1 "register_operand" "")
9874              (match_operand 2 "const_int_operand" "")))
9875    (clobber (reg:CC FLAGS_REG))]
9876    "reload_completed
9877     && QI_REG_P (operands[0])
9878     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9879     && !(INTVAL (operands[2]) & ~(255 << 8))
9880     && GET_MODE (operands[0]) != QImode"
9881   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9882                    (ior:SI (zero_extract:SI (match_dup 1)
9883                                             (const_int 8) (const_int 8))
9884                            (match_dup 2)))
9885               (clobber (reg:CC FLAGS_REG))])]
9886   "operands[0] = gen_lowpart (SImode, operands[0]);
9887    operands[1] = gen_lowpart (SImode, operands[1]);
9888    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9890 ;; Since OR can be encoded with sign extended immediate, this is only
9891 ;; profitable when 7th bit is set.
9892 (define_split
9893   [(set (match_operand 0 "register_operand" "")
9894         (ior (match_operand 1 "general_operand" "")
9895              (match_operand 2 "const_int_operand" "")))
9896    (clobber (reg:CC FLAGS_REG))]
9897    "reload_completed
9898     && ANY_QI_REG_P (operands[0])
9899     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9900     && !(INTVAL (operands[2]) & ~255)
9901     && (INTVAL (operands[2]) & 128)
9902     && GET_MODE (operands[0]) != QImode"
9903   [(parallel [(set (strict_low_part (match_dup 0))
9904                    (ior:QI (match_dup 1)
9905                            (match_dup 2)))
9906               (clobber (reg:CC FLAGS_REG))])]
9907   "operands[0] = gen_lowpart (QImode, operands[0]);
9908    operands[1] = gen_lowpart (QImode, operands[1]);
9909    operands[2] = gen_lowpart (QImode, operands[2]);")
9911 ;; Logical XOR instructions
9913 ;; %%% This used to optimize known byte-wide and operations to memory.
9914 ;; If this is considered useful, it should be done with splitters.
9916 (define_expand "xordi3"
9917   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9918         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9919                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9920   "TARGET_64BIT"
9921   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9923 (define_insn "*xordi_1_rex64"
9924   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9925         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9926                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9927    (clobber (reg:CC FLAGS_REG))]
9928   "TARGET_64BIT
9929    && ix86_binary_operator_ok (XOR, DImode, operands)"
9930   "xor{q}\t{%2, %0|%0, %2}"
9931   [(set_attr "type" "alu")
9932    (set_attr "mode" "DI")])
9934 (define_insn "*xordi_2_rex64"
9935   [(set (reg FLAGS_REG)
9936         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9937                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9938                  (const_int 0)))
9939    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9940         (xor:DI (match_dup 1) (match_dup 2)))]
9941   "TARGET_64BIT
9942    && ix86_match_ccmode (insn, CCNOmode)
9943    && ix86_binary_operator_ok (XOR, DImode, operands)"
9944   "xor{q}\t{%2, %0|%0, %2}"
9945   [(set_attr "type" "alu")
9946    (set_attr "mode" "DI")])
9948 (define_insn "*xordi_3_rex64"
9949   [(set (reg FLAGS_REG)
9950         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9951                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9952                  (const_int 0)))
9953    (clobber (match_scratch:DI 0 "=r"))]
9954   "TARGET_64BIT
9955    && ix86_match_ccmode (insn, CCNOmode)
9956    && ix86_binary_operator_ok (XOR, DImode, operands)"
9957   "xor{q}\t{%2, %0|%0, %2}"
9958   [(set_attr "type" "alu")
9959    (set_attr "mode" "DI")])
9961 (define_expand "xorsi3"
9962   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9963         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9964                 (match_operand:SI 2 "general_operand" "")))]
9965   ""
9966   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9968 (define_insn "*xorsi_1"
9969   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9970         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9971                 (match_operand:SI 2 "general_operand" "ri,rm")))
9972    (clobber (reg:CC FLAGS_REG))]
9973   "ix86_binary_operator_ok (XOR, SImode, operands)"
9974   "xor{l}\t{%2, %0|%0, %2}"
9975   [(set_attr "type" "alu")
9976    (set_attr "mode" "SI")])
9978 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9979 ;; Add speccase for immediates
9980 (define_insn "*xorsi_1_zext"
9981   [(set (match_operand:DI 0 "register_operand" "=r")
9982         (zero_extend:DI
9983           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9984                   (match_operand:SI 2 "general_operand" "g"))))
9985    (clobber (reg:CC FLAGS_REG))]
9986   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9987   "xor{l}\t{%2, %k0|%k0, %2}"
9988   [(set_attr "type" "alu")
9989    (set_attr "mode" "SI")])
9991 (define_insn "*xorsi_1_zext_imm"
9992   [(set (match_operand:DI 0 "register_operand" "=r")
9993         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9994                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9995    (clobber (reg:CC FLAGS_REG))]
9996   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9997   "xor{l}\t{%2, %k0|%k0, %2}"
9998   [(set_attr "type" "alu")
9999    (set_attr "mode" "SI")])
10001 (define_insn "*xorsi_2"
10002   [(set (reg FLAGS_REG)
10003         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10004                          (match_operand:SI 2 "general_operand" "g,ri"))
10005                  (const_int 0)))
10006    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10007         (xor:SI (match_dup 1) (match_dup 2)))]
10008   "ix86_match_ccmode (insn, CCNOmode)
10009    && ix86_binary_operator_ok (XOR, SImode, operands)"
10010   "xor{l}\t{%2, %0|%0, %2}"
10011   [(set_attr "type" "alu")
10012    (set_attr "mode" "SI")])
10014 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10015 ;; ??? Special case for immediate operand is missing - it is tricky.
10016 (define_insn "*xorsi_2_zext"
10017   [(set (reg FLAGS_REG)
10018         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10019                          (match_operand:SI 2 "general_operand" "g"))
10020                  (const_int 0)))
10021    (set (match_operand:DI 0 "register_operand" "=r")
10022         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10023   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10024    && ix86_binary_operator_ok (XOR, SImode, operands)"
10025   "xor{l}\t{%2, %k0|%k0, %2}"
10026   [(set_attr "type" "alu")
10027    (set_attr "mode" "SI")])
10029 (define_insn "*xorsi_2_zext_imm"
10030   [(set (reg FLAGS_REG)
10031         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10032                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10033                  (const_int 0)))
10034    (set (match_operand:DI 0 "register_operand" "=r")
10035         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10036   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10037    && ix86_binary_operator_ok (XOR, SImode, operands)"
10038   "xor{l}\t{%2, %k0|%k0, %2}"
10039   [(set_attr "type" "alu")
10040    (set_attr "mode" "SI")])
10042 (define_insn "*xorsi_3"
10043   [(set (reg FLAGS_REG)
10044         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10045                          (match_operand:SI 2 "general_operand" "g"))
10046                  (const_int 0)))
10047    (clobber (match_scratch:SI 0 "=r"))]
10048   "ix86_match_ccmode (insn, CCNOmode)
10049    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10050   "xor{l}\t{%2, %0|%0, %2}"
10051   [(set_attr "type" "alu")
10052    (set_attr "mode" "SI")])
10054 (define_expand "xorhi3"
10055   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10056         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10057                 (match_operand:HI 2 "general_operand" "")))]
10058   "TARGET_HIMODE_MATH"
10059   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10061 (define_insn "*xorhi_1"
10062   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10063         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10064                 (match_operand:HI 2 "general_operand" "rmn,rn")))
10065    (clobber (reg:CC FLAGS_REG))]
10066   "ix86_binary_operator_ok (XOR, HImode, operands)"
10067   "xor{w}\t{%2, %0|%0, %2}"
10068   [(set_attr "type" "alu")
10069    (set_attr "mode" "HI")])
10071 (define_insn "*xorhi_2"
10072   [(set (reg FLAGS_REG)
10073         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10074                          (match_operand:HI 2 "general_operand" "rmn,rn"))
10075                  (const_int 0)))
10076    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10077         (xor:HI (match_dup 1) (match_dup 2)))]
10078   "ix86_match_ccmode (insn, CCNOmode)
10079    && ix86_binary_operator_ok (XOR, HImode, operands)"
10080   "xor{w}\t{%2, %0|%0, %2}"
10081   [(set_attr "type" "alu")
10082    (set_attr "mode" "HI")])
10084 (define_insn "*xorhi_3"
10085   [(set (reg FLAGS_REG)
10086         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10087                          (match_operand:HI 2 "general_operand" "rmn"))
10088                  (const_int 0)))
10089    (clobber (match_scratch:HI 0 "=r"))]
10090   "ix86_match_ccmode (insn, CCNOmode)
10091    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10092   "xor{w}\t{%2, %0|%0, %2}"
10093   [(set_attr "type" "alu")
10094    (set_attr "mode" "HI")])
10096 (define_expand "xorqi3"
10097   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10098         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10099                 (match_operand:QI 2 "general_operand" "")))]
10100   "TARGET_QIMODE_MATH"
10101   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10103 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10104 (define_insn "*xorqi_1"
10105   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10106         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10107                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10108    (clobber (reg:CC FLAGS_REG))]
10109   "ix86_binary_operator_ok (XOR, QImode, operands)"
10110   "@
10111    xor{b}\t{%2, %0|%0, %2}
10112    xor{b}\t{%2, %0|%0, %2}
10113    xor{l}\t{%k2, %k0|%k0, %k2}"
10114   [(set_attr "type" "alu")
10115    (set_attr "mode" "QI,QI,SI")])
10117 (define_insn "*xorqi_1_slp"
10118   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10119         (xor:QI (match_dup 0)
10120                 (match_operand:QI 1 "general_operand" "qn,qmn")))
10121    (clobber (reg:CC FLAGS_REG))]
10122   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10123    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10124   "xor{b}\t{%1, %0|%0, %1}"
10125   [(set_attr "type" "alu1")
10126    (set_attr "mode" "QI")])
10128 (define_insn "*xorqi_ext_0"
10129   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10130                          (const_int 8)
10131                          (const_int 8))
10132         (xor:SI
10133           (zero_extract:SI
10134             (match_operand 1 "ext_register_operand" "0")
10135             (const_int 8)
10136             (const_int 8))
10137           (match_operand 2 "const_int_operand" "n")))
10138    (clobber (reg:CC FLAGS_REG))]
10139   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10140   "xor{b}\t{%2, %h0|%h0, %2}"
10141   [(set_attr "type" "alu")
10142    (set_attr "length_immediate" "1")
10143    (set_attr "mode" "QI")])
10145 (define_insn "*xorqi_ext_1"
10146   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10147                          (const_int 8)
10148                          (const_int 8))
10149         (xor:SI
10150           (zero_extract:SI
10151             (match_operand 1 "ext_register_operand" "0")
10152             (const_int 8)
10153             (const_int 8))
10154           (zero_extend:SI
10155             (match_operand:QI 2 "general_operand" "Qm"))))
10156    (clobber (reg:CC FLAGS_REG))]
10157   "!TARGET_64BIT
10158    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10159   "xor{b}\t{%2, %h0|%h0, %2}"
10160   [(set_attr "type" "alu")
10161    (set_attr "length_immediate" "0")
10162    (set_attr "mode" "QI")])
10164 (define_insn "*xorqi_ext_1_rex64"
10165   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10166                          (const_int 8)
10167                          (const_int 8))
10168         (xor:SI
10169           (zero_extract:SI
10170             (match_operand 1 "ext_register_operand" "0")
10171             (const_int 8)
10172             (const_int 8))
10173           (zero_extend:SI
10174             (match_operand 2 "ext_register_operand" "Q"))))
10175    (clobber (reg:CC FLAGS_REG))]
10176   "TARGET_64BIT
10177    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10178   "xor{b}\t{%2, %h0|%h0, %2}"
10179   [(set_attr "type" "alu")
10180    (set_attr "length_immediate" "0")
10181    (set_attr "mode" "QI")])
10183 (define_insn "*xorqi_ext_2"
10184   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10185                          (const_int 8)
10186                          (const_int 8))
10187         (xor:SI
10188           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10189                            (const_int 8)
10190                            (const_int 8))
10191           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10192                            (const_int 8)
10193                            (const_int 8))))
10194    (clobber (reg:CC FLAGS_REG))]
10195   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10196   "xor{b}\t{%h2, %h0|%h0, %h2}"
10197   [(set_attr "type" "alu")
10198    (set_attr "length_immediate" "0")
10199    (set_attr "mode" "QI")])
10201 (define_insn "*xorqi_cc_1"
10202   [(set (reg FLAGS_REG)
10203         (compare
10204           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10205                   (match_operand:QI 2 "general_operand" "qmn,qn"))
10206           (const_int 0)))
10207    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10208         (xor:QI (match_dup 1) (match_dup 2)))]
10209   "ix86_match_ccmode (insn, CCNOmode)
10210    && ix86_binary_operator_ok (XOR, QImode, operands)"
10211   "xor{b}\t{%2, %0|%0, %2}"
10212   [(set_attr "type" "alu")
10213    (set_attr "mode" "QI")])
10215 (define_insn "*xorqi_2_slp"
10216   [(set (reg FLAGS_REG)
10217         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10218                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10219                  (const_int 0)))
10220    (set (strict_low_part (match_dup 0))
10221         (xor:QI (match_dup 0) (match_dup 1)))]
10222   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10223    && ix86_match_ccmode (insn, CCNOmode)
10224    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10225   "xor{b}\t{%1, %0|%0, %1}"
10226   [(set_attr "type" "alu1")
10227    (set_attr "mode" "QI")])
10229 (define_insn "*xorqi_cc_2"
10230   [(set (reg FLAGS_REG)
10231         (compare
10232           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10233                   (match_operand:QI 2 "general_operand" "qmn"))
10234           (const_int 0)))
10235    (clobber (match_scratch:QI 0 "=q"))]
10236   "ix86_match_ccmode (insn, CCNOmode)
10237    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10238   "xor{b}\t{%2, %0|%0, %2}"
10239   [(set_attr "type" "alu")
10240    (set_attr "mode" "QI")])
10242 (define_insn "*xorqi_cc_ext_1"
10243   [(set (reg FLAGS_REG)
10244         (compare
10245           (xor:SI
10246             (zero_extract:SI
10247               (match_operand 1 "ext_register_operand" "0")
10248               (const_int 8)
10249               (const_int 8))
10250             (match_operand:QI 2 "general_operand" "qmn"))
10251           (const_int 0)))
10252    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10253                          (const_int 8)
10254                          (const_int 8))
10255         (xor:SI
10256           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10257           (match_dup 2)))]
10258   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10259   "xor{b}\t{%2, %h0|%h0, %2}"
10260   [(set_attr "type" "alu")
10261    (set_attr "mode" "QI")])
10263 (define_insn "*xorqi_cc_ext_1_rex64"
10264   [(set (reg FLAGS_REG)
10265         (compare
10266           (xor:SI
10267             (zero_extract:SI
10268               (match_operand 1 "ext_register_operand" "0")
10269               (const_int 8)
10270               (const_int 8))
10271             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10272           (const_int 0)))
10273    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10274                          (const_int 8)
10275                          (const_int 8))
10276         (xor:SI
10277           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10278           (match_dup 2)))]
10279   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10280   "xor{b}\t{%2, %h0|%h0, %2}"
10281   [(set_attr "type" "alu")
10282    (set_attr "mode" "QI")])
10284 (define_expand "xorqi_cc_ext_1"
10285   [(parallel [
10286      (set (reg:CCNO FLAGS_REG)
10287           (compare:CCNO
10288             (xor:SI
10289               (zero_extract:SI
10290                 (match_operand 1 "ext_register_operand" "")
10291                 (const_int 8)
10292                 (const_int 8))
10293               (match_operand:QI 2 "general_operand" ""))
10294             (const_int 0)))
10295      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10296                            (const_int 8)
10297                            (const_int 8))
10298           (xor:SI
10299             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10300             (match_dup 2)))])]
10301   ""
10302   "")
10304 (define_split
10305   [(set (match_operand 0 "register_operand" "")
10306         (xor (match_operand 1 "register_operand" "")
10307              (match_operand 2 "const_int_operand" "")))
10308    (clobber (reg:CC FLAGS_REG))]
10309    "reload_completed
10310     && QI_REG_P (operands[0])
10311     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10312     && !(INTVAL (operands[2]) & ~(255 << 8))
10313     && GET_MODE (operands[0]) != QImode"
10314   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10315                    (xor:SI (zero_extract:SI (match_dup 1)
10316                                             (const_int 8) (const_int 8))
10317                            (match_dup 2)))
10318               (clobber (reg:CC FLAGS_REG))])]
10319   "operands[0] = gen_lowpart (SImode, operands[0]);
10320    operands[1] = gen_lowpart (SImode, operands[1]);
10321    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10323 ;; Since XOR can be encoded with sign extended immediate, this is only
10324 ;; profitable when 7th bit is set.
10325 (define_split
10326   [(set (match_operand 0 "register_operand" "")
10327         (xor (match_operand 1 "general_operand" "")
10328              (match_operand 2 "const_int_operand" "")))
10329    (clobber (reg:CC FLAGS_REG))]
10330    "reload_completed
10331     && ANY_QI_REG_P (operands[0])
10332     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10333     && !(INTVAL (operands[2]) & ~255)
10334     && (INTVAL (operands[2]) & 128)
10335     && GET_MODE (operands[0]) != QImode"
10336   [(parallel [(set (strict_low_part (match_dup 0))
10337                    (xor:QI (match_dup 1)
10338                            (match_dup 2)))
10339               (clobber (reg:CC FLAGS_REG))])]
10340   "operands[0] = gen_lowpart (QImode, operands[0]);
10341    operands[1] = gen_lowpart (QImode, operands[1]);
10342    operands[2] = gen_lowpart (QImode, operands[2]);")
10344 ;; Negation instructions
10346 (define_expand "negti2"
10347   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10348         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10349   "TARGET_64BIT"
10350   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10352 (define_insn "*negti2_1"
10353   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10354         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10355    (clobber (reg:CC FLAGS_REG))]
10356   "TARGET_64BIT
10357    && ix86_unary_operator_ok (NEG, TImode, operands)"
10358   "#")
10360 (define_split
10361   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10362         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10363    (clobber (reg:CC FLAGS_REG))]
10364   "TARGET_64BIT && reload_completed"
10365   [(parallel
10366     [(set (reg:CCZ FLAGS_REG)
10367           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10368      (set (match_dup 0) (neg:DI (match_dup 1)))])
10369    (parallel
10370     [(set (match_dup 2)
10371           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10372                             (match_dup 3))
10373                    (const_int 0)))
10374      (clobber (reg:CC FLAGS_REG))])
10375    (parallel
10376     [(set (match_dup 2)
10377           (neg:DI (match_dup 2)))
10378      (clobber (reg:CC FLAGS_REG))])]
10379   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10381 (define_expand "negdi2"
10382   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10383         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10384   ""
10385   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10387 (define_insn "*negdi2_1"
10388   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10389         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10390    (clobber (reg:CC FLAGS_REG))]
10391   "!TARGET_64BIT
10392    && ix86_unary_operator_ok (NEG, DImode, operands)"
10393   "#")
10395 (define_split
10396   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10397         (neg:DI (match_operand:DI 1 "general_operand" "")))
10398    (clobber (reg:CC FLAGS_REG))]
10399   "!TARGET_64BIT && reload_completed"
10400   [(parallel
10401     [(set (reg:CCZ FLAGS_REG)
10402           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10403      (set (match_dup 0) (neg:SI (match_dup 1)))])
10404    (parallel
10405     [(set (match_dup 2)
10406           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10407                             (match_dup 3))
10408                    (const_int 0)))
10409      (clobber (reg:CC FLAGS_REG))])
10410    (parallel
10411     [(set (match_dup 2)
10412           (neg:SI (match_dup 2)))
10413      (clobber (reg:CC FLAGS_REG))])]
10414   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10416 (define_insn "*negdi2_1_rex64"
10417   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10418         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10419    (clobber (reg:CC FLAGS_REG))]
10420   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10421   "neg{q}\t%0"
10422   [(set_attr "type" "negnot")
10423    (set_attr "mode" "DI")])
10425 ;; The problem with neg is that it does not perform (compare x 0),
10426 ;; it really performs (compare 0 x), which leaves us with the zero
10427 ;; flag being the only useful item.
10429 (define_insn "*negdi2_cmpz_rex64"
10430   [(set (reg:CCZ FLAGS_REG)
10431         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10432                      (const_int 0)))
10433    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10434         (neg:DI (match_dup 1)))]
10435   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10436   "neg{q}\t%0"
10437   [(set_attr "type" "negnot")
10438    (set_attr "mode" "DI")])
10441 (define_expand "negsi2"
10442   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10443         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10444   ""
10445   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10447 (define_insn "*negsi2_1"
10448   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10449         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10450    (clobber (reg:CC FLAGS_REG))]
10451   "ix86_unary_operator_ok (NEG, SImode, operands)"
10452   "neg{l}\t%0"
10453   [(set_attr "type" "negnot")
10454    (set_attr "mode" "SI")])
10456 ;; Combine is quite creative about this pattern.
10457 (define_insn "*negsi2_1_zext"
10458   [(set (match_operand:DI 0 "register_operand" "=r")
10459         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10460                                         (const_int 32)))
10461                      (const_int 32)))
10462    (clobber (reg:CC FLAGS_REG))]
10463   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10464   "neg{l}\t%k0"
10465   [(set_attr "type" "negnot")
10466    (set_attr "mode" "SI")])
10468 ;; The problem with neg is that it does not perform (compare x 0),
10469 ;; it really performs (compare 0 x), which leaves us with the zero
10470 ;; flag being the only useful item.
10472 (define_insn "*negsi2_cmpz"
10473   [(set (reg:CCZ FLAGS_REG)
10474         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10475                      (const_int 0)))
10476    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10477         (neg:SI (match_dup 1)))]
10478   "ix86_unary_operator_ok (NEG, SImode, operands)"
10479   "neg{l}\t%0"
10480   [(set_attr "type" "negnot")
10481    (set_attr "mode" "SI")])
10483 (define_insn "*negsi2_cmpz_zext"
10484   [(set (reg:CCZ FLAGS_REG)
10485         (compare:CCZ (lshiftrt:DI
10486                        (neg:DI (ashift:DI
10487                                  (match_operand:DI 1 "register_operand" "0")
10488                                  (const_int 32)))
10489                        (const_int 32))
10490                      (const_int 0)))
10491    (set (match_operand:DI 0 "register_operand" "=r")
10492         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10493                                         (const_int 32)))
10494                      (const_int 32)))]
10495   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10496   "neg{l}\t%k0"
10497   [(set_attr "type" "negnot")
10498    (set_attr "mode" "SI")])
10500 (define_expand "neghi2"
10501   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10502         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10503   "TARGET_HIMODE_MATH"
10504   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10506 (define_insn "*neghi2_1"
10507   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10508         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10509    (clobber (reg:CC FLAGS_REG))]
10510   "ix86_unary_operator_ok (NEG, HImode, operands)"
10511   "neg{w}\t%0"
10512   [(set_attr "type" "negnot")
10513    (set_attr "mode" "HI")])
10515 (define_insn "*neghi2_cmpz"
10516   [(set (reg:CCZ FLAGS_REG)
10517         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10518                      (const_int 0)))
10519    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10520         (neg:HI (match_dup 1)))]
10521   "ix86_unary_operator_ok (NEG, HImode, operands)"
10522   "neg{w}\t%0"
10523   [(set_attr "type" "negnot")
10524    (set_attr "mode" "HI")])
10526 (define_expand "negqi2"
10527   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10528         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10529   "TARGET_QIMODE_MATH"
10530   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10532 (define_insn "*negqi2_1"
10533   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10534         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10535    (clobber (reg:CC FLAGS_REG))]
10536   "ix86_unary_operator_ok (NEG, QImode, operands)"
10537   "neg{b}\t%0"
10538   [(set_attr "type" "negnot")
10539    (set_attr "mode" "QI")])
10541 (define_insn "*negqi2_cmpz"
10542   [(set (reg:CCZ FLAGS_REG)
10543         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10544                      (const_int 0)))
10545    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10546         (neg:QI (match_dup 1)))]
10547   "ix86_unary_operator_ok (NEG, QImode, operands)"
10548   "neg{b}\t%0"
10549   [(set_attr "type" "negnot")
10550    (set_attr "mode" "QI")])
10552 ;; Changing of sign for FP values is doable using integer unit too.
10554 (define_expand "<code><mode>2"
10555   [(set (match_operand:X87MODEF 0 "register_operand" "")
10556         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10557   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10558   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10560 (define_insn "*absneg<mode>2_mixed"
10561   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10562         (match_operator:MODEF 3 "absneg_operator"
10563           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10564    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10565    (clobber (reg:CC FLAGS_REG))]
10566   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10567   "#")
10569 (define_insn "*absneg<mode>2_sse"
10570   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10571         (match_operator:MODEF 3 "absneg_operator"
10572           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10573    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10574    (clobber (reg:CC FLAGS_REG))]
10575   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10576   "#")
10578 (define_insn "*absneg<mode>2_i387"
10579   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10580         (match_operator:X87MODEF 3 "absneg_operator"
10581           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10582    (use (match_operand 2 "" ""))
10583    (clobber (reg:CC FLAGS_REG))]
10584   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10585   "#")
10587 (define_expand "<code>tf2"
10588   [(set (match_operand:TF 0 "register_operand" "")
10589         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10590   "TARGET_SSE2"
10591   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10593 (define_insn "*absnegtf2_sse"
10594   [(set (match_operand:TF 0 "register_operand" "=x,x")
10595         (match_operator:TF 3 "absneg_operator"
10596           [(match_operand:TF 1 "register_operand" "0,x")]))
10597    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10598    (clobber (reg:CC FLAGS_REG))]
10599   "TARGET_SSE2"
10600   "#")
10602 ;; Splitters for fp abs and neg.
10604 (define_split
10605   [(set (match_operand 0 "fp_register_operand" "")
10606         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10607    (use (match_operand 2 "" ""))
10608    (clobber (reg:CC FLAGS_REG))]
10609   "reload_completed"
10610   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10612 (define_split
10613   [(set (match_operand 0 "register_operand" "")
10614         (match_operator 3 "absneg_operator"
10615           [(match_operand 1 "register_operand" "")]))
10616    (use (match_operand 2 "nonimmediate_operand" ""))
10617    (clobber (reg:CC FLAGS_REG))]
10618   "reload_completed && SSE_REG_P (operands[0])"
10619   [(set (match_dup 0) (match_dup 3))]
10621   enum machine_mode mode = GET_MODE (operands[0]);
10622   enum machine_mode vmode = GET_MODE (operands[2]);
10623   rtx tmp;
10625   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10626   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10627   if (operands_match_p (operands[0], operands[2]))
10628     {
10629       tmp = operands[1];
10630       operands[1] = operands[2];
10631       operands[2] = tmp;
10632     }
10633   if (GET_CODE (operands[3]) == ABS)
10634     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10635   else
10636     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10637   operands[3] = tmp;
10640 (define_split
10641   [(set (match_operand:SF 0 "register_operand" "")
10642         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10643    (use (match_operand:V4SF 2 "" ""))
10644    (clobber (reg:CC FLAGS_REG))]
10645   "reload_completed"
10646   [(parallel [(set (match_dup 0) (match_dup 1))
10647               (clobber (reg:CC FLAGS_REG))])]
10649   rtx tmp;
10650   operands[0] = gen_lowpart (SImode, operands[0]);
10651   if (GET_CODE (operands[1]) == ABS)
10652     {
10653       tmp = gen_int_mode (0x7fffffff, SImode);
10654       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10655     }
10656   else
10657     {
10658       tmp = gen_int_mode (0x80000000, SImode);
10659       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10660     }
10661   operands[1] = tmp;
10664 (define_split
10665   [(set (match_operand:DF 0 "register_operand" "")
10666         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10667    (use (match_operand 2 "" ""))
10668    (clobber (reg:CC FLAGS_REG))]
10669   "reload_completed"
10670   [(parallel [(set (match_dup 0) (match_dup 1))
10671               (clobber (reg:CC FLAGS_REG))])]
10673   rtx tmp;
10674   if (TARGET_64BIT)
10675     {
10676       tmp = gen_lowpart (DImode, operands[0]);
10677       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10678       operands[0] = tmp;
10680       if (GET_CODE (operands[1]) == ABS)
10681         tmp = const0_rtx;
10682       else
10683         tmp = gen_rtx_NOT (DImode, tmp);
10684     }
10685   else
10686     {
10687       operands[0] = gen_highpart (SImode, operands[0]);
10688       if (GET_CODE (operands[1]) == ABS)
10689         {
10690           tmp = gen_int_mode (0x7fffffff, SImode);
10691           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10692         }
10693       else
10694         {
10695           tmp = gen_int_mode (0x80000000, SImode);
10696           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10697         }
10698     }
10699   operands[1] = tmp;
10702 (define_split
10703   [(set (match_operand:XF 0 "register_operand" "")
10704         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10705    (use (match_operand 2 "" ""))
10706    (clobber (reg:CC FLAGS_REG))]
10707   "reload_completed"
10708   [(parallel [(set (match_dup 0) (match_dup 1))
10709               (clobber (reg:CC FLAGS_REG))])]
10711   rtx tmp;
10712   operands[0] = gen_rtx_REG (SImode,
10713                              true_regnum (operands[0])
10714                              + (TARGET_64BIT ? 1 : 2));
10715   if (GET_CODE (operands[1]) == ABS)
10716     {
10717       tmp = GEN_INT (0x7fff);
10718       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10719     }
10720   else
10721     {
10722       tmp = GEN_INT (0x8000);
10723       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10724     }
10725   operands[1] = tmp;
10728 ;; Conditionalize these after reload. If they match before reload, we
10729 ;; lose the clobber and ability to use integer instructions.
10731 (define_insn "*<code><mode>2_1"
10732   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10733         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10734   "TARGET_80387
10735    && (reload_completed
10736        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10737   "f<absnegprefix>"
10738   [(set_attr "type" "fsgn")
10739    (set_attr "mode" "<MODE>")])
10741 (define_insn "*<code>extendsfdf2"
10742   [(set (match_operand:DF 0 "register_operand" "=f")
10743         (absneg:DF (float_extend:DF
10744                      (match_operand:SF 1 "register_operand" "0"))))]
10745   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10746   "f<absnegprefix>"
10747   [(set_attr "type" "fsgn")
10748    (set_attr "mode" "DF")])
10750 (define_insn "*<code>extendsfxf2"
10751   [(set (match_operand:XF 0 "register_operand" "=f")
10752         (absneg:XF (float_extend:XF
10753                      (match_operand:SF 1 "register_operand" "0"))))]
10754   "TARGET_80387"
10755   "f<absnegprefix>"
10756   [(set_attr "type" "fsgn")
10757    (set_attr "mode" "XF")])
10759 (define_insn "*<code>extenddfxf2"
10760   [(set (match_operand:XF 0 "register_operand" "=f")
10761         (absneg:XF (float_extend:XF
10762                       (match_operand:DF 1 "register_operand" "0"))))]
10763   "TARGET_80387"
10764   "f<absnegprefix>"
10765   [(set_attr "type" "fsgn")
10766    (set_attr "mode" "XF")])
10768 ;; Copysign instructions
10770 (define_mode_iterator CSGNMODE [SF DF TF])
10771 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10773 (define_expand "copysign<mode>3"
10774   [(match_operand:CSGNMODE 0 "register_operand" "")
10775    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10776    (match_operand:CSGNMODE 2 "register_operand" "")]
10777   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10778    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10780   ix86_expand_copysign (operands);
10781   DONE;
10784 (define_insn_and_split "copysign<mode>3_const"
10785   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10786         (unspec:CSGNMODE
10787           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10788            (match_operand:CSGNMODE 2 "register_operand" "0")
10789            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10790           UNSPEC_COPYSIGN))]
10791   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10792    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10793   "#"
10794   "&& reload_completed"
10795   [(const_int 0)]
10797   ix86_split_copysign_const (operands);
10798   DONE;
10801 (define_insn "copysign<mode>3_var"
10802   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10803         (unspec:CSGNMODE
10804           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10805            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10806            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10807            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10808           UNSPEC_COPYSIGN))
10809    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10810   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10811    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10812   "#")
10814 (define_split
10815   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10816         (unspec:CSGNMODE
10817           [(match_operand:CSGNMODE 2 "register_operand" "")
10818            (match_operand:CSGNMODE 3 "register_operand" "")
10819            (match_operand:<CSGNVMODE> 4 "" "")
10820            (match_operand:<CSGNVMODE> 5 "" "")]
10821           UNSPEC_COPYSIGN))
10822    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10823   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10824     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10825    && reload_completed"
10826   [(const_int 0)]
10828   ix86_split_copysign_var (operands);
10829   DONE;
10832 ;; One complement instructions
10834 (define_expand "one_cmpldi2"
10835   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10836         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10837   "TARGET_64BIT"
10838   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10840 (define_insn "*one_cmpldi2_1_rex64"
10841   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10842         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10843   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10844   "not{q}\t%0"
10845   [(set_attr "type" "negnot")
10846    (set_attr "mode" "DI")])
10848 (define_insn "*one_cmpldi2_2_rex64"
10849   [(set (reg FLAGS_REG)
10850         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10851                  (const_int 0)))
10852    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10853         (not:DI (match_dup 1)))]
10854   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10855    && ix86_unary_operator_ok (NOT, DImode, operands)"
10856   "#"
10857   [(set_attr "type" "alu1")
10858    (set_attr "mode" "DI")])
10860 (define_split
10861   [(set (match_operand 0 "flags_reg_operand" "")
10862         (match_operator 2 "compare_operator"
10863           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10864            (const_int 0)]))
10865    (set (match_operand:DI 1 "nonimmediate_operand" "")
10866         (not:DI (match_dup 3)))]
10867   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10868   [(parallel [(set (match_dup 0)
10869                    (match_op_dup 2
10870                      [(xor:DI (match_dup 3) (const_int -1))
10871                       (const_int 0)]))
10872               (set (match_dup 1)
10873                    (xor:DI (match_dup 3) (const_int -1)))])]
10874   "")
10876 (define_expand "one_cmplsi2"
10877   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10878         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10879   ""
10880   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10882 (define_insn "*one_cmplsi2_1"
10883   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10884         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10885   "ix86_unary_operator_ok (NOT, SImode, operands)"
10886   "not{l}\t%0"
10887   [(set_attr "type" "negnot")
10888    (set_attr "mode" "SI")])
10890 ;; ??? Currently never generated - xor is used instead.
10891 (define_insn "*one_cmplsi2_1_zext"
10892   [(set (match_operand:DI 0 "register_operand" "=r")
10893         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10894   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10895   "not{l}\t%k0"
10896   [(set_attr "type" "negnot")
10897    (set_attr "mode" "SI")])
10899 (define_insn "*one_cmplsi2_2"
10900   [(set (reg FLAGS_REG)
10901         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10902                  (const_int 0)))
10903    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10904         (not:SI (match_dup 1)))]
10905   "ix86_match_ccmode (insn, CCNOmode)
10906    && ix86_unary_operator_ok (NOT, SImode, operands)"
10907   "#"
10908   [(set_attr "type" "alu1")
10909    (set_attr "mode" "SI")])
10911 (define_split
10912   [(set (match_operand 0 "flags_reg_operand" "")
10913         (match_operator 2 "compare_operator"
10914           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10915            (const_int 0)]))
10916    (set (match_operand:SI 1 "nonimmediate_operand" "")
10917         (not:SI (match_dup 3)))]
10918   "ix86_match_ccmode (insn, CCNOmode)"
10919   [(parallel [(set (match_dup 0)
10920                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10921                                     (const_int 0)]))
10922               (set (match_dup 1)
10923                    (xor:SI (match_dup 3) (const_int -1)))])]
10924   "")
10926 ;; ??? Currently never generated - xor is used instead.
10927 (define_insn "*one_cmplsi2_2_zext"
10928   [(set (reg FLAGS_REG)
10929         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10930                  (const_int 0)))
10931    (set (match_operand:DI 0 "register_operand" "=r")
10932         (zero_extend:DI (not:SI (match_dup 1))))]
10933   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10934    && ix86_unary_operator_ok (NOT, SImode, operands)"
10935   "#"
10936   [(set_attr "type" "alu1")
10937    (set_attr "mode" "SI")])
10939 (define_split
10940   [(set (match_operand 0 "flags_reg_operand" "")
10941         (match_operator 2 "compare_operator"
10942           [(not:SI (match_operand:SI 3 "register_operand" ""))
10943            (const_int 0)]))
10944    (set (match_operand:DI 1 "register_operand" "")
10945         (zero_extend:DI (not:SI (match_dup 3))))]
10946   "ix86_match_ccmode (insn, CCNOmode)"
10947   [(parallel [(set (match_dup 0)
10948                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10949                                     (const_int 0)]))
10950               (set (match_dup 1)
10951                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10952   "")
10954 (define_expand "one_cmplhi2"
10955   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10956         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10957   "TARGET_HIMODE_MATH"
10958   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10960 (define_insn "*one_cmplhi2_1"
10961   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10962         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10963   "ix86_unary_operator_ok (NOT, HImode, operands)"
10964   "not{w}\t%0"
10965   [(set_attr "type" "negnot")
10966    (set_attr "mode" "HI")])
10968 (define_insn "*one_cmplhi2_2"
10969   [(set (reg FLAGS_REG)
10970         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10971                  (const_int 0)))
10972    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10973         (not:HI (match_dup 1)))]
10974   "ix86_match_ccmode (insn, CCNOmode)
10975    && ix86_unary_operator_ok (NEG, HImode, operands)"
10976   "#"
10977   [(set_attr "type" "alu1")
10978    (set_attr "mode" "HI")])
10980 (define_split
10981   [(set (match_operand 0 "flags_reg_operand" "")
10982         (match_operator 2 "compare_operator"
10983           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10984            (const_int 0)]))
10985    (set (match_operand:HI 1 "nonimmediate_operand" "")
10986         (not:HI (match_dup 3)))]
10987   "ix86_match_ccmode (insn, CCNOmode)"
10988   [(parallel [(set (match_dup 0)
10989                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10990                                     (const_int 0)]))
10991               (set (match_dup 1)
10992                    (xor:HI (match_dup 3) (const_int -1)))])]
10993   "")
10995 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10996 (define_expand "one_cmplqi2"
10997   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10998         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10999   "TARGET_QIMODE_MATH"
11000   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11002 (define_insn "*one_cmplqi2_1"
11003   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11004         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11005   "ix86_unary_operator_ok (NOT, QImode, operands)"
11006   "@
11007    not{b}\t%0
11008    not{l}\t%k0"
11009   [(set_attr "type" "negnot")
11010    (set_attr "mode" "QI,SI")])
11012 (define_insn "*one_cmplqi2_2"
11013   [(set (reg FLAGS_REG)
11014         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11015                  (const_int 0)))
11016    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11017         (not:QI (match_dup 1)))]
11018   "ix86_match_ccmode (insn, CCNOmode)
11019    && ix86_unary_operator_ok (NOT, QImode, operands)"
11020   "#"
11021   [(set_attr "type" "alu1")
11022    (set_attr "mode" "QI")])
11024 (define_split
11025   [(set (match_operand 0 "flags_reg_operand" "")
11026         (match_operator 2 "compare_operator"
11027           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11028            (const_int 0)]))
11029    (set (match_operand:QI 1 "nonimmediate_operand" "")
11030         (not:QI (match_dup 3)))]
11031   "ix86_match_ccmode (insn, CCNOmode)"
11032   [(parallel [(set (match_dup 0)
11033                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11034                                     (const_int 0)]))
11035               (set (match_dup 1)
11036                    (xor:QI (match_dup 3) (const_int -1)))])]
11037   "")
11039 ;; Arithmetic shift instructions
11041 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11042 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
11043 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11044 ;; from the assembler input.
11046 ;; This instruction shifts the target reg/mem as usual, but instead of
11047 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
11048 ;; is a left shift double, bits are taken from the high order bits of
11049 ;; reg, else if the insn is a shift right double, bits are taken from the
11050 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
11051 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11053 ;; Since sh[lr]d does not change the `reg' operand, that is done
11054 ;; separately, making all shifts emit pairs of shift double and normal
11055 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
11056 ;; support a 63 bit shift, each shift where the count is in a reg expands
11057 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11059 ;; If the shift count is a constant, we need never emit more than one
11060 ;; shift pair, instead using moves and sign extension for counts greater
11061 ;; than 31.
11063 (define_expand "ashlti3"
11064   [(set (match_operand:TI 0 "register_operand" "")
11065         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11066                    (match_operand:QI 2 "nonmemory_operand" "")))]
11067   "TARGET_64BIT"
11068   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11070 ;; This pattern must be defined before *ashlti3_1 to prevent
11071 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11073 (define_insn "*avx_ashlti3"
11074   [(set (match_operand:TI 0 "register_operand" "=x")
11075         (ashift:TI (match_operand:TI 1 "register_operand" "x")
11076                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11077   "TARGET_AVX"
11079   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11080   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11082   [(set_attr "type" "sseishft")
11083    (set_attr "prefix" "vex")
11084    (set_attr "mode" "TI")])
11086 (define_insn "sse2_ashlti3"
11087   [(set (match_operand:TI 0 "register_operand" "=x")
11088         (ashift:TI (match_operand:TI 1 "register_operand" "0")
11089                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11090   "TARGET_SSE2"
11092   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11093   return "pslldq\t{%2, %0|%0, %2}";
11095   [(set_attr "type" "sseishft")
11096    (set_attr "prefix_data16" "1")
11097    (set_attr "mode" "TI")])
11099 (define_insn "*ashlti3_1"
11100   [(set (match_operand:TI 0 "register_operand" "=&r,r")
11101         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11102                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11103    (clobber (reg:CC FLAGS_REG))]
11104   "TARGET_64BIT"
11105   "#"
11106   [(set_attr "type" "multi")])
11108 (define_peephole2
11109   [(match_scratch:DI 3 "r")
11110    (parallel [(set (match_operand:TI 0 "register_operand" "")
11111                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11112                               (match_operand:QI 2 "nonmemory_operand" "")))
11113               (clobber (reg:CC FLAGS_REG))])
11114    (match_dup 3)]
11115   "TARGET_64BIT"
11116   [(const_int 0)]
11117   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11119 (define_split
11120   [(set (match_operand:TI 0 "register_operand" "")
11121         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11122                    (match_operand:QI 2 "nonmemory_operand" "")))
11123    (clobber (reg:CC FLAGS_REG))]
11124   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11125                     ? epilogue_completed : reload_completed)"
11126   [(const_int 0)]
11127   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11129 (define_insn "x86_64_shld"
11130   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11131         (ior:DI (ashift:DI (match_dup 0)
11132                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11133                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11134                   (minus:QI (const_int 64) (match_dup 2)))))
11135    (clobber (reg:CC FLAGS_REG))]
11136   "TARGET_64BIT"
11137   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11138   [(set_attr "type" "ishift")
11139    (set_attr "prefix_0f" "1")
11140    (set_attr "mode" "DI")
11141    (set_attr "athlon_decode" "vector")
11142    (set_attr "amdfam10_decode" "vector")])
11144 (define_expand "x86_64_shift_adj_1"
11145   [(set (reg:CCZ FLAGS_REG)
11146         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11147                              (const_int 64))
11148                      (const_int 0)))
11149    (set (match_operand:DI 0 "register_operand" "")
11150         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11151                          (match_operand:DI 1 "register_operand" "")
11152                          (match_dup 0)))
11153    (set (match_dup 1)
11154         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11155                          (match_operand:DI 3 "register_operand" "r")
11156                          (match_dup 1)))]
11157   "TARGET_64BIT"
11158   "")
11160 (define_expand "x86_64_shift_adj_2"
11161   [(use (match_operand:DI 0 "register_operand" ""))
11162    (use (match_operand:DI 1 "register_operand" ""))
11163    (use (match_operand:QI 2 "register_operand" ""))]
11164   "TARGET_64BIT"
11166   rtx label = gen_label_rtx ();
11167   rtx tmp;
11169   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11171   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11172   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11173   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11174                               gen_rtx_LABEL_REF (VOIDmode, label),
11175                               pc_rtx);
11176   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11177   JUMP_LABEL (tmp) = label;
11179   emit_move_insn (operands[0], operands[1]);
11180   ix86_expand_clear (operands[1]);
11182   emit_label (label);
11183   LABEL_NUSES (label) = 1;
11185   DONE;
11188 (define_expand "ashldi3"
11189   [(set (match_operand:DI 0 "shiftdi_operand" "")
11190         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11191                    (match_operand:QI 2 "nonmemory_operand" "")))]
11192   ""
11193   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11195 (define_insn "*ashldi3_1_rex64"
11196   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11197         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11198                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11199    (clobber (reg:CC FLAGS_REG))]
11200   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11202   switch (get_attr_type (insn))
11203     {
11204     case TYPE_ALU:
11205       gcc_assert (operands[2] == const1_rtx);
11206       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11207       return "add{q}\t%0, %0";
11209     case TYPE_LEA:
11210       gcc_assert (CONST_INT_P (operands[2]));
11211       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11212       operands[1] = gen_rtx_MULT (DImode, operands[1],
11213                                   GEN_INT (1 << INTVAL (operands[2])));
11214       return "lea{q}\t{%a1, %0|%0, %a1}";
11216     default:
11217       if (REG_P (operands[2]))
11218         return "sal{q}\t{%b2, %0|%0, %b2}";
11219       else if (operands[2] == const1_rtx
11220                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11221         return "sal{q}\t%0";
11222       else
11223         return "sal{q}\t{%2, %0|%0, %2}";
11224     }
11226   [(set (attr "type")
11227      (cond [(eq_attr "alternative" "1")
11228               (const_string "lea")
11229             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11230                           (const_int 0))
11231                       (match_operand 0 "register_operand" ""))
11232                  (match_operand 2 "const1_operand" ""))
11233               (const_string "alu")
11234            ]
11235            (const_string "ishift")))
11236    (set_attr "mode" "DI")])
11238 ;; Convert lea to the lea pattern to avoid flags dependency.
11239 (define_split
11240   [(set (match_operand:DI 0 "register_operand" "")
11241         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11242                    (match_operand:QI 2 "immediate_operand" "")))
11243    (clobber (reg:CC FLAGS_REG))]
11244   "TARGET_64BIT && reload_completed
11245    && true_regnum (operands[0]) != true_regnum (operands[1])"
11246   [(set (match_dup 0)
11247         (mult:DI (match_dup 1)
11248                  (match_dup 2)))]
11249   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11251 ;; This pattern can't accept a variable shift count, since shifts by
11252 ;; zero don't affect the flags.  We assume that shifts by constant
11253 ;; zero are optimized away.
11254 (define_insn "*ashldi3_cmp_rex64"
11255   [(set (reg FLAGS_REG)
11256         (compare
11257           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11258                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11259           (const_int 0)))
11260    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11261         (ashift:DI (match_dup 1) (match_dup 2)))]
11262   "TARGET_64BIT
11263    && (optimize_function_for_size_p (cfun)
11264        || !TARGET_PARTIAL_FLAG_REG_STALL
11265        || (operands[2] == const1_rtx
11266            && (TARGET_SHIFT1
11267                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11268    && ix86_match_ccmode (insn, CCGOCmode)
11269    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11271   switch (get_attr_type (insn))
11272     {
11273     case TYPE_ALU:
11274       gcc_assert (operands[2] == const1_rtx);
11275       return "add{q}\t%0, %0";
11277     default:
11278       if (REG_P (operands[2]))
11279         return "sal{q}\t{%b2, %0|%0, %b2}";
11280       else if (operands[2] == const1_rtx
11281                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11282         return "sal{q}\t%0";
11283       else
11284         return "sal{q}\t{%2, %0|%0, %2}";
11285     }
11287   [(set (attr "type")
11288      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11289                           (const_int 0))
11290                       (match_operand 0 "register_operand" ""))
11291                  (match_operand 2 "const1_operand" ""))
11292               (const_string "alu")
11293            ]
11294            (const_string "ishift")))
11295    (set_attr "mode" "DI")])
11297 (define_insn "*ashldi3_cconly_rex64"
11298   [(set (reg FLAGS_REG)
11299         (compare
11300           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11301                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11302           (const_int 0)))
11303    (clobber (match_scratch:DI 0 "=r"))]
11304   "TARGET_64BIT
11305    && (optimize_function_for_size_p (cfun)
11306        || !TARGET_PARTIAL_FLAG_REG_STALL
11307        || (operands[2] == const1_rtx
11308            && (TARGET_SHIFT1
11309                || TARGET_DOUBLE_WITH_ADD)))
11310    && ix86_match_ccmode (insn, CCGOCmode)
11311    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11313   switch (get_attr_type (insn))
11314     {
11315     case TYPE_ALU:
11316       gcc_assert (operands[2] == const1_rtx);
11317       return "add{q}\t%0, %0";
11319     default:
11320       if (REG_P (operands[2]))
11321         return "sal{q}\t{%b2, %0|%0, %b2}";
11322       else if (operands[2] == const1_rtx
11323                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11324         return "sal{q}\t%0";
11325       else
11326         return "sal{q}\t{%2, %0|%0, %2}";
11327     }
11329   [(set (attr "type")
11330      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11331                           (const_int 0))
11332                       (match_operand 0 "register_operand" ""))
11333                  (match_operand 2 "const1_operand" ""))
11334               (const_string "alu")
11335            ]
11336            (const_string "ishift")))
11337    (set_attr "mode" "DI")])
11339 (define_insn "*ashldi3_1"
11340   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11341         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11342                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11343    (clobber (reg:CC FLAGS_REG))]
11344   "!TARGET_64BIT"
11345   "#"
11346   [(set_attr "type" "multi")])
11348 ;; By default we don't ask for a scratch register, because when DImode
11349 ;; values are manipulated, registers are already at a premium.  But if
11350 ;; we have one handy, we won't turn it away.
11351 (define_peephole2
11352   [(match_scratch:SI 3 "r")
11353    (parallel [(set (match_operand:DI 0 "register_operand" "")
11354                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11355                               (match_operand:QI 2 "nonmemory_operand" "")))
11356               (clobber (reg:CC FLAGS_REG))])
11357    (match_dup 3)]
11358   "!TARGET_64BIT && TARGET_CMOVE"
11359   [(const_int 0)]
11360   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11362 (define_split
11363   [(set (match_operand:DI 0 "register_operand" "")
11364         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11365                    (match_operand:QI 2 "nonmemory_operand" "")))
11366    (clobber (reg:CC FLAGS_REG))]
11367   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11368                      ? epilogue_completed : reload_completed)"
11369   [(const_int 0)]
11370   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11372 (define_insn "x86_shld"
11373   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11374         (ior:SI (ashift:SI (match_dup 0)
11375                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11376                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11377                   (minus:QI (const_int 32) (match_dup 2)))))
11378    (clobber (reg:CC FLAGS_REG))]
11379   ""
11380   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11381   [(set_attr "type" "ishift")
11382    (set_attr "prefix_0f" "1")
11383    (set_attr "mode" "SI")
11384    (set_attr "pent_pair" "np")
11385    (set_attr "athlon_decode" "vector")
11386    (set_attr "amdfam10_decode" "vector")])
11388 (define_expand "x86_shift_adj_1"
11389   [(set (reg:CCZ FLAGS_REG)
11390         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11391                              (const_int 32))
11392                      (const_int 0)))
11393    (set (match_operand:SI 0 "register_operand" "")
11394         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11395                          (match_operand:SI 1 "register_operand" "")
11396                          (match_dup 0)))
11397    (set (match_dup 1)
11398         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11399                          (match_operand:SI 3 "register_operand" "r")
11400                          (match_dup 1)))]
11401   "TARGET_CMOVE"
11402   "")
11404 (define_expand "x86_shift_adj_2"
11405   [(use (match_operand:SI 0 "register_operand" ""))
11406    (use (match_operand:SI 1 "register_operand" ""))
11407    (use (match_operand:QI 2 "register_operand" ""))]
11408   ""
11410   rtx label = gen_label_rtx ();
11411   rtx tmp;
11413   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11415   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11416   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11417   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11418                               gen_rtx_LABEL_REF (VOIDmode, label),
11419                               pc_rtx);
11420   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11421   JUMP_LABEL (tmp) = label;
11423   emit_move_insn (operands[0], operands[1]);
11424   ix86_expand_clear (operands[1]);
11426   emit_label (label);
11427   LABEL_NUSES (label) = 1;
11429   DONE;
11432 (define_expand "ashlsi3"
11433   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11434         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11435                    (match_operand:QI 2 "nonmemory_operand" "")))]
11436   ""
11437   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11439 (define_insn "*ashlsi3_1"
11440   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11441         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11442                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11443    (clobber (reg:CC FLAGS_REG))]
11444   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11446   switch (get_attr_type (insn))
11447     {
11448     case TYPE_ALU:
11449       gcc_assert (operands[2] == const1_rtx);
11450       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11451       return "add{l}\t%0, %0";
11453     case TYPE_LEA:
11454       return "#";
11456     default:
11457       if (REG_P (operands[2]))
11458         return "sal{l}\t{%b2, %0|%0, %b2}";
11459       else if (operands[2] == const1_rtx
11460                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11461         return "sal{l}\t%0";
11462       else
11463         return "sal{l}\t{%2, %0|%0, %2}";
11464     }
11466   [(set (attr "type")
11467      (cond [(eq_attr "alternative" "1")
11468               (const_string "lea")
11469             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11470                           (const_int 0))
11471                       (match_operand 0 "register_operand" ""))
11472                  (match_operand 2 "const1_operand" ""))
11473               (const_string "alu")
11474            ]
11475            (const_string "ishift")))
11476    (set_attr "mode" "SI")])
11478 ;; Convert lea to the lea pattern to avoid flags dependency.
11479 (define_split
11480   [(set (match_operand 0 "register_operand" "")
11481         (ashift (match_operand 1 "index_register_operand" "")
11482                 (match_operand:QI 2 "const_int_operand" "")))
11483    (clobber (reg:CC FLAGS_REG))]
11484   "reload_completed
11485    && true_regnum (operands[0]) != true_regnum (operands[1])
11486    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11487   [(const_int 0)]
11489   rtx pat;
11490   enum machine_mode mode = GET_MODE (operands[0]);
11492   if (GET_MODE_SIZE (mode) < 4)
11493     operands[0] = gen_lowpart (SImode, operands[0]);
11494   if (mode != Pmode)
11495     operands[1] = gen_lowpart (Pmode, operands[1]);
11496   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11498   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11499   if (Pmode != SImode)
11500     pat = gen_rtx_SUBREG (SImode, pat, 0);
11501   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11502   DONE;
11505 ;; Rare case of shifting RSP is handled by generating move and shift
11506 (define_split
11507   [(set (match_operand 0 "register_operand" "")
11508         (ashift (match_operand 1 "register_operand" "")
11509                 (match_operand:QI 2 "const_int_operand" "")))
11510    (clobber (reg:CC FLAGS_REG))]
11511   "reload_completed
11512    && true_regnum (operands[0]) != true_regnum (operands[1])"
11513   [(const_int 0)]
11515   rtx pat, clob;
11516   emit_move_insn (operands[0], operands[1]);
11517   pat = gen_rtx_SET (VOIDmode, operands[0],
11518                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11519                                      operands[0], operands[2]));
11520   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11521   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11522   DONE;
11525 (define_insn "*ashlsi3_1_zext"
11526   [(set (match_operand:DI 0 "register_operand" "=r,r")
11527         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11528                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11529    (clobber (reg:CC FLAGS_REG))]
11530   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11532   switch (get_attr_type (insn))
11533     {
11534     case TYPE_ALU:
11535       gcc_assert (operands[2] == const1_rtx);
11536       return "add{l}\t%k0, %k0";
11538     case TYPE_LEA:
11539       return "#";
11541     default:
11542       if (REG_P (operands[2]))
11543         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11544       else if (operands[2] == const1_rtx
11545                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11546         return "sal{l}\t%k0";
11547       else
11548         return "sal{l}\t{%2, %k0|%k0, %2}";
11549     }
11551   [(set (attr "type")
11552      (cond [(eq_attr "alternative" "1")
11553               (const_string "lea")
11554             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11555                      (const_int 0))
11556                  (match_operand 2 "const1_operand" ""))
11557               (const_string "alu")
11558            ]
11559            (const_string "ishift")))
11560    (set_attr "mode" "SI")])
11562 ;; Convert lea to the lea pattern to avoid flags dependency.
11563 (define_split
11564   [(set (match_operand:DI 0 "register_operand" "")
11565         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11566                                 (match_operand:QI 2 "const_int_operand" ""))))
11567    (clobber (reg:CC FLAGS_REG))]
11568   "TARGET_64BIT && reload_completed
11569    && true_regnum (operands[0]) != true_regnum (operands[1])"
11570   [(set (match_dup 0) (zero_extend:DI
11571                         (subreg:SI (mult:SI (match_dup 1)
11572                                             (match_dup 2)) 0)))]
11574   operands[1] = gen_lowpart (Pmode, operands[1]);
11575   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11578 ;; This pattern can't accept a variable shift count, since shifts by
11579 ;; zero don't affect the flags.  We assume that shifts by constant
11580 ;; zero are optimized away.
11581 (define_insn "*ashlsi3_cmp"
11582   [(set (reg FLAGS_REG)
11583         (compare
11584           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11585                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11586           (const_int 0)))
11587    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11588         (ashift:SI (match_dup 1) (match_dup 2)))]
11589    "(optimize_function_for_size_p (cfun)
11590      || !TARGET_PARTIAL_FLAG_REG_STALL
11591      || (operands[2] == const1_rtx
11592          && (TARGET_SHIFT1
11593              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11594    && ix86_match_ccmode (insn, CCGOCmode)
11595    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11597   switch (get_attr_type (insn))
11598     {
11599     case TYPE_ALU:
11600       gcc_assert (operands[2] == const1_rtx);
11601       return "add{l}\t%0, %0";
11603     default:
11604       if (REG_P (operands[2]))
11605         return "sal{l}\t{%b2, %0|%0, %b2}";
11606       else if (operands[2] == const1_rtx
11607                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11608         return "sal{l}\t%0";
11609       else
11610         return "sal{l}\t{%2, %0|%0, %2}";
11611     }
11613   [(set (attr "type")
11614      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11615                           (const_int 0))
11616                       (match_operand 0 "register_operand" ""))
11617                  (match_operand 2 "const1_operand" ""))
11618               (const_string "alu")
11619            ]
11620            (const_string "ishift")))
11621    (set_attr "mode" "SI")])
11623 (define_insn "*ashlsi3_cconly"
11624   [(set (reg FLAGS_REG)
11625         (compare
11626           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11627                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11628           (const_int 0)))
11629    (clobber (match_scratch:SI 0 "=r"))]
11630   "(optimize_function_for_size_p (cfun)
11631     || !TARGET_PARTIAL_FLAG_REG_STALL
11632     || (operands[2] == const1_rtx
11633         && (TARGET_SHIFT1
11634             || TARGET_DOUBLE_WITH_ADD)))
11635    && ix86_match_ccmode (insn, CCGOCmode)
11636    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11638   switch (get_attr_type (insn))
11639     {
11640     case TYPE_ALU:
11641       gcc_assert (operands[2] == const1_rtx);
11642       return "add{l}\t%0, %0";
11644     default:
11645       if (REG_P (operands[2]))
11646         return "sal{l}\t{%b2, %0|%0, %b2}";
11647       else if (operands[2] == const1_rtx
11648                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11649         return "sal{l}\t%0";
11650       else
11651         return "sal{l}\t{%2, %0|%0, %2}";
11652     }
11654   [(set (attr "type")
11655      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11656                           (const_int 0))
11657                       (match_operand 0 "register_operand" ""))
11658                  (match_operand 2 "const1_operand" ""))
11659               (const_string "alu")
11660            ]
11661            (const_string "ishift")))
11662    (set_attr "mode" "SI")])
11664 (define_insn "*ashlsi3_cmp_zext"
11665   [(set (reg FLAGS_REG)
11666         (compare
11667           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11668                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11669           (const_int 0)))
11670    (set (match_operand:DI 0 "register_operand" "=r")
11671         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11672   "TARGET_64BIT
11673    && (optimize_function_for_size_p (cfun)
11674        || !TARGET_PARTIAL_FLAG_REG_STALL
11675        || (operands[2] == const1_rtx
11676            && (TARGET_SHIFT1
11677                || TARGET_DOUBLE_WITH_ADD)))
11678    && ix86_match_ccmode (insn, CCGOCmode)
11679    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11681   switch (get_attr_type (insn))
11682     {
11683     case TYPE_ALU:
11684       gcc_assert (operands[2] == const1_rtx);
11685       return "add{l}\t%k0, %k0";
11687     default:
11688       if (REG_P (operands[2]))
11689         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11690       else if (operands[2] == const1_rtx
11691                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11692         return "sal{l}\t%k0";
11693       else
11694         return "sal{l}\t{%2, %k0|%k0, %2}";
11695     }
11697   [(set (attr "type")
11698      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11699                      (const_int 0))
11700                  (match_operand 2 "const1_operand" ""))
11701               (const_string "alu")
11702            ]
11703            (const_string "ishift")))
11704    (set_attr "mode" "SI")])
11706 (define_expand "ashlhi3"
11707   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11708         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11709                    (match_operand:QI 2 "nonmemory_operand" "")))]
11710   "TARGET_HIMODE_MATH"
11711   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11713 (define_insn "*ashlhi3_1_lea"
11714   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11715         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11716                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11717    (clobber (reg:CC FLAGS_REG))]
11718   "!TARGET_PARTIAL_REG_STALL
11719    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11721   switch (get_attr_type (insn))
11722     {
11723     case TYPE_LEA:
11724       return "#";
11725     case TYPE_ALU:
11726       gcc_assert (operands[2] == const1_rtx);
11727       return "add{w}\t%0, %0";
11729     default:
11730       if (REG_P (operands[2]))
11731         return "sal{w}\t{%b2, %0|%0, %b2}";
11732       else if (operands[2] == const1_rtx
11733                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11734         return "sal{w}\t%0";
11735       else
11736         return "sal{w}\t{%2, %0|%0, %2}";
11737     }
11739   [(set (attr "type")
11740      (cond [(eq_attr "alternative" "1")
11741               (const_string "lea")
11742             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11743                           (const_int 0))
11744                       (match_operand 0 "register_operand" ""))
11745                  (match_operand 2 "const1_operand" ""))
11746               (const_string "alu")
11747            ]
11748            (const_string "ishift")))
11749    (set_attr "mode" "HI,SI")])
11751 (define_insn "*ashlhi3_1"
11752   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11753         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11754                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11755    (clobber (reg:CC FLAGS_REG))]
11756   "TARGET_PARTIAL_REG_STALL
11757    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11759   switch (get_attr_type (insn))
11760     {
11761     case TYPE_ALU:
11762       gcc_assert (operands[2] == const1_rtx);
11763       return "add{w}\t%0, %0";
11765     default:
11766       if (REG_P (operands[2]))
11767         return "sal{w}\t{%b2, %0|%0, %b2}";
11768       else if (operands[2] == const1_rtx
11769                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11770         return "sal{w}\t%0";
11771       else
11772         return "sal{w}\t{%2, %0|%0, %2}";
11773     }
11775   [(set (attr "type")
11776      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11777                           (const_int 0))
11778                       (match_operand 0 "register_operand" ""))
11779                  (match_operand 2 "const1_operand" ""))
11780               (const_string "alu")
11781            ]
11782            (const_string "ishift")))
11783    (set_attr "mode" "HI")])
11785 ;; This pattern can't accept a variable shift count, since shifts by
11786 ;; zero don't affect the flags.  We assume that shifts by constant
11787 ;; zero are optimized away.
11788 (define_insn "*ashlhi3_cmp"
11789   [(set (reg FLAGS_REG)
11790         (compare
11791           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11792                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11793           (const_int 0)))
11794    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11795         (ashift:HI (match_dup 1) (match_dup 2)))]
11796   "(optimize_function_for_size_p (cfun)
11797     || !TARGET_PARTIAL_FLAG_REG_STALL
11798     || (operands[2] == const1_rtx
11799         && (TARGET_SHIFT1
11800             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11801    && ix86_match_ccmode (insn, CCGOCmode)
11802    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11804   switch (get_attr_type (insn))
11805     {
11806     case TYPE_ALU:
11807       gcc_assert (operands[2] == const1_rtx);
11808       return "add{w}\t%0, %0";
11810     default:
11811       if (REG_P (operands[2]))
11812         return "sal{w}\t{%b2, %0|%0, %b2}";
11813       else if (operands[2] == const1_rtx
11814                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11815         return "sal{w}\t%0";
11816       else
11817         return "sal{w}\t{%2, %0|%0, %2}";
11818     }
11820   [(set (attr "type")
11821      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11822                           (const_int 0))
11823                       (match_operand 0 "register_operand" ""))
11824                  (match_operand 2 "const1_operand" ""))
11825               (const_string "alu")
11826            ]
11827            (const_string "ishift")))
11828    (set_attr "mode" "HI")])
11830 (define_insn "*ashlhi3_cconly"
11831   [(set (reg FLAGS_REG)
11832         (compare
11833           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11834                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11835           (const_int 0)))
11836    (clobber (match_scratch:HI 0 "=r"))]
11837   "(optimize_function_for_size_p (cfun)
11838     || !TARGET_PARTIAL_FLAG_REG_STALL
11839     || (operands[2] == const1_rtx
11840         && (TARGET_SHIFT1
11841             || TARGET_DOUBLE_WITH_ADD)))
11842    && ix86_match_ccmode (insn, CCGOCmode)
11843    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11845   switch (get_attr_type (insn))
11846     {
11847     case TYPE_ALU:
11848       gcc_assert (operands[2] == const1_rtx);
11849       return "add{w}\t%0, %0";
11851     default:
11852       if (REG_P (operands[2]))
11853         return "sal{w}\t{%b2, %0|%0, %b2}";
11854       else if (operands[2] == const1_rtx
11855                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11856         return "sal{w}\t%0";
11857       else
11858         return "sal{w}\t{%2, %0|%0, %2}";
11859     }
11861   [(set (attr "type")
11862      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11863                           (const_int 0))
11864                       (match_operand 0 "register_operand" ""))
11865                  (match_operand 2 "const1_operand" ""))
11866               (const_string "alu")
11867            ]
11868            (const_string "ishift")))
11869    (set_attr "mode" "HI")])
11871 (define_expand "ashlqi3"
11872   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11873         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11874                    (match_operand:QI 2 "nonmemory_operand" "")))]
11875   "TARGET_QIMODE_MATH"
11876   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11878 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11880 (define_insn "*ashlqi3_1_lea"
11881   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11882         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11883                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11884    (clobber (reg:CC FLAGS_REG))]
11885   "!TARGET_PARTIAL_REG_STALL
11886    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11888   switch (get_attr_type (insn))
11889     {
11890     case TYPE_LEA:
11891       return "#";
11892     case TYPE_ALU:
11893       gcc_assert (operands[2] == const1_rtx);
11894       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11895         return "add{l}\t%k0, %k0";
11896       else
11897         return "add{b}\t%0, %0";
11899     default:
11900       if (REG_P (operands[2]))
11901         {
11902           if (get_attr_mode (insn) == MODE_SI)
11903             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11904           else
11905             return "sal{b}\t{%b2, %0|%0, %b2}";
11906         }
11907       else if (operands[2] == const1_rtx
11908                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11909         {
11910           if (get_attr_mode (insn) == MODE_SI)
11911             return "sal{l}\t%0";
11912           else
11913             return "sal{b}\t%0";
11914         }
11915       else
11916         {
11917           if (get_attr_mode (insn) == MODE_SI)
11918             return "sal{l}\t{%2, %k0|%k0, %2}";
11919           else
11920             return "sal{b}\t{%2, %0|%0, %2}";
11921         }
11922     }
11924   [(set (attr "type")
11925      (cond [(eq_attr "alternative" "2")
11926               (const_string "lea")
11927             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11928                           (const_int 0))
11929                       (match_operand 0 "register_operand" ""))
11930                  (match_operand 2 "const1_operand" ""))
11931               (const_string "alu")
11932            ]
11933            (const_string "ishift")))
11934    (set_attr "mode" "QI,SI,SI")])
11936 (define_insn "*ashlqi3_1"
11937   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11938         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11939                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11940    (clobber (reg:CC FLAGS_REG))]
11941   "TARGET_PARTIAL_REG_STALL
11942    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11944   switch (get_attr_type (insn))
11945     {
11946     case TYPE_ALU:
11947       gcc_assert (operands[2] == const1_rtx);
11948       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11949         return "add{l}\t%k0, %k0";
11950       else
11951         return "add{b}\t%0, %0";
11953     default:
11954       if (REG_P (operands[2]))
11955         {
11956           if (get_attr_mode (insn) == MODE_SI)
11957             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11958           else
11959             return "sal{b}\t{%b2, %0|%0, %b2}";
11960         }
11961       else if (operands[2] == const1_rtx
11962                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11963         {
11964           if (get_attr_mode (insn) == MODE_SI)
11965             return "sal{l}\t%0";
11966           else
11967             return "sal{b}\t%0";
11968         }
11969       else
11970         {
11971           if (get_attr_mode (insn) == MODE_SI)
11972             return "sal{l}\t{%2, %k0|%k0, %2}";
11973           else
11974             return "sal{b}\t{%2, %0|%0, %2}";
11975         }
11976     }
11978   [(set (attr "type")
11979      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11980                           (const_int 0))
11981                       (match_operand 0 "register_operand" ""))
11982                  (match_operand 2 "const1_operand" ""))
11983               (const_string "alu")
11984            ]
11985            (const_string "ishift")))
11986    (set_attr "mode" "QI,SI")])
11988 ;; This pattern can't accept a variable shift count, since shifts by
11989 ;; zero don't affect the flags.  We assume that shifts by constant
11990 ;; zero are optimized away.
11991 (define_insn "*ashlqi3_cmp"
11992   [(set (reg FLAGS_REG)
11993         (compare
11994           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11995                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11996           (const_int 0)))
11997    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11998         (ashift:QI (match_dup 1) (match_dup 2)))]
11999   "(optimize_function_for_size_p (cfun)
12000     || !TARGET_PARTIAL_FLAG_REG_STALL
12001     || (operands[2] == const1_rtx
12002         && (TARGET_SHIFT1
12003             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12004    && ix86_match_ccmode (insn, CCGOCmode)
12005    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12007   switch (get_attr_type (insn))
12008     {
12009     case TYPE_ALU:
12010       gcc_assert (operands[2] == const1_rtx);
12011       return "add{b}\t%0, %0";
12013     default:
12014       if (REG_P (operands[2]))
12015         return "sal{b}\t{%b2, %0|%0, %b2}";
12016       else if (operands[2] == const1_rtx
12017                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12018         return "sal{b}\t%0";
12019       else
12020         return "sal{b}\t{%2, %0|%0, %2}";
12021     }
12023   [(set (attr "type")
12024      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12025                           (const_int 0))
12026                       (match_operand 0 "register_operand" ""))
12027                  (match_operand 2 "const1_operand" ""))
12028               (const_string "alu")
12029            ]
12030            (const_string "ishift")))
12031    (set_attr "mode" "QI")])
12033 (define_insn "*ashlqi3_cconly"
12034   [(set (reg FLAGS_REG)
12035         (compare
12036           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12037                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12038           (const_int 0)))
12039    (clobber (match_scratch:QI 0 "=q"))]
12040   "(optimize_function_for_size_p (cfun)
12041     || !TARGET_PARTIAL_FLAG_REG_STALL
12042     || (operands[2] == const1_rtx
12043         && (TARGET_SHIFT1
12044             || TARGET_DOUBLE_WITH_ADD)))
12045    && ix86_match_ccmode (insn, CCGOCmode)
12046    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12048   switch (get_attr_type (insn))
12049     {
12050     case TYPE_ALU:
12051       gcc_assert (operands[2] == const1_rtx);
12052       return "add{b}\t%0, %0";
12054     default:
12055       if (REG_P (operands[2]))
12056         return "sal{b}\t{%b2, %0|%0, %b2}";
12057       else if (operands[2] == const1_rtx
12058                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12059         return "sal{b}\t%0";
12060       else
12061         return "sal{b}\t{%2, %0|%0, %2}";
12062     }
12064   [(set (attr "type")
12065      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12066                           (const_int 0))
12067                       (match_operand 0 "register_operand" ""))
12068                  (match_operand 2 "const1_operand" ""))
12069               (const_string "alu")
12070            ]
12071            (const_string "ishift")))
12072    (set_attr "mode" "QI")])
12074 ;; See comment above `ashldi3' about how this works.
12076 (define_expand "ashrti3"
12077   [(set (match_operand:TI 0 "register_operand" "")
12078         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12079                      (match_operand:QI 2 "nonmemory_operand" "")))]
12080   "TARGET_64BIT"
12081   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12083 (define_insn "*ashrti3_1"
12084   [(set (match_operand:TI 0 "register_operand" "=r")
12085         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12086                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12087    (clobber (reg:CC FLAGS_REG))]
12088   "TARGET_64BIT"
12089   "#"
12090   [(set_attr "type" "multi")])
12092 (define_peephole2
12093   [(match_scratch:DI 3 "r")
12094    (parallel [(set (match_operand:TI 0 "register_operand" "")
12095                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12096                                 (match_operand:QI 2 "nonmemory_operand" "")))
12097               (clobber (reg:CC FLAGS_REG))])
12098    (match_dup 3)]
12099   "TARGET_64BIT"
12100   [(const_int 0)]
12101   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12103 (define_split
12104   [(set (match_operand:TI 0 "register_operand" "")
12105         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12106                      (match_operand:QI 2 "nonmemory_operand" "")))
12107    (clobber (reg:CC FLAGS_REG))]
12108   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12109                     ? epilogue_completed : reload_completed)"
12110   [(const_int 0)]
12111   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12113 (define_insn "x86_64_shrd"
12114   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12115         (ior:DI (ashiftrt:DI (match_dup 0)
12116                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
12117                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12118                   (minus:QI (const_int 64) (match_dup 2)))))
12119    (clobber (reg:CC FLAGS_REG))]
12120   "TARGET_64BIT"
12121   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12122   [(set_attr "type" "ishift")
12123    (set_attr "prefix_0f" "1")
12124    (set_attr "mode" "DI")
12125    (set_attr "athlon_decode" "vector")
12126    (set_attr "amdfam10_decode" "vector")])
12128 (define_expand "ashrdi3"
12129   [(set (match_operand:DI 0 "shiftdi_operand" "")
12130         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12131                      (match_operand:QI 2 "nonmemory_operand" "")))]
12132   ""
12133   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12135 (define_expand "x86_64_shift_adj_3"
12136   [(use (match_operand:DI 0 "register_operand" ""))
12137    (use (match_operand:DI 1 "register_operand" ""))
12138    (use (match_operand:QI 2 "register_operand" ""))]
12139   ""
12141   rtx label = gen_label_rtx ();
12142   rtx tmp;
12144   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12146   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12147   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12148   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12149                               gen_rtx_LABEL_REF (VOIDmode, label),
12150                               pc_rtx);
12151   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12152   JUMP_LABEL (tmp) = label;
12154   emit_move_insn (operands[0], operands[1]);
12155   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12157   emit_label (label);
12158   LABEL_NUSES (label) = 1;
12160   DONE;
12163 (define_insn "ashrdi3_63_rex64"
12164   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12165         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12166                      (match_operand:DI 2 "const_int_operand" "i,i")))
12167    (clobber (reg:CC FLAGS_REG))]
12168   "TARGET_64BIT && INTVAL (operands[2]) == 63
12169    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12170    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12171   "@
12172    {cqto|cqo}
12173    sar{q}\t{%2, %0|%0, %2}"
12174   [(set_attr "type" "imovx,ishift")
12175    (set_attr "prefix_0f" "0,*")
12176    (set_attr "length_immediate" "0,*")
12177    (set_attr "modrm" "0,1")
12178    (set_attr "mode" "DI")])
12180 (define_insn "*ashrdi3_1_one_bit_rex64"
12181   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12182         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12183                      (match_operand:QI 2 "const1_operand" "")))
12184    (clobber (reg:CC FLAGS_REG))]
12185   "TARGET_64BIT
12186    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12187    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12188   "sar{q}\t%0"
12189   [(set_attr "type" "ishift")
12190    (set (attr "length")
12191      (if_then_else (match_operand:DI 0 "register_operand" "")
12192         (const_string "2")
12193         (const_string "*")))])
12195 (define_insn "*ashrdi3_1_rex64"
12196   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12197         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12198                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12199    (clobber (reg:CC FLAGS_REG))]
12200   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12201   "@
12202    sar{q}\t{%2, %0|%0, %2}
12203    sar{q}\t{%b2, %0|%0, %b2}"
12204   [(set_attr "type" "ishift")
12205    (set_attr "mode" "DI")])
12207 ;; This pattern can't accept a variable shift count, since shifts by
12208 ;; zero don't affect the flags.  We assume that shifts by constant
12209 ;; zero are optimized away.
12210 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12211   [(set (reg FLAGS_REG)
12212         (compare
12213           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12214                        (match_operand:QI 2 "const1_operand" ""))
12215           (const_int 0)))
12216    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12217         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12218   "TARGET_64BIT
12219    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12220    && ix86_match_ccmode (insn, CCGOCmode)
12221    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12222   "sar{q}\t%0"
12223   [(set_attr "type" "ishift")
12224    (set (attr "length")
12225      (if_then_else (match_operand:DI 0 "register_operand" "")
12226         (const_string "2")
12227         (const_string "*")))])
12229 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12230   [(set (reg FLAGS_REG)
12231         (compare
12232           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12233                        (match_operand:QI 2 "const1_operand" ""))
12234           (const_int 0)))
12235    (clobber (match_scratch:DI 0 "=r"))]
12236   "TARGET_64BIT
12237    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12238    && ix86_match_ccmode (insn, CCGOCmode)
12239    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12240   "sar{q}\t%0"
12241   [(set_attr "type" "ishift")
12242    (set_attr "length" "2")])
12244 ;; This pattern can't accept a variable shift count, since shifts by
12245 ;; zero don't affect the flags.  We assume that shifts by constant
12246 ;; zero are optimized away.
12247 (define_insn "*ashrdi3_cmp_rex64"
12248   [(set (reg FLAGS_REG)
12249         (compare
12250           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12251                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12252           (const_int 0)))
12253    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12254         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12255   "TARGET_64BIT
12256    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12257    && ix86_match_ccmode (insn, CCGOCmode)
12258    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12259   "sar{q}\t{%2, %0|%0, %2}"
12260   [(set_attr "type" "ishift")
12261    (set_attr "mode" "DI")])
12263 (define_insn "*ashrdi3_cconly_rex64"
12264   [(set (reg FLAGS_REG)
12265         (compare
12266           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12267                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12268           (const_int 0)))
12269    (clobber (match_scratch:DI 0 "=r"))]
12270   "TARGET_64BIT
12271    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12272    && ix86_match_ccmode (insn, CCGOCmode)
12273    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12274   "sar{q}\t{%2, %0|%0, %2}"
12275   [(set_attr "type" "ishift")
12276    (set_attr "mode" "DI")])
12278 (define_insn "*ashrdi3_1"
12279   [(set (match_operand:DI 0 "register_operand" "=r")
12280         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12281                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12282    (clobber (reg:CC FLAGS_REG))]
12283   "!TARGET_64BIT"
12284   "#"
12285   [(set_attr "type" "multi")])
12287 ;; By default we don't ask for a scratch register, because when DImode
12288 ;; values are manipulated, registers are already at a premium.  But if
12289 ;; we have one handy, we won't turn it away.
12290 (define_peephole2
12291   [(match_scratch:SI 3 "r")
12292    (parallel [(set (match_operand:DI 0 "register_operand" "")
12293                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12294                                 (match_operand:QI 2 "nonmemory_operand" "")))
12295               (clobber (reg:CC FLAGS_REG))])
12296    (match_dup 3)]
12297   "!TARGET_64BIT && TARGET_CMOVE"
12298   [(const_int 0)]
12299   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12301 (define_split
12302   [(set (match_operand:DI 0 "register_operand" "")
12303         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12304                      (match_operand:QI 2 "nonmemory_operand" "")))
12305    (clobber (reg:CC FLAGS_REG))]
12306   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12307                      ? epilogue_completed : reload_completed)"
12308   [(const_int 0)]
12309   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12311 (define_insn "x86_shrd"
12312   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12313         (ior:SI (ashiftrt:SI (match_dup 0)
12314                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
12315                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12316                   (minus:QI (const_int 32) (match_dup 2)))))
12317    (clobber (reg:CC FLAGS_REG))]
12318   ""
12319   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12320   [(set_attr "type" "ishift")
12321    (set_attr "prefix_0f" "1")
12322    (set_attr "pent_pair" "np")
12323    (set_attr "mode" "SI")])
12325 (define_expand "x86_shift_adj_3"
12326   [(use (match_operand:SI 0 "register_operand" ""))
12327    (use (match_operand:SI 1 "register_operand" ""))
12328    (use (match_operand:QI 2 "register_operand" ""))]
12329   ""
12331   rtx label = gen_label_rtx ();
12332   rtx tmp;
12334   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12336   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12337   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12338   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12339                               gen_rtx_LABEL_REF (VOIDmode, label),
12340                               pc_rtx);
12341   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12342   JUMP_LABEL (tmp) = label;
12344   emit_move_insn (operands[0], operands[1]);
12345   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12347   emit_label (label);
12348   LABEL_NUSES (label) = 1;
12350   DONE;
12353 (define_expand "ashrsi3_31"
12354   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12355                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12356                                 (match_operand:SI 2 "const_int_operand" "i,i")))
12357               (clobber (reg:CC FLAGS_REG))])]
12358   "")
12360 (define_insn "*ashrsi3_31"
12361   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12362         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12363                      (match_operand:SI 2 "const_int_operand" "i,i")))
12364    (clobber (reg:CC FLAGS_REG))]
12365   "INTVAL (operands[2]) == 31
12366    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12367    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12368   "@
12369    {cltd|cdq}
12370    sar{l}\t{%2, %0|%0, %2}"
12371   [(set_attr "type" "imovx,ishift")
12372    (set_attr "prefix_0f" "0,*")
12373    (set_attr "length_immediate" "0,*")
12374    (set_attr "modrm" "0,1")
12375    (set_attr "mode" "SI")])
12377 (define_insn "*ashrsi3_31_zext"
12378   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12379         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12380                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12381    (clobber (reg:CC FLAGS_REG))]
12382   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12383    && INTVAL (operands[2]) == 31
12384    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12385   "@
12386    {cltd|cdq}
12387    sar{l}\t{%2, %k0|%k0, %2}"
12388   [(set_attr "type" "imovx,ishift")
12389    (set_attr "prefix_0f" "0,*")
12390    (set_attr "length_immediate" "0,*")
12391    (set_attr "modrm" "0,1")
12392    (set_attr "mode" "SI")])
12394 (define_expand "ashrsi3"
12395   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12396         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12397                      (match_operand:QI 2 "nonmemory_operand" "")))]
12398   ""
12399   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12401 (define_insn "*ashrsi3_1_one_bit"
12402   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12403         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12404                      (match_operand:QI 2 "const1_operand" "")))
12405    (clobber (reg:CC FLAGS_REG))]
12406   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12407    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12408   "sar{l}\t%0"
12409   [(set_attr "type" "ishift")
12410    (set (attr "length")
12411      (if_then_else (match_operand:SI 0 "register_operand" "")
12412         (const_string "2")
12413         (const_string "*")))])
12415 (define_insn "*ashrsi3_1_one_bit_zext"
12416   [(set (match_operand:DI 0 "register_operand" "=r")
12417         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12418                                      (match_operand:QI 2 "const1_operand" ""))))
12419    (clobber (reg:CC FLAGS_REG))]
12420   "TARGET_64BIT
12421    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12422    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12423   "sar{l}\t%k0"
12424   [(set_attr "type" "ishift")
12425    (set_attr "length" "2")])
12427 (define_insn "*ashrsi3_1"
12428   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12429         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12430                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12431    (clobber (reg:CC FLAGS_REG))]
12432   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12433   "@
12434    sar{l}\t{%2, %0|%0, %2}
12435    sar{l}\t{%b2, %0|%0, %b2}"
12436   [(set_attr "type" "ishift")
12437    (set_attr "mode" "SI")])
12439 (define_insn "*ashrsi3_1_zext"
12440   [(set (match_operand:DI 0 "register_operand" "=r,r")
12441         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12442                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12443    (clobber (reg:CC FLAGS_REG))]
12444   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12445   "@
12446    sar{l}\t{%2, %k0|%k0, %2}
12447    sar{l}\t{%b2, %k0|%k0, %b2}"
12448   [(set_attr "type" "ishift")
12449    (set_attr "mode" "SI")])
12451 ;; This pattern can't accept a variable shift count, since shifts by
12452 ;; zero don't affect the flags.  We assume that shifts by constant
12453 ;; zero are optimized away.
12454 (define_insn "*ashrsi3_one_bit_cmp"
12455   [(set (reg FLAGS_REG)
12456         (compare
12457           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12458                        (match_operand:QI 2 "const1_operand" ""))
12459           (const_int 0)))
12460    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12461         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12462   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12463    && ix86_match_ccmode (insn, CCGOCmode)
12464    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12465   "sar{l}\t%0"
12466   [(set_attr "type" "ishift")
12467    (set (attr "length")
12468      (if_then_else (match_operand:SI 0 "register_operand" "")
12469         (const_string "2")
12470         (const_string "*")))])
12472 (define_insn "*ashrsi3_one_bit_cconly"
12473   [(set (reg FLAGS_REG)
12474         (compare
12475           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12476                        (match_operand:QI 2 "const1_operand" ""))
12477           (const_int 0)))
12478    (clobber (match_scratch:SI 0 "=r"))]
12479   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12480    && ix86_match_ccmode (insn, CCGOCmode)
12481    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12482   "sar{l}\t%0"
12483   [(set_attr "type" "ishift")
12484    (set_attr "length" "2")])
12486 (define_insn "*ashrsi3_one_bit_cmp_zext"
12487   [(set (reg FLAGS_REG)
12488         (compare
12489           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12490                        (match_operand:QI 2 "const1_operand" ""))
12491           (const_int 0)))
12492    (set (match_operand:DI 0 "register_operand" "=r")
12493         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12494   "TARGET_64BIT
12495    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12496    && ix86_match_ccmode (insn, CCmode)
12497    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12498   "sar{l}\t%k0"
12499   [(set_attr "type" "ishift")
12500    (set_attr "length" "2")])
12502 ;; This pattern can't accept a variable shift count, since shifts by
12503 ;; zero don't affect the flags.  We assume that shifts by constant
12504 ;; zero are optimized away.
12505 (define_insn "*ashrsi3_cmp"
12506   [(set (reg FLAGS_REG)
12507         (compare
12508           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12509                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12510           (const_int 0)))
12511    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12512         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12513   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12514    && ix86_match_ccmode (insn, CCGOCmode)
12515    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12516   "sar{l}\t{%2, %0|%0, %2}"
12517   [(set_attr "type" "ishift")
12518    (set_attr "mode" "SI")])
12520 (define_insn "*ashrsi3_cconly"
12521   [(set (reg FLAGS_REG)
12522         (compare
12523           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12524                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12525           (const_int 0)))
12526    (clobber (match_scratch:SI 0 "=r"))]
12527   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12528    && ix86_match_ccmode (insn, CCGOCmode)
12529    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12530   "sar{l}\t{%2, %0|%0, %2}"
12531   [(set_attr "type" "ishift")
12532    (set_attr "mode" "SI")])
12534 (define_insn "*ashrsi3_cmp_zext"
12535   [(set (reg FLAGS_REG)
12536         (compare
12537           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12538                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12539           (const_int 0)))
12540    (set (match_operand:DI 0 "register_operand" "=r")
12541         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12542   "TARGET_64BIT
12543    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12544    && ix86_match_ccmode (insn, CCGOCmode)
12545    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12546   "sar{l}\t{%2, %k0|%k0, %2}"
12547   [(set_attr "type" "ishift")
12548    (set_attr "mode" "SI")])
12550 (define_expand "ashrhi3"
12551   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12552         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12553                      (match_operand:QI 2 "nonmemory_operand" "")))]
12554   "TARGET_HIMODE_MATH"
12555   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12557 (define_insn "*ashrhi3_1_one_bit"
12558   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12559         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12560                      (match_operand:QI 2 "const1_operand" "")))
12561    (clobber (reg:CC FLAGS_REG))]
12562   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12563    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12564   "sar{w}\t%0"
12565   [(set_attr "type" "ishift")
12566    (set (attr "length")
12567      (if_then_else (match_operand 0 "register_operand" "")
12568         (const_string "2")
12569         (const_string "*")))])
12571 (define_insn "*ashrhi3_1"
12572   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12573         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12574                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12575    (clobber (reg:CC FLAGS_REG))]
12576   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12577   "@
12578    sar{w}\t{%2, %0|%0, %2}
12579    sar{w}\t{%b2, %0|%0, %b2}"
12580   [(set_attr "type" "ishift")
12581    (set_attr "mode" "HI")])
12583 ;; This pattern can't accept a variable shift count, since shifts by
12584 ;; zero don't affect the flags.  We assume that shifts by constant
12585 ;; zero are optimized away.
12586 (define_insn "*ashrhi3_one_bit_cmp"
12587   [(set (reg FLAGS_REG)
12588         (compare
12589           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12590                        (match_operand:QI 2 "const1_operand" ""))
12591           (const_int 0)))
12592    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12593         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12594   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12595    && ix86_match_ccmode (insn, CCGOCmode)
12596    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12597   "sar{w}\t%0"
12598   [(set_attr "type" "ishift")
12599    (set (attr "length")
12600      (if_then_else (match_operand 0 "register_operand" "")
12601         (const_string "2")
12602         (const_string "*")))])
12604 (define_insn "*ashrhi3_one_bit_cconly"
12605   [(set (reg FLAGS_REG)
12606         (compare
12607           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12608                        (match_operand:QI 2 "const1_operand" ""))
12609           (const_int 0)))
12610    (clobber (match_scratch:HI 0 "=r"))]
12611   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12612    && ix86_match_ccmode (insn, CCGOCmode)
12613    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12614   "sar{w}\t%0"
12615   [(set_attr "type" "ishift")
12616    (set_attr "length" "2")])
12618 ;; This pattern can't accept a variable shift count, since shifts by
12619 ;; zero don't affect the flags.  We assume that shifts by constant
12620 ;; zero are optimized away.
12621 (define_insn "*ashrhi3_cmp"
12622   [(set (reg FLAGS_REG)
12623         (compare
12624           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12625                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12626           (const_int 0)))
12627    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12628         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12629   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12630    && ix86_match_ccmode (insn, CCGOCmode)
12631    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12632   "sar{w}\t{%2, %0|%0, %2}"
12633   [(set_attr "type" "ishift")
12634    (set_attr "mode" "HI")])
12636 (define_insn "*ashrhi3_cconly"
12637   [(set (reg FLAGS_REG)
12638         (compare
12639           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12640                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12641           (const_int 0)))
12642    (clobber (match_scratch:HI 0 "=r"))]
12643   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12644    && ix86_match_ccmode (insn, CCGOCmode)
12645    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12646   "sar{w}\t{%2, %0|%0, %2}"
12647   [(set_attr "type" "ishift")
12648    (set_attr "mode" "HI")])
12650 (define_expand "ashrqi3"
12651   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12652         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12653                      (match_operand:QI 2 "nonmemory_operand" "")))]
12654   "TARGET_QIMODE_MATH"
12655   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12657 (define_insn "*ashrqi3_1_one_bit"
12658   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12659         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12660                      (match_operand:QI 2 "const1_operand" "")))
12661    (clobber (reg:CC FLAGS_REG))]
12662   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12663    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12664   "sar{b}\t%0"
12665   [(set_attr "type" "ishift")
12666    (set (attr "length")
12667      (if_then_else (match_operand 0 "register_operand" "")
12668         (const_string "2")
12669         (const_string "*")))])
12671 (define_insn "*ashrqi3_1_one_bit_slp"
12672   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12673         (ashiftrt:QI (match_dup 0)
12674                      (match_operand:QI 1 "const1_operand" "")))
12675    (clobber (reg:CC FLAGS_REG))]
12676   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12677    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12678    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12679   "sar{b}\t%0"
12680   [(set_attr "type" "ishift1")
12681    (set (attr "length")
12682      (if_then_else (match_operand 0 "register_operand" "")
12683         (const_string "2")
12684         (const_string "*")))])
12686 (define_insn "*ashrqi3_1"
12687   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12688         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12689                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12690    (clobber (reg:CC FLAGS_REG))]
12691   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12692   "@
12693    sar{b}\t{%2, %0|%0, %2}
12694    sar{b}\t{%b2, %0|%0, %b2}"
12695   [(set_attr "type" "ishift")
12696    (set_attr "mode" "QI")])
12698 (define_insn "*ashrqi3_1_slp"
12699   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12700         (ashiftrt:QI (match_dup 0)
12701                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12702    (clobber (reg:CC FLAGS_REG))]
12703   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12704    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12705   "@
12706    sar{b}\t{%1, %0|%0, %1}
12707    sar{b}\t{%b1, %0|%0, %b1}"
12708   [(set_attr "type" "ishift1")
12709    (set_attr "mode" "QI")])
12711 ;; This pattern can't accept a variable shift count, since shifts by
12712 ;; zero don't affect the flags.  We assume that shifts by constant
12713 ;; zero are optimized away.
12714 (define_insn "*ashrqi3_one_bit_cmp"
12715   [(set (reg FLAGS_REG)
12716         (compare
12717           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12718                        (match_operand:QI 2 "const1_operand" "I"))
12719           (const_int 0)))
12720    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12721         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12722   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12723    && ix86_match_ccmode (insn, CCGOCmode)
12724    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12725   "sar{b}\t%0"
12726   [(set_attr "type" "ishift")
12727    (set (attr "length")
12728      (if_then_else (match_operand 0 "register_operand" "")
12729         (const_string "2")
12730         (const_string "*")))])
12732 (define_insn "*ashrqi3_one_bit_cconly"
12733   [(set (reg FLAGS_REG)
12734         (compare
12735           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12736                        (match_operand:QI 2 "const1_operand" ""))
12737           (const_int 0)))
12738    (clobber (match_scratch:QI 0 "=q"))]
12739   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12740    && ix86_match_ccmode (insn, CCGOCmode)
12741    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12742   "sar{b}\t%0"
12743   [(set_attr "type" "ishift")
12744    (set_attr "length" "2")])
12746 ;; This pattern can't accept a variable shift count, since shifts by
12747 ;; zero don't affect the flags.  We assume that shifts by constant
12748 ;; zero are optimized away.
12749 (define_insn "*ashrqi3_cmp"
12750   [(set (reg FLAGS_REG)
12751         (compare
12752           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12753                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12754           (const_int 0)))
12755    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12756         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12757   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12758    && ix86_match_ccmode (insn, CCGOCmode)
12759    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12760   "sar{b}\t{%2, %0|%0, %2}"
12761   [(set_attr "type" "ishift")
12762    (set_attr "mode" "QI")])
12764 (define_insn "*ashrqi3_cconly"
12765   [(set (reg FLAGS_REG)
12766         (compare
12767           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12768                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12769           (const_int 0)))
12770    (clobber (match_scratch:QI 0 "=q"))]
12771   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12772    && ix86_match_ccmode (insn, CCGOCmode)
12773    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12774   "sar{b}\t{%2, %0|%0, %2}"
12775   [(set_attr "type" "ishift")
12776    (set_attr "mode" "QI")])
12779 ;; Logical shift instructions
12781 ;; See comment above `ashldi3' about how this works.
12783 (define_expand "lshrti3"
12784   [(set (match_operand:TI 0 "register_operand" "")
12785         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12786                      (match_operand:QI 2 "nonmemory_operand" "")))]
12787   "TARGET_64BIT"
12788   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12790 ;; This pattern must be defined before *lshrti3_1 to prevent
12791 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12793 (define_insn "*avx_lshrti3"
12794   [(set (match_operand:TI 0 "register_operand" "=x")
12795         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12796                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12797   "TARGET_AVX"
12799   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12800   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12802   [(set_attr "type" "sseishft")
12803    (set_attr "prefix" "vex")
12804    (set_attr "mode" "TI")])
12806 (define_insn "sse2_lshrti3"
12807   [(set (match_operand:TI 0 "register_operand" "=x")
12808         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12809                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12810   "TARGET_SSE2"
12812   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12813   return "psrldq\t{%2, %0|%0, %2}";
12815   [(set_attr "type" "sseishft")
12816    (set_attr "prefix_data16" "1")
12817    (set_attr "mode" "TI")])
12819 (define_insn "*lshrti3_1"
12820   [(set (match_operand:TI 0 "register_operand" "=r")
12821         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12822                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12823    (clobber (reg:CC FLAGS_REG))]
12824   "TARGET_64BIT"
12825   "#"
12826   [(set_attr "type" "multi")])
12828 (define_peephole2
12829   [(match_scratch:DI 3 "r")
12830    (parallel [(set (match_operand:TI 0 "register_operand" "")
12831                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12832                                 (match_operand:QI 2 "nonmemory_operand" "")))
12833               (clobber (reg:CC FLAGS_REG))])
12834    (match_dup 3)]
12835   "TARGET_64BIT"
12836   [(const_int 0)]
12837   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12839 (define_split
12840   [(set (match_operand:TI 0 "register_operand" "")
12841         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12842                      (match_operand:QI 2 "nonmemory_operand" "")))
12843    (clobber (reg:CC FLAGS_REG))]
12844   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12845                     ? epilogue_completed : reload_completed)"
12846   [(const_int 0)]
12847   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12849 (define_expand "lshrdi3"
12850   [(set (match_operand:DI 0 "shiftdi_operand" "")
12851         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12852                      (match_operand:QI 2 "nonmemory_operand" "")))]
12853   ""
12854   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12856 (define_insn "*lshrdi3_1_one_bit_rex64"
12857   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12858         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12859                      (match_operand:QI 2 "const1_operand" "")))
12860    (clobber (reg:CC FLAGS_REG))]
12861   "TARGET_64BIT
12862    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12863    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12864   "shr{q}\t%0"
12865   [(set_attr "type" "ishift")
12866    (set (attr "length")
12867      (if_then_else (match_operand:DI 0 "register_operand" "")
12868         (const_string "2")
12869         (const_string "*")))])
12871 (define_insn "*lshrdi3_1_rex64"
12872   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12873         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12874                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12875    (clobber (reg:CC FLAGS_REG))]
12876   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12877   "@
12878    shr{q}\t{%2, %0|%0, %2}
12879    shr{q}\t{%b2, %0|%0, %b2}"
12880   [(set_attr "type" "ishift")
12881    (set_attr "mode" "DI")])
12883 ;; This pattern can't accept a variable shift count, since shifts by
12884 ;; zero don't affect the flags.  We assume that shifts by constant
12885 ;; zero are optimized away.
12886 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12887   [(set (reg FLAGS_REG)
12888         (compare
12889           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12890                        (match_operand:QI 2 "const1_operand" ""))
12891           (const_int 0)))
12892    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12893         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12894   "TARGET_64BIT
12895    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12896    && ix86_match_ccmode (insn, CCGOCmode)
12897    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12898   "shr{q}\t%0"
12899   [(set_attr "type" "ishift")
12900    (set (attr "length")
12901      (if_then_else (match_operand:DI 0 "register_operand" "")
12902         (const_string "2")
12903         (const_string "*")))])
12905 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12906   [(set (reg FLAGS_REG)
12907         (compare
12908           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12909                        (match_operand:QI 2 "const1_operand" ""))
12910           (const_int 0)))
12911    (clobber (match_scratch:DI 0 "=r"))]
12912   "TARGET_64BIT
12913    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12914    && ix86_match_ccmode (insn, CCGOCmode)
12915    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12916   "shr{q}\t%0"
12917   [(set_attr "type" "ishift")
12918    (set_attr "length" "2")])
12920 ;; This pattern can't accept a variable shift count, since shifts by
12921 ;; zero don't affect the flags.  We assume that shifts by constant
12922 ;; zero are optimized away.
12923 (define_insn "*lshrdi3_cmp_rex64"
12924   [(set (reg FLAGS_REG)
12925         (compare
12926           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12927                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12928           (const_int 0)))
12929    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12930         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12931   "TARGET_64BIT
12932    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12933    && ix86_match_ccmode (insn, CCGOCmode)
12934    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12935   "shr{q}\t{%2, %0|%0, %2}"
12936   [(set_attr "type" "ishift")
12937    (set_attr "mode" "DI")])
12939 (define_insn "*lshrdi3_cconly_rex64"
12940   [(set (reg FLAGS_REG)
12941         (compare
12942           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12943                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12944           (const_int 0)))
12945    (clobber (match_scratch:DI 0 "=r"))]
12946   "TARGET_64BIT
12947    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12948    && ix86_match_ccmode (insn, CCGOCmode)
12949    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12950   "shr{q}\t{%2, %0|%0, %2}"
12951   [(set_attr "type" "ishift")
12952    (set_attr "mode" "DI")])
12954 (define_insn "*lshrdi3_1"
12955   [(set (match_operand:DI 0 "register_operand" "=r")
12956         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12957                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12958    (clobber (reg:CC FLAGS_REG))]
12959   "!TARGET_64BIT"
12960   "#"
12961   [(set_attr "type" "multi")])
12963 ;; By default we don't ask for a scratch register, because when DImode
12964 ;; values are manipulated, registers are already at a premium.  But if
12965 ;; we have one handy, we won't turn it away.
12966 (define_peephole2
12967   [(match_scratch:SI 3 "r")
12968    (parallel [(set (match_operand:DI 0 "register_operand" "")
12969                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12970                                 (match_operand:QI 2 "nonmemory_operand" "")))
12971               (clobber (reg:CC FLAGS_REG))])
12972    (match_dup 3)]
12973   "!TARGET_64BIT && TARGET_CMOVE"
12974   [(const_int 0)]
12975   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12977 (define_split
12978   [(set (match_operand:DI 0 "register_operand" "")
12979         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12980                      (match_operand:QI 2 "nonmemory_operand" "")))
12981    (clobber (reg:CC FLAGS_REG))]
12982   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12983                      ? epilogue_completed : reload_completed)"
12984   [(const_int 0)]
12985   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12987 (define_expand "lshrsi3"
12988   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12989         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12990                      (match_operand:QI 2 "nonmemory_operand" "")))]
12991   ""
12992   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12994 (define_insn "*lshrsi3_1_one_bit"
12995   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12996         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12997                      (match_operand:QI 2 "const1_operand" "")))
12998    (clobber (reg:CC FLAGS_REG))]
12999   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13000    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13001   "shr{l}\t%0"
13002   [(set_attr "type" "ishift")
13003    (set (attr "length")
13004      (if_then_else (match_operand:SI 0 "register_operand" "")
13005         (const_string "2")
13006         (const_string "*")))])
13008 (define_insn "*lshrsi3_1_one_bit_zext"
13009   [(set (match_operand:DI 0 "register_operand" "=r")
13010         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13011                      (match_operand:QI 2 "const1_operand" "")))
13012    (clobber (reg:CC FLAGS_REG))]
13013   "TARGET_64BIT
13014    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13015    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13016   "shr{l}\t%k0"
13017   [(set_attr "type" "ishift")
13018    (set_attr "length" "2")])
13020 (define_insn "*lshrsi3_1"
13021   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13022         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13023                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13024    (clobber (reg:CC FLAGS_REG))]
13025   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13026   "@
13027    shr{l}\t{%2, %0|%0, %2}
13028    shr{l}\t{%b2, %0|%0, %b2}"
13029   [(set_attr "type" "ishift")
13030    (set_attr "mode" "SI")])
13032 (define_insn "*lshrsi3_1_zext"
13033   [(set (match_operand:DI 0 "register_operand" "=r,r")
13034         (zero_extend:DI
13035           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13036                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13037    (clobber (reg:CC FLAGS_REG))]
13038   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13039   "@
13040    shr{l}\t{%2, %k0|%k0, %2}
13041    shr{l}\t{%b2, %k0|%k0, %b2}"
13042   [(set_attr "type" "ishift")
13043    (set_attr "mode" "SI")])
13045 ;; This pattern can't accept a variable shift count, since shifts by
13046 ;; zero don't affect the flags.  We assume that shifts by constant
13047 ;; zero are optimized away.
13048 (define_insn "*lshrsi3_one_bit_cmp"
13049   [(set (reg FLAGS_REG)
13050         (compare
13051           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13052                        (match_operand:QI 2 "const1_operand" ""))
13053           (const_int 0)))
13054    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13055         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13056   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13057    && ix86_match_ccmode (insn, CCGOCmode)
13058    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13059   "shr{l}\t%0"
13060   [(set_attr "type" "ishift")
13061    (set (attr "length")
13062      (if_then_else (match_operand:SI 0 "register_operand" "")
13063         (const_string "2")
13064         (const_string "*")))])
13066 (define_insn "*lshrsi3_one_bit_cconly"
13067   [(set (reg FLAGS_REG)
13068         (compare
13069           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13070                        (match_operand:QI 2 "const1_operand" ""))
13071           (const_int 0)))
13072    (clobber (match_scratch:SI 0 "=r"))]
13073   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13074    && ix86_match_ccmode (insn, CCGOCmode)
13075    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13076   "shr{l}\t%0"
13077   [(set_attr "type" "ishift")
13078    (set_attr "length" "2")])
13080 (define_insn "*lshrsi3_cmp_one_bit_zext"
13081   [(set (reg FLAGS_REG)
13082         (compare
13083           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13084                        (match_operand:QI 2 "const1_operand" ""))
13085           (const_int 0)))
13086    (set (match_operand:DI 0 "register_operand" "=r")
13087         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13088   "TARGET_64BIT
13089    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13090    && ix86_match_ccmode (insn, CCGOCmode)
13091    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13092   "shr{l}\t%k0"
13093   [(set_attr "type" "ishift")
13094    (set_attr "length" "2")])
13096 ;; This pattern can't accept a variable shift count, since shifts by
13097 ;; zero don't affect the flags.  We assume that shifts by constant
13098 ;; zero are optimized away.
13099 (define_insn "*lshrsi3_cmp"
13100   [(set (reg FLAGS_REG)
13101         (compare
13102           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13103                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13104           (const_int 0)))
13105    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13106         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13107   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13108    && ix86_match_ccmode (insn, CCGOCmode)
13109    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13110   "shr{l}\t{%2, %0|%0, %2}"
13111   [(set_attr "type" "ishift")
13112    (set_attr "mode" "SI")])
13114 (define_insn "*lshrsi3_cconly"
13115   [(set (reg FLAGS_REG)
13116       (compare
13117         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13118                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
13119         (const_int 0)))
13120    (clobber (match_scratch:SI 0 "=r"))]
13121   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13122    && ix86_match_ccmode (insn, CCGOCmode)
13123    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13124   "shr{l}\t{%2, %0|%0, %2}"
13125   [(set_attr "type" "ishift")
13126    (set_attr "mode" "SI")])
13128 (define_insn "*lshrsi3_cmp_zext"
13129   [(set (reg FLAGS_REG)
13130         (compare
13131           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13132                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13133           (const_int 0)))
13134    (set (match_operand:DI 0 "register_operand" "=r")
13135         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13136   "TARGET_64BIT
13137    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13138    && ix86_match_ccmode (insn, CCGOCmode)
13139    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13140   "shr{l}\t{%2, %k0|%k0, %2}"
13141   [(set_attr "type" "ishift")
13142    (set_attr "mode" "SI")])
13144 (define_expand "lshrhi3"
13145   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13146         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13147                      (match_operand:QI 2 "nonmemory_operand" "")))]
13148   "TARGET_HIMODE_MATH"
13149   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13151 (define_insn "*lshrhi3_1_one_bit"
13152   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13153         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13154                      (match_operand:QI 2 "const1_operand" "")))
13155    (clobber (reg:CC FLAGS_REG))]
13156   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13157    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13158   "shr{w}\t%0"
13159   [(set_attr "type" "ishift")
13160    (set (attr "length")
13161      (if_then_else (match_operand 0 "register_operand" "")
13162         (const_string "2")
13163         (const_string "*")))])
13165 (define_insn "*lshrhi3_1"
13166   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13167         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13168                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13169    (clobber (reg:CC FLAGS_REG))]
13170   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13171   "@
13172    shr{w}\t{%2, %0|%0, %2}
13173    shr{w}\t{%b2, %0|%0, %b2}"
13174   [(set_attr "type" "ishift")
13175    (set_attr "mode" "HI")])
13177 ;; This pattern can't accept a variable shift count, since shifts by
13178 ;; zero don't affect the flags.  We assume that shifts by constant
13179 ;; zero are optimized away.
13180 (define_insn "*lshrhi3_one_bit_cmp"
13181   [(set (reg FLAGS_REG)
13182         (compare
13183           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13184                        (match_operand:QI 2 "const1_operand" ""))
13185           (const_int 0)))
13186    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13187         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13188   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13189    && ix86_match_ccmode (insn, CCGOCmode)
13190    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13191   "shr{w}\t%0"
13192   [(set_attr "type" "ishift")
13193    (set (attr "length")
13194      (if_then_else (match_operand:SI 0 "register_operand" "")
13195         (const_string "2")
13196         (const_string "*")))])
13198 (define_insn "*lshrhi3_one_bit_cconly"
13199   [(set (reg FLAGS_REG)
13200         (compare
13201           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13202                        (match_operand:QI 2 "const1_operand" ""))
13203           (const_int 0)))
13204    (clobber (match_scratch:HI 0 "=r"))]
13205   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13206    && ix86_match_ccmode (insn, CCGOCmode)
13207    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13208   "shr{w}\t%0"
13209   [(set_attr "type" "ishift")
13210    (set_attr "length" "2")])
13212 ;; This pattern can't accept a variable shift count, since shifts by
13213 ;; zero don't affect the flags.  We assume that shifts by constant
13214 ;; zero are optimized away.
13215 (define_insn "*lshrhi3_cmp"
13216   [(set (reg FLAGS_REG)
13217         (compare
13218           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13219                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13220           (const_int 0)))
13221    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13222         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13223   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13224    && ix86_match_ccmode (insn, CCGOCmode)
13225    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13226   "shr{w}\t{%2, %0|%0, %2}"
13227   [(set_attr "type" "ishift")
13228    (set_attr "mode" "HI")])
13230 (define_insn "*lshrhi3_cconly"
13231   [(set (reg FLAGS_REG)
13232         (compare
13233           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13234                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13235           (const_int 0)))
13236    (clobber (match_scratch:HI 0 "=r"))]
13237   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13238    && ix86_match_ccmode (insn, CCGOCmode)
13239    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13240   "shr{w}\t{%2, %0|%0, %2}"
13241   [(set_attr "type" "ishift")
13242    (set_attr "mode" "HI")])
13244 (define_expand "lshrqi3"
13245   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13246         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13247                      (match_operand:QI 2 "nonmemory_operand" "")))]
13248   "TARGET_QIMODE_MATH"
13249   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13251 (define_insn "*lshrqi3_1_one_bit"
13252   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13253         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13254                      (match_operand:QI 2 "const1_operand" "")))
13255    (clobber (reg:CC FLAGS_REG))]
13256   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13257    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13258   "shr{b}\t%0"
13259   [(set_attr "type" "ishift")
13260    (set (attr "length")
13261      (if_then_else (match_operand 0 "register_operand" "")
13262         (const_string "2")
13263         (const_string "*")))])
13265 (define_insn "*lshrqi3_1_one_bit_slp"
13266   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13267         (lshiftrt:QI (match_dup 0)
13268                      (match_operand:QI 1 "const1_operand" "")))
13269    (clobber (reg:CC FLAGS_REG))]
13270   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13271    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13272   "shr{b}\t%0"
13273   [(set_attr "type" "ishift1")
13274    (set (attr "length")
13275      (if_then_else (match_operand 0 "register_operand" "")
13276         (const_string "2")
13277         (const_string "*")))])
13279 (define_insn "*lshrqi3_1"
13280   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13281         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13282                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13283    (clobber (reg:CC FLAGS_REG))]
13284   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13285   "@
13286    shr{b}\t{%2, %0|%0, %2}
13287    shr{b}\t{%b2, %0|%0, %b2}"
13288   [(set_attr "type" "ishift")
13289    (set_attr "mode" "QI")])
13291 (define_insn "*lshrqi3_1_slp"
13292   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13293         (lshiftrt:QI (match_dup 0)
13294                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13295    (clobber (reg:CC FLAGS_REG))]
13296   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13297    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13298   "@
13299    shr{b}\t{%1, %0|%0, %1}
13300    shr{b}\t{%b1, %0|%0, %b1}"
13301   [(set_attr "type" "ishift1")
13302    (set_attr "mode" "QI")])
13304 ;; This pattern can't accept a variable shift count, since shifts by
13305 ;; zero don't affect the flags.  We assume that shifts by constant
13306 ;; zero are optimized away.
13307 (define_insn "*lshrqi2_one_bit_cmp"
13308   [(set (reg FLAGS_REG)
13309         (compare
13310           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13311                        (match_operand:QI 2 "const1_operand" ""))
13312           (const_int 0)))
13313    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13314         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13315   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13316    && ix86_match_ccmode (insn, CCGOCmode)
13317    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13318   "shr{b}\t%0"
13319   [(set_attr "type" "ishift")
13320    (set (attr "length")
13321      (if_then_else (match_operand:SI 0 "register_operand" "")
13322         (const_string "2")
13323         (const_string "*")))])
13325 (define_insn "*lshrqi2_one_bit_cconly"
13326   [(set (reg FLAGS_REG)
13327         (compare
13328           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13329                        (match_operand:QI 2 "const1_operand" ""))
13330           (const_int 0)))
13331    (clobber (match_scratch:QI 0 "=q"))]
13332   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13333    && ix86_match_ccmode (insn, CCGOCmode)
13334    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13335   "shr{b}\t%0"
13336   [(set_attr "type" "ishift")
13337    (set_attr "length" "2")])
13339 ;; This pattern can't accept a variable shift count, since shifts by
13340 ;; zero don't affect the flags.  We assume that shifts by constant
13341 ;; zero are optimized away.
13342 (define_insn "*lshrqi2_cmp"
13343   [(set (reg FLAGS_REG)
13344         (compare
13345           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13346                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13347           (const_int 0)))
13348    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13349         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13350   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13351    && ix86_match_ccmode (insn, CCGOCmode)
13352    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13353   "shr{b}\t{%2, %0|%0, %2}"
13354   [(set_attr "type" "ishift")
13355    (set_attr "mode" "QI")])
13357 (define_insn "*lshrqi2_cconly"
13358   [(set (reg FLAGS_REG)
13359         (compare
13360           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13361                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13362           (const_int 0)))
13363    (clobber (match_scratch:QI 0 "=q"))]
13364   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13365    && ix86_match_ccmode (insn, CCGOCmode)
13366    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13367   "shr{b}\t{%2, %0|%0, %2}"
13368   [(set_attr "type" "ishift")
13369    (set_attr "mode" "QI")])
13371 ;; Rotate instructions
13373 (define_expand "rotldi3"
13374   [(set (match_operand:DI 0 "shiftdi_operand" "")
13375         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13376                    (match_operand:QI 2 "nonmemory_operand" "")))]
13377  ""
13379   if (TARGET_64BIT)
13380     {
13381       ix86_expand_binary_operator (ROTATE, DImode, operands);
13382       DONE;
13383     }
13384   if (!const_1_to_31_operand (operands[2], VOIDmode))
13385     FAIL;
13386   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13387   DONE;
13390 ;; Implement rotation using two double-precision shift instructions
13391 ;; and a scratch register.
13392 (define_insn_and_split "ix86_rotldi3"
13393  [(set (match_operand:DI 0 "register_operand" "=r")
13394        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13395                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13396   (clobber (reg:CC FLAGS_REG))
13397   (clobber (match_scratch:SI 3 "=&r"))]
13398  "!TARGET_64BIT"
13399  ""
13400  "&& reload_completed"
13401  [(set (match_dup 3) (match_dup 4))
13402   (parallel
13403    [(set (match_dup 4)
13404          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13405                  (lshiftrt:SI (match_dup 5)
13406                               (minus:QI (const_int 32) (match_dup 2)))))
13407     (clobber (reg:CC FLAGS_REG))])
13408   (parallel
13409    [(set (match_dup 5)
13410          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13411                  (lshiftrt:SI (match_dup 3)
13412                               (minus:QI (const_int 32) (match_dup 2)))))
13413     (clobber (reg:CC FLAGS_REG))])]
13414  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13416 (define_insn "*rotlsi3_1_one_bit_rex64"
13417   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13418         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13419                    (match_operand:QI 2 "const1_operand" "")))
13420    (clobber (reg:CC FLAGS_REG))]
13421   "TARGET_64BIT
13422    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13423    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13424   "rol{q}\t%0"
13425   [(set_attr "type" "rotate")
13426    (set (attr "length")
13427      (if_then_else (match_operand:DI 0 "register_operand" "")
13428         (const_string "2")
13429         (const_string "*")))])
13431 (define_insn "*rotldi3_1_rex64"
13432   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13433         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13434                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13435    (clobber (reg:CC FLAGS_REG))]
13436   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13437   "@
13438    rol{q}\t{%2, %0|%0, %2}
13439    rol{q}\t{%b2, %0|%0, %b2}"
13440   [(set_attr "type" "rotate")
13441    (set_attr "mode" "DI")])
13443 (define_expand "rotlsi3"
13444   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13445         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13446                    (match_operand:QI 2 "nonmemory_operand" "")))]
13447   ""
13448   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13450 (define_insn "*rotlsi3_1_one_bit"
13451   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13452         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13453                    (match_operand:QI 2 "const1_operand" "")))
13454    (clobber (reg:CC FLAGS_REG))]
13455   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13456    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13457   "rol{l}\t%0"
13458   [(set_attr "type" "rotate")
13459    (set (attr "length")
13460      (if_then_else (match_operand:SI 0 "register_operand" "")
13461         (const_string "2")
13462         (const_string "*")))])
13464 (define_insn "*rotlsi3_1_one_bit_zext"
13465   [(set (match_operand:DI 0 "register_operand" "=r")
13466         (zero_extend:DI
13467           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13468                      (match_operand:QI 2 "const1_operand" ""))))
13469    (clobber (reg:CC FLAGS_REG))]
13470   "TARGET_64BIT
13471    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13472    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13473   "rol{l}\t%k0"
13474   [(set_attr "type" "rotate")
13475    (set_attr "length" "2")])
13477 (define_insn "*rotlsi3_1"
13478   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13479         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13480                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13481    (clobber (reg:CC FLAGS_REG))]
13482   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13483   "@
13484    rol{l}\t{%2, %0|%0, %2}
13485    rol{l}\t{%b2, %0|%0, %b2}"
13486   [(set_attr "type" "rotate")
13487    (set_attr "mode" "SI")])
13489 (define_insn "*rotlsi3_1_zext"
13490   [(set (match_operand:DI 0 "register_operand" "=r,r")
13491         (zero_extend:DI
13492           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13493                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13494    (clobber (reg:CC FLAGS_REG))]
13495   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13496   "@
13497    rol{l}\t{%2, %k0|%k0, %2}
13498    rol{l}\t{%b2, %k0|%k0, %b2}"
13499   [(set_attr "type" "rotate")
13500    (set_attr "mode" "SI")])
13502 (define_expand "rotlhi3"
13503   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13504         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13505                    (match_operand:QI 2 "nonmemory_operand" "")))]
13506   "TARGET_HIMODE_MATH"
13507   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13509 (define_insn "*rotlhi3_1_one_bit"
13510   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13511         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13512                    (match_operand:QI 2 "const1_operand" "")))
13513    (clobber (reg:CC FLAGS_REG))]
13514   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13515    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13516   "rol{w}\t%0"
13517   [(set_attr "type" "rotate")
13518    (set (attr "length")
13519      (if_then_else (match_operand 0 "register_operand" "")
13520         (const_string "2")
13521         (const_string "*")))])
13523 (define_insn "*rotlhi3_1"
13524   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13525         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13526                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13527    (clobber (reg:CC FLAGS_REG))]
13528   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13529   "@
13530    rol{w}\t{%2, %0|%0, %2}
13531    rol{w}\t{%b2, %0|%0, %b2}"
13532   [(set_attr "type" "rotate")
13533    (set_attr "mode" "HI")])
13535 (define_split
13536  [(set (match_operand:HI 0 "register_operand" "")
13537        (rotate:HI (match_dup 0) (const_int 8)))
13538   (clobber (reg:CC FLAGS_REG))]
13539  "reload_completed"
13540  [(parallel [(set (strict_low_part (match_dup 0))
13541                   (bswap:HI (match_dup 0)))
13542              (clobber (reg:CC FLAGS_REG))])]
13543  "")
13545 (define_expand "rotlqi3"
13546   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13547         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13548                    (match_operand:QI 2 "nonmemory_operand" "")))]
13549   "TARGET_QIMODE_MATH"
13550   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13552 (define_insn "*rotlqi3_1_one_bit_slp"
13553   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13554         (rotate:QI (match_dup 0)
13555                    (match_operand:QI 1 "const1_operand" "")))
13556    (clobber (reg:CC FLAGS_REG))]
13557   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13558    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13559   "rol{b}\t%0"
13560   [(set_attr "type" "rotate1")
13561    (set (attr "length")
13562      (if_then_else (match_operand 0 "register_operand" "")
13563         (const_string "2")
13564         (const_string "*")))])
13566 (define_insn "*rotlqi3_1_one_bit"
13567   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13568         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13569                    (match_operand:QI 2 "const1_operand" "")))
13570    (clobber (reg:CC FLAGS_REG))]
13571   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13572    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13573   "rol{b}\t%0"
13574   [(set_attr "type" "rotate")
13575    (set (attr "length")
13576      (if_then_else (match_operand 0 "register_operand" "")
13577         (const_string "2")
13578         (const_string "*")))])
13580 (define_insn "*rotlqi3_1_slp"
13581   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13582         (rotate:QI (match_dup 0)
13583                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13584    (clobber (reg:CC FLAGS_REG))]
13585   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13586    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13587   "@
13588    rol{b}\t{%1, %0|%0, %1}
13589    rol{b}\t{%b1, %0|%0, %b1}"
13590   [(set_attr "type" "rotate1")
13591    (set_attr "mode" "QI")])
13593 (define_insn "*rotlqi3_1"
13594   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13595         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13596                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13597    (clobber (reg:CC FLAGS_REG))]
13598   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13599   "@
13600    rol{b}\t{%2, %0|%0, %2}
13601    rol{b}\t{%b2, %0|%0, %b2}"
13602   [(set_attr "type" "rotate")
13603    (set_attr "mode" "QI")])
13605 (define_expand "rotrdi3"
13606   [(set (match_operand:DI 0 "shiftdi_operand" "")
13607         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13608                    (match_operand:QI 2 "nonmemory_operand" "")))]
13609  ""
13611   if (TARGET_64BIT)
13612     {
13613       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13614       DONE;
13615     }
13616   if (!const_1_to_31_operand (operands[2], VOIDmode))
13617     FAIL;
13618   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13619   DONE;
13622 ;; Implement rotation using two double-precision shift instructions
13623 ;; and a scratch register.
13624 (define_insn_and_split "ix86_rotrdi3"
13625  [(set (match_operand:DI 0 "register_operand" "=r")
13626        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13627                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13628   (clobber (reg:CC FLAGS_REG))
13629   (clobber (match_scratch:SI 3 "=&r"))]
13630  "!TARGET_64BIT"
13631  ""
13632  "&& reload_completed"
13633  [(set (match_dup 3) (match_dup 4))
13634   (parallel
13635    [(set (match_dup 4)
13636          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13637                  (ashift:SI (match_dup 5)
13638                             (minus:QI (const_int 32) (match_dup 2)))))
13639     (clobber (reg:CC FLAGS_REG))])
13640   (parallel
13641    [(set (match_dup 5)
13642          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13643                  (ashift:SI (match_dup 3)
13644                             (minus:QI (const_int 32) (match_dup 2)))))
13645     (clobber (reg:CC FLAGS_REG))])]
13646  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13648 (define_insn "*rotrdi3_1_one_bit_rex64"
13649   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13650         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13651                      (match_operand:QI 2 "const1_operand" "")))
13652    (clobber (reg:CC FLAGS_REG))]
13653   "TARGET_64BIT
13654    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13655    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13656   "ror{q}\t%0"
13657   [(set_attr "type" "rotate")
13658    (set (attr "length")
13659      (if_then_else (match_operand:DI 0 "register_operand" "")
13660         (const_string "2")
13661         (const_string "*")))])
13663 (define_insn "*rotrdi3_1_rex64"
13664   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13665         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13666                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13667    (clobber (reg:CC FLAGS_REG))]
13668   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13669   "@
13670    ror{q}\t{%2, %0|%0, %2}
13671    ror{q}\t{%b2, %0|%0, %b2}"
13672   [(set_attr "type" "rotate")
13673    (set_attr "mode" "DI")])
13675 (define_expand "rotrsi3"
13676   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13677         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13678                      (match_operand:QI 2 "nonmemory_operand" "")))]
13679   ""
13680   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13682 (define_insn "*rotrsi3_1_one_bit"
13683   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13684         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13685                      (match_operand:QI 2 "const1_operand" "")))
13686    (clobber (reg:CC FLAGS_REG))]
13687   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13688    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13689   "ror{l}\t%0"
13690   [(set_attr "type" "rotate")
13691    (set (attr "length")
13692      (if_then_else (match_operand:SI 0 "register_operand" "")
13693         (const_string "2")
13694         (const_string "*")))])
13696 (define_insn "*rotrsi3_1_one_bit_zext"
13697   [(set (match_operand:DI 0 "register_operand" "=r")
13698         (zero_extend:DI
13699           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13700                        (match_operand:QI 2 "const1_operand" ""))))
13701    (clobber (reg:CC FLAGS_REG))]
13702   "TARGET_64BIT
13703    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13704    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13705   "ror{l}\t%k0"
13706   [(set_attr "type" "rotate")
13707    (set (attr "length")
13708      (if_then_else (match_operand:SI 0 "register_operand" "")
13709         (const_string "2")
13710         (const_string "*")))])
13712 (define_insn "*rotrsi3_1"
13713   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13714         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13715                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13716    (clobber (reg:CC FLAGS_REG))]
13717   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13718   "@
13719    ror{l}\t{%2, %0|%0, %2}
13720    ror{l}\t{%b2, %0|%0, %b2}"
13721   [(set_attr "type" "rotate")
13722    (set_attr "mode" "SI")])
13724 (define_insn "*rotrsi3_1_zext"
13725   [(set (match_operand:DI 0 "register_operand" "=r,r")
13726         (zero_extend:DI
13727           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13728                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13729    (clobber (reg:CC FLAGS_REG))]
13730   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13731   "@
13732    ror{l}\t{%2, %k0|%k0, %2}
13733    ror{l}\t{%b2, %k0|%k0, %b2}"
13734   [(set_attr "type" "rotate")
13735    (set_attr "mode" "SI")])
13737 (define_expand "rotrhi3"
13738   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13739         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13740                      (match_operand:QI 2 "nonmemory_operand" "")))]
13741   "TARGET_HIMODE_MATH"
13742   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13744 (define_insn "*rotrhi3_one_bit"
13745   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13746         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13747                      (match_operand:QI 2 "const1_operand" "")))
13748    (clobber (reg:CC FLAGS_REG))]
13749   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13750    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13751   "ror{w}\t%0"
13752   [(set_attr "type" "rotate")
13753    (set (attr "length")
13754      (if_then_else (match_operand 0 "register_operand" "")
13755         (const_string "2")
13756         (const_string "*")))])
13758 (define_insn "*rotrhi3_1"
13759   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13760         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13761                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13762    (clobber (reg:CC FLAGS_REG))]
13763   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13764   "@
13765    ror{w}\t{%2, %0|%0, %2}
13766    ror{w}\t{%b2, %0|%0, %b2}"
13767   [(set_attr "type" "rotate")
13768    (set_attr "mode" "HI")])
13770 (define_split
13771  [(set (match_operand:HI 0 "register_operand" "")
13772        (rotatert:HI (match_dup 0) (const_int 8)))
13773   (clobber (reg:CC FLAGS_REG))]
13774  "reload_completed"
13775  [(parallel [(set (strict_low_part (match_dup 0))
13776                   (bswap:HI (match_dup 0)))
13777              (clobber (reg:CC FLAGS_REG))])]
13778  "")
13780 (define_expand "rotrqi3"
13781   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13782         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13783                      (match_operand:QI 2 "nonmemory_operand" "")))]
13784   "TARGET_QIMODE_MATH"
13785   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13787 (define_insn "*rotrqi3_1_one_bit"
13788   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13789         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13790                      (match_operand:QI 2 "const1_operand" "")))
13791    (clobber (reg:CC FLAGS_REG))]
13792   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13793    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13794   "ror{b}\t%0"
13795   [(set_attr "type" "rotate")
13796    (set (attr "length")
13797      (if_then_else (match_operand 0 "register_operand" "")
13798         (const_string "2")
13799         (const_string "*")))])
13801 (define_insn "*rotrqi3_1_one_bit_slp"
13802   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13803         (rotatert:QI (match_dup 0)
13804                      (match_operand:QI 1 "const1_operand" "")))
13805    (clobber (reg:CC FLAGS_REG))]
13806   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13807    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13808   "ror{b}\t%0"
13809   [(set_attr "type" "rotate1")
13810    (set (attr "length")
13811      (if_then_else (match_operand 0 "register_operand" "")
13812         (const_string "2")
13813         (const_string "*")))])
13815 (define_insn "*rotrqi3_1"
13816   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13817         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13818                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13819    (clobber (reg:CC FLAGS_REG))]
13820   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13821   "@
13822    ror{b}\t{%2, %0|%0, %2}
13823    ror{b}\t{%b2, %0|%0, %b2}"
13824   [(set_attr "type" "rotate")
13825    (set_attr "mode" "QI")])
13827 (define_insn "*rotrqi3_1_slp"
13828   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13829         (rotatert:QI (match_dup 0)
13830                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13831    (clobber (reg:CC FLAGS_REG))]
13832   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13833    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13834   "@
13835    ror{b}\t{%1, %0|%0, %1}
13836    ror{b}\t{%b1, %0|%0, %b1}"
13837   [(set_attr "type" "rotate1")
13838    (set_attr "mode" "QI")])
13840 ;; Bit set / bit test instructions
13842 (define_expand "extv"
13843   [(set (match_operand:SI 0 "register_operand" "")
13844         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13845                          (match_operand:SI 2 "const8_operand" "")
13846                          (match_operand:SI 3 "const8_operand" "")))]
13847   ""
13849   /* Handle extractions from %ah et al.  */
13850   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13851     FAIL;
13853   /* From mips.md: extract_bit_field doesn't verify that our source
13854      matches the predicate, so check it again here.  */
13855   if (! ext_register_operand (operands[1], VOIDmode))
13856     FAIL;
13859 (define_expand "extzv"
13860   [(set (match_operand:SI 0 "register_operand" "")
13861         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13862                          (match_operand:SI 2 "const8_operand" "")
13863                          (match_operand:SI 3 "const8_operand" "")))]
13864   ""
13866   /* Handle extractions from %ah et al.  */
13867   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13868     FAIL;
13870   /* From mips.md: extract_bit_field doesn't verify that our source
13871      matches the predicate, so check it again here.  */
13872   if (! ext_register_operand (operands[1], VOIDmode))
13873     FAIL;
13876 (define_expand "insv"
13877   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13878                       (match_operand 1 "const8_operand" "")
13879                       (match_operand 2 "const8_operand" ""))
13880         (match_operand 3 "register_operand" ""))]
13881   ""
13883   /* Handle insertions to %ah et al.  */
13884   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13885     FAIL;
13887   /* From mips.md: insert_bit_field doesn't verify that our source
13888      matches the predicate, so check it again here.  */
13889   if (! ext_register_operand (operands[0], VOIDmode))
13890     FAIL;
13892   if (TARGET_64BIT)
13893     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13894   else
13895     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13897   DONE;
13900 ;; %%% bts, btr, btc, bt.
13901 ;; In general these instructions are *slow* when applied to memory,
13902 ;; since they enforce atomic operation.  When applied to registers,
13903 ;; it depends on the cpu implementation.  They're never faster than
13904 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13905 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13906 ;; within the instruction itself, so operating on bits in the high
13907 ;; 32-bits of a register becomes easier.
13909 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13910 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13911 ;; negdf respectively, so they can never be disabled entirely.
13913 (define_insn "*btsq"
13914   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13915                          (const_int 1)
13916                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13917         (const_int 1))
13918    (clobber (reg:CC FLAGS_REG))]
13919   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13920   "bts{q}\t{%1, %0|%0, %1}"
13921   [(set_attr "type" "alu1")])
13923 (define_insn "*btrq"
13924   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13925                          (const_int 1)
13926                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13927         (const_int 0))
13928    (clobber (reg:CC FLAGS_REG))]
13929   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13930   "btr{q}\t{%1, %0|%0, %1}"
13931   [(set_attr "type" "alu1")])
13933 (define_insn "*btcq"
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         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13938    (clobber (reg:CC FLAGS_REG))]
13939   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13940   "btc{q}\t{%1, %0|%0, %1}"
13941   [(set_attr "type" "alu1")])
13943 ;; Allow Nocona to avoid these instructions if a register is available.
13945 (define_peephole2
13946   [(match_scratch:DI 2 "r")
13947    (parallel [(set (zero_extract:DI
13948                      (match_operand:DI 0 "register_operand" "")
13949                      (const_int 1)
13950                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13951                    (const_int 1))
13952               (clobber (reg:CC FLAGS_REG))])]
13953   "TARGET_64BIT && !TARGET_USE_BT"
13954   [(const_int 0)]
13956   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13957   rtx op1;
13959   if (HOST_BITS_PER_WIDE_INT >= 64)
13960     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13961   else if (i < HOST_BITS_PER_WIDE_INT)
13962     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13963   else
13964     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13966   op1 = immed_double_const (lo, hi, DImode);
13967   if (i >= 31)
13968     {
13969       emit_move_insn (operands[2], op1);
13970       op1 = operands[2];
13971     }
13973   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13974   DONE;
13977 (define_peephole2
13978   [(match_scratch:DI 2 "r")
13979    (parallel [(set (zero_extract:DI
13980                      (match_operand:DI 0 "register_operand" "")
13981                      (const_int 1)
13982                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13983                    (const_int 0))
13984               (clobber (reg:CC FLAGS_REG))])]
13985   "TARGET_64BIT && !TARGET_USE_BT"
13986   [(const_int 0)]
13988   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13989   rtx op1;
13991   if (HOST_BITS_PER_WIDE_INT >= 64)
13992     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13993   else if (i < HOST_BITS_PER_WIDE_INT)
13994     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13995   else
13996     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13998   op1 = immed_double_const (~lo, ~hi, DImode);
13999   if (i >= 32)
14000     {
14001       emit_move_insn (operands[2], op1);
14002       op1 = operands[2];
14003     }
14005   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14006   DONE;
14009 (define_peephole2
14010   [(match_scratch:DI 2 "r")
14011    (parallel [(set (zero_extract:DI
14012                      (match_operand:DI 0 "register_operand" "")
14013                      (const_int 1)
14014                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14015               (not:DI (zero_extract:DI
14016                         (match_dup 0) (const_int 1) (match_dup 1))))
14017               (clobber (reg:CC FLAGS_REG))])]
14018   "TARGET_64BIT && !TARGET_USE_BT"
14019   [(const_int 0)]
14021   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14022   rtx op1;
14024   if (HOST_BITS_PER_WIDE_INT >= 64)
14025     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14026   else if (i < HOST_BITS_PER_WIDE_INT)
14027     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14028   else
14029     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14031   op1 = immed_double_const (lo, hi, DImode);
14032   if (i >= 31)
14033     {
14034       emit_move_insn (operands[2], op1);
14035       op1 = operands[2];
14036     }
14038   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14039   DONE;
14042 (define_insn "*btdi_rex64"
14043   [(set (reg:CCC FLAGS_REG)
14044         (compare:CCC
14045           (zero_extract:DI
14046             (match_operand:DI 0 "register_operand" "r")
14047             (const_int 1)
14048             (match_operand:DI 1 "nonmemory_operand" "rN"))
14049           (const_int 0)))]
14050   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14051   "bt{q}\t{%1, %0|%0, %1}"
14052   [(set_attr "type" "alu1")])
14054 (define_insn "*btsi"
14055   [(set (reg:CCC FLAGS_REG)
14056         (compare:CCC
14057           (zero_extract:SI
14058             (match_operand:SI 0 "register_operand" "r")
14059             (const_int 1)
14060             (match_operand:SI 1 "nonmemory_operand" "rN"))
14061           (const_int 0)))]
14062   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14063   "bt{l}\t{%1, %0|%0, %1}"
14064   [(set_attr "type" "alu1")])
14066 ;; Store-flag instructions.
14068 ;; For all sCOND expanders, also expand the compare or test insn that
14069 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
14071 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
14072 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
14073 ;; way, which can later delete the movzx if only QImode is needed.
14075 (define_expand "s<code>"
14076   [(set (match_operand:QI 0 "register_operand" "")
14077         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14078   ""
14079   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14081 (define_expand "s<code>"
14082   [(set (match_operand:QI 0 "register_operand" "")
14083         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14084   "TARGET_80387 || TARGET_SSE"
14085   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14087 (define_insn "*setcc_1"
14088   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14089         (match_operator:QI 1 "ix86_comparison_operator"
14090           [(reg FLAGS_REG) (const_int 0)]))]
14091   ""
14092   "set%C1\t%0"
14093   [(set_attr "type" "setcc")
14094    (set_attr "mode" "QI")])
14096 (define_insn "*setcc_2"
14097   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14098         (match_operator:QI 1 "ix86_comparison_operator"
14099           [(reg FLAGS_REG) (const_int 0)]))]
14100   ""
14101   "set%C1\t%0"
14102   [(set_attr "type" "setcc")
14103    (set_attr "mode" "QI")])
14105 ;; In general it is not safe to assume too much about CCmode registers,
14106 ;; so simplify-rtx stops when it sees a second one.  Under certain
14107 ;; conditions this is safe on x86, so help combine not create
14109 ;;      seta    %al
14110 ;;      testb   %al, %al
14111 ;;      sete    %al
14113 (define_split
14114   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14115         (ne:QI (match_operator 1 "ix86_comparison_operator"
14116                  [(reg FLAGS_REG) (const_int 0)])
14117             (const_int 0)))]
14118   ""
14119   [(set (match_dup 0) (match_dup 1))]
14121   PUT_MODE (operands[1], QImode);
14124 (define_split
14125   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14126         (ne:QI (match_operator 1 "ix86_comparison_operator"
14127                  [(reg FLAGS_REG) (const_int 0)])
14128             (const_int 0)))]
14129   ""
14130   [(set (match_dup 0) (match_dup 1))]
14132   PUT_MODE (operands[1], QImode);
14135 (define_split
14136   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14137         (eq:QI (match_operator 1 "ix86_comparison_operator"
14138                  [(reg FLAGS_REG) (const_int 0)])
14139             (const_int 0)))]
14140   ""
14141   [(set (match_dup 0) (match_dup 1))]
14143   rtx new_op1 = copy_rtx (operands[1]);
14144   operands[1] = new_op1;
14145   PUT_MODE (new_op1, QImode);
14146   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14147                                              GET_MODE (XEXP (new_op1, 0))));
14149   /* Make sure that (a) the CCmode we have for the flags is strong
14150      enough for the reversed compare or (b) we have a valid FP compare.  */
14151   if (! ix86_comparison_operator (new_op1, VOIDmode))
14152     FAIL;
14155 (define_split
14156   [(set (strict_low_part (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 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14176 ;; subsequent logical operations are used to imitate conditional moves.
14177 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14178 ;; it directly.
14180 (define_insn "*avx_setcc<mode>"
14181   [(set (match_operand:MODEF 0 "register_operand" "=x")
14182         (match_operator:MODEF 1 "avx_comparison_float_operator"
14183           [(match_operand:MODEF 2 "register_operand" "x")
14184            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14185   "TARGET_AVX"
14186   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14187   [(set_attr "type" "ssecmp")
14188    (set_attr "prefix" "vex")
14189    (set_attr "mode" "<MODE>")])
14191 (define_insn "*sse_setcc<mode>"
14192   [(set (match_operand:MODEF 0 "register_operand" "=x")
14193         (match_operator:MODEF 1 "sse_comparison_operator"
14194           [(match_operand:MODEF 2 "register_operand" "0")
14195            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14196   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14197   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14198   [(set_attr "type" "ssecmp")
14199    (set_attr "mode" "<MODE>")])
14201 (define_insn "*sse5_setcc<mode>"
14202   [(set (match_operand:MODEF 0 "register_operand" "=x")
14203         (match_operator:MODEF 1 "sse5_comparison_float_operator"
14204           [(match_operand:MODEF 2 "register_operand" "x")
14205            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14206   "TARGET_SSE5"
14207   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14208   [(set_attr "type" "sse4arg")
14209    (set_attr "mode" "<MODE>")])
14212 ;; Basic conditional jump instructions.
14213 ;; We ignore the overflow flag for signed branch instructions.
14215 ;; For all bCOND expanders, also expand the compare or test insn that
14216 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
14218 (define_expand "b<code>"
14219   [(set (pc)
14220         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14221                                    (const_int 0))
14222                       (label_ref (match_operand 0 ""))
14223                       (pc)))]
14224   ""
14225   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14227 (define_expand "b<code>"
14228   [(set (pc)
14229         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14230                                   (const_int 0))
14231                       (label_ref (match_operand 0 ""))
14232                       (pc)))]
14233   "TARGET_80387 || TARGET_SSE_MATH"
14234   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14236 (define_insn "*jcc_1"
14237   [(set (pc)
14238         (if_then_else (match_operator 1 "ix86_comparison_operator"
14239                                       [(reg FLAGS_REG) (const_int 0)])
14240                       (label_ref (match_operand 0 "" ""))
14241                       (pc)))]
14242   ""
14243   "%+j%C1\t%l0"
14244   [(set_attr "type" "ibr")
14245    (set_attr "modrm" "0")
14246    (set (attr "length")
14247            (if_then_else (and (ge (minus (match_dup 0) (pc))
14248                                   (const_int -126))
14249                               (lt (minus (match_dup 0) (pc))
14250                                   (const_int 128)))
14251              (const_int 2)
14252              (const_int 6)))])
14254 (define_insn "*jcc_2"
14255   [(set (pc)
14256         (if_then_else (match_operator 1 "ix86_comparison_operator"
14257                                       [(reg FLAGS_REG) (const_int 0)])
14258                       (pc)
14259                       (label_ref (match_operand 0 "" ""))))]
14260   ""
14261   "%+j%c1\t%l0"
14262   [(set_attr "type" "ibr")
14263    (set_attr "modrm" "0")
14264    (set (attr "length")
14265            (if_then_else (and (ge (minus (match_dup 0) (pc))
14266                                   (const_int -126))
14267                               (lt (minus (match_dup 0) (pc))
14268                                   (const_int 128)))
14269              (const_int 2)
14270              (const_int 6)))])
14272 ;; In general it is not safe to assume too much about CCmode registers,
14273 ;; so simplify-rtx stops when it sees a second one.  Under certain
14274 ;; conditions this is safe on x86, so help combine not create
14276 ;;      seta    %al
14277 ;;      testb   %al, %al
14278 ;;      je      Lfoo
14280 (define_split
14281   [(set (pc)
14282         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14283                                       [(reg FLAGS_REG) (const_int 0)])
14284                           (const_int 0))
14285                       (label_ref (match_operand 1 "" ""))
14286                       (pc)))]
14287   ""
14288   [(set (pc)
14289         (if_then_else (match_dup 0)
14290                       (label_ref (match_dup 1))
14291                       (pc)))]
14293   PUT_MODE (operands[0], VOIDmode);
14296 (define_split
14297   [(set (pc)
14298         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14299                                       [(reg FLAGS_REG) (const_int 0)])
14300                           (const_int 0))
14301                       (label_ref (match_operand 1 "" ""))
14302                       (pc)))]
14303   ""
14304   [(set (pc)
14305         (if_then_else (match_dup 0)
14306                       (label_ref (match_dup 1))
14307                       (pc)))]
14309   rtx new_op0 = copy_rtx (operands[0]);
14310   operands[0] = new_op0;
14311   PUT_MODE (new_op0, VOIDmode);
14312   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14313                                              GET_MODE (XEXP (new_op0, 0))));
14315   /* Make sure that (a) the CCmode we have for the flags is strong
14316      enough for the reversed compare or (b) we have a valid FP compare.  */
14317   if (! ix86_comparison_operator (new_op0, VOIDmode))
14318     FAIL;
14321 ;; zero_extend in SImode is correct, since this is what combine pass
14322 ;; generates from shift insn with QImode operand.  Actually, the mode of
14323 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14324 ;; appropriate modulo of the bit offset value.
14326 (define_insn_and_split "*jcc_btdi_rex64"
14327   [(set (pc)
14328         (if_then_else (match_operator 0 "bt_comparison_operator"
14329                         [(zero_extract:DI
14330                            (match_operand:DI 1 "register_operand" "r")
14331                            (const_int 1)
14332                            (zero_extend:SI
14333                              (match_operand:QI 2 "register_operand" "r")))
14334                          (const_int 0)])
14335                       (label_ref (match_operand 3 "" ""))
14336                       (pc)))
14337    (clobber (reg:CC FLAGS_REG))]
14338   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14339   "#"
14340   "&& 1"
14341   [(set (reg:CCC FLAGS_REG)
14342         (compare:CCC
14343           (zero_extract:DI
14344             (match_dup 1)
14345             (const_int 1)
14346             (match_dup 2))
14347           (const_int 0)))
14348    (set (pc)
14349         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14350                       (label_ref (match_dup 3))
14351                       (pc)))]
14353   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14355   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14358 ;; avoid useless masking of bit offset operand
14359 (define_insn_and_split "*jcc_btdi_mask_rex64"
14360   [(set (pc)
14361         (if_then_else (match_operator 0 "bt_comparison_operator"
14362                         [(zero_extract:DI
14363                            (match_operand:DI 1 "register_operand" "r")
14364                            (const_int 1)
14365                            (and:SI
14366                              (match_operand:SI 2 "register_operand" "r")
14367                              (match_operand:SI 3 "const_int_operand" "n")))])
14368                       (label_ref (match_operand 4 "" ""))
14369                       (pc)))
14370    (clobber (reg:CC FLAGS_REG))]
14371   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14372    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14373   "#"
14374   "&& 1"
14375   [(set (reg:CCC FLAGS_REG)
14376         (compare:CCC
14377           (zero_extract:DI
14378             (match_dup 1)
14379             (const_int 1)
14380             (match_dup 2))
14381           (const_int 0)))
14382    (set (pc)
14383         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14384                       (label_ref (match_dup 4))
14385                       (pc)))]
14387   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14389   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14392 (define_insn_and_split "*jcc_btsi"
14393   [(set (pc)
14394         (if_then_else (match_operator 0 "bt_comparison_operator"
14395                         [(zero_extract:SI
14396                            (match_operand:SI 1 "register_operand" "r")
14397                            (const_int 1)
14398                            (zero_extend:SI
14399                              (match_operand:QI 2 "register_operand" "r")))
14400                          (const_int 0)])
14401                       (label_ref (match_operand 3 "" ""))
14402                       (pc)))
14403    (clobber (reg:CC FLAGS_REG))]
14404   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14405   "#"
14406   "&& 1"
14407   [(set (reg:CCC FLAGS_REG)
14408         (compare:CCC
14409           (zero_extract:SI
14410             (match_dup 1)
14411             (const_int 1)
14412             (match_dup 2))
14413           (const_int 0)))
14414    (set (pc)
14415         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14416                       (label_ref (match_dup 3))
14417                       (pc)))]
14419   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14421   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14424 ;; avoid useless masking of bit offset operand
14425 (define_insn_and_split "*jcc_btsi_mask"
14426   [(set (pc)
14427         (if_then_else (match_operator 0 "bt_comparison_operator"
14428                         [(zero_extract:SI
14429                            (match_operand:SI 1 "register_operand" "r")
14430                            (const_int 1)
14431                            (and:SI
14432                              (match_operand:SI 2 "register_operand" "r")
14433                              (match_operand:SI 3 "const_int_operand" "n")))])
14434                       (label_ref (match_operand 4 "" ""))
14435                       (pc)))
14436    (clobber (reg:CC FLAGS_REG))]
14437   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14438    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14439   "#"
14440   "&& 1"
14441   [(set (reg:CCC FLAGS_REG)
14442         (compare:CCC
14443           (zero_extract:SI
14444             (match_dup 1)
14445             (const_int 1)
14446             (match_dup 2))
14447           (const_int 0)))
14448    (set (pc)
14449         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14450                       (label_ref (match_dup 4))
14451                       (pc)))]
14452   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14454 (define_insn_and_split "*jcc_btsi_1"
14455   [(set (pc)
14456         (if_then_else (match_operator 0 "bt_comparison_operator"
14457                         [(and:SI
14458                            (lshiftrt:SI
14459                              (match_operand:SI 1 "register_operand" "r")
14460                              (match_operand:QI 2 "register_operand" "r"))
14461                            (const_int 1))
14462                          (const_int 0)])
14463                       (label_ref (match_operand 3 "" ""))
14464                       (pc)))
14465    (clobber (reg:CC FLAGS_REG))]
14466   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14467   "#"
14468   "&& 1"
14469   [(set (reg:CCC FLAGS_REG)
14470         (compare:CCC
14471           (zero_extract:SI
14472             (match_dup 1)
14473             (const_int 1)
14474             (match_dup 2))
14475           (const_int 0)))
14476    (set (pc)
14477         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14478                       (label_ref (match_dup 3))
14479                       (pc)))]
14481   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14483   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14486 ;; avoid useless masking of bit offset operand
14487 (define_insn_and_split "*jcc_btsi_mask_1"
14488   [(set (pc)
14489         (if_then_else
14490           (match_operator 0 "bt_comparison_operator"
14491             [(and:SI
14492                (lshiftrt:SI
14493                  (match_operand:SI 1 "register_operand" "r")
14494                  (subreg:QI
14495                    (and:SI
14496                      (match_operand:SI 2 "register_operand" "r")
14497                      (match_operand:SI 3 "const_int_operand" "n")) 0))
14498                (const_int 1))
14499              (const_int 0)])
14500           (label_ref (match_operand 4 "" ""))
14501           (pc)))
14502    (clobber (reg:CC FLAGS_REG))]
14503   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14504    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14505   "#"
14506   "&& 1"
14507   [(set (reg:CCC FLAGS_REG)
14508         (compare:CCC
14509           (zero_extract:SI
14510             (match_dup 1)
14511             (const_int 1)
14512             (match_dup 2))
14513           (const_int 0)))
14514    (set (pc)
14515         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14516                       (label_ref (match_dup 4))
14517                       (pc)))]
14518   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14520 ;; Define combination compare-and-branch fp compare instructions to use
14521 ;; during early optimization.  Splitting the operation apart early makes
14522 ;; for bad code when we want to reverse the operation.
14524 (define_insn "*fp_jcc_1_mixed"
14525   [(set (pc)
14526         (if_then_else (match_operator 0 "comparison_operator"
14527                         [(match_operand 1 "register_operand" "f,x")
14528                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14529           (label_ref (match_operand 3 "" ""))
14530           (pc)))
14531    (clobber (reg:CCFP FPSR_REG))
14532    (clobber (reg:CCFP FLAGS_REG))]
14533   "TARGET_MIX_SSE_I387
14534    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14535    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14536    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14537   "#")
14539 (define_insn "*fp_jcc_1_sse"
14540   [(set (pc)
14541         (if_then_else (match_operator 0 "comparison_operator"
14542                         [(match_operand 1 "register_operand" "x")
14543                          (match_operand 2 "nonimmediate_operand" "xm")])
14544           (label_ref (match_operand 3 "" ""))
14545           (pc)))
14546    (clobber (reg:CCFP FPSR_REG))
14547    (clobber (reg:CCFP FLAGS_REG))]
14548   "TARGET_SSE_MATH
14549    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14550    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14551    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14552   "#")
14554 (define_insn "*fp_jcc_1_387"
14555   [(set (pc)
14556         (if_then_else (match_operator 0 "comparison_operator"
14557                         [(match_operand 1 "register_operand" "f")
14558                          (match_operand 2 "register_operand" "f")])
14559           (label_ref (match_operand 3 "" ""))
14560           (pc)))
14561    (clobber (reg:CCFP FPSR_REG))
14562    (clobber (reg:CCFP FLAGS_REG))]
14563   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14564    && TARGET_CMOVE
14565    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14566    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14567   "#")
14569 (define_insn "*fp_jcc_2_mixed"
14570   [(set (pc)
14571         (if_then_else (match_operator 0 "comparison_operator"
14572                         [(match_operand 1 "register_operand" "f,x")
14573                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14574           (pc)
14575           (label_ref (match_operand 3 "" ""))))
14576    (clobber (reg:CCFP FPSR_REG))
14577    (clobber (reg:CCFP FLAGS_REG))]
14578   "TARGET_MIX_SSE_I387
14579    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14580    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14581    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14582   "#")
14584 (define_insn "*fp_jcc_2_sse"
14585   [(set (pc)
14586         (if_then_else (match_operator 0 "comparison_operator"
14587                         [(match_operand 1 "register_operand" "x")
14588                          (match_operand 2 "nonimmediate_operand" "xm")])
14589           (pc)
14590           (label_ref (match_operand 3 "" ""))))
14591    (clobber (reg:CCFP FPSR_REG))
14592    (clobber (reg:CCFP FLAGS_REG))]
14593   "TARGET_SSE_MATH
14594    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14595    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14596    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14597   "#")
14599 (define_insn "*fp_jcc_2_387"
14600   [(set (pc)
14601         (if_then_else (match_operator 0 "comparison_operator"
14602                         [(match_operand 1 "register_operand" "f")
14603                          (match_operand 2 "register_operand" "f")])
14604           (pc)
14605           (label_ref (match_operand 3 "" ""))))
14606    (clobber (reg:CCFP FPSR_REG))
14607    (clobber (reg:CCFP FLAGS_REG))]
14608   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14609    && TARGET_CMOVE
14610    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14611    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14612   "#")
14614 (define_insn "*fp_jcc_3_387"
14615   [(set (pc)
14616         (if_then_else (match_operator 0 "comparison_operator"
14617                         [(match_operand 1 "register_operand" "f")
14618                          (match_operand 2 "nonimmediate_operand" "fm")])
14619           (label_ref (match_operand 3 "" ""))
14620           (pc)))
14621    (clobber (reg:CCFP FPSR_REG))
14622    (clobber (reg:CCFP FLAGS_REG))
14623    (clobber (match_scratch:HI 4 "=a"))]
14624   "TARGET_80387
14625    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14626    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14627    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14628    && SELECT_CC_MODE (GET_CODE (operands[0]),
14629                       operands[1], operands[2]) == CCFPmode
14630    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14631   "#")
14633 (define_insn "*fp_jcc_4_387"
14634   [(set (pc)
14635         (if_then_else (match_operator 0 "comparison_operator"
14636                         [(match_operand 1 "register_operand" "f")
14637                          (match_operand 2 "nonimmediate_operand" "fm")])
14638           (pc)
14639           (label_ref (match_operand 3 "" ""))))
14640    (clobber (reg:CCFP FPSR_REG))
14641    (clobber (reg:CCFP FLAGS_REG))
14642    (clobber (match_scratch:HI 4 "=a"))]
14643   "TARGET_80387
14644    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14645    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14646    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14647    && SELECT_CC_MODE (GET_CODE (operands[0]),
14648                       operands[1], operands[2]) == CCFPmode
14649    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14650   "#")
14652 (define_insn "*fp_jcc_5_387"
14653   [(set (pc)
14654         (if_then_else (match_operator 0 "comparison_operator"
14655                         [(match_operand 1 "register_operand" "f")
14656                          (match_operand 2 "register_operand" "f")])
14657           (label_ref (match_operand 3 "" ""))
14658           (pc)))
14659    (clobber (reg:CCFP FPSR_REG))
14660    (clobber (reg:CCFP FLAGS_REG))
14661    (clobber (match_scratch:HI 4 "=a"))]
14662   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14663    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14664    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14665   "#")
14667 (define_insn "*fp_jcc_6_387"
14668   [(set (pc)
14669         (if_then_else (match_operator 0 "comparison_operator"
14670                         [(match_operand 1 "register_operand" "f")
14671                          (match_operand 2 "register_operand" "f")])
14672           (pc)
14673           (label_ref (match_operand 3 "" ""))))
14674    (clobber (reg:CCFP FPSR_REG))
14675    (clobber (reg:CCFP FLAGS_REG))
14676    (clobber (match_scratch:HI 4 "=a"))]
14677   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14678    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14679    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14680   "#")
14682 (define_insn "*fp_jcc_7_387"
14683   [(set (pc)
14684         (if_then_else (match_operator 0 "comparison_operator"
14685                         [(match_operand 1 "register_operand" "f")
14686                          (match_operand 2 "const0_operand" "")])
14687           (label_ref (match_operand 3 "" ""))
14688           (pc)))
14689    (clobber (reg:CCFP FPSR_REG))
14690    (clobber (reg:CCFP FLAGS_REG))
14691    (clobber (match_scratch:HI 4 "=a"))]
14692   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14693    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14694    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14695    && SELECT_CC_MODE (GET_CODE (operands[0]),
14696                       operands[1], operands[2]) == CCFPmode
14697    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14698   "#")
14700 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14701 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14702 ;; with a precedence over other operators and is always put in the first
14703 ;; place. Swap condition and operands to match ficom instruction.
14705 (define_insn "*fp_jcc_8<mode>_387"
14706   [(set (pc)
14707         (if_then_else (match_operator 0 "comparison_operator"
14708                         [(match_operator 1 "float_operator"
14709                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14710                            (match_operand 3 "register_operand" "f,f")])
14711           (label_ref (match_operand 4 "" ""))
14712           (pc)))
14713    (clobber (reg:CCFP FPSR_REG))
14714    (clobber (reg:CCFP FLAGS_REG))
14715    (clobber (match_scratch:HI 5 "=a,a"))]
14716   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14717    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14718    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14719    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14720    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14721    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14722   "#")
14724 (define_split
14725   [(set (pc)
14726         (if_then_else (match_operator 0 "comparison_operator"
14727                         [(match_operand 1 "register_operand" "")
14728                          (match_operand 2 "nonimmediate_operand" "")])
14729           (match_operand 3 "" "")
14730           (match_operand 4 "" "")))
14731    (clobber (reg:CCFP FPSR_REG))
14732    (clobber (reg:CCFP FLAGS_REG))]
14733   "reload_completed"
14734   [(const_int 0)]
14736   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14737                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14738   DONE;
14741 (define_split
14742   [(set (pc)
14743         (if_then_else (match_operator 0 "comparison_operator"
14744                         [(match_operand 1 "register_operand" "")
14745                          (match_operand 2 "general_operand" "")])
14746           (match_operand 3 "" "")
14747           (match_operand 4 "" "")))
14748    (clobber (reg:CCFP FPSR_REG))
14749    (clobber (reg:CCFP FLAGS_REG))
14750    (clobber (match_scratch:HI 5 "=a"))]
14751   "reload_completed"
14752   [(const_int 0)]
14754   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14755                         operands[3], operands[4], operands[5], NULL_RTX);
14756   DONE;
14759 (define_split
14760   [(set (pc)
14761         (if_then_else (match_operator 0 "comparison_operator"
14762                         [(match_operator 1 "float_operator"
14763                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14764                            (match_operand 3 "register_operand" "")])
14765           (match_operand 4 "" "")
14766           (match_operand 5 "" "")))
14767    (clobber (reg:CCFP FPSR_REG))
14768    (clobber (reg:CCFP FLAGS_REG))
14769    (clobber (match_scratch:HI 6 "=a"))]
14770   "reload_completed"
14771   [(const_int 0)]
14773   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14774   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14775                         operands[3], operands[7],
14776                         operands[4], operands[5], operands[6], NULL_RTX);
14777   DONE;
14780 ;; %%% Kill this when reload knows how to do it.
14781 (define_split
14782   [(set (pc)
14783         (if_then_else (match_operator 0 "comparison_operator"
14784                         [(match_operator 1 "float_operator"
14785                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14786                            (match_operand 3 "register_operand" "")])
14787           (match_operand 4 "" "")
14788           (match_operand 5 "" "")))
14789    (clobber (reg:CCFP FPSR_REG))
14790    (clobber (reg:CCFP FLAGS_REG))
14791    (clobber (match_scratch:HI 6 "=a"))]
14792   "reload_completed"
14793   [(const_int 0)]
14795   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14796   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14797   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14798                         operands[3], operands[7],
14799                         operands[4], operands[5], operands[6], operands[2]);
14800   DONE;
14803 ;; Unconditional and other jump instructions
14805 (define_insn "jump"
14806   [(set (pc)
14807         (label_ref (match_operand 0 "" "")))]
14808   ""
14809   "jmp\t%l0"
14810   [(set_attr "type" "ibr")
14811    (set (attr "length")
14812            (if_then_else (and (ge (minus (match_dup 0) (pc))
14813                                   (const_int -126))
14814                               (lt (minus (match_dup 0) (pc))
14815                                   (const_int 128)))
14816              (const_int 2)
14817              (const_int 5)))
14818    (set_attr "modrm" "0")])
14820 (define_expand "indirect_jump"
14821   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14822   ""
14823   "")
14825 (define_insn "*indirect_jump"
14826   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14827   ""
14828   "jmp\t%A0"
14829   [(set_attr "type" "ibr")
14830    (set_attr "length_immediate" "0")])
14832 (define_expand "tablejump"
14833   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14834               (use (label_ref (match_operand 1 "" "")))])]
14835   ""
14837   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14838      relative.  Convert the relative address to an absolute address.  */
14839   if (flag_pic)
14840     {
14841       rtx op0, op1;
14842       enum rtx_code code;
14844       /* We can't use @GOTOFF for text labels on VxWorks;
14845          see gotoff_operand.  */
14846       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14847         {
14848           code = PLUS;
14849           op0 = operands[0];
14850           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14851         }
14852       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14853         {
14854           code = PLUS;
14855           op0 = operands[0];
14856           op1 = pic_offset_table_rtx;
14857         }
14858       else
14859         {
14860           code = MINUS;
14861           op0 = pic_offset_table_rtx;
14862           op1 = operands[0];
14863         }
14865       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14866                                          OPTAB_DIRECT);
14867     }
14870 (define_insn "*tablejump_1"
14871   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14872    (use (label_ref (match_operand 1 "" "")))]
14873   ""
14874   "jmp\t%A0"
14875   [(set_attr "type" "ibr")
14876    (set_attr "length_immediate" "0")])
14878 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14880 (define_peephole2
14881   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14882    (set (match_operand:QI 1 "register_operand" "")
14883         (match_operator:QI 2 "ix86_comparison_operator"
14884           [(reg FLAGS_REG) (const_int 0)]))
14885    (set (match_operand 3 "q_regs_operand" "")
14886         (zero_extend (match_dup 1)))]
14887   "(peep2_reg_dead_p (3, operands[1])
14888     || operands_match_p (operands[1], operands[3]))
14889    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14890   [(set (match_dup 4) (match_dup 0))
14891    (set (strict_low_part (match_dup 5))
14892         (match_dup 2))]
14894   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14895   operands[5] = gen_lowpart (QImode, operands[3]);
14896   ix86_expand_clear (operands[3]);
14899 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14901 (define_peephole2
14902   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14903    (set (match_operand:QI 1 "register_operand" "")
14904         (match_operator:QI 2 "ix86_comparison_operator"
14905           [(reg FLAGS_REG) (const_int 0)]))
14906    (parallel [(set (match_operand 3 "q_regs_operand" "")
14907                    (zero_extend (match_dup 1)))
14908               (clobber (reg:CC FLAGS_REG))])]
14909   "(peep2_reg_dead_p (3, operands[1])
14910     || operands_match_p (operands[1], operands[3]))
14911    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14912   [(set (match_dup 4) (match_dup 0))
14913    (set (strict_low_part (match_dup 5))
14914         (match_dup 2))]
14916   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14917   operands[5] = gen_lowpart (QImode, operands[3]);
14918   ix86_expand_clear (operands[3]);
14921 ;; Call instructions.
14923 ;; The predicates normally associated with named expanders are not properly
14924 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14925 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14927 ;; Call subroutine returning no value.
14929 (define_expand "call_pop"
14930   [(parallel [(call (match_operand:QI 0 "" "")
14931                     (match_operand:SI 1 "" ""))
14932               (set (reg:SI SP_REG)
14933                    (plus:SI (reg:SI SP_REG)
14934                             (match_operand:SI 3 "" "")))])]
14935   "!TARGET_64BIT"
14937   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14938   DONE;
14941 (define_insn "*call_pop_0"
14942   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14943          (match_operand:SI 1 "" ""))
14944    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14945                             (match_operand:SI 2 "immediate_operand" "")))]
14946   "!TARGET_64BIT"
14948   if (SIBLING_CALL_P (insn))
14949     return "jmp\t%P0";
14950   else
14951     return "call\t%P0";
14953   [(set_attr "type" "call")])
14955 (define_insn "*call_pop_1"
14956   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14957          (match_operand:SI 1 "" ""))
14958    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14959                             (match_operand:SI 2 "immediate_operand" "i")))]
14960   "!TARGET_64BIT"
14962   if (constant_call_address_operand (operands[0], Pmode))
14963     {
14964       if (SIBLING_CALL_P (insn))
14965         return "jmp\t%P0";
14966       else
14967         return "call\t%P0";
14968     }
14969   if (SIBLING_CALL_P (insn))
14970     return "jmp\t%A0";
14971   else
14972     return "call\t%A0";
14974   [(set_attr "type" "call")])
14976 (define_expand "call"
14977   [(call (match_operand:QI 0 "" "")
14978          (match_operand 1 "" ""))
14979    (use (match_operand 2 "" ""))]
14980   ""
14982   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14983   DONE;
14986 (define_expand "sibcall"
14987   [(call (match_operand:QI 0 "" "")
14988          (match_operand 1 "" ""))
14989    (use (match_operand 2 "" ""))]
14990   ""
14992   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14993   DONE;
14996 (define_insn "*call_0"
14997   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14998          (match_operand 1 "" ""))]
14999   ""
15001   if (SIBLING_CALL_P (insn))
15002     return "jmp\t%P0";
15003   else
15004     return "call\t%P0";
15006   [(set_attr "type" "call")])
15008 (define_insn "*call_1"
15009   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15010          (match_operand 1 "" ""))]
15011   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15013   if (constant_call_address_operand (operands[0], Pmode))
15014     return "call\t%P0";
15015   return "call\t%A0";
15017   [(set_attr "type" "call")])
15019 (define_insn "*sibcall_1"
15020   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15021          (match_operand 1 "" ""))]
15022   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15024   if (constant_call_address_operand (operands[0], Pmode))
15025     return "jmp\t%P0";
15026   return "jmp\t%A0";
15028   [(set_attr "type" "call")])
15030 (define_insn "*call_1_rex64"
15031   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15032          (match_operand 1 "" ""))]
15033   "!SIBLING_CALL_P (insn) && TARGET_64BIT
15034    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15036   if (constant_call_address_operand (operands[0], Pmode))
15037     return "call\t%P0";
15038   return "call\t%A0";
15040   [(set_attr "type" "call")])
15042 (define_insn "*call_1_rex64_large"
15043   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15044          (match_operand 1 "" ""))]
15045   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15046   "call\t%A0"
15047   [(set_attr "type" "call")])
15049 (define_insn "*sibcall_1_rex64"
15050   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15051          (match_operand 1 "" ""))]
15052   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15053   "jmp\t%P0"
15054   [(set_attr "type" "call")])
15056 (define_insn "*sibcall_1_rex64_v"
15057   [(call (mem:QI (reg:DI R11_REG))
15058          (match_operand 0 "" ""))]
15059   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15060   "jmp\t{*%%}r11"
15061   [(set_attr "type" "call")])
15064 ;; Call subroutine, returning value in operand 0
15066 (define_expand "call_value_pop"
15067   [(parallel [(set (match_operand 0 "" "")
15068                    (call (match_operand:QI 1 "" "")
15069                          (match_operand:SI 2 "" "")))
15070               (set (reg:SI SP_REG)
15071                    (plus:SI (reg:SI SP_REG)
15072                             (match_operand:SI 4 "" "")))])]
15073   "!TARGET_64BIT"
15075   ix86_expand_call (operands[0], operands[1], operands[2],
15076                     operands[3], operands[4], 0);
15077   DONE;
15080 (define_expand "call_value"
15081   [(set (match_operand 0 "" "")
15082         (call (match_operand:QI 1 "" "")
15083               (match_operand:SI 2 "" "")))
15084    (use (match_operand:SI 3 "" ""))]
15085   ;; Operand 2 not used on the i386.
15086   ""
15088   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15089   DONE;
15092 (define_expand "sibcall_value"
15093   [(set (match_operand 0 "" "")
15094         (call (match_operand:QI 1 "" "")
15095               (match_operand:SI 2 "" "")))
15096    (use (match_operand:SI 3 "" ""))]
15097   ;; Operand 2 not used on the i386.
15098   ""
15100   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15101   DONE;
15104 ;; Call subroutine returning any type.
15106 (define_expand "untyped_call"
15107   [(parallel [(call (match_operand 0 "" "")
15108                     (const_int 0))
15109               (match_operand 1 "" "")
15110               (match_operand 2 "" "")])]
15111   ""
15113   int i;
15115   /* In order to give reg-stack an easier job in validating two
15116      coprocessor registers as containing a possible return value,
15117      simply pretend the untyped call returns a complex long double
15118      value.  */
15120   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15121                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15122                     operands[0], const0_rtx,
15123                     GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
15124                                                       : X64_SSE_REGPARM_MAX)
15125                              - 1),
15126                     NULL, 0);
15128   for (i = 0; i < XVECLEN (operands[2], 0); i++)
15129     {
15130       rtx set = XVECEXP (operands[2], 0, i);
15131       emit_move_insn (SET_DEST (set), SET_SRC (set));
15132     }
15134   /* The optimizer does not know that the call sets the function value
15135      registers we stored in the result block.  We avoid problems by
15136      claiming that all hard registers are used and clobbered at this
15137      point.  */
15138   emit_insn (gen_blockage ());
15140   DONE;
15143 ;; Prologue and epilogue instructions
15145 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15146 ;; all of memory.  This blocks insns from being moved across this point.
15148 (define_insn "blockage"
15149   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15150   ""
15151   ""
15152   [(set_attr "length" "0")])
15154 ;; As USE insns aren't meaningful after reload, this is used instead
15155 ;; to prevent deleting instructions setting registers for PIC code
15156 (define_insn "prologue_use"
15157   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15158   ""
15159   ""
15160   [(set_attr "length" "0")])
15162 ;; Insn emitted into the body of a function to return from a function.
15163 ;; This is only done if the function's epilogue is known to be simple.
15164 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15166 (define_expand "return"
15167   [(return)]
15168   "ix86_can_use_return_insn_p ()"
15170   if (crtl->args.pops_args)
15171     {
15172       rtx popc = GEN_INT (crtl->args.pops_args);
15173       emit_jump_insn (gen_return_pop_internal (popc));
15174       DONE;
15175     }
15178 (define_insn "return_internal"
15179   [(return)]
15180   "reload_completed"
15181   "ret"
15182   [(set_attr "length" "1")
15183    (set_attr "length_immediate" "0")
15184    (set_attr "modrm" "0")])
15186 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15187 ;; instruction Athlon and K8 have.
15189 (define_insn "return_internal_long"
15190   [(return)
15191    (unspec [(const_int 0)] UNSPEC_REP)]
15192   "reload_completed"
15193   "rep\;ret"
15194   [(set_attr "length" "1")
15195    (set_attr "length_immediate" "0")
15196    (set_attr "prefix_rep" "1")
15197    (set_attr "modrm" "0")])
15199 (define_insn "return_pop_internal"
15200   [(return)
15201    (use (match_operand:SI 0 "const_int_operand" ""))]
15202   "reload_completed"
15203   "ret\t%0"
15204   [(set_attr "length" "3")
15205    (set_attr "length_immediate" "2")
15206    (set_attr "modrm" "0")])
15208 (define_insn "return_indirect_internal"
15209   [(return)
15210    (use (match_operand:SI 0 "register_operand" "r"))]
15211   "reload_completed"
15212   "jmp\t%A0"
15213   [(set_attr "type" "ibr")
15214    (set_attr "length_immediate" "0")])
15216 (define_insn "nop"
15217   [(const_int 0)]
15218   ""
15219   "nop"
15220   [(set_attr "length" "1")
15221    (set_attr "length_immediate" "0")
15222    (set_attr "modrm" "0")])
15224 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
15225 ;; branch prediction penalty for the third jump in a 16-byte
15226 ;; block on K8.
15228 (define_insn "align"
15229   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15230   ""
15232 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15233   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15234 #else
15235   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15236      The align insn is used to avoid 3 jump instructions in the row to improve
15237      branch prediction and the benefits hardly outweigh the cost of extra 8
15238      nops on the average inserted by full alignment pseudo operation.  */
15239 #endif
15240   return "";
15242   [(set_attr "length" "16")])
15244 (define_expand "prologue"
15245   [(const_int 0)]
15246   ""
15247   "ix86_expand_prologue (); DONE;")
15249 (define_insn "set_got"
15250   [(set (match_operand:SI 0 "register_operand" "=r")
15251         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15252    (clobber (reg:CC FLAGS_REG))]
15253   "!TARGET_64BIT"
15254   { return output_set_got (operands[0], NULL_RTX); }
15255   [(set_attr "type" "multi")
15256    (set_attr "length" "12")])
15258 (define_insn "set_got_labelled"
15259   [(set (match_operand:SI 0 "register_operand" "=r")
15260         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15261          UNSPEC_SET_GOT))
15262    (clobber (reg:CC FLAGS_REG))]
15263   "!TARGET_64BIT"
15264   { return output_set_got (operands[0], operands[1]); }
15265   [(set_attr "type" "multi")
15266    (set_attr "length" "12")])
15268 (define_insn "set_got_rex64"
15269   [(set (match_operand:DI 0 "register_operand" "=r")
15270         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15271   "TARGET_64BIT"
15272   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15273   [(set_attr "type" "lea")
15274    (set_attr "length" "6")])
15276 (define_insn "set_rip_rex64"
15277   [(set (match_operand:DI 0 "register_operand" "=r")
15278         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15279   "TARGET_64BIT"
15280   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15281   [(set_attr "type" "lea")
15282    (set_attr "length" "6")])
15284 (define_insn "set_got_offset_rex64"
15285   [(set (match_operand:DI 0 "register_operand" "=r")
15286         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15287   "TARGET_64BIT"
15288   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15289   [(set_attr "type" "imov")
15290    (set_attr "length" "11")])
15292 (define_expand "epilogue"
15293   [(const_int 0)]
15294   ""
15295   "ix86_expand_epilogue (1); DONE;")
15297 (define_expand "sibcall_epilogue"
15298   [(const_int 0)]
15299   ""
15300   "ix86_expand_epilogue (0); DONE;")
15302 (define_expand "eh_return"
15303   [(use (match_operand 0 "register_operand" ""))]
15304   ""
15306   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15308   /* Tricky bit: we write the address of the handler to which we will
15309      be returning into someone else's stack frame, one word below the
15310      stack address we wish to restore.  */
15311   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15312   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15313   tmp = gen_rtx_MEM (Pmode, tmp);
15314   emit_move_insn (tmp, ra);
15316   if (Pmode == SImode)
15317     emit_jump_insn (gen_eh_return_si (sa));
15318   else
15319     emit_jump_insn (gen_eh_return_di (sa));
15320   emit_barrier ();
15321   DONE;
15324 (define_insn_and_split "eh_return_<mode>"
15325   [(set (pc)
15326         (unspec [(match_operand:P 0 "register_operand" "c")]
15327                  UNSPEC_EH_RETURN))]
15328   ""
15329   "#"
15330   "reload_completed"
15331   [(const_int 0)]
15332   "ix86_expand_epilogue (2); DONE;")
15334 (define_insn "leave"
15335   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15336    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15337    (clobber (mem:BLK (scratch)))]
15338   "!TARGET_64BIT"
15339   "leave"
15340   [(set_attr "type" "leave")])
15342 (define_insn "leave_rex64"
15343   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15344    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15345    (clobber (mem:BLK (scratch)))]
15346   "TARGET_64BIT"
15347   "leave"
15348   [(set_attr "type" "leave")])
15350 (define_expand "ffssi2"
15351   [(parallel
15352      [(set (match_operand:SI 0 "register_operand" "")
15353            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15354       (clobber (match_scratch:SI 2 ""))
15355       (clobber (reg:CC FLAGS_REG))])]
15356   ""
15358   if (TARGET_CMOVE)
15359     {
15360       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15361       DONE;
15362     }
15365 (define_expand "ffs_cmove"
15366   [(set (match_dup 2) (const_int -1))
15367    (parallel [(set (reg:CCZ FLAGS_REG)
15368                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15369                                 (const_int 0)))
15370               (set (match_operand:SI 0 "register_operand" "")
15371                    (ctz:SI (match_dup 1)))])
15372    (set (match_dup 0) (if_then_else:SI
15373                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15374                         (match_dup 2)
15375                         (match_dup 0)))
15376    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15377               (clobber (reg:CC FLAGS_REG))])]
15378   "TARGET_CMOVE"
15379   "operands[2] = gen_reg_rtx (SImode);")
15381 (define_insn_and_split "*ffs_no_cmove"
15382   [(set (match_operand:SI 0 "register_operand" "=r")
15383         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15384    (clobber (match_scratch:SI 2 "=&q"))
15385    (clobber (reg:CC FLAGS_REG))]
15386   "!TARGET_CMOVE"
15387   "#"
15388   "&& reload_completed"
15389   [(parallel [(set (reg:CCZ FLAGS_REG)
15390                    (compare:CCZ (match_dup 1) (const_int 0)))
15391               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15392    (set (strict_low_part (match_dup 3))
15393         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15394    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15395               (clobber (reg:CC FLAGS_REG))])
15396    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15397               (clobber (reg:CC FLAGS_REG))])
15398    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15399               (clobber (reg:CC FLAGS_REG))])]
15401   operands[3] = gen_lowpart (QImode, operands[2]);
15402   ix86_expand_clear (operands[2]);
15405 (define_insn "*ffssi_1"
15406   [(set (reg:CCZ FLAGS_REG)
15407         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15408                      (const_int 0)))
15409    (set (match_operand:SI 0 "register_operand" "=r")
15410         (ctz:SI (match_dup 1)))]
15411   ""
15412   "bsf{l}\t{%1, %0|%0, %1}"
15413   [(set_attr "prefix_0f" "1")])
15415 (define_expand "ffsdi2"
15416   [(set (match_dup 2) (const_int -1))
15417    (parallel [(set (reg:CCZ FLAGS_REG)
15418                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15419                                 (const_int 0)))
15420               (set (match_operand:DI 0 "register_operand" "")
15421                    (ctz:DI (match_dup 1)))])
15422    (set (match_dup 0) (if_then_else:DI
15423                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15424                         (match_dup 2)
15425                         (match_dup 0)))
15426    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15427               (clobber (reg:CC FLAGS_REG))])]
15428   "TARGET_64BIT"
15429   "operands[2] = gen_reg_rtx (DImode);")
15431 (define_insn "*ffsdi_1"
15432   [(set (reg:CCZ FLAGS_REG)
15433         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15434                      (const_int 0)))
15435    (set (match_operand:DI 0 "register_operand" "=r")
15436         (ctz:DI (match_dup 1)))]
15437   "TARGET_64BIT"
15438   "bsf{q}\t{%1, %0|%0, %1}"
15439   [(set_attr "prefix_0f" "1")])
15441 (define_insn "ctzsi2"
15442   [(set (match_operand:SI 0 "register_operand" "=r")
15443         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15444    (clobber (reg:CC FLAGS_REG))]
15445   ""
15446   "bsf{l}\t{%1, %0|%0, %1}"
15447   [(set_attr "prefix_0f" "1")])
15449 (define_insn "ctzdi2"
15450   [(set (match_operand:DI 0 "register_operand" "=r")
15451         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15452    (clobber (reg:CC FLAGS_REG))]
15453   "TARGET_64BIT"
15454   "bsf{q}\t{%1, %0|%0, %1}"
15455   [(set_attr "prefix_0f" "1")])
15457 (define_expand "clzsi2"
15458   [(parallel
15459      [(set (match_operand:SI 0 "register_operand" "")
15460            (minus:SI (const_int 31)
15461                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15462       (clobber (reg:CC FLAGS_REG))])
15463    (parallel
15464      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15465       (clobber (reg:CC FLAGS_REG))])]
15466   ""
15468   if (TARGET_ABM)
15469     {
15470       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15471       DONE;
15472     }
15475 (define_insn "clzsi2_abm"
15476   [(set (match_operand:SI 0 "register_operand" "=r")
15477         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15478    (clobber (reg:CC FLAGS_REG))]
15479   "TARGET_ABM"
15480   "lzcnt{l}\t{%1, %0|%0, %1}"
15481   [(set_attr "prefix_rep" "1")
15482    (set_attr "type" "bitmanip")
15483    (set_attr "mode" "SI")])
15485 (define_insn "*bsr"
15486   [(set (match_operand:SI 0 "register_operand" "=r")
15487         (minus:SI (const_int 31)
15488                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15489    (clobber (reg:CC FLAGS_REG))]
15490   ""
15491   "bsr{l}\t{%1, %0|%0, %1}"
15492   [(set_attr "prefix_0f" "1")
15493    (set_attr "mode" "SI")])
15495 (define_insn "popcount<mode>2"
15496   [(set (match_operand:SWI248 0 "register_operand" "=r")
15497         (popcount:SWI248
15498           (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
15499    (clobber (reg:CC FLAGS_REG))]
15500   "TARGET_POPCNT"
15502 #if TARGET_MACHO
15503   return "popcnt\t{%1, %0|%0, %1}";
15504 #else
15505   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15506 #endif
15508   [(set_attr "prefix_rep" "1")
15509    (set_attr "type" "bitmanip")
15510    (set_attr "mode" "<MODE>")])
15512 (define_insn "*popcount<mode>2_cmp"
15513   [(set (reg FLAGS_REG)
15514         (compare
15515           (popcount:SWI248
15516             (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
15517           (const_int 0)))
15518    (set (match_operand:SWI248 0 "register_operand" "=r")
15519         (popcount:SWI248 (match_dup 1)))]
15520   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15522 #if TARGET_MACHO
15523   return "popcnt\t{%1, %0|%0, %1}";
15524 #else
15525   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15526 #endif
15528   [(set_attr "prefix_rep" "1")
15529    (set_attr "type" "bitmanip")
15530    (set_attr "mode" "<MODE>")])
15532 (define_insn "*popcountsi2_cmp_zext"
15533   [(set (reg FLAGS_REG)
15534         (compare
15535           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15536           (const_int 0)))
15537    (set (match_operand:DI 0 "register_operand" "=r")
15538         (zero_extend:DI(popcount:SI (match_dup 1))))]
15539   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15541 #if TARGET_MACHO
15542   return "popcnt\t{%1, %0|%0, %1}";
15543 #else
15544   return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15545 #endif
15547   [(set_attr "prefix_rep" "1")
15548    (set_attr "type" "bitmanip")
15549    (set_attr "mode" "SI")])
15551 (define_expand "bswapsi2"
15552   [(set (match_operand:SI 0 "register_operand" "")
15553         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15554   ""
15556   if (!TARGET_BSWAP)
15557     {
15558       rtx x = operands[0];
15560       emit_move_insn (x, operands[1]);
15561       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15562       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15563       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15564       DONE;
15565     }
15568 (define_insn "*bswapsi_1"
15569   [(set (match_operand:SI 0 "register_operand" "=r")
15570         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15571   "TARGET_BSWAP"
15572   "bswap\t%0"
15573   [(set_attr "prefix_0f" "1")
15574    (set_attr "length" "2")])
15576 (define_insn "*bswaphi_lowpart_1"
15577   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15578         (bswap:HI (match_dup 0)))
15579    (clobber (reg:CC FLAGS_REG))]
15580   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15581   "@
15582     xchg{b}\t{%h0, %b0|%b0, %h0}
15583     rol{w}\t{$8, %0|%0, 8}"
15584   [(set_attr "length" "2,4")
15585    (set_attr "mode" "QI,HI")])
15587 (define_insn "bswaphi_lowpart"
15588   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15589         (bswap:HI (match_dup 0)))
15590    (clobber (reg:CC FLAGS_REG))]
15591   ""
15592   "rol{w}\t{$8, %0|%0, 8}"
15593   [(set_attr "length" "4")
15594    (set_attr "mode" "HI")])
15596 (define_insn "bswapdi2"
15597   [(set (match_operand:DI 0 "register_operand" "=r")
15598         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15599   "TARGET_64BIT"
15600   "bswap\t%0"
15601   [(set_attr "prefix_0f" "1")
15602    (set_attr "length" "3")])
15604 (define_expand "clzdi2"
15605   [(parallel
15606      [(set (match_operand:DI 0 "register_operand" "")
15607            (minus:DI (const_int 63)
15608                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15609       (clobber (reg:CC FLAGS_REG))])
15610    (parallel
15611      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15612       (clobber (reg:CC FLAGS_REG))])]
15613   "TARGET_64BIT"
15615   if (TARGET_ABM)
15616     {
15617       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15618       DONE;
15619     }
15622 (define_insn "clzdi2_abm"
15623   [(set (match_operand:DI 0 "register_operand" "=r")
15624         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15625    (clobber (reg:CC FLAGS_REG))]
15626   "TARGET_64BIT && TARGET_ABM"
15627   "lzcnt{q}\t{%1, %0|%0, %1}"
15628   [(set_attr "prefix_rep" "1")
15629    (set_attr "type" "bitmanip")
15630    (set_attr "mode" "DI")])
15632 (define_insn "*bsr_rex64"
15633   [(set (match_operand:DI 0 "register_operand" "=r")
15634         (minus:DI (const_int 63)
15635                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15636    (clobber (reg:CC FLAGS_REG))]
15637   "TARGET_64BIT"
15638   "bsr{q}\t{%1, %0|%0, %1}"
15639   [(set_attr "prefix_0f" "1")
15640    (set_attr "mode" "DI")])
15642 (define_expand "clzhi2"
15643   [(parallel
15644      [(set (match_operand:HI 0 "register_operand" "")
15645            (minus:HI (const_int 15)
15646                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15647       (clobber (reg:CC FLAGS_REG))])
15648    (parallel
15649      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15650       (clobber (reg:CC FLAGS_REG))])]
15651   ""
15653   if (TARGET_ABM)
15654     {
15655       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15656       DONE;
15657     }
15660 (define_insn "clzhi2_abm"
15661   [(set (match_operand:HI 0 "register_operand" "=r")
15662         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15663    (clobber (reg:CC FLAGS_REG))]
15664   "TARGET_ABM"
15665   "lzcnt{w}\t{%1, %0|%0, %1}"
15666   [(set_attr "prefix_rep" "1")
15667    (set_attr "type" "bitmanip")
15668    (set_attr "mode" "HI")])
15670 (define_insn "*bsrhi"
15671   [(set (match_operand:HI 0 "register_operand" "=r")
15672         (minus:HI (const_int 15)
15673                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15674    (clobber (reg:CC FLAGS_REG))]
15675   ""
15676   "bsr{w}\t{%1, %0|%0, %1}"
15677   [(set_attr "prefix_0f" "1")
15678    (set_attr "mode" "HI")])
15680 (define_expand "paritydi2"
15681   [(set (match_operand:DI 0 "register_operand" "")
15682         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15683   "! TARGET_POPCNT"
15685   rtx scratch = gen_reg_rtx (QImode);
15686   rtx cond;
15688   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15689                                 NULL_RTX, operands[1]));
15691   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15692                          gen_rtx_REG (CCmode, FLAGS_REG),
15693                          const0_rtx);
15694   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15696   if (TARGET_64BIT)
15697     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15698   else
15699     {
15700       rtx tmp = gen_reg_rtx (SImode);
15702       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15703       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15704     }
15705   DONE;
15708 (define_insn_and_split "paritydi2_cmp"
15709   [(set (reg:CC FLAGS_REG)
15710         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15711    (clobber (match_scratch:DI 0 "=r"))
15712    (clobber (match_scratch:SI 1 "=&r"))
15713    (clobber (match_scratch:HI 2 "=Q"))]
15714   "! TARGET_POPCNT"
15715   "#"
15716   "&& reload_completed"
15717   [(parallel
15718      [(set (match_dup 1)
15719            (xor:SI (match_dup 1) (match_dup 4)))
15720       (clobber (reg:CC FLAGS_REG))])
15721    (parallel
15722      [(set (reg:CC FLAGS_REG)
15723            (parity:CC (match_dup 1)))
15724       (clobber (match_dup 1))
15725       (clobber (match_dup 2))])]
15727   operands[4] = gen_lowpart (SImode, operands[3]);
15729   if (TARGET_64BIT)
15730     {
15731       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15732       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15733     }
15734   else
15735     operands[1] = gen_highpart (SImode, operands[3]);
15738 (define_expand "paritysi2"
15739   [(set (match_operand:SI 0 "register_operand" "")
15740         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15741   "! TARGET_POPCNT"
15743   rtx scratch = gen_reg_rtx (QImode);
15744   rtx cond;
15746   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15748   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15749                          gen_rtx_REG (CCmode, FLAGS_REG),
15750                          const0_rtx);
15751   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15753   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15754   DONE;
15757 (define_insn_and_split "paritysi2_cmp"
15758   [(set (reg:CC FLAGS_REG)
15759         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15760    (clobber (match_scratch:SI 0 "=r"))
15761    (clobber (match_scratch:HI 1 "=&Q"))]
15762   "! TARGET_POPCNT"
15763   "#"
15764   "&& reload_completed"
15765   [(parallel
15766      [(set (match_dup 1)
15767            (xor:HI (match_dup 1) (match_dup 3)))
15768       (clobber (reg:CC FLAGS_REG))])
15769    (parallel
15770      [(set (reg:CC FLAGS_REG)
15771            (parity:CC (match_dup 1)))
15772       (clobber (match_dup 1))])]
15774   operands[3] = gen_lowpart (HImode, operands[2]);
15776   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15777   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15780 (define_insn "*parityhi2_cmp"
15781   [(set (reg:CC FLAGS_REG)
15782         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15783    (clobber (match_scratch:HI 0 "=Q"))]
15784   "! TARGET_POPCNT"
15785   "xor{b}\t{%h0, %b0|%b0, %h0}"
15786   [(set_attr "length" "2")
15787    (set_attr "mode" "HI")])
15789 (define_insn "*parityqi2_cmp"
15790   [(set (reg:CC FLAGS_REG)
15791         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15792   "! TARGET_POPCNT"
15793   "test{b}\t%0, %0"
15794   [(set_attr "length" "2")
15795    (set_attr "mode" "QI")])
15797 ;; Thread-local storage patterns for ELF.
15799 ;; Note that these code sequences must appear exactly as shown
15800 ;; in order to allow linker relaxation.
15802 (define_insn "*tls_global_dynamic_32_gnu"
15803   [(set (match_operand:SI 0 "register_operand" "=a")
15804         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15805                     (match_operand:SI 2 "tls_symbolic_operand" "")
15806                     (match_operand:SI 3 "call_insn_operand" "")]
15807                     UNSPEC_TLS_GD))
15808    (clobber (match_scratch:SI 4 "=d"))
15809    (clobber (match_scratch:SI 5 "=c"))
15810    (clobber (reg:CC FLAGS_REG))]
15811   "!TARGET_64BIT && TARGET_GNU_TLS"
15812   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15813   [(set_attr "type" "multi")
15814    (set_attr "length" "12")])
15816 (define_insn "*tls_global_dynamic_32_sun"
15817   [(set (match_operand:SI 0 "register_operand" "=a")
15818         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15819                     (match_operand:SI 2 "tls_symbolic_operand" "")
15820                     (match_operand:SI 3 "call_insn_operand" "")]
15821                     UNSPEC_TLS_GD))
15822    (clobber (match_scratch:SI 4 "=d"))
15823    (clobber (match_scratch:SI 5 "=c"))
15824    (clobber (reg:CC FLAGS_REG))]
15825   "!TARGET_64BIT && TARGET_SUN_TLS"
15826   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15827         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15828   [(set_attr "type" "multi")
15829    (set_attr "length" "14")])
15831 (define_expand "tls_global_dynamic_32"
15832   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15833                    (unspec:SI
15834                     [(match_dup 2)
15835                      (match_operand:SI 1 "tls_symbolic_operand" "")
15836                      (match_dup 3)]
15837                     UNSPEC_TLS_GD))
15838               (clobber (match_scratch:SI 4 ""))
15839               (clobber (match_scratch:SI 5 ""))
15840               (clobber (reg:CC FLAGS_REG))])]
15841   ""
15843   if (flag_pic)
15844     operands[2] = pic_offset_table_rtx;
15845   else
15846     {
15847       operands[2] = gen_reg_rtx (Pmode);
15848       emit_insn (gen_set_got (operands[2]));
15849     }
15850   if (TARGET_GNU2_TLS)
15851     {
15852        emit_insn (gen_tls_dynamic_gnu2_32
15853                   (operands[0], operands[1], operands[2]));
15854        DONE;
15855     }
15856   operands[3] = ix86_tls_get_addr ();
15859 (define_insn "*tls_global_dynamic_64"
15860   [(set (match_operand:DI 0 "register_operand" "=a")
15861         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15862                  (match_operand:DI 3 "" "")))
15863    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15864               UNSPEC_TLS_GD)]
15865   "TARGET_64BIT"
15866   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15867   [(set_attr "type" "multi")
15868    (set_attr "length" "16")])
15870 (define_expand "tls_global_dynamic_64"
15871   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15872                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15873               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15874                          UNSPEC_TLS_GD)])]
15875   ""
15877   if (TARGET_GNU2_TLS)
15878     {
15879        emit_insn (gen_tls_dynamic_gnu2_64
15880                   (operands[0], operands[1]));
15881        DONE;
15882     }
15883   operands[2] = ix86_tls_get_addr ();
15886 (define_insn "*tls_local_dynamic_base_32_gnu"
15887   [(set (match_operand:SI 0 "register_operand" "=a")
15888         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15889                     (match_operand:SI 2 "call_insn_operand" "")]
15890                    UNSPEC_TLS_LD_BASE))
15891    (clobber (match_scratch:SI 3 "=d"))
15892    (clobber (match_scratch:SI 4 "=c"))
15893    (clobber (reg:CC FLAGS_REG))]
15894   "!TARGET_64BIT && TARGET_GNU_TLS"
15895   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15896   [(set_attr "type" "multi")
15897    (set_attr "length" "11")])
15899 (define_insn "*tls_local_dynamic_base_32_sun"
15900   [(set (match_operand:SI 0 "register_operand" "=a")
15901         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15902                     (match_operand:SI 2 "call_insn_operand" "")]
15903                    UNSPEC_TLS_LD_BASE))
15904    (clobber (match_scratch:SI 3 "=d"))
15905    (clobber (match_scratch:SI 4 "=c"))
15906    (clobber (reg:CC FLAGS_REG))]
15907   "!TARGET_64BIT && TARGET_SUN_TLS"
15908   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15909         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15910   [(set_attr "type" "multi")
15911    (set_attr "length" "13")])
15913 (define_expand "tls_local_dynamic_base_32"
15914   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15915                    (unspec:SI [(match_dup 1) (match_dup 2)]
15916                               UNSPEC_TLS_LD_BASE))
15917               (clobber (match_scratch:SI 3 ""))
15918               (clobber (match_scratch:SI 4 ""))
15919               (clobber (reg:CC FLAGS_REG))])]
15920   ""
15922   if (flag_pic)
15923     operands[1] = pic_offset_table_rtx;
15924   else
15925     {
15926       operands[1] = gen_reg_rtx (Pmode);
15927       emit_insn (gen_set_got (operands[1]));
15928     }
15929   if (TARGET_GNU2_TLS)
15930     {
15931        emit_insn (gen_tls_dynamic_gnu2_32
15932                   (operands[0], ix86_tls_module_base (), operands[1]));
15933        DONE;
15934     }
15935   operands[2] = ix86_tls_get_addr ();
15938 (define_insn "*tls_local_dynamic_base_64"
15939   [(set (match_operand:DI 0 "register_operand" "=a")
15940         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15941                  (match_operand:DI 2 "" "")))
15942    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15943   "TARGET_64BIT"
15944   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15945   [(set_attr "type" "multi")
15946    (set_attr "length" "12")])
15948 (define_expand "tls_local_dynamic_base_64"
15949   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15950                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15951               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15952   ""
15954   if (TARGET_GNU2_TLS)
15955     {
15956        emit_insn (gen_tls_dynamic_gnu2_64
15957                   (operands[0], ix86_tls_module_base ()));
15958        DONE;
15959     }
15960   operands[1] = ix86_tls_get_addr ();
15963 ;; Local dynamic of a single variable is a lose.  Show combine how
15964 ;; to convert that back to global dynamic.
15966 (define_insn_and_split "*tls_local_dynamic_32_once"
15967   [(set (match_operand:SI 0 "register_operand" "=a")
15968         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15969                              (match_operand:SI 2 "call_insn_operand" "")]
15970                             UNSPEC_TLS_LD_BASE)
15971                  (const:SI (unspec:SI
15972                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15973                             UNSPEC_DTPOFF))))
15974    (clobber (match_scratch:SI 4 "=d"))
15975    (clobber (match_scratch:SI 5 "=c"))
15976    (clobber (reg:CC FLAGS_REG))]
15977   ""
15978   "#"
15979   ""
15980   [(parallel [(set (match_dup 0)
15981                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15982                               UNSPEC_TLS_GD))
15983               (clobber (match_dup 4))
15984               (clobber (match_dup 5))
15985               (clobber (reg:CC FLAGS_REG))])]
15986   "")
15988 ;; Load and add the thread base pointer from %gs:0.
15990 (define_insn "*load_tp_si"
15991   [(set (match_operand:SI 0 "register_operand" "=r")
15992         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15993   "!TARGET_64BIT"
15994   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15995   [(set_attr "type" "imov")
15996    (set_attr "modrm" "0")
15997    (set_attr "length" "7")
15998    (set_attr "memory" "load")
15999    (set_attr "imm_disp" "false")])
16001 (define_insn "*add_tp_si"
16002   [(set (match_operand:SI 0 "register_operand" "=r")
16003         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16004                  (match_operand:SI 1 "register_operand" "0")))
16005    (clobber (reg:CC FLAGS_REG))]
16006   "!TARGET_64BIT"
16007   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16008   [(set_attr "type" "alu")
16009    (set_attr "modrm" "0")
16010    (set_attr "length" "7")
16011    (set_attr "memory" "load")
16012    (set_attr "imm_disp" "false")])
16014 (define_insn "*load_tp_di"
16015   [(set (match_operand:DI 0 "register_operand" "=r")
16016         (unspec:DI [(const_int 0)] UNSPEC_TP))]
16017   "TARGET_64BIT"
16018   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16019   [(set_attr "type" "imov")
16020    (set_attr "modrm" "0")
16021    (set_attr "length" "7")
16022    (set_attr "memory" "load")
16023    (set_attr "imm_disp" "false")])
16025 (define_insn "*add_tp_di"
16026   [(set (match_operand:DI 0 "register_operand" "=r")
16027         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16028                  (match_operand:DI 1 "register_operand" "0")))
16029    (clobber (reg:CC FLAGS_REG))]
16030   "TARGET_64BIT"
16031   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16032   [(set_attr "type" "alu")
16033    (set_attr "modrm" "0")
16034    (set_attr "length" "7")
16035    (set_attr "memory" "load")
16036    (set_attr "imm_disp" "false")])
16038 ;; GNU2 TLS patterns can be split.
16040 (define_expand "tls_dynamic_gnu2_32"
16041   [(set (match_dup 3)
16042         (plus:SI (match_operand:SI 2 "register_operand" "")
16043                  (const:SI
16044                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16045                              UNSPEC_TLSDESC))))
16046    (parallel
16047     [(set (match_operand:SI 0 "register_operand" "")
16048           (unspec:SI [(match_dup 1) (match_dup 3)
16049                       (match_dup 2) (reg:SI SP_REG)]
16050                       UNSPEC_TLSDESC))
16051      (clobber (reg:CC FLAGS_REG))])]
16052   "!TARGET_64BIT && TARGET_GNU2_TLS"
16054   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16055   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16058 (define_insn "*tls_dynamic_lea_32"
16059   [(set (match_operand:SI 0 "register_operand" "=r")
16060         (plus:SI (match_operand:SI 1 "register_operand" "b")
16061                  (const:SI
16062                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16063                               UNSPEC_TLSDESC))))]
16064   "!TARGET_64BIT && TARGET_GNU2_TLS"
16065   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16066   [(set_attr "type" "lea")
16067    (set_attr "mode" "SI")
16068    (set_attr "length" "6")
16069    (set_attr "length_address" "4")])
16071 (define_insn "*tls_dynamic_call_32"
16072   [(set (match_operand:SI 0 "register_operand" "=a")
16073         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16074                     (match_operand:SI 2 "register_operand" "0")
16075                     ;; we have to make sure %ebx still points to the GOT
16076                     (match_operand:SI 3 "register_operand" "b")
16077                     (reg:SI SP_REG)]
16078                    UNSPEC_TLSDESC))
16079    (clobber (reg:CC FLAGS_REG))]
16080   "!TARGET_64BIT && TARGET_GNU2_TLS"
16081   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16082   [(set_attr "type" "call")
16083    (set_attr "length" "2")
16084    (set_attr "length_address" "0")])
16086 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16087   [(set (match_operand:SI 0 "register_operand" "=&a")
16088         (plus:SI
16089          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16090                      (match_operand:SI 4 "" "")
16091                      (match_operand:SI 2 "register_operand" "b")
16092                      (reg:SI SP_REG)]
16093                     UNSPEC_TLSDESC)
16094          (const:SI (unspec:SI
16095                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
16096                     UNSPEC_DTPOFF))))
16097    (clobber (reg:CC FLAGS_REG))]
16098   "!TARGET_64BIT && TARGET_GNU2_TLS"
16099   "#"
16100   ""
16101   [(set (match_dup 0) (match_dup 5))]
16103   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16104   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16107 (define_expand "tls_dynamic_gnu2_64"
16108   [(set (match_dup 2)
16109         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16110                    UNSPEC_TLSDESC))
16111    (parallel
16112     [(set (match_operand:DI 0 "register_operand" "")
16113           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16114                      UNSPEC_TLSDESC))
16115      (clobber (reg:CC FLAGS_REG))])]
16116   "TARGET_64BIT && TARGET_GNU2_TLS"
16118   operands[2] = !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_64"
16123   [(set (match_operand:DI 0 "register_operand" "=r")
16124         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16125                    UNSPEC_TLSDESC))]
16126   "TARGET_64BIT && TARGET_GNU2_TLS"
16127   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16128   [(set_attr "type" "lea")
16129    (set_attr "mode" "DI")
16130    (set_attr "length" "7")
16131    (set_attr "length_address" "4")])
16133 (define_insn "*tls_dynamic_call_64"
16134   [(set (match_operand:DI 0 "register_operand" "=a")
16135         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16136                     (match_operand:DI 2 "register_operand" "0")
16137                     (reg:DI SP_REG)]
16138                    UNSPEC_TLSDESC))
16139    (clobber (reg:CC FLAGS_REG))]
16140   "TARGET_64BIT && TARGET_GNU2_TLS"
16141   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16142   [(set_attr "type" "call")
16143    (set_attr "length" "2")
16144    (set_attr "length_address" "0")])
16146 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16147   [(set (match_operand:DI 0 "register_operand" "=&a")
16148         (plus:DI
16149          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16150                      (match_operand:DI 3 "" "")
16151                      (reg:DI SP_REG)]
16152                     UNSPEC_TLSDESC)
16153          (const:DI (unspec:DI
16154                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16155                     UNSPEC_DTPOFF))))
16156    (clobber (reg:CC FLAGS_REG))]
16157   "TARGET_64BIT && TARGET_GNU2_TLS"
16158   "#"
16159   ""
16160   [(set (match_dup 0) (match_dup 4))]
16162   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16163   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16168 ;; These patterns match the binary 387 instructions for addM3, subM3,
16169 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16170 ;; SFmode.  The first is the normal insn, the second the same insn but
16171 ;; with one operand a conversion, and the third the same insn but with
16172 ;; the other operand a conversion.  The conversion may be SFmode or
16173 ;; SImode if the target mode DFmode, but only SImode if the target mode
16174 ;; is SFmode.
16176 ;; Gcc is slightly more smart about handling normal two address instructions
16177 ;; so use special patterns for add and mull.
16179 (define_insn "*fop_<mode>_comm_mixed_avx"
16180   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16181         (match_operator:MODEF 3 "binary_fp_operator"
16182           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16183            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16184   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16185    && COMMUTATIVE_ARITH_P (operands[3])
16186    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16187   "* return output_387_binary_op (insn, operands);"
16188   [(set (attr "type")
16189         (if_then_else (eq_attr "alternative" "1")
16190            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16191               (const_string "ssemul")
16192               (const_string "sseadd"))
16193            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16194               (const_string "fmul")
16195               (const_string "fop"))))
16196    (set_attr "prefix" "orig,maybe_vex")
16197    (set_attr "mode" "<MODE>")])
16199 (define_insn "*fop_<mode>_comm_mixed"
16200   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16201         (match_operator:MODEF 3 "binary_fp_operator"
16202           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16203            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16204   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16205    && COMMUTATIVE_ARITH_P (operands[3])
16206    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16207   "* return output_387_binary_op (insn, operands);"
16208   [(set (attr "type")
16209         (if_then_else (eq_attr "alternative" "1")
16210            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16211               (const_string "ssemul")
16212               (const_string "sseadd"))
16213            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16214               (const_string "fmul")
16215               (const_string "fop"))))
16216    (set_attr "mode" "<MODE>")])
16218 (define_insn "*fop_<mode>_comm_avx"
16219   [(set (match_operand:MODEF 0 "register_operand" "=x")
16220         (match_operator:MODEF 3 "binary_fp_operator"
16221           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16222            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16223   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16224    && COMMUTATIVE_ARITH_P (operands[3])
16225    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16226   "* return output_387_binary_op (insn, operands);"
16227   [(set (attr "type")
16228         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16229            (const_string "ssemul")
16230            (const_string "sseadd")))
16231    (set_attr "prefix" "vex")
16232    (set_attr "mode" "<MODE>")])
16234 (define_insn "*fop_<mode>_comm_sse"
16235   [(set (match_operand:MODEF 0 "register_operand" "=x")
16236         (match_operator:MODEF 3 "binary_fp_operator"
16237           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16238            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16239   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16240    && COMMUTATIVE_ARITH_P (operands[3])
16241    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16242   "* return output_387_binary_op (insn, operands);"
16243   [(set (attr "type")
16244         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16245            (const_string "ssemul")
16246            (const_string "sseadd")))
16247    (set_attr "mode" "<MODE>")])
16249 (define_insn "*fop_<mode>_comm_i387"
16250   [(set (match_operand:MODEF 0 "register_operand" "=f")
16251         (match_operator:MODEF 3 "binary_fp_operator"
16252           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16253            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16254   "TARGET_80387
16255    && COMMUTATIVE_ARITH_P (operands[3])
16256    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16257   "* return output_387_binary_op (insn, operands);"
16258   [(set (attr "type")
16259         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16260            (const_string "fmul")
16261            (const_string "fop")))
16262    (set_attr "mode" "<MODE>")])
16264 (define_insn "*fop_<mode>_1_mixed_avx"
16265   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16266         (match_operator:MODEF 3 "binary_fp_operator"
16267           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16268            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16269   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16270    && !COMMUTATIVE_ARITH_P (operands[3])
16271    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16272   "* return output_387_binary_op (insn, operands);"
16273   [(set (attr "type")
16274         (cond [(and (eq_attr "alternative" "2")
16275                     (match_operand:MODEF 3 "mult_operator" ""))
16276                  (const_string "ssemul")
16277                (and (eq_attr "alternative" "2")
16278                     (match_operand:MODEF 3 "div_operator" ""))
16279                  (const_string "ssediv")
16280                (eq_attr "alternative" "2")
16281                  (const_string "sseadd")
16282                (match_operand:MODEF 3 "mult_operator" "")
16283                  (const_string "fmul")
16284                (match_operand:MODEF 3 "div_operator" "")
16285                  (const_string "fdiv")
16286               ]
16287               (const_string "fop")))
16288    (set_attr "prefix" "orig,orig,maybe_vex")
16289    (set_attr "mode" "<MODE>")])
16291 (define_insn "*fop_<mode>_1_mixed"
16292   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16293         (match_operator:MODEF 3 "binary_fp_operator"
16294           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16295            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16296   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16297    && !COMMUTATIVE_ARITH_P (operands[3])
16298    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16299   "* return output_387_binary_op (insn, operands);"
16300   [(set (attr "type")
16301         (cond [(and (eq_attr "alternative" "2")
16302                     (match_operand:MODEF 3 "mult_operator" ""))
16303                  (const_string "ssemul")
16304                (and (eq_attr "alternative" "2")
16305                     (match_operand:MODEF 3 "div_operator" ""))
16306                  (const_string "ssediv")
16307                (eq_attr "alternative" "2")
16308                  (const_string "sseadd")
16309                (match_operand:MODEF 3 "mult_operator" "")
16310                  (const_string "fmul")
16311                (match_operand:MODEF 3 "div_operator" "")
16312                  (const_string "fdiv")
16313               ]
16314               (const_string "fop")))
16315    (set_attr "mode" "<MODE>")])
16317 (define_insn "*rcpsf2_sse"
16318   [(set (match_operand:SF 0 "register_operand" "=x")
16319         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16320                    UNSPEC_RCP))]
16321   "TARGET_SSE_MATH"
16322   "%vrcpss\t{%1, %d0|%d0, %1}"
16323   [(set_attr "type" "sse")
16324    (set_attr "prefix" "maybe_vex")
16325    (set_attr "mode" "SF")])
16327 (define_insn "*fop_<mode>_1_avx"
16328   [(set (match_operand:MODEF 0 "register_operand" "=x")
16329         (match_operator:MODEF 3 "binary_fp_operator"
16330           [(match_operand:MODEF 1 "register_operand" "x")
16331            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16332   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16333    && !COMMUTATIVE_ARITH_P (operands[3])"
16334   "* return output_387_binary_op (insn, operands);"
16335   [(set (attr "type")
16336         (cond [(match_operand:MODEF 3 "mult_operator" "")
16337                  (const_string "ssemul")
16338                (match_operand:MODEF 3 "div_operator" "")
16339                  (const_string "ssediv")
16340               ]
16341               (const_string "sseadd")))
16342    (set_attr "prefix" "vex")
16343    (set_attr "mode" "<MODE>")])
16345 (define_insn "*fop_<mode>_1_sse"
16346   [(set (match_operand:MODEF 0 "register_operand" "=x")
16347         (match_operator:MODEF 3 "binary_fp_operator"
16348           [(match_operand:MODEF 1 "register_operand" "0")
16349            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16350   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16351    && !COMMUTATIVE_ARITH_P (operands[3])"
16352   "* return output_387_binary_op (insn, operands);"
16353   [(set (attr "type")
16354         (cond [(match_operand:MODEF 3 "mult_operator" "")
16355                  (const_string "ssemul")
16356                (match_operand:MODEF 3 "div_operator" "")
16357                  (const_string "ssediv")
16358               ]
16359               (const_string "sseadd")))
16360    (set_attr "mode" "<MODE>")])
16362 ;; This pattern is not fully shadowed by the pattern above.
16363 (define_insn "*fop_<mode>_1_i387"
16364   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16365         (match_operator:MODEF 3 "binary_fp_operator"
16366           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16367            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16368   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16369    && !COMMUTATIVE_ARITH_P (operands[3])
16370    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16371   "* return output_387_binary_op (insn, operands);"
16372   [(set (attr "type")
16373         (cond [(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 ;; ??? Add SSE splitters for these!
16382 (define_insn "*fop_<MODEF:mode>_2_i387"
16383   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16384         (match_operator:MODEF 3 "binary_fp_operator"
16385           [(float:MODEF
16386              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16387            (match_operand:MODEF 2 "register_operand" "0,0")]))]
16388   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16389    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16390   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16391   [(set (attr "type")
16392         (cond [(match_operand:MODEF 3 "mult_operator" "")
16393                  (const_string "fmul")
16394                (match_operand:MODEF 3 "div_operator" "")
16395                  (const_string "fdiv")
16396               ]
16397               (const_string "fop")))
16398    (set_attr "fp_int_src" "true")
16399    (set_attr "mode" "<X87MODEI12:MODE>")])
16401 (define_insn "*fop_<MODEF:mode>_3_i387"
16402   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16403         (match_operator:MODEF 3 "binary_fp_operator"
16404           [(match_operand:MODEF 1 "register_operand" "0,0")
16405            (float:MODEF
16406              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16407   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16408    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16409   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16410   [(set (attr "type")
16411         (cond [(match_operand:MODEF 3 "mult_operator" "")
16412                  (const_string "fmul")
16413                (match_operand:MODEF 3 "div_operator" "")
16414                  (const_string "fdiv")
16415               ]
16416               (const_string "fop")))
16417    (set_attr "fp_int_src" "true")
16418    (set_attr "mode" "<MODE>")])
16420 (define_insn "*fop_df_4_i387"
16421   [(set (match_operand:DF 0 "register_operand" "=f,f")
16422         (match_operator:DF 3 "binary_fp_operator"
16423            [(float_extend:DF
16424              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16425             (match_operand:DF 2 "register_operand" "0,f")]))]
16426   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16427    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16428   "* return output_387_binary_op (insn, operands);"
16429   [(set (attr "type")
16430         (cond [(match_operand:DF 3 "mult_operator" "")
16431                  (const_string "fmul")
16432                (match_operand:DF 3 "div_operator" "")
16433                  (const_string "fdiv")
16434               ]
16435               (const_string "fop")))
16436    (set_attr "mode" "SF")])
16438 (define_insn "*fop_df_5_i387"
16439   [(set (match_operand:DF 0 "register_operand" "=f,f")
16440         (match_operator:DF 3 "binary_fp_operator"
16441           [(match_operand:DF 1 "register_operand" "0,f")
16442            (float_extend:DF
16443             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16444   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16445   "* return output_387_binary_op (insn, operands);"
16446   [(set (attr "type")
16447         (cond [(match_operand:DF 3 "mult_operator" "")
16448                  (const_string "fmul")
16449                (match_operand:DF 3 "div_operator" "")
16450                  (const_string "fdiv")
16451               ]
16452               (const_string "fop")))
16453    (set_attr "mode" "SF")])
16455 (define_insn "*fop_df_6_i387"
16456   [(set (match_operand:DF 0 "register_operand" "=f,f")
16457         (match_operator:DF 3 "binary_fp_operator"
16458           [(float_extend:DF
16459             (match_operand:SF 1 "register_operand" "0,f"))
16460            (float_extend:DF
16461             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16462   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16463   "* return output_387_binary_op (insn, operands);"
16464   [(set (attr "type")
16465         (cond [(match_operand:DF 3 "mult_operator" "")
16466                  (const_string "fmul")
16467                (match_operand:DF 3 "div_operator" "")
16468                  (const_string "fdiv")
16469               ]
16470               (const_string "fop")))
16471    (set_attr "mode" "SF")])
16473 (define_insn "*fop_xf_comm_i387"
16474   [(set (match_operand:XF 0 "register_operand" "=f")
16475         (match_operator:XF 3 "binary_fp_operator"
16476                         [(match_operand:XF 1 "register_operand" "%0")
16477                          (match_operand:XF 2 "register_operand" "f")]))]
16478   "TARGET_80387
16479    && COMMUTATIVE_ARITH_P (operands[3])"
16480   "* return output_387_binary_op (insn, operands);"
16481   [(set (attr "type")
16482         (if_then_else (match_operand:XF 3 "mult_operator" "")
16483            (const_string "fmul")
16484            (const_string "fop")))
16485    (set_attr "mode" "XF")])
16487 (define_insn "*fop_xf_1_i387"
16488   [(set (match_operand:XF 0 "register_operand" "=f,f")
16489         (match_operator:XF 3 "binary_fp_operator"
16490                         [(match_operand:XF 1 "register_operand" "0,f")
16491                          (match_operand:XF 2 "register_operand" "f,0")]))]
16492   "TARGET_80387
16493    && !COMMUTATIVE_ARITH_P (operands[3])"
16494   "* return output_387_binary_op (insn, operands);"
16495   [(set (attr "type")
16496         (cond [(match_operand:XF 3 "mult_operator" "")
16497                  (const_string "fmul")
16498                (match_operand:XF 3 "div_operator" "")
16499                  (const_string "fdiv")
16500               ]
16501               (const_string "fop")))
16502    (set_attr "mode" "XF")])
16504 (define_insn "*fop_xf_2_i387"
16505   [(set (match_operand:XF 0 "register_operand" "=f,f")
16506         (match_operator:XF 3 "binary_fp_operator"
16507           [(float:XF
16508              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16509            (match_operand:XF 2 "register_operand" "0,0")]))]
16510   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16511   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16512   [(set (attr "type")
16513         (cond [(match_operand:XF 3 "mult_operator" "")
16514                  (const_string "fmul")
16515                (match_operand:XF 3 "div_operator" "")
16516                  (const_string "fdiv")
16517               ]
16518               (const_string "fop")))
16519    (set_attr "fp_int_src" "true")
16520    (set_attr "mode" "<MODE>")])
16522 (define_insn "*fop_xf_3_i387"
16523   [(set (match_operand:XF 0 "register_operand" "=f,f")
16524         (match_operator:XF 3 "binary_fp_operator"
16525           [(match_operand:XF 1 "register_operand" "0,0")
16526            (float:XF
16527              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16528   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16529   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16530   [(set (attr "type")
16531         (cond [(match_operand:XF 3 "mult_operator" "")
16532                  (const_string "fmul")
16533                (match_operand:XF 3 "div_operator" "")
16534                  (const_string "fdiv")
16535               ]
16536               (const_string "fop")))
16537    (set_attr "fp_int_src" "true")
16538    (set_attr "mode" "<MODE>")])
16540 (define_insn "*fop_xf_4_i387"
16541   [(set (match_operand:XF 0 "register_operand" "=f,f")
16542         (match_operator:XF 3 "binary_fp_operator"
16543            [(float_extend:XF
16544               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16545             (match_operand:XF 2 "register_operand" "0,f")]))]
16546   "TARGET_80387"
16547   "* return output_387_binary_op (insn, operands);"
16548   [(set (attr "type")
16549         (cond [(match_operand:XF 3 "mult_operator" "")
16550                  (const_string "fmul")
16551                (match_operand:XF 3 "div_operator" "")
16552                  (const_string "fdiv")
16553               ]
16554               (const_string "fop")))
16555    (set_attr "mode" "<MODE>")])
16557 (define_insn "*fop_xf_5_i387"
16558   [(set (match_operand:XF 0 "register_operand" "=f,f")
16559         (match_operator:XF 3 "binary_fp_operator"
16560           [(match_operand:XF 1 "register_operand" "0,f")
16561            (float_extend:XF
16562              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16563   "TARGET_80387"
16564   "* return output_387_binary_op (insn, operands);"
16565   [(set (attr "type")
16566         (cond [(match_operand:XF 3 "mult_operator" "")
16567                  (const_string "fmul")
16568                (match_operand:XF 3 "div_operator" "")
16569                  (const_string "fdiv")
16570               ]
16571               (const_string "fop")))
16572    (set_attr "mode" "<MODE>")])
16574 (define_insn "*fop_xf_6_i387"
16575   [(set (match_operand:XF 0 "register_operand" "=f,f")
16576         (match_operator:XF 3 "binary_fp_operator"
16577           [(float_extend:XF
16578              (match_operand:MODEF 1 "register_operand" "0,f"))
16579            (float_extend:XF
16580              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16581   "TARGET_80387"
16582   "* return output_387_binary_op (insn, operands);"
16583   [(set (attr "type")
16584         (cond [(match_operand:XF 3 "mult_operator" "")
16585                  (const_string "fmul")
16586                (match_operand:XF 3 "div_operator" "")
16587                  (const_string "fdiv")
16588               ]
16589               (const_string "fop")))
16590    (set_attr "mode" "<MODE>")])
16592 (define_split
16593   [(set (match_operand 0 "register_operand" "")
16594         (match_operator 3 "binary_fp_operator"
16595            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16596             (match_operand 2 "register_operand" "")]))]
16597   "reload_completed
16598    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16599   [(const_int 0)]
16601   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16602   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16603   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16604                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16605                                           GET_MODE (operands[3]),
16606                                           operands[4],
16607                                           operands[2])));
16608   ix86_free_from_memory (GET_MODE (operands[1]));
16609   DONE;
16612 (define_split
16613   [(set (match_operand 0 "register_operand" "")
16614         (match_operator 3 "binary_fp_operator"
16615            [(match_operand 1 "register_operand" "")
16616             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16617   "reload_completed
16618    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16619   [(const_int 0)]
16621   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16622   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16623   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16624                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16625                                           GET_MODE (operands[3]),
16626                                           operands[1],
16627                                           operands[4])));
16628   ix86_free_from_memory (GET_MODE (operands[2]));
16629   DONE;
16632 ;; FPU special functions.
16634 ;; This pattern implements a no-op XFmode truncation for
16635 ;; all fancy i386 XFmode math functions.
16637 (define_insn "truncxf<mode>2_i387_noop_unspec"
16638   [(set (match_operand:MODEF 0 "register_operand" "=f")
16639         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16640         UNSPEC_TRUNC_NOOP))]
16641   "TARGET_USE_FANCY_MATH_387"
16642   "* return output_387_reg_move (insn, operands);"
16643   [(set_attr "type" "fmov")
16644    (set_attr "mode" "<MODE>")])
16646 (define_insn "sqrtxf2"
16647   [(set (match_operand:XF 0 "register_operand" "=f")
16648         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16649   "TARGET_USE_FANCY_MATH_387"
16650   "fsqrt"
16651   [(set_attr "type" "fpspc")
16652    (set_attr "mode" "XF")
16653    (set_attr "athlon_decode" "direct")
16654    (set_attr "amdfam10_decode" "direct")])
16656 (define_insn "sqrt_extend<mode>xf2_i387"
16657   [(set (match_operand:XF 0 "register_operand" "=f")
16658         (sqrt:XF
16659           (float_extend:XF
16660             (match_operand:MODEF 1 "register_operand" "0"))))]
16661   "TARGET_USE_FANCY_MATH_387"
16662   "fsqrt"
16663   [(set_attr "type" "fpspc")
16664    (set_attr "mode" "XF")
16665    (set_attr "athlon_decode" "direct")
16666    (set_attr "amdfam10_decode" "direct")])
16668 (define_insn "*rsqrtsf2_sse"
16669   [(set (match_operand:SF 0 "register_operand" "=x")
16670         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16671                    UNSPEC_RSQRT))]
16672   "TARGET_SSE_MATH"
16673   "%vrsqrtss\t{%1, %d0|%d0, %1}"
16674   [(set_attr "type" "sse")
16675    (set_attr "prefix" "maybe_vex")
16676    (set_attr "mode" "SF")])
16678 (define_expand "rsqrtsf2"
16679   [(set (match_operand:SF 0 "register_operand" "")
16680         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16681                    UNSPEC_RSQRT))]
16682   "TARGET_SSE_MATH"
16684   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16685   DONE;
16688 (define_insn "*sqrt<mode>2_sse"
16689   [(set (match_operand:MODEF 0 "register_operand" "=x")
16690         (sqrt:MODEF
16691           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16692   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16693   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16694   [(set_attr "type" "sse")
16695    (set_attr "prefix" "maybe_vex")
16696    (set_attr "mode" "<MODE>")
16697    (set_attr "athlon_decode" "*")
16698    (set_attr "amdfam10_decode" "*")])
16700 (define_expand "sqrt<mode>2"
16701   [(set (match_operand:MODEF 0 "register_operand" "")
16702         (sqrt:MODEF
16703           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16704   "TARGET_USE_FANCY_MATH_387
16705    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16707   if (<MODE>mode == SFmode
16708       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16709       && flag_finite_math_only && !flag_trapping_math
16710       && flag_unsafe_math_optimizations)
16711     {
16712       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16713       DONE;
16714     }
16716   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16717     {
16718       rtx op0 = gen_reg_rtx (XFmode);
16719       rtx op1 = force_reg (<MODE>mode, operands[1]);
16721       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16722       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16723       DONE;
16724    }
16727 (define_insn "fpremxf4_i387"
16728   [(set (match_operand:XF 0 "register_operand" "=f")
16729         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16730                     (match_operand:XF 3 "register_operand" "1")]
16731                    UNSPEC_FPREM_F))
16732    (set (match_operand:XF 1 "register_operand" "=u")
16733         (unspec:XF [(match_dup 2) (match_dup 3)]
16734                    UNSPEC_FPREM_U))
16735    (set (reg:CCFP FPSR_REG)
16736         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16737                      UNSPEC_C2_FLAG))]
16738   "TARGET_USE_FANCY_MATH_387"
16739   "fprem"
16740   [(set_attr "type" "fpspc")
16741    (set_attr "mode" "XF")])
16743 (define_expand "fmodxf3"
16744   [(use (match_operand:XF 0 "register_operand" ""))
16745    (use (match_operand:XF 1 "general_operand" ""))
16746    (use (match_operand:XF 2 "general_operand" ""))]
16747   "TARGET_USE_FANCY_MATH_387"
16749   rtx label = gen_label_rtx ();
16751   rtx op1 = gen_reg_rtx (XFmode);
16752   rtx op2 = gen_reg_rtx (XFmode);
16754   emit_move_insn (op2, operands[2]);
16755   emit_move_insn (op1, operands[1]);
16757   emit_label (label);
16758   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16759   ix86_emit_fp_unordered_jump (label);
16760   LABEL_NUSES (label) = 1;
16762   emit_move_insn (operands[0], op1);
16763   DONE;
16766 (define_expand "fmod<mode>3"
16767   [(use (match_operand:MODEF 0 "register_operand" ""))
16768    (use (match_operand:MODEF 1 "general_operand" ""))
16769    (use (match_operand:MODEF 2 "general_operand" ""))]
16770   "TARGET_USE_FANCY_MATH_387"
16772   rtx label = gen_label_rtx ();
16774   rtx op1 = gen_reg_rtx (XFmode);
16775   rtx op2 = gen_reg_rtx (XFmode);
16777   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16778   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16780   emit_label (label);
16781   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16782   ix86_emit_fp_unordered_jump (label);
16783   LABEL_NUSES (label) = 1;
16785   /* Truncate the result properly for strict SSE math.  */
16786   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16787       && !TARGET_MIX_SSE_I387)
16788     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16789   else
16790     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16792   DONE;
16795 (define_insn "fprem1xf4_i387"
16796   [(set (match_operand:XF 0 "register_operand" "=f")
16797         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16798                     (match_operand:XF 3 "register_operand" "1")]
16799                    UNSPEC_FPREM1_F))
16800    (set (match_operand:XF 1 "register_operand" "=u")
16801         (unspec:XF [(match_dup 2) (match_dup 3)]
16802                    UNSPEC_FPREM1_U))
16803    (set (reg:CCFP FPSR_REG)
16804         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16805                      UNSPEC_C2_FLAG))]
16806   "TARGET_USE_FANCY_MATH_387"
16807   "fprem1"
16808   [(set_attr "type" "fpspc")
16809    (set_attr "mode" "XF")])
16811 (define_expand "remainderxf3"
16812   [(use (match_operand:XF 0 "register_operand" ""))
16813    (use (match_operand:XF 1 "general_operand" ""))
16814    (use (match_operand:XF 2 "general_operand" ""))]
16815   "TARGET_USE_FANCY_MATH_387"
16817   rtx label = gen_label_rtx ();
16819   rtx op1 = gen_reg_rtx (XFmode);
16820   rtx op2 = gen_reg_rtx (XFmode);
16822   emit_move_insn (op2, operands[2]);
16823   emit_move_insn (op1, operands[1]);
16825   emit_label (label);
16826   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16827   ix86_emit_fp_unordered_jump (label);
16828   LABEL_NUSES (label) = 1;
16830   emit_move_insn (operands[0], op1);
16831   DONE;
16834 (define_expand "remainder<mode>3"
16835   [(use (match_operand:MODEF 0 "register_operand" ""))
16836    (use (match_operand:MODEF 1 "general_operand" ""))
16837    (use (match_operand:MODEF 2 "general_operand" ""))]
16838   "TARGET_USE_FANCY_MATH_387"
16840   rtx label = gen_label_rtx ();
16842   rtx op1 = gen_reg_rtx (XFmode);
16843   rtx op2 = gen_reg_rtx (XFmode);
16845   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16846   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16848   emit_label (label);
16850   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16851   ix86_emit_fp_unordered_jump (label);
16852   LABEL_NUSES (label) = 1;
16854   /* Truncate the result properly for strict SSE math.  */
16855   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16856       && !TARGET_MIX_SSE_I387)
16857     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16858   else
16859     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16861   DONE;
16864 (define_insn "*sinxf2_i387"
16865   [(set (match_operand:XF 0 "register_operand" "=f")
16866         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16867   "TARGET_USE_FANCY_MATH_387
16868    && flag_unsafe_math_optimizations"
16869   "fsin"
16870   [(set_attr "type" "fpspc")
16871    (set_attr "mode" "XF")])
16873 (define_insn "*sin_extend<mode>xf2_i387"
16874   [(set (match_operand:XF 0 "register_operand" "=f")
16875         (unspec:XF [(float_extend:XF
16876                       (match_operand:MODEF 1 "register_operand" "0"))]
16877                    UNSPEC_SIN))]
16878   "TARGET_USE_FANCY_MATH_387
16879    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16880        || TARGET_MIX_SSE_I387)
16881    && flag_unsafe_math_optimizations"
16882   "fsin"
16883   [(set_attr "type" "fpspc")
16884    (set_attr "mode" "XF")])
16886 (define_insn "*cosxf2_i387"
16887   [(set (match_operand:XF 0 "register_operand" "=f")
16888         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16889   "TARGET_USE_FANCY_MATH_387
16890    && flag_unsafe_math_optimizations"
16891   "fcos"
16892   [(set_attr "type" "fpspc")
16893    (set_attr "mode" "XF")])
16895 (define_insn "*cos_extend<mode>xf2_i387"
16896   [(set (match_operand:XF 0 "register_operand" "=f")
16897         (unspec:XF [(float_extend:XF
16898                       (match_operand:MODEF 1 "register_operand" "0"))]
16899                    UNSPEC_COS))]
16900   "TARGET_USE_FANCY_MATH_387
16901    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16902        || TARGET_MIX_SSE_I387)
16903    && flag_unsafe_math_optimizations"
16904   "fcos"
16905   [(set_attr "type" "fpspc")
16906    (set_attr "mode" "XF")])
16908 ;; When sincos pattern is defined, sin and cos builtin functions will be
16909 ;; expanded to sincos pattern with one of its outputs left unused.
16910 ;; CSE pass will figure out if two sincos patterns can be combined,
16911 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16912 ;; depending on the unused output.
16914 (define_insn "sincosxf3"
16915   [(set (match_operand:XF 0 "register_operand" "=f")
16916         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16917                    UNSPEC_SINCOS_COS))
16918    (set (match_operand:XF 1 "register_operand" "=u")
16919         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16920   "TARGET_USE_FANCY_MATH_387
16921    && flag_unsafe_math_optimizations"
16922   "fsincos"
16923   [(set_attr "type" "fpspc")
16924    (set_attr "mode" "XF")])
16926 (define_split
16927   [(set (match_operand:XF 0 "register_operand" "")
16928         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16929                    UNSPEC_SINCOS_COS))
16930    (set (match_operand:XF 1 "register_operand" "")
16931         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16932   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16933    && !(reload_completed || reload_in_progress)"
16934   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16935   "")
16937 (define_split
16938   [(set (match_operand:XF 0 "register_operand" "")
16939         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16940                    UNSPEC_SINCOS_COS))
16941    (set (match_operand:XF 1 "register_operand" "")
16942         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16943   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16944    && !(reload_completed || reload_in_progress)"
16945   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16946   "")
16948 (define_insn "sincos_extend<mode>xf3_i387"
16949   [(set (match_operand:XF 0 "register_operand" "=f")
16950         (unspec:XF [(float_extend:XF
16951                       (match_operand:MODEF 2 "register_operand" "0"))]
16952                    UNSPEC_SINCOS_COS))
16953    (set (match_operand:XF 1 "register_operand" "=u")
16954         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16955   "TARGET_USE_FANCY_MATH_387
16956    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16957        || TARGET_MIX_SSE_I387)
16958    && flag_unsafe_math_optimizations"
16959   "fsincos"
16960   [(set_attr "type" "fpspc")
16961    (set_attr "mode" "XF")])
16963 (define_split
16964   [(set (match_operand:XF 0 "register_operand" "")
16965         (unspec:XF [(float_extend:XF
16966                       (match_operand:MODEF 2 "register_operand" ""))]
16967                    UNSPEC_SINCOS_COS))
16968    (set (match_operand:XF 1 "register_operand" "")
16969         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16970   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16971    && !(reload_completed || reload_in_progress)"
16972   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16973   "")
16975 (define_split
16976   [(set (match_operand:XF 0 "register_operand" "")
16977         (unspec:XF [(float_extend:XF
16978                       (match_operand:MODEF 2 "register_operand" ""))]
16979                    UNSPEC_SINCOS_COS))
16980    (set (match_operand:XF 1 "register_operand" "")
16981         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16982   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16983    && !(reload_completed || reload_in_progress)"
16984   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16985   "")
16987 (define_expand "sincos<mode>3"
16988   [(use (match_operand:MODEF 0 "register_operand" ""))
16989    (use (match_operand:MODEF 1 "register_operand" ""))
16990    (use (match_operand:MODEF 2 "register_operand" ""))]
16991   "TARGET_USE_FANCY_MATH_387
16992    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16993        || TARGET_MIX_SSE_I387)
16994    && flag_unsafe_math_optimizations"
16996   rtx op0 = gen_reg_rtx (XFmode);
16997   rtx op1 = gen_reg_rtx (XFmode);
16999   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17000   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17001   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17002   DONE;
17005 (define_insn "fptanxf4_i387"
17006   [(set (match_operand:XF 0 "register_operand" "=f")
17007         (match_operand:XF 3 "const_double_operand" "F"))
17008    (set (match_operand:XF 1 "register_operand" "=u")
17009         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17010                    UNSPEC_TAN))]
17011   "TARGET_USE_FANCY_MATH_387
17012    && flag_unsafe_math_optimizations
17013    && standard_80387_constant_p (operands[3]) == 2"
17014   "fptan"
17015   [(set_attr "type" "fpspc")
17016    (set_attr "mode" "XF")])
17018 (define_insn "fptan_extend<mode>xf4_i387"
17019   [(set (match_operand:MODEF 0 "register_operand" "=f")
17020         (match_operand:MODEF 3 "const_double_operand" "F"))
17021    (set (match_operand:XF 1 "register_operand" "=u")
17022         (unspec:XF [(float_extend:XF
17023                       (match_operand:MODEF 2 "register_operand" "0"))]
17024                    UNSPEC_TAN))]
17025   "TARGET_USE_FANCY_MATH_387
17026    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17027        || TARGET_MIX_SSE_I387)
17028    && flag_unsafe_math_optimizations
17029    && standard_80387_constant_p (operands[3]) == 2"
17030   "fptan"
17031   [(set_attr "type" "fpspc")
17032    (set_attr "mode" "XF")])
17034 (define_expand "tanxf2"
17035   [(use (match_operand:XF 0 "register_operand" ""))
17036    (use (match_operand:XF 1 "register_operand" ""))]
17037   "TARGET_USE_FANCY_MATH_387
17038    && flag_unsafe_math_optimizations"
17040   rtx one = gen_reg_rtx (XFmode);
17041   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17043   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17044   DONE;
17047 (define_expand "tan<mode>2"
17048   [(use (match_operand:MODEF 0 "register_operand" ""))
17049    (use (match_operand:MODEF 1 "register_operand" ""))]
17050   "TARGET_USE_FANCY_MATH_387
17051    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17052        || TARGET_MIX_SSE_I387)
17053    && flag_unsafe_math_optimizations"
17055   rtx op0 = gen_reg_rtx (XFmode);
17057   rtx one = gen_reg_rtx (<MODE>mode);
17058   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17060   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17061                                              operands[1], op2));
17062   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17063   DONE;
17066 (define_insn "*fpatanxf3_i387"
17067   [(set (match_operand:XF 0 "register_operand" "=f")
17068         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17069                     (match_operand:XF 2 "register_operand" "u")]
17070                    UNSPEC_FPATAN))
17071    (clobber (match_scratch:XF 3 "=2"))]
17072   "TARGET_USE_FANCY_MATH_387
17073    && flag_unsafe_math_optimizations"
17074   "fpatan"
17075   [(set_attr "type" "fpspc")
17076    (set_attr "mode" "XF")])
17078 (define_insn "fpatan_extend<mode>xf3_i387"
17079   [(set (match_operand:XF 0 "register_operand" "=f")
17080         (unspec:XF [(float_extend:XF
17081                       (match_operand:MODEF 1 "register_operand" "0"))
17082                     (float_extend:XF
17083                       (match_operand:MODEF 2 "register_operand" "u"))]
17084                    UNSPEC_FPATAN))
17085    (clobber (match_scratch:XF 3 "=2"))]
17086   "TARGET_USE_FANCY_MATH_387
17087    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17088        || TARGET_MIX_SSE_I387)
17089    && flag_unsafe_math_optimizations"
17090   "fpatan"
17091   [(set_attr "type" "fpspc")
17092    (set_attr "mode" "XF")])
17094 (define_expand "atan2xf3"
17095   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17096                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
17097                                (match_operand:XF 1 "register_operand" "")]
17098                               UNSPEC_FPATAN))
17099               (clobber (match_scratch:XF 3 ""))])]
17100   "TARGET_USE_FANCY_MATH_387
17101    && flag_unsafe_math_optimizations"
17102   "")
17104 (define_expand "atan2<mode>3"
17105   [(use (match_operand:MODEF 0 "register_operand" ""))
17106    (use (match_operand:MODEF 1 "register_operand" ""))
17107    (use (match_operand:MODEF 2 "register_operand" ""))]
17108   "TARGET_USE_FANCY_MATH_387
17109    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17110        || TARGET_MIX_SSE_I387)
17111    && flag_unsafe_math_optimizations"
17113   rtx op0 = gen_reg_rtx (XFmode);
17115   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17116   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17117   DONE;
17120 (define_expand "atanxf2"
17121   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17122                    (unspec:XF [(match_dup 2)
17123                                (match_operand:XF 1 "register_operand" "")]
17124                               UNSPEC_FPATAN))
17125               (clobber (match_scratch:XF 3 ""))])]
17126   "TARGET_USE_FANCY_MATH_387
17127    && flag_unsafe_math_optimizations"
17129   operands[2] = gen_reg_rtx (XFmode);
17130   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17133 (define_expand "atan<mode>2"
17134   [(use (match_operand:MODEF 0 "register_operand" ""))
17135    (use (match_operand:MODEF 1 "register_operand" ""))]
17136   "TARGET_USE_FANCY_MATH_387
17137    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17138        || TARGET_MIX_SSE_I387)
17139    && flag_unsafe_math_optimizations"
17141   rtx op0 = gen_reg_rtx (XFmode);
17143   rtx op2 = gen_reg_rtx (<MODE>mode);
17144   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17146   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17147   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17148   DONE;
17151 (define_expand "asinxf2"
17152   [(set (match_dup 2)
17153         (mult:XF (match_operand:XF 1 "register_operand" "")
17154                  (match_dup 1)))
17155    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17156    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17157    (parallel [(set (match_operand:XF 0 "register_operand" "")
17158                    (unspec:XF [(match_dup 5) (match_dup 1)]
17159                               UNSPEC_FPATAN))
17160               (clobber (match_scratch:XF 6 ""))])]
17161   "TARGET_USE_FANCY_MATH_387
17162    && flag_unsafe_math_optimizations"
17164   int i;
17166   if (optimize_insn_for_size_p ())
17167     FAIL;
17169   for (i = 2; i < 6; i++)
17170     operands[i] = gen_reg_rtx (XFmode);
17172   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17175 (define_expand "asin<mode>2"
17176   [(use (match_operand:MODEF 0 "register_operand" ""))
17177    (use (match_operand:MODEF 1 "general_operand" ""))]
17178  "TARGET_USE_FANCY_MATH_387
17179    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17180        || TARGET_MIX_SSE_I387)
17181    && flag_unsafe_math_optimizations"
17183   rtx op0 = gen_reg_rtx (XFmode);
17184   rtx op1 = gen_reg_rtx (XFmode);
17186   if (optimize_insn_for_size_p ())
17187     FAIL;
17189   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17190   emit_insn (gen_asinxf2 (op0, op1));
17191   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17192   DONE;
17195 (define_expand "acosxf2"
17196   [(set (match_dup 2)
17197         (mult:XF (match_operand:XF 1 "register_operand" "")
17198                  (match_dup 1)))
17199    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17200    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17201    (parallel [(set (match_operand:XF 0 "register_operand" "")
17202                    (unspec:XF [(match_dup 1) (match_dup 5)]
17203                               UNSPEC_FPATAN))
17204               (clobber (match_scratch:XF 6 ""))])]
17205   "TARGET_USE_FANCY_MATH_387
17206    && flag_unsafe_math_optimizations"
17208   int i;
17210   if (optimize_insn_for_size_p ())
17211     FAIL;
17213   for (i = 2; i < 6; i++)
17214     operands[i] = gen_reg_rtx (XFmode);
17216   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17219 (define_expand "acos<mode>2"
17220   [(use (match_operand:MODEF 0 "register_operand" ""))
17221    (use (match_operand:MODEF 1 "general_operand" ""))]
17222  "TARGET_USE_FANCY_MATH_387
17223    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17224        || TARGET_MIX_SSE_I387)
17225    && flag_unsafe_math_optimizations"
17227   rtx op0 = gen_reg_rtx (XFmode);
17228   rtx op1 = gen_reg_rtx (XFmode);
17230   if (optimize_insn_for_size_p ())
17231     FAIL;
17233   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17234   emit_insn (gen_acosxf2 (op0, op1));
17235   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17236   DONE;
17239 (define_insn "fyl2xxf3_i387"
17240   [(set (match_operand:XF 0 "register_operand" "=f")
17241         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17242                     (match_operand:XF 2 "register_operand" "u")]
17243                    UNSPEC_FYL2X))
17244    (clobber (match_scratch:XF 3 "=2"))]
17245   "TARGET_USE_FANCY_MATH_387
17246    && flag_unsafe_math_optimizations"
17247   "fyl2x"
17248   [(set_attr "type" "fpspc")
17249    (set_attr "mode" "XF")])
17251 (define_insn "fyl2x_extend<mode>xf3_i387"
17252   [(set (match_operand:XF 0 "register_operand" "=f")
17253         (unspec:XF [(float_extend:XF
17254                       (match_operand:MODEF 1 "register_operand" "0"))
17255                     (match_operand:XF 2 "register_operand" "u")]
17256                    UNSPEC_FYL2X))
17257    (clobber (match_scratch:XF 3 "=2"))]
17258   "TARGET_USE_FANCY_MATH_387
17259    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17260        || TARGET_MIX_SSE_I387)
17261    && flag_unsafe_math_optimizations"
17262   "fyl2x"
17263   [(set_attr "type" "fpspc")
17264    (set_attr "mode" "XF")])
17266 (define_expand "logxf2"
17267   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17268                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17269                                (match_dup 2)] UNSPEC_FYL2X))
17270               (clobber (match_scratch:XF 3 ""))])]
17271   "TARGET_USE_FANCY_MATH_387
17272    && flag_unsafe_math_optimizations"
17274   operands[2] = gen_reg_rtx (XFmode);
17275   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17278 (define_expand "log<mode>2"
17279   [(use (match_operand:MODEF 0 "register_operand" ""))
17280    (use (match_operand:MODEF 1 "register_operand" ""))]
17281   "TARGET_USE_FANCY_MATH_387
17282    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17283        || TARGET_MIX_SSE_I387)
17284    && flag_unsafe_math_optimizations"
17286   rtx op0 = gen_reg_rtx (XFmode);
17288   rtx op2 = gen_reg_rtx (XFmode);
17289   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17291   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17292   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17293   DONE;
17296 (define_expand "log10xf2"
17297   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17298                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17299                                (match_dup 2)] UNSPEC_FYL2X))
17300               (clobber (match_scratch:XF 3 ""))])]
17301   "TARGET_USE_FANCY_MATH_387
17302    && flag_unsafe_math_optimizations"
17304   operands[2] = gen_reg_rtx (XFmode);
17305   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17308 (define_expand "log10<mode>2"
17309   [(use (match_operand:MODEF 0 "register_operand" ""))
17310    (use (match_operand:MODEF 1 "register_operand" ""))]
17311   "TARGET_USE_FANCY_MATH_387
17312    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17313        || TARGET_MIX_SSE_I387)
17314    && flag_unsafe_math_optimizations"
17316   rtx op0 = gen_reg_rtx (XFmode);
17318   rtx op2 = gen_reg_rtx (XFmode);
17319   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17321   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17322   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17323   DONE;
17326 (define_expand "log2xf2"
17327   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17328                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17329                                (match_dup 2)] UNSPEC_FYL2X))
17330               (clobber (match_scratch:XF 3 ""))])]
17331   "TARGET_USE_FANCY_MATH_387
17332    && flag_unsafe_math_optimizations"
17334   operands[2] = gen_reg_rtx (XFmode);
17335   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17338 (define_expand "log2<mode>2"
17339   [(use (match_operand:MODEF 0 "register_operand" ""))
17340    (use (match_operand:MODEF 1 "register_operand" ""))]
17341   "TARGET_USE_FANCY_MATH_387
17342    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17343        || TARGET_MIX_SSE_I387)
17344    && flag_unsafe_math_optimizations"
17346   rtx op0 = gen_reg_rtx (XFmode);
17348   rtx op2 = gen_reg_rtx (XFmode);
17349   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17351   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17352   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17353   DONE;
17356 (define_insn "fyl2xp1xf3_i387"
17357   [(set (match_operand:XF 0 "register_operand" "=f")
17358         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17359                     (match_operand:XF 2 "register_operand" "u")]
17360                    UNSPEC_FYL2XP1))
17361    (clobber (match_scratch:XF 3 "=2"))]
17362   "TARGET_USE_FANCY_MATH_387
17363    && flag_unsafe_math_optimizations"
17364   "fyl2xp1"
17365   [(set_attr "type" "fpspc")
17366    (set_attr "mode" "XF")])
17368 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17369   [(set (match_operand:XF 0 "register_operand" "=f")
17370         (unspec:XF [(float_extend:XF
17371                       (match_operand:MODEF 1 "register_operand" "0"))
17372                     (match_operand:XF 2 "register_operand" "u")]
17373                    UNSPEC_FYL2XP1))
17374    (clobber (match_scratch:XF 3 "=2"))]
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"
17379   "fyl2xp1"
17380   [(set_attr "type" "fpspc")
17381    (set_attr "mode" "XF")])
17383 (define_expand "log1pxf2"
17384   [(use (match_operand:XF 0 "register_operand" ""))
17385    (use (match_operand:XF 1 "register_operand" ""))]
17386   "TARGET_USE_FANCY_MATH_387
17387    && flag_unsafe_math_optimizations"
17389   if (optimize_insn_for_size_p ())
17390     FAIL;
17392   ix86_emit_i387_log1p (operands[0], operands[1]);
17393   DONE;
17396 (define_expand "log1p<mode>2"
17397   [(use (match_operand:MODEF 0 "register_operand" ""))
17398    (use (match_operand:MODEF 1 "register_operand" ""))]
17399   "TARGET_USE_FANCY_MATH_387
17400    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17401        || TARGET_MIX_SSE_I387)
17402    && flag_unsafe_math_optimizations"
17404   rtx op0;
17406   if (optimize_insn_for_size_p ())
17407     FAIL;
17409   op0 = gen_reg_rtx (XFmode);
17411   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17413   ix86_emit_i387_log1p (op0, operands[1]);
17414   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17415   DONE;
17418 (define_insn "fxtractxf3_i387"
17419   [(set (match_operand:XF 0 "register_operand" "=f")
17420         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17421                    UNSPEC_XTRACT_FRACT))
17422    (set (match_operand:XF 1 "register_operand" "=u")
17423         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17424   "TARGET_USE_FANCY_MATH_387
17425    && flag_unsafe_math_optimizations"
17426   "fxtract"
17427   [(set_attr "type" "fpspc")
17428    (set_attr "mode" "XF")])
17430 (define_insn "fxtract_extend<mode>xf3_i387"
17431   [(set (match_operand:XF 0 "register_operand" "=f")
17432         (unspec:XF [(float_extend:XF
17433                       (match_operand:MODEF 2 "register_operand" "0"))]
17434                    UNSPEC_XTRACT_FRACT))
17435    (set (match_operand:XF 1 "register_operand" "=u")
17436         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17437   "TARGET_USE_FANCY_MATH_387
17438    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17439        || TARGET_MIX_SSE_I387)
17440    && flag_unsafe_math_optimizations"
17441   "fxtract"
17442   [(set_attr "type" "fpspc")
17443    (set_attr "mode" "XF")])
17445 (define_expand "logbxf2"
17446   [(parallel [(set (match_dup 2)
17447                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17448                               UNSPEC_XTRACT_FRACT))
17449               (set (match_operand:XF 0 "register_operand" "")
17450                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17451   "TARGET_USE_FANCY_MATH_387
17452    && flag_unsafe_math_optimizations"
17454   operands[2] = gen_reg_rtx (XFmode);
17457 (define_expand "logb<mode>2"
17458   [(use (match_operand:MODEF 0 "register_operand" ""))
17459    (use (match_operand:MODEF 1 "register_operand" ""))]
17460   "TARGET_USE_FANCY_MATH_387
17461    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17462        || TARGET_MIX_SSE_I387)
17463    && flag_unsafe_math_optimizations"
17465   rtx op0 = gen_reg_rtx (XFmode);
17466   rtx op1 = gen_reg_rtx (XFmode);
17468   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17469   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17470   DONE;
17473 (define_expand "ilogbxf2"
17474   [(use (match_operand:SI 0 "register_operand" ""))
17475    (use (match_operand:XF 1 "register_operand" ""))]
17476   "TARGET_USE_FANCY_MATH_387
17477    && flag_unsafe_math_optimizations"
17479   rtx op0, op1;
17481   if (optimize_insn_for_size_p ())
17482     FAIL;
17484   op0 = gen_reg_rtx (XFmode);
17485   op1 = gen_reg_rtx (XFmode);
17487   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17488   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17489   DONE;
17492 (define_expand "ilogb<mode>2"
17493   [(use (match_operand:SI 0 "register_operand" ""))
17494    (use (match_operand:MODEF 1 "register_operand" ""))]
17495   "TARGET_USE_FANCY_MATH_387
17496    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17497        || TARGET_MIX_SSE_I387)
17498    && flag_unsafe_math_optimizations"
17500   rtx op0, op1;
17502   if (optimize_insn_for_size_p ())
17503     FAIL;
17505   op0 = gen_reg_rtx (XFmode);
17506   op1 = gen_reg_rtx (XFmode);
17508   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17509   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17510   DONE;
17513 (define_insn "*f2xm1xf2_i387"
17514   [(set (match_operand:XF 0 "register_operand" "=f")
17515         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17516                    UNSPEC_F2XM1))]
17517   "TARGET_USE_FANCY_MATH_387
17518    && flag_unsafe_math_optimizations"
17519   "f2xm1"
17520   [(set_attr "type" "fpspc")
17521    (set_attr "mode" "XF")])
17523 (define_insn "*fscalexf4_i387"
17524   [(set (match_operand:XF 0 "register_operand" "=f")
17525         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17526                     (match_operand:XF 3 "register_operand" "1")]
17527                    UNSPEC_FSCALE_FRACT))
17528    (set (match_operand:XF 1 "register_operand" "=u")
17529         (unspec:XF [(match_dup 2) (match_dup 3)]
17530                    UNSPEC_FSCALE_EXP))]
17531   "TARGET_USE_FANCY_MATH_387
17532    && flag_unsafe_math_optimizations"
17533   "fscale"
17534   [(set_attr "type" "fpspc")
17535    (set_attr "mode" "XF")])
17537 (define_expand "expNcorexf3"
17538   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17539                                (match_operand:XF 2 "register_operand" "")))
17540    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17541    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17542    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17543    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17544    (parallel [(set (match_operand:XF 0 "register_operand" "")
17545                    (unspec:XF [(match_dup 8) (match_dup 4)]
17546                               UNSPEC_FSCALE_FRACT))
17547               (set (match_dup 9)
17548                    (unspec:XF [(match_dup 8) (match_dup 4)]
17549                               UNSPEC_FSCALE_EXP))])]
17550   "TARGET_USE_FANCY_MATH_387
17551    && flag_unsafe_math_optimizations"
17553   int i;
17555   if (optimize_insn_for_size_p ())
17556     FAIL;
17558   for (i = 3; i < 10; i++)
17559     operands[i] = gen_reg_rtx (XFmode);
17561   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17564 (define_expand "expxf2"
17565   [(use (match_operand:XF 0 "register_operand" ""))
17566    (use (match_operand:XF 1 "register_operand" ""))]
17567   "TARGET_USE_FANCY_MATH_387
17568    && flag_unsafe_math_optimizations"
17570   rtx op2;
17572   if (optimize_insn_for_size_p ())
17573     FAIL;
17575   op2 = gen_reg_rtx (XFmode);
17576   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17578   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17579   DONE;
17582 (define_expand "exp<mode>2"
17583   [(use (match_operand:MODEF 0 "register_operand" ""))
17584    (use (match_operand:MODEF 1 "general_operand" ""))]
17585  "TARGET_USE_FANCY_MATH_387
17586    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17587        || TARGET_MIX_SSE_I387)
17588    && flag_unsafe_math_optimizations"
17590   rtx op0, op1;
17592   if (optimize_insn_for_size_p ())
17593     FAIL;
17595   op0 = gen_reg_rtx (XFmode);
17596   op1 = gen_reg_rtx (XFmode);
17598   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17599   emit_insn (gen_expxf2 (op0, op1));
17600   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17601   DONE;
17604 (define_expand "exp10xf2"
17605   [(use (match_operand:XF 0 "register_operand" ""))
17606    (use (match_operand:XF 1 "register_operand" ""))]
17607   "TARGET_USE_FANCY_MATH_387
17608    && flag_unsafe_math_optimizations"
17610   rtx op2;
17612   if (optimize_insn_for_size_p ())
17613     FAIL;
17615   op2 = gen_reg_rtx (XFmode);
17616   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17618   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17619   DONE;
17622 (define_expand "exp10<mode>2"
17623   [(use (match_operand:MODEF 0 "register_operand" ""))
17624    (use (match_operand:MODEF 1 "general_operand" ""))]
17625  "TARGET_USE_FANCY_MATH_387
17626    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17627        || TARGET_MIX_SSE_I387)
17628    && flag_unsafe_math_optimizations"
17630   rtx op0, op1;
17632   if (optimize_insn_for_size_p ())
17633     FAIL;
17635   op0 = gen_reg_rtx (XFmode);
17636   op1 = gen_reg_rtx (XFmode);
17638   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17639   emit_insn (gen_exp10xf2 (op0, op1));
17640   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17641   DONE;
17644 (define_expand "exp2xf2"
17645   [(use (match_operand:XF 0 "register_operand" ""))
17646    (use (match_operand:XF 1 "register_operand" ""))]
17647   "TARGET_USE_FANCY_MATH_387
17648    && flag_unsafe_math_optimizations"
17650   rtx op2;
17652   if (optimize_insn_for_size_p ())
17653     FAIL;
17655   op2 = gen_reg_rtx (XFmode);
17656   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17658   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17659   DONE;
17662 (define_expand "exp2<mode>2"
17663   [(use (match_operand:MODEF 0 "register_operand" ""))
17664    (use (match_operand:MODEF 1 "general_operand" ""))]
17665  "TARGET_USE_FANCY_MATH_387
17666    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17667        || TARGET_MIX_SSE_I387)
17668    && flag_unsafe_math_optimizations"
17670   rtx op0, op1;
17672   if (optimize_insn_for_size_p ())
17673     FAIL;
17675   op0 = gen_reg_rtx (XFmode);
17676   op1 = gen_reg_rtx (XFmode);
17678   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17679   emit_insn (gen_exp2xf2 (op0, op1));
17680   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17681   DONE;
17684 (define_expand "expm1xf2"
17685   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17686                                (match_dup 2)))
17687    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17688    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17689    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17690    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17691    (parallel [(set (match_dup 7)
17692                    (unspec:XF [(match_dup 6) (match_dup 4)]
17693                               UNSPEC_FSCALE_FRACT))
17694               (set (match_dup 8)
17695                    (unspec:XF [(match_dup 6) (match_dup 4)]
17696                               UNSPEC_FSCALE_EXP))])
17697    (parallel [(set (match_dup 10)
17698                    (unspec:XF [(match_dup 9) (match_dup 8)]
17699                               UNSPEC_FSCALE_FRACT))
17700               (set (match_dup 11)
17701                    (unspec:XF [(match_dup 9) (match_dup 8)]
17702                               UNSPEC_FSCALE_EXP))])
17703    (set (match_dup 12) (minus:XF (match_dup 10)
17704                                  (float_extend:XF (match_dup 13))))
17705    (set (match_operand:XF 0 "register_operand" "")
17706         (plus:XF (match_dup 12) (match_dup 7)))]
17707   "TARGET_USE_FANCY_MATH_387
17708    && flag_unsafe_math_optimizations"
17710   int i;
17712   if (optimize_insn_for_size_p ())
17713     FAIL;
17715   for (i = 2; i < 13; i++)
17716     operands[i] = gen_reg_rtx (XFmode);
17718   operands[13]
17719     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17721   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17724 (define_expand "expm1<mode>2"
17725   [(use (match_operand:MODEF 0 "register_operand" ""))
17726    (use (match_operand:MODEF 1 "general_operand" ""))]
17727  "TARGET_USE_FANCY_MATH_387
17728    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17729        || TARGET_MIX_SSE_I387)
17730    && flag_unsafe_math_optimizations"
17732   rtx op0, op1;
17734   if (optimize_insn_for_size_p ())
17735     FAIL;
17737   op0 = gen_reg_rtx (XFmode);
17738   op1 = gen_reg_rtx (XFmode);
17740   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17741   emit_insn (gen_expm1xf2 (op0, op1));
17742   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17743   DONE;
17746 (define_expand "ldexpxf3"
17747   [(set (match_dup 3)
17748         (float:XF (match_operand:SI 2 "register_operand" "")))
17749    (parallel [(set (match_operand:XF 0 " register_operand" "")
17750                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17751                                (match_dup 3)]
17752                               UNSPEC_FSCALE_FRACT))
17753               (set (match_dup 4)
17754                    (unspec:XF [(match_dup 1) (match_dup 3)]
17755                               UNSPEC_FSCALE_EXP))])]
17756   "TARGET_USE_FANCY_MATH_387
17757    && flag_unsafe_math_optimizations"
17759   if (optimize_insn_for_size_p ())
17760     FAIL;
17762   operands[3] = gen_reg_rtx (XFmode);
17763   operands[4] = gen_reg_rtx (XFmode);
17766 (define_expand "ldexp<mode>3"
17767   [(use (match_operand:MODEF 0 "register_operand" ""))
17768    (use (match_operand:MODEF 1 "general_operand" ""))
17769    (use (match_operand:SI 2 "register_operand" ""))]
17770  "TARGET_USE_FANCY_MATH_387
17771    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17772        || TARGET_MIX_SSE_I387)
17773    && flag_unsafe_math_optimizations"
17775   rtx op0, op1;
17777   if (optimize_insn_for_size_p ())
17778     FAIL;
17780   op0 = gen_reg_rtx (XFmode);
17781   op1 = gen_reg_rtx (XFmode);
17783   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17784   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17785   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17786   DONE;
17789 (define_expand "scalbxf3"
17790   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17791                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17792                                (match_operand:XF 2 "register_operand" "")]
17793                               UNSPEC_FSCALE_FRACT))
17794               (set (match_dup 3)
17795                    (unspec:XF [(match_dup 1) (match_dup 2)]
17796                               UNSPEC_FSCALE_EXP))])]
17797   "TARGET_USE_FANCY_MATH_387
17798    && flag_unsafe_math_optimizations"
17800   if (optimize_insn_for_size_p ())
17801     FAIL;
17803   operands[3] = gen_reg_rtx (XFmode);
17806 (define_expand "scalb<mode>3"
17807   [(use (match_operand:MODEF 0 "register_operand" ""))
17808    (use (match_operand:MODEF 1 "general_operand" ""))
17809    (use (match_operand:MODEF 2 "register_operand" ""))]
17810  "TARGET_USE_FANCY_MATH_387
17811    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17812        || TARGET_MIX_SSE_I387)
17813    && flag_unsafe_math_optimizations"
17815   rtx op0, op1, op2;
17817   if (optimize_insn_for_size_p ())
17818     FAIL;
17820   op0 = gen_reg_rtx (XFmode);
17821   op1 = gen_reg_rtx (XFmode);
17822   op2 = gen_reg_rtx (XFmode);
17824   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17825   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17826   emit_insn (gen_scalbxf3 (op0, op1, op2));
17827   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17828   DONE;
17832 (define_insn "sse4_1_round<mode>2"
17833   [(set (match_operand:MODEF 0 "register_operand" "=x")
17834         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17835                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17836                       UNSPEC_ROUND))]
17837   "TARGET_ROUND"
17838   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17839   [(set_attr "type" "ssecvt")
17840    (set_attr "prefix_extra" "1")
17841    (set_attr "prefix" "maybe_vex")
17842    (set_attr "mode" "<MODE>")])
17844 (define_insn "rintxf2"
17845   [(set (match_operand:XF 0 "register_operand" "=f")
17846         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17847                    UNSPEC_FRNDINT))]
17848   "TARGET_USE_FANCY_MATH_387
17849    && flag_unsafe_math_optimizations"
17850   "frndint"
17851   [(set_attr "type" "fpspc")
17852    (set_attr "mode" "XF")])
17854 (define_expand "rint<mode>2"
17855   [(use (match_operand:MODEF 0 "register_operand" ""))
17856    (use (match_operand:MODEF 1 "register_operand" ""))]
17857   "(TARGET_USE_FANCY_MATH_387
17858     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17859         || TARGET_MIX_SSE_I387)
17860     && flag_unsafe_math_optimizations)
17861    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17862        && !flag_trapping_math)"
17864   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17865       && !flag_trapping_math)
17866     {
17867       if (!TARGET_ROUND && optimize_insn_for_size_p ())
17868         FAIL;
17869       if (TARGET_ROUND)
17870         emit_insn (gen_sse4_1_round<mode>2
17871                    (operands[0], operands[1], GEN_INT (0x04)));
17872       else
17873         ix86_expand_rint (operand0, operand1);
17874     }
17875   else
17876     {
17877       rtx op0 = gen_reg_rtx (XFmode);
17878       rtx op1 = gen_reg_rtx (XFmode);
17880       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17881       emit_insn (gen_rintxf2 (op0, op1));
17883       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17884     }
17885   DONE;
17888 (define_expand "round<mode>2"
17889   [(match_operand:MODEF 0 "register_operand" "")
17890    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17891   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17892    && !flag_trapping_math && !flag_rounding_math"
17894   if (optimize_insn_for_size_p ())
17895     FAIL;
17896   if (TARGET_64BIT || (<MODE>mode != DFmode))
17897     ix86_expand_round (operand0, operand1);
17898   else
17899     ix86_expand_rounddf_32 (operand0, operand1);
17900   DONE;
17903 (define_insn_and_split "*fistdi2_1"
17904   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17905         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17906                    UNSPEC_FIST))]
17907   "TARGET_USE_FANCY_MATH_387
17908    && !(reload_completed || reload_in_progress)"
17909   "#"
17910   "&& 1"
17911   [(const_int 0)]
17913   if (memory_operand (operands[0], VOIDmode))
17914     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17915   else
17916     {
17917       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17918       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17919                                          operands[2]));
17920     }
17921   DONE;
17923   [(set_attr "type" "fpspc")
17924    (set_attr "mode" "DI")])
17926 (define_insn "fistdi2"
17927   [(set (match_operand:DI 0 "memory_operand" "=m")
17928         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17929                    UNSPEC_FIST))
17930    (clobber (match_scratch:XF 2 "=&1f"))]
17931   "TARGET_USE_FANCY_MATH_387"
17932   "* return output_fix_trunc (insn, operands, 0);"
17933   [(set_attr "type" "fpspc")
17934    (set_attr "mode" "DI")])
17936 (define_insn "fistdi2_with_temp"
17937   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17938         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17939                    UNSPEC_FIST))
17940    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17941    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17942   "TARGET_USE_FANCY_MATH_387"
17943   "#"
17944   [(set_attr "type" "fpspc")
17945    (set_attr "mode" "DI")])
17947 (define_split
17948   [(set (match_operand:DI 0 "register_operand" "")
17949         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17950                    UNSPEC_FIST))
17951    (clobber (match_operand:DI 2 "memory_operand" ""))
17952    (clobber (match_scratch 3 ""))]
17953   "reload_completed"
17954   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17955               (clobber (match_dup 3))])
17956    (set (match_dup 0) (match_dup 2))]
17957   "")
17959 (define_split
17960   [(set (match_operand:DI 0 "memory_operand" "")
17961         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17962                    UNSPEC_FIST))
17963    (clobber (match_operand:DI 2 "memory_operand" ""))
17964    (clobber (match_scratch 3 ""))]
17965   "reload_completed"
17966   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17967               (clobber (match_dup 3))])]
17968   "")
17970 (define_insn_and_split "*fist<mode>2_1"
17971   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17972         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17973                            UNSPEC_FIST))]
17974   "TARGET_USE_FANCY_MATH_387
17975    && !(reload_completed || reload_in_progress)"
17976   "#"
17977   "&& 1"
17978   [(const_int 0)]
17980   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17981   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17982                                         operands[2]));
17983   DONE;
17985   [(set_attr "type" "fpspc")
17986    (set_attr "mode" "<MODE>")])
17988 (define_insn "fist<mode>2"
17989   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17990         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17991                            UNSPEC_FIST))]
17992   "TARGET_USE_FANCY_MATH_387"
17993   "* return output_fix_trunc (insn, operands, 0);"
17994   [(set_attr "type" "fpspc")
17995    (set_attr "mode" "<MODE>")])
17997 (define_insn "fist<mode>2_with_temp"
17998   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17999         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18000                            UNSPEC_FIST))
18001    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18002   "TARGET_USE_FANCY_MATH_387"
18003   "#"
18004   [(set_attr "type" "fpspc")
18005    (set_attr "mode" "<MODE>")])
18007 (define_split
18008   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18009         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18010                            UNSPEC_FIST))
18011    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18012   "reload_completed"
18013   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18014    (set (match_dup 0) (match_dup 2))]
18015   "")
18017 (define_split
18018   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18019         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18020                            UNSPEC_FIST))
18021    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18022   "reload_completed"
18023   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18024   "")
18026 (define_expand "lrintxf<mode>2"
18027   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18028      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18029                       UNSPEC_FIST))]
18030   "TARGET_USE_FANCY_MATH_387"
18031   "")
18033 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18034   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18035      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18036                         UNSPEC_FIX_NOTRUNC))]
18037   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18038    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18039   "")
18041 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18042   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18043    (match_operand:MODEF 1 "register_operand" "")]
18044   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18045    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18046    && !flag_trapping_math && !flag_rounding_math"
18048   if (optimize_insn_for_size_p ())
18049     FAIL;
18050   ix86_expand_lround (operand0, operand1);
18051   DONE;
18054 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18055 (define_insn_and_split "frndintxf2_floor"
18056   [(set (match_operand:XF 0 "register_operand" "")
18057         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18058          UNSPEC_FRNDINT_FLOOR))
18059    (clobber (reg:CC FLAGS_REG))]
18060   "TARGET_USE_FANCY_MATH_387
18061    && flag_unsafe_math_optimizations
18062    && !(reload_completed || reload_in_progress)"
18063   "#"
18064   "&& 1"
18065   [(const_int 0)]
18067   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18069   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18070   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18072   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18073                                         operands[2], operands[3]));
18074   DONE;
18076   [(set_attr "type" "frndint")
18077    (set_attr "i387_cw" "floor")
18078    (set_attr "mode" "XF")])
18080 (define_insn "frndintxf2_floor_i387"
18081   [(set (match_operand:XF 0 "register_operand" "=f")
18082         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18083          UNSPEC_FRNDINT_FLOOR))
18084    (use (match_operand:HI 2 "memory_operand" "m"))
18085    (use (match_operand:HI 3 "memory_operand" "m"))]
18086   "TARGET_USE_FANCY_MATH_387
18087    && flag_unsafe_math_optimizations"
18088   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18089   [(set_attr "type" "frndint")
18090    (set_attr "i387_cw" "floor")
18091    (set_attr "mode" "XF")])
18093 (define_expand "floorxf2"
18094   [(use (match_operand:XF 0 "register_operand" ""))
18095    (use (match_operand:XF 1 "register_operand" ""))]
18096   "TARGET_USE_FANCY_MATH_387
18097    && flag_unsafe_math_optimizations"
18099   if (optimize_insn_for_size_p ())
18100     FAIL;
18101   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18102   DONE;
18105 (define_expand "floor<mode>2"
18106   [(use (match_operand:MODEF 0 "register_operand" ""))
18107    (use (match_operand:MODEF 1 "register_operand" ""))]
18108   "(TARGET_USE_FANCY_MATH_387
18109     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18110         || TARGET_MIX_SSE_I387)
18111     && flag_unsafe_math_optimizations)
18112    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18113        && !flag_trapping_math)"
18115   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18116       && !flag_trapping_math
18117       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18118     {
18119       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18120         FAIL;
18121       if (TARGET_ROUND)
18122         emit_insn (gen_sse4_1_round<mode>2
18123                    (operands[0], operands[1], GEN_INT (0x01)));
18124       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18125         ix86_expand_floorceil (operand0, operand1, true);
18126       else
18127         ix86_expand_floorceildf_32 (operand0, operand1, true);
18128     }
18129   else
18130     {
18131       rtx op0, op1;
18133       if (optimize_insn_for_size_p ())
18134         FAIL;
18136       op0 = gen_reg_rtx (XFmode);
18137       op1 = gen_reg_rtx (XFmode);
18138       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18139       emit_insn (gen_frndintxf2_floor (op0, op1));
18141       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18142     }
18143   DONE;
18146 (define_insn_and_split "*fist<mode>2_floor_1"
18147   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18148         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18149          UNSPEC_FIST_FLOOR))
18150    (clobber (reg:CC FLAGS_REG))]
18151   "TARGET_USE_FANCY_MATH_387
18152    && flag_unsafe_math_optimizations
18153    && !(reload_completed || reload_in_progress)"
18154   "#"
18155   "&& 1"
18156   [(const_int 0)]
18158   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18160   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18161   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18162   if (memory_operand (operands[0], VOIDmode))
18163     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18164                                       operands[2], operands[3]));
18165   else
18166     {
18167       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18168       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18169                                                   operands[2], operands[3],
18170                                                   operands[4]));
18171     }
18172   DONE;
18174   [(set_attr "type" "fistp")
18175    (set_attr "i387_cw" "floor")
18176    (set_attr "mode" "<MODE>")])
18178 (define_insn "fistdi2_floor"
18179   [(set (match_operand:DI 0 "memory_operand" "=m")
18180         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18181          UNSPEC_FIST_FLOOR))
18182    (use (match_operand:HI 2 "memory_operand" "m"))
18183    (use (match_operand:HI 3 "memory_operand" "m"))
18184    (clobber (match_scratch:XF 4 "=&1f"))]
18185   "TARGET_USE_FANCY_MATH_387
18186    && flag_unsafe_math_optimizations"
18187   "* return output_fix_trunc (insn, operands, 0);"
18188   [(set_attr "type" "fistp")
18189    (set_attr "i387_cw" "floor")
18190    (set_attr "mode" "DI")])
18192 (define_insn "fistdi2_floor_with_temp"
18193   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18194         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18195          UNSPEC_FIST_FLOOR))
18196    (use (match_operand:HI 2 "memory_operand" "m,m"))
18197    (use (match_operand:HI 3 "memory_operand" "m,m"))
18198    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18199    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18200   "TARGET_USE_FANCY_MATH_387
18201    && flag_unsafe_math_optimizations"
18202   "#"
18203   [(set_attr "type" "fistp")
18204    (set_attr "i387_cw" "floor")
18205    (set_attr "mode" "DI")])
18207 (define_split
18208   [(set (match_operand:DI 0 "register_operand" "")
18209         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18210          UNSPEC_FIST_FLOOR))
18211    (use (match_operand:HI 2 "memory_operand" ""))
18212    (use (match_operand:HI 3 "memory_operand" ""))
18213    (clobber (match_operand:DI 4 "memory_operand" ""))
18214    (clobber (match_scratch 5 ""))]
18215   "reload_completed"
18216   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18217               (use (match_dup 2))
18218               (use (match_dup 3))
18219               (clobber (match_dup 5))])
18220    (set (match_dup 0) (match_dup 4))]
18221   "")
18223 (define_split
18224   [(set (match_operand:DI 0 "memory_operand" "")
18225         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18226          UNSPEC_FIST_FLOOR))
18227    (use (match_operand:HI 2 "memory_operand" ""))
18228    (use (match_operand:HI 3 "memory_operand" ""))
18229    (clobber (match_operand:DI 4 "memory_operand" ""))
18230    (clobber (match_scratch 5 ""))]
18231   "reload_completed"
18232   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18233               (use (match_dup 2))
18234               (use (match_dup 3))
18235               (clobber (match_dup 5))])]
18236   "")
18238 (define_insn "fist<mode>2_floor"
18239   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18240         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18241          UNSPEC_FIST_FLOOR))
18242    (use (match_operand:HI 2 "memory_operand" "m"))
18243    (use (match_operand:HI 3 "memory_operand" "m"))]
18244   "TARGET_USE_FANCY_MATH_387
18245    && flag_unsafe_math_optimizations"
18246   "* return output_fix_trunc (insn, operands, 0);"
18247   [(set_attr "type" "fistp")
18248    (set_attr "i387_cw" "floor")
18249    (set_attr "mode" "<MODE>")])
18251 (define_insn "fist<mode>2_floor_with_temp"
18252   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18253         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18254          UNSPEC_FIST_FLOOR))
18255    (use (match_operand:HI 2 "memory_operand" "m,m"))
18256    (use (match_operand:HI 3 "memory_operand" "m,m"))
18257    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18258   "TARGET_USE_FANCY_MATH_387
18259    && flag_unsafe_math_optimizations"
18260   "#"
18261   [(set_attr "type" "fistp")
18262    (set_attr "i387_cw" "floor")
18263    (set_attr "mode" "<MODE>")])
18265 (define_split
18266   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18267         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18268          UNSPEC_FIST_FLOOR))
18269    (use (match_operand:HI 2 "memory_operand" ""))
18270    (use (match_operand:HI 3 "memory_operand" ""))
18271    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18272   "reload_completed"
18273   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18274                                   UNSPEC_FIST_FLOOR))
18275               (use (match_dup 2))
18276               (use (match_dup 3))])
18277    (set (match_dup 0) (match_dup 4))]
18278   "")
18280 (define_split
18281   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18282         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18283          UNSPEC_FIST_FLOOR))
18284    (use (match_operand:HI 2 "memory_operand" ""))
18285    (use (match_operand:HI 3 "memory_operand" ""))
18286    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18287   "reload_completed"
18288   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18289                                   UNSPEC_FIST_FLOOR))
18290               (use (match_dup 2))
18291               (use (match_dup 3))])]
18292   "")
18294 (define_expand "lfloorxf<mode>2"
18295   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18296                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18297                     UNSPEC_FIST_FLOOR))
18298               (clobber (reg:CC FLAGS_REG))])]
18299   "TARGET_USE_FANCY_MATH_387
18300    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18301    && flag_unsafe_math_optimizations"
18302   "")
18304 (define_expand "lfloor<mode>di2"
18305   [(match_operand:DI 0 "nonimmediate_operand" "")
18306    (match_operand:MODEF 1 "register_operand" "")]
18307   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18308    && !flag_trapping_math"
18310   if (optimize_insn_for_size_p ())
18311     FAIL;
18312   ix86_expand_lfloorceil (operand0, operand1, true);
18313   DONE;
18316 (define_expand "lfloor<mode>si2"
18317   [(match_operand:SI 0 "nonimmediate_operand" "")
18318    (match_operand:MODEF 1 "register_operand" "")]
18319   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18320    && !flag_trapping_math"
18322   if (optimize_insn_for_size_p () && TARGET_64BIT)
18323     FAIL;
18324   ix86_expand_lfloorceil (operand0, operand1, true);
18325   DONE;
18328 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18329 (define_insn_and_split "frndintxf2_ceil"
18330   [(set (match_operand:XF 0 "register_operand" "")
18331         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18332          UNSPEC_FRNDINT_CEIL))
18333    (clobber (reg:CC FLAGS_REG))]
18334   "TARGET_USE_FANCY_MATH_387
18335    && flag_unsafe_math_optimizations
18336    && !(reload_completed || reload_in_progress)"
18337   "#"
18338   "&& 1"
18339   [(const_int 0)]
18341   ix86_optimize_mode_switching[I387_CEIL] = 1;
18343   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18344   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18346   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18347                                        operands[2], operands[3]));
18348   DONE;
18350   [(set_attr "type" "frndint")
18351    (set_attr "i387_cw" "ceil")
18352    (set_attr "mode" "XF")])
18354 (define_insn "frndintxf2_ceil_i387"
18355   [(set (match_operand:XF 0 "register_operand" "=f")
18356         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18357          UNSPEC_FRNDINT_CEIL))
18358    (use (match_operand:HI 2 "memory_operand" "m"))
18359    (use (match_operand:HI 3 "memory_operand" "m"))]
18360   "TARGET_USE_FANCY_MATH_387
18361    && flag_unsafe_math_optimizations"
18362   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18363   [(set_attr "type" "frndint")
18364    (set_attr "i387_cw" "ceil")
18365    (set_attr "mode" "XF")])
18367 (define_expand "ceilxf2"
18368   [(use (match_operand:XF 0 "register_operand" ""))
18369    (use (match_operand:XF 1 "register_operand" ""))]
18370   "TARGET_USE_FANCY_MATH_387
18371    && flag_unsafe_math_optimizations"
18373   if (optimize_insn_for_size_p ())
18374     FAIL;
18375   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18376   DONE;
18379 (define_expand "ceil<mode>2"
18380   [(use (match_operand:MODEF 0 "register_operand" ""))
18381    (use (match_operand:MODEF 1 "register_operand" ""))]
18382   "(TARGET_USE_FANCY_MATH_387
18383     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18384         || TARGET_MIX_SSE_I387)
18385     && flag_unsafe_math_optimizations)
18386    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18387        && !flag_trapping_math)"
18389   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18390       && !flag_trapping_math
18391       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18392     {
18393       if (TARGET_ROUND)
18394         emit_insn (gen_sse4_1_round<mode>2
18395                    (operands[0], operands[1], GEN_INT (0x02)));
18396       else if (optimize_insn_for_size_p ())
18397         FAIL;
18398       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18399         ix86_expand_floorceil (operand0, operand1, false);
18400       else
18401         ix86_expand_floorceildf_32 (operand0, operand1, false);
18402     }
18403   else
18404     {
18405       rtx op0, op1;
18407       if (optimize_insn_for_size_p ())
18408         FAIL;
18410       op0 = gen_reg_rtx (XFmode);
18411       op1 = gen_reg_rtx (XFmode);
18412       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18413       emit_insn (gen_frndintxf2_ceil (op0, op1));
18415       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18416     }
18417   DONE;
18420 (define_insn_and_split "*fist<mode>2_ceil_1"
18421   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18422         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18423          UNSPEC_FIST_CEIL))
18424    (clobber (reg:CC FLAGS_REG))]
18425   "TARGET_USE_FANCY_MATH_387
18426    && flag_unsafe_math_optimizations
18427    && !(reload_completed || reload_in_progress)"
18428   "#"
18429   "&& 1"
18430   [(const_int 0)]
18432   ix86_optimize_mode_switching[I387_CEIL] = 1;
18434   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18435   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18436   if (memory_operand (operands[0], VOIDmode))
18437     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18438                                      operands[2], operands[3]));
18439   else
18440     {
18441       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18442       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18443                                                  operands[2], operands[3],
18444                                                  operands[4]));
18445     }
18446   DONE;
18448   [(set_attr "type" "fistp")
18449    (set_attr "i387_cw" "ceil")
18450    (set_attr "mode" "<MODE>")])
18452 (define_insn "fistdi2_ceil"
18453   [(set (match_operand:DI 0 "memory_operand" "=m")
18454         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18455          UNSPEC_FIST_CEIL))
18456    (use (match_operand:HI 2 "memory_operand" "m"))
18457    (use (match_operand:HI 3 "memory_operand" "m"))
18458    (clobber (match_scratch:XF 4 "=&1f"))]
18459   "TARGET_USE_FANCY_MATH_387
18460    && flag_unsafe_math_optimizations"
18461   "* return output_fix_trunc (insn, operands, 0);"
18462   [(set_attr "type" "fistp")
18463    (set_attr "i387_cw" "ceil")
18464    (set_attr "mode" "DI")])
18466 (define_insn "fistdi2_ceil_with_temp"
18467   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18468         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18469          UNSPEC_FIST_CEIL))
18470    (use (match_operand:HI 2 "memory_operand" "m,m"))
18471    (use (match_operand:HI 3 "memory_operand" "m,m"))
18472    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18473    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18474   "TARGET_USE_FANCY_MATH_387
18475    && flag_unsafe_math_optimizations"
18476   "#"
18477   [(set_attr "type" "fistp")
18478    (set_attr "i387_cw" "ceil")
18479    (set_attr "mode" "DI")])
18481 (define_split
18482   [(set (match_operand:DI 0 "register_operand" "")
18483         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18484          UNSPEC_FIST_CEIL))
18485    (use (match_operand:HI 2 "memory_operand" ""))
18486    (use (match_operand:HI 3 "memory_operand" ""))
18487    (clobber (match_operand:DI 4 "memory_operand" ""))
18488    (clobber (match_scratch 5 ""))]
18489   "reload_completed"
18490   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18491               (use (match_dup 2))
18492               (use (match_dup 3))
18493               (clobber (match_dup 5))])
18494    (set (match_dup 0) (match_dup 4))]
18495   "")
18497 (define_split
18498   [(set (match_operand:DI 0 "memory_operand" "")
18499         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18500          UNSPEC_FIST_CEIL))
18501    (use (match_operand:HI 2 "memory_operand" ""))
18502    (use (match_operand:HI 3 "memory_operand" ""))
18503    (clobber (match_operand:DI 4 "memory_operand" ""))
18504    (clobber (match_scratch 5 ""))]
18505   "reload_completed"
18506   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18507               (use (match_dup 2))
18508               (use (match_dup 3))
18509               (clobber (match_dup 5))])]
18510   "")
18512 (define_insn "fist<mode>2_ceil"
18513   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18514         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18515          UNSPEC_FIST_CEIL))
18516    (use (match_operand:HI 2 "memory_operand" "m"))
18517    (use (match_operand:HI 3 "memory_operand" "m"))]
18518   "TARGET_USE_FANCY_MATH_387
18519    && flag_unsafe_math_optimizations"
18520   "* return output_fix_trunc (insn, operands, 0);"
18521   [(set_attr "type" "fistp")
18522    (set_attr "i387_cw" "ceil")
18523    (set_attr "mode" "<MODE>")])
18525 (define_insn "fist<mode>2_ceil_with_temp"
18526   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18527         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18528          UNSPEC_FIST_CEIL))
18529    (use (match_operand:HI 2 "memory_operand" "m,m"))
18530    (use (match_operand:HI 3 "memory_operand" "m,m"))
18531    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18532   "TARGET_USE_FANCY_MATH_387
18533    && flag_unsafe_math_optimizations"
18534   "#"
18535   [(set_attr "type" "fistp")
18536    (set_attr "i387_cw" "ceil")
18537    (set_attr "mode" "<MODE>")])
18539 (define_split
18540   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18541         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18542          UNSPEC_FIST_CEIL))
18543    (use (match_operand:HI 2 "memory_operand" ""))
18544    (use (match_operand:HI 3 "memory_operand" ""))
18545    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18546   "reload_completed"
18547   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18548                                   UNSPEC_FIST_CEIL))
18549               (use (match_dup 2))
18550               (use (match_dup 3))])
18551    (set (match_dup 0) (match_dup 4))]
18552   "")
18554 (define_split
18555   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18556         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18557          UNSPEC_FIST_CEIL))
18558    (use (match_operand:HI 2 "memory_operand" ""))
18559    (use (match_operand:HI 3 "memory_operand" ""))
18560    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18561   "reload_completed"
18562   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18563                                   UNSPEC_FIST_CEIL))
18564               (use (match_dup 2))
18565               (use (match_dup 3))])]
18566   "")
18568 (define_expand "lceilxf<mode>2"
18569   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18570                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18571                     UNSPEC_FIST_CEIL))
18572               (clobber (reg:CC FLAGS_REG))])]
18573   "TARGET_USE_FANCY_MATH_387
18574    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18575    && flag_unsafe_math_optimizations"
18576   "")
18578 (define_expand "lceil<mode>di2"
18579   [(match_operand:DI 0 "nonimmediate_operand" "")
18580    (match_operand:MODEF 1 "register_operand" "")]
18581   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18582    && !flag_trapping_math"
18584   ix86_expand_lfloorceil (operand0, operand1, false);
18585   DONE;
18588 (define_expand "lceil<mode>si2"
18589   [(match_operand:SI 0 "nonimmediate_operand" "")
18590    (match_operand:MODEF 1 "register_operand" "")]
18591   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18592    && !flag_trapping_math"
18594   ix86_expand_lfloorceil (operand0, operand1, false);
18595   DONE;
18598 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18599 (define_insn_and_split "frndintxf2_trunc"
18600   [(set (match_operand:XF 0 "register_operand" "")
18601         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18602          UNSPEC_FRNDINT_TRUNC))
18603    (clobber (reg:CC FLAGS_REG))]
18604   "TARGET_USE_FANCY_MATH_387
18605    && flag_unsafe_math_optimizations
18606    && !(reload_completed || reload_in_progress)"
18607   "#"
18608   "&& 1"
18609   [(const_int 0)]
18611   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18613   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18614   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18616   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18617                                         operands[2], operands[3]));
18618   DONE;
18620   [(set_attr "type" "frndint")
18621    (set_attr "i387_cw" "trunc")
18622    (set_attr "mode" "XF")])
18624 (define_insn "frndintxf2_trunc_i387"
18625   [(set (match_operand:XF 0 "register_operand" "=f")
18626         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18627          UNSPEC_FRNDINT_TRUNC))
18628    (use (match_operand:HI 2 "memory_operand" "m"))
18629    (use (match_operand:HI 3 "memory_operand" "m"))]
18630   "TARGET_USE_FANCY_MATH_387
18631    && flag_unsafe_math_optimizations"
18632   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18633   [(set_attr "type" "frndint")
18634    (set_attr "i387_cw" "trunc")
18635    (set_attr "mode" "XF")])
18637 (define_expand "btruncxf2"
18638   [(use (match_operand:XF 0 "register_operand" ""))
18639    (use (match_operand:XF 1 "register_operand" ""))]
18640   "TARGET_USE_FANCY_MATH_387
18641    && flag_unsafe_math_optimizations"
18643   if (optimize_insn_for_size_p ())
18644     FAIL;
18645   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18646   DONE;
18649 (define_expand "btrunc<mode>2"
18650   [(use (match_operand:MODEF 0 "register_operand" ""))
18651    (use (match_operand:MODEF 1 "register_operand" ""))]
18652   "(TARGET_USE_FANCY_MATH_387
18653     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18654         || TARGET_MIX_SSE_I387)
18655     && flag_unsafe_math_optimizations)
18656    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18657        && !flag_trapping_math)"
18659   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18660       && !flag_trapping_math
18661       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18662     {
18663       if (TARGET_ROUND)
18664         emit_insn (gen_sse4_1_round<mode>2
18665                    (operands[0], operands[1], GEN_INT (0x03)));
18666       else if (optimize_insn_for_size_p ())
18667         FAIL;
18668       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18669         ix86_expand_trunc (operand0, operand1);
18670       else
18671         ix86_expand_truncdf_32 (operand0, operand1);
18672     }
18673   else
18674     {
18675       rtx op0, op1;
18677       if (optimize_insn_for_size_p ())
18678         FAIL;
18680       op0 = gen_reg_rtx (XFmode);
18681       op1 = gen_reg_rtx (XFmode);
18682       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18683       emit_insn (gen_frndintxf2_trunc (op0, op1));
18685       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18686     }
18687   DONE;
18690 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18691 (define_insn_and_split "frndintxf2_mask_pm"
18692   [(set (match_operand:XF 0 "register_operand" "")
18693         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18694          UNSPEC_FRNDINT_MASK_PM))
18695    (clobber (reg:CC FLAGS_REG))]
18696   "TARGET_USE_FANCY_MATH_387
18697    && flag_unsafe_math_optimizations
18698    && !(reload_completed || reload_in_progress)"
18699   "#"
18700   "&& 1"
18701   [(const_int 0)]
18703   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18705   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18706   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18708   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18709                                           operands[2], operands[3]));
18710   DONE;
18712   [(set_attr "type" "frndint")
18713    (set_attr "i387_cw" "mask_pm")
18714    (set_attr "mode" "XF")])
18716 (define_insn "frndintxf2_mask_pm_i387"
18717   [(set (match_operand:XF 0 "register_operand" "=f")
18718         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18719          UNSPEC_FRNDINT_MASK_PM))
18720    (use (match_operand:HI 2 "memory_operand" "m"))
18721    (use (match_operand:HI 3 "memory_operand" "m"))]
18722   "TARGET_USE_FANCY_MATH_387
18723    && flag_unsafe_math_optimizations"
18724   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18725   [(set_attr "type" "frndint")
18726    (set_attr "i387_cw" "mask_pm")
18727    (set_attr "mode" "XF")])
18729 (define_expand "nearbyintxf2"
18730   [(use (match_operand:XF 0 "register_operand" ""))
18731    (use (match_operand:XF 1 "register_operand" ""))]
18732   "TARGET_USE_FANCY_MATH_387
18733    && flag_unsafe_math_optimizations"
18735   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18737   DONE;
18740 (define_expand "nearbyint<mode>2"
18741   [(use (match_operand:MODEF 0 "register_operand" ""))
18742    (use (match_operand:MODEF 1 "register_operand" ""))]
18743   "TARGET_USE_FANCY_MATH_387
18744    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18745        || TARGET_MIX_SSE_I387)
18746    && flag_unsafe_math_optimizations"
18748   rtx op0 = gen_reg_rtx (XFmode);
18749   rtx op1 = gen_reg_rtx (XFmode);
18751   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18752   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18754   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18755   DONE;
18758 (define_insn "fxam<mode>2_i387"
18759   [(set (match_operand:HI 0 "register_operand" "=a")
18760         (unspec:HI
18761           [(match_operand:X87MODEF 1 "register_operand" "f")]
18762           UNSPEC_FXAM))]
18763   "TARGET_USE_FANCY_MATH_387"
18764   "fxam\n\tfnstsw\t%0"
18765   [(set_attr "type" "multi")
18766    (set_attr "unit" "i387")
18767    (set_attr "mode" "<MODE>")])
18769 (define_expand "isinf<mode>2"
18770   [(use (match_operand:SI 0 "register_operand" ""))
18771    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18772   "TARGET_USE_FANCY_MATH_387
18773    && TARGET_C99_FUNCTIONS
18774    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18776   rtx mask = GEN_INT (0x45);
18777   rtx val = GEN_INT (0x05);
18779   rtx cond;
18781   rtx scratch = gen_reg_rtx (HImode);
18782   rtx res = gen_reg_rtx (QImode);
18784   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18785   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18786   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18787   cond = gen_rtx_fmt_ee (EQ, QImode,
18788                          gen_rtx_REG (CCmode, FLAGS_REG),
18789                          const0_rtx);
18790   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18791   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18792   DONE;
18795 (define_expand "signbit<mode>2"
18796   [(use (match_operand:SI 0 "register_operand" ""))
18797    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18798   "TARGET_USE_FANCY_MATH_387
18799    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18801   rtx mask = GEN_INT (0x0200);
18803   rtx scratch = gen_reg_rtx (HImode);
18805   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18806   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18807   DONE;
18810 ;; Block operation instructions
18812 (define_insn "cld"
18813   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18814   ""
18815   "cld"
18816   [(set_attr "length" "1")
18817    (set_attr "length_immediate" "0")
18818    (set_attr "modrm" "0")])
18820 (define_expand "movmemsi"
18821   [(use (match_operand:BLK 0 "memory_operand" ""))
18822    (use (match_operand:BLK 1 "memory_operand" ""))
18823    (use (match_operand:SI 2 "nonmemory_operand" ""))
18824    (use (match_operand:SI 3 "const_int_operand" ""))
18825    (use (match_operand:SI 4 "const_int_operand" ""))
18826    (use (match_operand:SI 5 "const_int_operand" ""))]
18827   ""
18829  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18830                          operands[4], operands[5]))
18831    DONE;
18832  else
18833    FAIL;
18836 (define_expand "movmemdi"
18837   [(use (match_operand:BLK 0 "memory_operand" ""))
18838    (use (match_operand:BLK 1 "memory_operand" ""))
18839    (use (match_operand:DI 2 "nonmemory_operand" ""))
18840    (use (match_operand:DI 3 "const_int_operand" ""))
18841    (use (match_operand:SI 4 "const_int_operand" ""))
18842    (use (match_operand:SI 5 "const_int_operand" ""))]
18843   "TARGET_64BIT"
18845  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18846                          operands[4], operands[5]))
18847    DONE;
18848  else
18849    FAIL;
18852 ;; Most CPUs don't like single string operations
18853 ;; Handle this case here to simplify previous expander.
18855 (define_expand "strmov"
18856   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18857    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18858    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18859               (clobber (reg:CC FLAGS_REG))])
18860    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18861               (clobber (reg:CC FLAGS_REG))])]
18862   ""
18864   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18866   /* If .md ever supports :P for Pmode, these can be directly
18867      in the pattern above.  */
18868   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18869   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18871   /* Can't use this if the user has appropriated esi or edi.  */
18872   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18873       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18874     {
18875       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18876                                       operands[2], operands[3],
18877                                       operands[5], operands[6]));
18878       DONE;
18879     }
18881   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18884 (define_expand "strmov_singleop"
18885   [(parallel [(set (match_operand 1 "memory_operand" "")
18886                    (match_operand 3 "memory_operand" ""))
18887               (set (match_operand 0 "register_operand" "")
18888                    (match_operand 4 "" ""))
18889               (set (match_operand 2 "register_operand" "")
18890                    (match_operand 5 "" ""))])]
18891   ""
18892   "ix86_current_function_needs_cld = 1;")
18894 (define_insn "*strmovdi_rex_1"
18895   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18896         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18897    (set (match_operand:DI 0 "register_operand" "=D")
18898         (plus:DI (match_dup 2)
18899                  (const_int 8)))
18900    (set (match_operand:DI 1 "register_operand" "=S")
18901         (plus:DI (match_dup 3)
18902                  (const_int 8)))]
18903   "TARGET_64BIT"
18904   "movsq"
18905   [(set_attr "type" "str")
18906    (set_attr "mode" "DI")
18907    (set_attr "memory" "both")])
18909 (define_insn "*strmovsi_1"
18910   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18911         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18912    (set (match_operand:SI 0 "register_operand" "=D")
18913         (plus:SI (match_dup 2)
18914                  (const_int 4)))
18915    (set (match_operand:SI 1 "register_operand" "=S")
18916         (plus:SI (match_dup 3)
18917                  (const_int 4)))]
18918   "!TARGET_64BIT"
18919   "movs{l|d}"
18920   [(set_attr "type" "str")
18921    (set_attr "mode" "SI")
18922    (set_attr "memory" "both")])
18924 (define_insn "*strmovsi_rex_1"
18925   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18926         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18927    (set (match_operand:DI 0 "register_operand" "=D")
18928         (plus:DI (match_dup 2)
18929                  (const_int 4)))
18930    (set (match_operand:DI 1 "register_operand" "=S")
18931         (plus:DI (match_dup 3)
18932                  (const_int 4)))]
18933   "TARGET_64BIT"
18934   "movs{l|d}"
18935   [(set_attr "type" "str")
18936    (set_attr "mode" "SI")
18937    (set_attr "memory" "both")])
18939 (define_insn "*strmovhi_1"
18940   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18941         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18942    (set (match_operand:SI 0 "register_operand" "=D")
18943         (plus:SI (match_dup 2)
18944                  (const_int 2)))
18945    (set (match_operand:SI 1 "register_operand" "=S")
18946         (plus:SI (match_dup 3)
18947                  (const_int 2)))]
18948   "!TARGET_64BIT"
18949   "movsw"
18950   [(set_attr "type" "str")
18951    (set_attr "memory" "both")
18952    (set_attr "mode" "HI")])
18954 (define_insn "*strmovhi_rex_1"
18955   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18956         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18957    (set (match_operand:DI 0 "register_operand" "=D")
18958         (plus:DI (match_dup 2)
18959                  (const_int 2)))
18960    (set (match_operand:DI 1 "register_operand" "=S")
18961         (plus:DI (match_dup 3)
18962                  (const_int 2)))]
18963   "TARGET_64BIT"
18964   "movsw"
18965   [(set_attr "type" "str")
18966    (set_attr "memory" "both")
18967    (set_attr "mode" "HI")])
18969 (define_insn "*strmovqi_1"
18970   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18971         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18972    (set (match_operand:SI 0 "register_operand" "=D")
18973         (plus:SI (match_dup 2)
18974                  (const_int 1)))
18975    (set (match_operand:SI 1 "register_operand" "=S")
18976         (plus:SI (match_dup 3)
18977                  (const_int 1)))]
18978   "!TARGET_64BIT"
18979   "movsb"
18980   [(set_attr "type" "str")
18981    (set_attr "memory" "both")
18982    (set_attr "mode" "QI")])
18984 (define_insn "*strmovqi_rex_1"
18985   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18986         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18987    (set (match_operand:DI 0 "register_operand" "=D")
18988         (plus:DI (match_dup 2)
18989                  (const_int 1)))
18990    (set (match_operand:DI 1 "register_operand" "=S")
18991         (plus:DI (match_dup 3)
18992                  (const_int 1)))]
18993   "TARGET_64BIT"
18994   "movsb"
18995   [(set_attr "type" "str")
18996    (set_attr "memory" "both")
18997    (set_attr "mode" "QI")])
18999 (define_expand "rep_mov"
19000   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19001               (set (match_operand 0 "register_operand" "")
19002                    (match_operand 5 "" ""))
19003               (set (match_operand 2 "register_operand" "")
19004                    (match_operand 6 "" ""))
19005               (set (match_operand 1 "memory_operand" "")
19006                    (match_operand 3 "memory_operand" ""))
19007               (use (match_dup 4))])]
19008   ""
19009   "ix86_current_function_needs_cld = 1;")
19011 (define_insn "*rep_movdi_rex64"
19012   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19013    (set (match_operand:DI 0 "register_operand" "=D")
19014         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19015                             (const_int 3))
19016                  (match_operand:DI 3 "register_operand" "0")))
19017    (set (match_operand:DI 1 "register_operand" "=S")
19018         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19019                  (match_operand:DI 4 "register_operand" "1")))
19020    (set (mem:BLK (match_dup 3))
19021         (mem:BLK (match_dup 4)))
19022    (use (match_dup 5))]
19023   "TARGET_64BIT"
19024   "rep movsq"
19025   [(set_attr "type" "str")
19026    (set_attr "prefix_rep" "1")
19027    (set_attr "memory" "both")
19028    (set_attr "mode" "DI")])
19030 (define_insn "*rep_movsi"
19031   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19032    (set (match_operand:SI 0 "register_operand" "=D")
19033         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19034                             (const_int 2))
19035                  (match_operand:SI 3 "register_operand" "0")))
19036    (set (match_operand:SI 1 "register_operand" "=S")
19037         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19038                  (match_operand:SI 4 "register_operand" "1")))
19039    (set (mem:BLK (match_dup 3))
19040         (mem:BLK (match_dup 4)))
19041    (use (match_dup 5))]
19042   "!TARGET_64BIT"
19043   "rep movs{l|d}"
19044   [(set_attr "type" "str")
19045    (set_attr "prefix_rep" "1")
19046    (set_attr "memory" "both")
19047    (set_attr "mode" "SI")])
19049 (define_insn "*rep_movsi_rex64"
19050   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19051    (set (match_operand:DI 0 "register_operand" "=D")
19052         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19053                             (const_int 2))
19054                  (match_operand:DI 3 "register_operand" "0")))
19055    (set (match_operand:DI 1 "register_operand" "=S")
19056         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19057                  (match_operand:DI 4 "register_operand" "1")))
19058    (set (mem:BLK (match_dup 3))
19059         (mem:BLK (match_dup 4)))
19060    (use (match_dup 5))]
19061   "TARGET_64BIT"
19062   "rep movs{l|d}"
19063   [(set_attr "type" "str")
19064    (set_attr "prefix_rep" "1")
19065    (set_attr "memory" "both")
19066    (set_attr "mode" "SI")])
19068 (define_insn "*rep_movqi"
19069   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19070    (set (match_operand:SI 0 "register_operand" "=D")
19071         (plus:SI (match_operand:SI 3 "register_operand" "0")
19072                  (match_operand:SI 5 "register_operand" "2")))
19073    (set (match_operand:SI 1 "register_operand" "=S")
19074         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19075    (set (mem:BLK (match_dup 3))
19076         (mem:BLK (match_dup 4)))
19077    (use (match_dup 5))]
19078   "!TARGET_64BIT"
19079   "rep movsb"
19080   [(set_attr "type" "str")
19081    (set_attr "prefix_rep" "1")
19082    (set_attr "memory" "both")
19083    (set_attr "mode" "SI")])
19085 (define_insn "*rep_movqi_rex64"
19086   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19087    (set (match_operand:DI 0 "register_operand" "=D")
19088         (plus:DI (match_operand:DI 3 "register_operand" "0")
19089                  (match_operand:DI 5 "register_operand" "2")))
19090    (set (match_operand:DI 1 "register_operand" "=S")
19091         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19092    (set (mem:BLK (match_dup 3))
19093         (mem:BLK (match_dup 4)))
19094    (use (match_dup 5))]
19095   "TARGET_64BIT"
19096   "rep movsb"
19097   [(set_attr "type" "str")
19098    (set_attr "prefix_rep" "1")
19099    (set_attr "memory" "both")
19100    (set_attr "mode" "SI")])
19102 (define_expand "setmemsi"
19103    [(use (match_operand:BLK 0 "memory_operand" ""))
19104     (use (match_operand:SI 1 "nonmemory_operand" ""))
19105     (use (match_operand 2 "const_int_operand" ""))
19106     (use (match_operand 3 "const_int_operand" ""))
19107     (use (match_operand:SI 4 "const_int_operand" ""))
19108     (use (match_operand:SI 5 "const_int_operand" ""))]
19109   ""
19111  if (ix86_expand_setmem (operands[0], operands[1],
19112                          operands[2], operands[3],
19113                          operands[4], operands[5]))
19114    DONE;
19115  else
19116    FAIL;
19119 (define_expand "setmemdi"
19120    [(use (match_operand:BLK 0 "memory_operand" ""))
19121     (use (match_operand:DI 1 "nonmemory_operand" ""))
19122     (use (match_operand 2 "const_int_operand" ""))
19123     (use (match_operand 3 "const_int_operand" ""))
19124     (use (match_operand 4 "const_int_operand" ""))
19125     (use (match_operand 5 "const_int_operand" ""))]
19126   "TARGET_64BIT"
19128  if (ix86_expand_setmem (operands[0], operands[1],
19129                          operands[2], operands[3],
19130                          operands[4], operands[5]))
19131    DONE;
19132  else
19133    FAIL;
19136 ;; Most CPUs don't like single string operations
19137 ;; Handle this case here to simplify previous expander.
19139 (define_expand "strset"
19140   [(set (match_operand 1 "memory_operand" "")
19141         (match_operand 2 "register_operand" ""))
19142    (parallel [(set (match_operand 0 "register_operand" "")
19143                    (match_dup 3))
19144               (clobber (reg:CC FLAGS_REG))])]
19145   ""
19147   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19148     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19150   /* If .md ever supports :P for Pmode, this can be directly
19151      in the pattern above.  */
19152   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19153                               GEN_INT (GET_MODE_SIZE (GET_MODE
19154                                                       (operands[2]))));
19155   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19156     {
19157       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19158                                       operands[3]));
19159       DONE;
19160     }
19163 (define_expand "strset_singleop"
19164   [(parallel [(set (match_operand 1 "memory_operand" "")
19165                    (match_operand 2 "register_operand" ""))
19166               (set (match_operand 0 "register_operand" "")
19167                    (match_operand 3 "" ""))])]
19168   ""
19169   "ix86_current_function_needs_cld = 1;")
19171 (define_insn "*strsetdi_rex_1"
19172   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19173         (match_operand:DI 2 "register_operand" "a"))
19174    (set (match_operand:DI 0 "register_operand" "=D")
19175         (plus:DI (match_dup 1)
19176                  (const_int 8)))]
19177   "TARGET_64BIT"
19178   "stosq"
19179   [(set_attr "type" "str")
19180    (set_attr "memory" "store")
19181    (set_attr "mode" "DI")])
19183 (define_insn "*strsetsi_1"
19184   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19185         (match_operand:SI 2 "register_operand" "a"))
19186    (set (match_operand:SI 0 "register_operand" "=D")
19187         (plus:SI (match_dup 1)
19188                  (const_int 4)))]
19189   "!TARGET_64BIT"
19190   "stos{l|d}"
19191   [(set_attr "type" "str")
19192    (set_attr "memory" "store")
19193    (set_attr "mode" "SI")])
19195 (define_insn "*strsetsi_rex_1"
19196   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19197         (match_operand:SI 2 "register_operand" "a"))
19198    (set (match_operand:DI 0 "register_operand" "=D")
19199         (plus:DI (match_dup 1)
19200                  (const_int 4)))]
19201   "TARGET_64BIT"
19202   "stos{l|d}"
19203   [(set_attr "type" "str")
19204    (set_attr "memory" "store")
19205    (set_attr "mode" "SI")])
19207 (define_insn "*strsethi_1"
19208   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19209         (match_operand:HI 2 "register_operand" "a"))
19210    (set (match_operand:SI 0 "register_operand" "=D")
19211         (plus:SI (match_dup 1)
19212                  (const_int 2)))]
19213   "!TARGET_64BIT"
19214   "stosw"
19215   [(set_attr "type" "str")
19216    (set_attr "memory" "store")
19217    (set_attr "mode" "HI")])
19219 (define_insn "*strsethi_rex_1"
19220   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19221         (match_operand:HI 2 "register_operand" "a"))
19222    (set (match_operand:DI 0 "register_operand" "=D")
19223         (plus:DI (match_dup 1)
19224                  (const_int 2)))]
19225   "TARGET_64BIT"
19226   "stosw"
19227   [(set_attr "type" "str")
19228    (set_attr "memory" "store")
19229    (set_attr "mode" "HI")])
19231 (define_insn "*strsetqi_1"
19232   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19233         (match_operand:QI 2 "register_operand" "a"))
19234    (set (match_operand:SI 0 "register_operand" "=D")
19235         (plus:SI (match_dup 1)
19236                  (const_int 1)))]
19237   "!TARGET_64BIT"
19238   "stosb"
19239   [(set_attr "type" "str")
19240    (set_attr "memory" "store")
19241    (set_attr "mode" "QI")])
19243 (define_insn "*strsetqi_rex_1"
19244   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19245         (match_operand:QI 2 "register_operand" "a"))
19246    (set (match_operand:DI 0 "register_operand" "=D")
19247         (plus:DI (match_dup 1)
19248                  (const_int 1)))]
19249   "TARGET_64BIT"
19250   "stosb"
19251   [(set_attr "type" "str")
19252    (set_attr "memory" "store")
19253    (set_attr "mode" "QI")])
19255 (define_expand "rep_stos"
19256   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19257               (set (match_operand 0 "register_operand" "")
19258                    (match_operand 4 "" ""))
19259               (set (match_operand 2 "memory_operand" "") (const_int 0))
19260               (use (match_operand 3 "register_operand" ""))
19261               (use (match_dup 1))])]
19262   ""
19263   "ix86_current_function_needs_cld = 1;")
19265 (define_insn "*rep_stosdi_rex64"
19266   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19267    (set (match_operand:DI 0 "register_operand" "=D")
19268         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19269                             (const_int 3))
19270                  (match_operand:DI 3 "register_operand" "0")))
19271    (set (mem:BLK (match_dup 3))
19272         (const_int 0))
19273    (use (match_operand:DI 2 "register_operand" "a"))
19274    (use (match_dup 4))]
19275   "TARGET_64BIT"
19276   "rep stosq"
19277   [(set_attr "type" "str")
19278    (set_attr "prefix_rep" "1")
19279    (set_attr "memory" "store")
19280    (set_attr "mode" "DI")])
19282 (define_insn "*rep_stossi"
19283   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19284    (set (match_operand:SI 0 "register_operand" "=D")
19285         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19286                             (const_int 2))
19287                  (match_operand:SI 3 "register_operand" "0")))
19288    (set (mem:BLK (match_dup 3))
19289         (const_int 0))
19290    (use (match_operand:SI 2 "register_operand" "a"))
19291    (use (match_dup 4))]
19292   "!TARGET_64BIT"
19293   "rep stos{l|d}"
19294   [(set_attr "type" "str")
19295    (set_attr "prefix_rep" "1")
19296    (set_attr "memory" "store")
19297    (set_attr "mode" "SI")])
19299 (define_insn "*rep_stossi_rex64"
19300   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19301    (set (match_operand:DI 0 "register_operand" "=D")
19302         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19303                             (const_int 2))
19304                  (match_operand:DI 3 "register_operand" "0")))
19305    (set (mem:BLK (match_dup 3))
19306         (const_int 0))
19307    (use (match_operand:SI 2 "register_operand" "a"))
19308    (use (match_dup 4))]
19309   "TARGET_64BIT"
19310   "rep stos{l|d}"
19311   [(set_attr "type" "str")
19312    (set_attr "prefix_rep" "1")
19313    (set_attr "memory" "store")
19314    (set_attr "mode" "SI")])
19316 (define_insn "*rep_stosqi"
19317   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19318    (set (match_operand:SI 0 "register_operand" "=D")
19319         (plus:SI (match_operand:SI 3 "register_operand" "0")
19320                  (match_operand:SI 4 "register_operand" "1")))
19321    (set (mem:BLK (match_dup 3))
19322         (const_int 0))
19323    (use (match_operand:QI 2 "register_operand" "a"))
19324    (use (match_dup 4))]
19325   "!TARGET_64BIT"
19326   "rep stosb"
19327   [(set_attr "type" "str")
19328    (set_attr "prefix_rep" "1")
19329    (set_attr "memory" "store")
19330    (set_attr "mode" "QI")])
19332 (define_insn "*rep_stosqi_rex64"
19333   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19334    (set (match_operand:DI 0 "register_operand" "=D")
19335         (plus:DI (match_operand:DI 3 "register_operand" "0")
19336                  (match_operand:DI 4 "register_operand" "1")))
19337    (set (mem:BLK (match_dup 3))
19338         (const_int 0))
19339    (use (match_operand:QI 2 "register_operand" "a"))
19340    (use (match_dup 4))]
19341   "TARGET_64BIT"
19342   "rep stosb"
19343   [(set_attr "type" "str")
19344    (set_attr "prefix_rep" "1")
19345    (set_attr "memory" "store")
19346    (set_attr "mode" "QI")])
19348 (define_expand "cmpstrnsi"
19349   [(set (match_operand:SI 0 "register_operand" "")
19350         (compare:SI (match_operand:BLK 1 "general_operand" "")
19351                     (match_operand:BLK 2 "general_operand" "")))
19352    (use (match_operand 3 "general_operand" ""))
19353    (use (match_operand 4 "immediate_operand" ""))]
19354   ""
19356   rtx addr1, addr2, out, outlow, count, countreg, align;
19358   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19359     FAIL;
19361   /* Can't use this if the user has appropriated esi or edi.  */
19362   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19363     FAIL;
19365   out = operands[0];
19366   if (!REG_P (out))
19367     out = gen_reg_rtx (SImode);
19369   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19370   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19371   if (addr1 != XEXP (operands[1], 0))
19372     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19373   if (addr2 != XEXP (operands[2], 0))
19374     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19376   count = operands[3];
19377   countreg = ix86_zero_extend_to_Pmode (count);
19379   /* %%% Iff we are testing strict equality, we can use known alignment
19380      to good advantage.  This may be possible with combine, particularly
19381      once cc0 is dead.  */
19382   align = operands[4];
19384   if (CONST_INT_P (count))
19385     {
19386       if (INTVAL (count) == 0)
19387         {
19388           emit_move_insn (operands[0], const0_rtx);
19389           DONE;
19390         }
19391       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19392                                      operands[1], operands[2]));
19393     }
19394   else
19395     {
19396       if (TARGET_64BIT)
19397         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19398       else
19399         emit_insn (gen_cmpsi_1 (countreg, countreg));
19400       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19401                                   operands[1], operands[2]));
19402     }
19404   outlow = gen_lowpart (QImode, out);
19405   emit_insn (gen_cmpintqi (outlow));
19406   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19408   if (operands[0] != out)
19409     emit_move_insn (operands[0], out);
19411   DONE;
19414 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19416 (define_expand "cmpintqi"
19417   [(set (match_dup 1)
19418         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19419    (set (match_dup 2)
19420         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19421    (parallel [(set (match_operand:QI 0 "register_operand" "")
19422                    (minus:QI (match_dup 1)
19423                              (match_dup 2)))
19424               (clobber (reg:CC FLAGS_REG))])]
19425   ""
19426   "operands[1] = gen_reg_rtx (QImode);
19427    operands[2] = gen_reg_rtx (QImode);")
19429 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19430 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19432 (define_expand "cmpstrnqi_nz_1"
19433   [(parallel [(set (reg:CC FLAGS_REG)
19434                    (compare:CC (match_operand 4 "memory_operand" "")
19435                                (match_operand 5 "memory_operand" "")))
19436               (use (match_operand 2 "register_operand" ""))
19437               (use (match_operand:SI 3 "immediate_operand" ""))
19438               (clobber (match_operand 0 "register_operand" ""))
19439               (clobber (match_operand 1 "register_operand" ""))
19440               (clobber (match_dup 2))])]
19441   ""
19442   "ix86_current_function_needs_cld = 1;")
19444 (define_insn "*cmpstrnqi_nz_1"
19445   [(set (reg:CC FLAGS_REG)
19446         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19447                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19448    (use (match_operand:SI 6 "register_operand" "2"))
19449    (use (match_operand:SI 3 "immediate_operand" "i"))
19450    (clobber (match_operand:SI 0 "register_operand" "=S"))
19451    (clobber (match_operand:SI 1 "register_operand" "=D"))
19452    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19453   "!TARGET_64BIT"
19454   "repz cmpsb"
19455   [(set_attr "type" "str")
19456    (set_attr "mode" "QI")
19457    (set_attr "prefix_rep" "1")])
19459 (define_insn "*cmpstrnqi_nz_rex_1"
19460   [(set (reg:CC FLAGS_REG)
19461         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19462                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19463    (use (match_operand:DI 6 "register_operand" "2"))
19464    (use (match_operand:SI 3 "immediate_operand" "i"))
19465    (clobber (match_operand:DI 0 "register_operand" "=S"))
19466    (clobber (match_operand:DI 1 "register_operand" "=D"))
19467    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19468   "TARGET_64BIT"
19469   "repz cmpsb"
19470   [(set_attr "type" "str")
19471    (set_attr "mode" "QI")
19472    (set_attr "prefix_rep" "1")])
19474 ;; The same, but the count is not known to not be zero.
19476 (define_expand "cmpstrnqi_1"
19477   [(parallel [(set (reg:CC FLAGS_REG)
19478                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19479                                      (const_int 0))
19480                   (compare:CC (match_operand 4 "memory_operand" "")
19481                               (match_operand 5 "memory_operand" ""))
19482                   (const_int 0)))
19483               (use (match_operand:SI 3 "immediate_operand" ""))
19484               (use (reg:CC FLAGS_REG))
19485               (clobber (match_operand 0 "register_operand" ""))
19486               (clobber (match_operand 1 "register_operand" ""))
19487               (clobber (match_dup 2))])]
19488   ""
19489   "ix86_current_function_needs_cld = 1;")
19491 (define_insn "*cmpstrnqi_1"
19492   [(set (reg:CC FLAGS_REG)
19493         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19494                              (const_int 0))
19495           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19496                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19497           (const_int 0)))
19498    (use (match_operand:SI 3 "immediate_operand" "i"))
19499    (use (reg:CC FLAGS_REG))
19500    (clobber (match_operand:SI 0 "register_operand" "=S"))
19501    (clobber (match_operand:SI 1 "register_operand" "=D"))
19502    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19503   "!TARGET_64BIT"
19504   "repz cmpsb"
19505   [(set_attr "type" "str")
19506    (set_attr "mode" "QI")
19507    (set_attr "prefix_rep" "1")])
19509 (define_insn "*cmpstrnqi_rex_1"
19510   [(set (reg:CC FLAGS_REG)
19511         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19512                              (const_int 0))
19513           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19514                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19515           (const_int 0)))
19516    (use (match_operand:SI 3 "immediate_operand" "i"))
19517    (use (reg:CC FLAGS_REG))
19518    (clobber (match_operand:DI 0 "register_operand" "=S"))
19519    (clobber (match_operand:DI 1 "register_operand" "=D"))
19520    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19521   "TARGET_64BIT"
19522   "repz cmpsb"
19523   [(set_attr "type" "str")
19524    (set_attr "mode" "QI")
19525    (set_attr "prefix_rep" "1")])
19527 (define_expand "strlensi"
19528   [(set (match_operand:SI 0 "register_operand" "")
19529         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19530                     (match_operand:QI 2 "immediate_operand" "")
19531                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19532   ""
19534  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19535    DONE;
19536  else
19537    FAIL;
19540 (define_expand "strlendi"
19541   [(set (match_operand:DI 0 "register_operand" "")
19542         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19543                     (match_operand:QI 2 "immediate_operand" "")
19544                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19545   ""
19547  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19548    DONE;
19549  else
19550    FAIL;
19553 (define_expand "strlenqi_1"
19554   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19555               (clobber (match_operand 1 "register_operand" ""))
19556               (clobber (reg:CC FLAGS_REG))])]
19557   ""
19558   "ix86_current_function_needs_cld = 1;")
19560 (define_insn "*strlenqi_1"
19561   [(set (match_operand:SI 0 "register_operand" "=&c")
19562         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19563                     (match_operand:QI 2 "register_operand" "a")
19564                     (match_operand:SI 3 "immediate_operand" "i")
19565                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19566    (clobber (match_operand:SI 1 "register_operand" "=D"))
19567    (clobber (reg:CC FLAGS_REG))]
19568   "!TARGET_64BIT"
19569   "repnz scasb"
19570   [(set_attr "type" "str")
19571    (set_attr "mode" "QI")
19572    (set_attr "prefix_rep" "1")])
19574 (define_insn "*strlenqi_rex_1"
19575   [(set (match_operand:DI 0 "register_operand" "=&c")
19576         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19577                     (match_operand:QI 2 "register_operand" "a")
19578                     (match_operand:DI 3 "immediate_operand" "i")
19579                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19580    (clobber (match_operand:DI 1 "register_operand" "=D"))
19581    (clobber (reg:CC FLAGS_REG))]
19582   "TARGET_64BIT"
19583   "repnz scasb"
19584   [(set_attr "type" "str")
19585    (set_attr "mode" "QI")
19586    (set_attr "prefix_rep" "1")])
19588 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19589 ;; handled in combine, but it is not currently up to the task.
19590 ;; When used for their truth value, the cmpstrn* expanders generate
19591 ;; code like this:
19593 ;;   repz cmpsb
19594 ;;   seta       %al
19595 ;;   setb       %dl
19596 ;;   cmpb       %al, %dl
19597 ;;   jcc        label
19599 ;; The intermediate three instructions are unnecessary.
19601 ;; This one handles cmpstrn*_nz_1...
19602 (define_peephole2
19603   [(parallel[
19604      (set (reg:CC FLAGS_REG)
19605           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19606                       (mem:BLK (match_operand 5 "register_operand" ""))))
19607      (use (match_operand 6 "register_operand" ""))
19608      (use (match_operand:SI 3 "immediate_operand" ""))
19609      (clobber (match_operand 0 "register_operand" ""))
19610      (clobber (match_operand 1 "register_operand" ""))
19611      (clobber (match_operand 2 "register_operand" ""))])
19612    (set (match_operand:QI 7 "register_operand" "")
19613         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19614    (set (match_operand:QI 8 "register_operand" "")
19615         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19616    (set (reg FLAGS_REG)
19617         (compare (match_dup 7) (match_dup 8)))
19618   ]
19619   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19620   [(parallel[
19621      (set (reg:CC FLAGS_REG)
19622           (compare:CC (mem:BLK (match_dup 4))
19623                       (mem:BLK (match_dup 5))))
19624      (use (match_dup 6))
19625      (use (match_dup 3))
19626      (clobber (match_dup 0))
19627      (clobber (match_dup 1))
19628      (clobber (match_dup 2))])]
19629   "")
19631 ;; ...and this one handles cmpstrn*_1.
19632 (define_peephole2
19633   [(parallel[
19634      (set (reg:CC FLAGS_REG)
19635           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19636                                (const_int 0))
19637             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19638                         (mem:BLK (match_operand 5 "register_operand" "")))
19639             (const_int 0)))
19640      (use (match_operand:SI 3 "immediate_operand" ""))
19641      (use (reg:CC FLAGS_REG))
19642      (clobber (match_operand 0 "register_operand" ""))
19643      (clobber (match_operand 1 "register_operand" ""))
19644      (clobber (match_operand 2 "register_operand" ""))])
19645    (set (match_operand:QI 7 "register_operand" "")
19646         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19647    (set (match_operand:QI 8 "register_operand" "")
19648         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19649    (set (reg FLAGS_REG)
19650         (compare (match_dup 7) (match_dup 8)))
19651   ]
19652   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19653   [(parallel[
19654      (set (reg:CC FLAGS_REG)
19655           (if_then_else:CC (ne (match_dup 6)
19656                                (const_int 0))
19657             (compare:CC (mem:BLK (match_dup 4))
19658                         (mem:BLK (match_dup 5)))
19659             (const_int 0)))
19660      (use (match_dup 3))
19661      (use (reg:CC FLAGS_REG))
19662      (clobber (match_dup 0))
19663      (clobber (match_dup 1))
19664      (clobber (match_dup 2))])]
19665   "")
19669 ;; Conditional move instructions.
19671 (define_expand "movdicc"
19672   [(set (match_operand:DI 0 "register_operand" "")
19673         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19674                          (match_operand:DI 2 "general_operand" "")
19675                          (match_operand:DI 3 "general_operand" "")))]
19676   "TARGET_64BIT"
19677   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19679 (define_insn "x86_movdicc_0_m1_rex64"
19680   [(set (match_operand:DI 0 "register_operand" "=r")
19681         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19682           (const_int -1)
19683           (const_int 0)))
19684    (clobber (reg:CC FLAGS_REG))]
19685   "TARGET_64BIT"
19686   "sbb{q}\t%0, %0"
19687   ; Since we don't have the proper number of operands for an alu insn,
19688   ; fill in all the blanks.
19689   [(set_attr "type" "alu")
19690    (set_attr "pent_pair" "pu")
19691    (set_attr "memory" "none")
19692    (set_attr "imm_disp" "false")
19693    (set_attr "mode" "DI")
19694    (set_attr "length_immediate" "0")])
19696 (define_insn "*x86_movdicc_0_m1_se"
19697   [(set (match_operand:DI 0 "register_operand" "=r")
19698         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19699                          (const_int 1)
19700                          (const_int 0)))
19701    (clobber (reg:CC FLAGS_REG))]
19702   ""
19703   "sbb{q}\t%0, %0"
19704   [(set_attr "type" "alu")
19705    (set_attr "pent_pair" "pu")
19706    (set_attr "memory" "none")
19707    (set_attr "imm_disp" "false")
19708    (set_attr "mode" "DI")
19709    (set_attr "length_immediate" "0")])
19711 (define_insn "*movdicc_c_rex64"
19712   [(set (match_operand:DI 0 "register_operand" "=r,r")
19713         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19714                                 [(reg FLAGS_REG) (const_int 0)])
19715                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19716                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19717   "TARGET_64BIT && TARGET_CMOVE
19718    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19719   "@
19720    cmov%O2%C1\t{%2, %0|%0, %2}
19721    cmov%O2%c1\t{%3, %0|%0, %3}"
19722   [(set_attr "type" "icmov")
19723    (set_attr "mode" "DI")])
19725 (define_expand "movsicc"
19726   [(set (match_operand:SI 0 "register_operand" "")
19727         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19728                          (match_operand:SI 2 "general_operand" "")
19729                          (match_operand:SI 3 "general_operand" "")))]
19730   ""
19731   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19733 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19734 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19735 ;; So just document what we're doing explicitly.
19737 (define_insn "x86_movsicc_0_m1"
19738   [(set (match_operand:SI 0 "register_operand" "=r")
19739         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19740           (const_int -1)
19741           (const_int 0)))
19742    (clobber (reg:CC FLAGS_REG))]
19743   ""
19744   "sbb{l}\t%0, %0"
19745   ; Since we don't have the proper number of operands for an alu insn,
19746   ; fill in all the blanks.
19747   [(set_attr "type" "alu")
19748    (set_attr "pent_pair" "pu")
19749    (set_attr "memory" "none")
19750    (set_attr "imm_disp" "false")
19751    (set_attr "mode" "SI")
19752    (set_attr "length_immediate" "0")])
19754 (define_insn "*x86_movsicc_0_m1_se"
19755   [(set (match_operand:SI 0 "register_operand" "=r")
19756         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19757                          (const_int 1)
19758                          (const_int 0)))
19759    (clobber (reg:CC FLAGS_REG))]
19760   ""
19761   "sbb{l}\t%0, %0"
19762   [(set_attr "type" "alu")
19763    (set_attr "pent_pair" "pu")
19764    (set_attr "memory" "none")
19765    (set_attr "imm_disp" "false")
19766    (set_attr "mode" "SI")
19767    (set_attr "length_immediate" "0")])
19769 (define_insn "*movsicc_noc"
19770   [(set (match_operand:SI 0 "register_operand" "=r,r")
19771         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19772                                 [(reg FLAGS_REG) (const_int 0)])
19773                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19774                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19775   "TARGET_CMOVE
19776    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19777   "@
19778    cmov%O2%C1\t{%2, %0|%0, %2}
19779    cmov%O2%c1\t{%3, %0|%0, %3}"
19780   [(set_attr "type" "icmov")
19781    (set_attr "mode" "SI")])
19783 (define_expand "movhicc"
19784   [(set (match_operand:HI 0 "register_operand" "")
19785         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19786                          (match_operand:HI 2 "general_operand" "")
19787                          (match_operand:HI 3 "general_operand" "")))]
19788   "TARGET_HIMODE_MATH"
19789   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19791 (define_insn "*movhicc_noc"
19792   [(set (match_operand:HI 0 "register_operand" "=r,r")
19793         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19794                                 [(reg FLAGS_REG) (const_int 0)])
19795                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19796                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19797   "TARGET_CMOVE
19798    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19799   "@
19800    cmov%O2%C1\t{%2, %0|%0, %2}
19801    cmov%O2%c1\t{%3, %0|%0, %3}"
19802   [(set_attr "type" "icmov")
19803    (set_attr "mode" "HI")])
19805 (define_expand "movqicc"
19806   [(set (match_operand:QI 0 "register_operand" "")
19807         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19808                          (match_operand:QI 2 "general_operand" "")
19809                          (match_operand:QI 3 "general_operand" "")))]
19810   "TARGET_QIMODE_MATH"
19811   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19813 (define_insn_and_split "*movqicc_noc"
19814   [(set (match_operand:QI 0 "register_operand" "=r,r")
19815         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19816                                 [(match_operand 4 "flags_reg_operand" "")
19817                                  (const_int 0)])
19818                       (match_operand:QI 2 "register_operand" "r,0")
19819                       (match_operand:QI 3 "register_operand" "0,r")))]
19820   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19821   "#"
19822   "&& reload_completed"
19823   [(set (match_dup 0)
19824         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19825                       (match_dup 2)
19826                       (match_dup 3)))]
19827   "operands[0] = gen_lowpart (SImode, operands[0]);
19828    operands[2] = gen_lowpart (SImode, operands[2]);
19829    operands[3] = gen_lowpart (SImode, operands[3]);"
19830   [(set_attr "type" "icmov")
19831    (set_attr "mode" "SI")])
19833 (define_expand "mov<mode>cc"
19834   [(set (match_operand:X87MODEF 0 "register_operand" "")
19835         (if_then_else:X87MODEF
19836           (match_operand 1 "comparison_operator" "")
19837           (match_operand:X87MODEF 2 "register_operand" "")
19838           (match_operand:X87MODEF 3 "register_operand" "")))]
19839   "(TARGET_80387 && TARGET_CMOVE)
19840    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19841   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19843 (define_insn "*movsfcc_1_387"
19844   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19845         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19846                                 [(reg FLAGS_REG) (const_int 0)])
19847                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19848                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19849   "TARGET_80387 && TARGET_CMOVE
19850    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19851   "@
19852    fcmov%F1\t{%2, %0|%0, %2}
19853    fcmov%f1\t{%3, %0|%0, %3}
19854    cmov%O2%C1\t{%2, %0|%0, %2}
19855    cmov%O2%c1\t{%3, %0|%0, %3}"
19856   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19857    (set_attr "mode" "SF,SF,SI,SI")])
19859 (define_insn "*movdfcc_1"
19860   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19861         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19862                                 [(reg FLAGS_REG) (const_int 0)])
19863                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19864                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19865   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19866    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19867   "@
19868    fcmov%F1\t{%2, %0|%0, %2}
19869    fcmov%f1\t{%3, %0|%0, %3}
19870    #
19871    #"
19872   [(set_attr "type" "fcmov,fcmov,multi,multi")
19873    (set_attr "mode" "DF")])
19875 (define_insn "*movdfcc_1_rex64"
19876   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19877         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19878                                 [(reg FLAGS_REG) (const_int 0)])
19879                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19880                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19881   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19882    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19883   "@
19884    fcmov%F1\t{%2, %0|%0, %2}
19885    fcmov%f1\t{%3, %0|%0, %3}
19886    cmov%O2%C1\t{%2, %0|%0, %2}
19887    cmov%O2%c1\t{%3, %0|%0, %3}"
19888   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19889    (set_attr "mode" "DF")])
19891 (define_split
19892   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19893         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19894                                 [(match_operand 4 "flags_reg_operand" "")
19895                                  (const_int 0)])
19896                       (match_operand:DF 2 "nonimmediate_operand" "")
19897                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19898   "!TARGET_64BIT && reload_completed"
19899   [(set (match_dup 2)
19900         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19901                       (match_dup 5)
19902                       (match_dup 6)))
19903    (set (match_dup 3)
19904         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19905                       (match_dup 7)
19906                       (match_dup 8)))]
19907   "split_di (&operands[2], 2, &operands[5], &operands[7]);
19908    split_di (&operands[0], 1, &operands[2], &operands[3]);")
19910 (define_insn "*movxfcc_1"
19911   [(set (match_operand:XF 0 "register_operand" "=f,f")
19912         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19913                                 [(reg FLAGS_REG) (const_int 0)])
19914                       (match_operand:XF 2 "register_operand" "f,0")
19915                       (match_operand:XF 3 "register_operand" "0,f")))]
19916   "TARGET_80387 && TARGET_CMOVE"
19917   "@
19918    fcmov%F1\t{%2, %0|%0, %2}
19919    fcmov%f1\t{%3, %0|%0, %3}"
19920   [(set_attr "type" "fcmov")
19921    (set_attr "mode" "XF")])
19923 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19924 ;; the scalar versions to have only XMM registers as operands.
19926 ;; SSE5 conditional move
19927 (define_insn "*sse5_pcmov_<mode>"
19928   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19929         (if_then_else:MODEF
19930           (match_operand:MODEF 1 "register_operand" "x,0")
19931           (match_operand:MODEF 2 "register_operand" "0,x")
19932           (match_operand:MODEF 3 "register_operand" "x,x")))]
19933   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
19934   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19935   [(set_attr "type" "sse4arg")])
19937 ;; These versions of the min/max patterns are intentionally ignorant of
19938 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19939 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19940 ;; are undefined in this condition, we're certain this is correct.
19942 (define_insn "*avx_<code><mode>3"
19943   [(set (match_operand:MODEF 0 "register_operand" "=x")
19944         (smaxmin:MODEF
19945           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19946           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19947   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19948   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19949   [(set_attr "type" "sseadd")
19950    (set_attr "prefix" "vex")
19951    (set_attr "mode" "<MODE>")])
19953 (define_insn "<code><mode>3"
19954   [(set (match_operand:MODEF 0 "register_operand" "=x")
19955         (smaxmin:MODEF
19956           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19957           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19958   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19959   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19960   [(set_attr "type" "sseadd")
19961    (set_attr "mode" "<MODE>")])
19963 ;; These versions of the min/max patterns implement exactly the operations
19964 ;;   min = (op1 < op2 ? op1 : op2)
19965 ;;   max = (!(op1 < op2) ? op1 : op2)
19966 ;; Their operands are not commutative, and thus they may be used in the
19967 ;; presence of -0.0 and NaN.
19969 (define_insn "*avx_ieee_smin<mode>3"
19970   [(set (match_operand:MODEF 0 "register_operand" "=x")
19971         (unspec:MODEF
19972           [(match_operand:MODEF 1 "register_operand" "x")
19973            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19974          UNSPEC_IEEE_MIN))]
19975   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19976   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19977   [(set_attr "type" "sseadd")
19978    (set_attr "prefix" "vex")
19979    (set_attr "mode" "<MODE>")])
19981 (define_insn "*ieee_smin<mode>3"
19982   [(set (match_operand:MODEF 0 "register_operand" "=x")
19983         (unspec:MODEF
19984           [(match_operand:MODEF 1 "register_operand" "0")
19985            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19986          UNSPEC_IEEE_MIN))]
19987   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19988   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19989   [(set_attr "type" "sseadd")
19990    (set_attr "mode" "<MODE>")])
19992 (define_insn "*avx_ieee_smax<mode>3"
19993   [(set (match_operand:MODEF 0 "register_operand" "=x")
19994         (unspec:MODEF
19995           [(match_operand:MODEF 1 "register_operand" "0")
19996            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19997          UNSPEC_IEEE_MAX))]
19998   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19999   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20000   [(set_attr "type" "sseadd")
20001    (set_attr "prefix" "vex")
20002    (set_attr "mode" "<MODE>")])
20004 (define_insn "*ieee_smax<mode>3"
20005   [(set (match_operand:MODEF 0 "register_operand" "=x")
20006         (unspec:MODEF
20007           [(match_operand:MODEF 1 "register_operand" "0")
20008            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20009          UNSPEC_IEEE_MAX))]
20010   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20011   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20012   [(set_attr "type" "sseadd")
20013    (set_attr "mode" "<MODE>")])
20015 ;; Make two stack loads independent:
20016 ;;   fld aa              fld aa
20017 ;;   fld %st(0)     ->   fld bb
20018 ;;   fmul bb             fmul %st(1), %st
20020 ;; Actually we only match the last two instructions for simplicity.
20021 (define_peephole2
20022   [(set (match_operand 0 "fp_register_operand" "")
20023         (match_operand 1 "fp_register_operand" ""))
20024    (set (match_dup 0)
20025         (match_operator 2 "binary_fp_operator"
20026            [(match_dup 0)
20027             (match_operand 3 "memory_operand" "")]))]
20028   "REGNO (operands[0]) != REGNO (operands[1])"
20029   [(set (match_dup 0) (match_dup 3))
20030    (set (match_dup 0) (match_dup 4))]
20032   ;; The % modifier is not operational anymore in peephole2's, so we have to
20033   ;; swap the operands manually in the case of addition and multiplication.
20034   "if (COMMUTATIVE_ARITH_P (operands[2]))
20035      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20036                                  operands[0], operands[1]);
20037    else
20038      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20039                                  operands[1], operands[0]);")
20041 ;; Conditional addition patterns
20042 (define_expand "add<mode>cc"
20043   [(match_operand:SWI 0 "register_operand" "")
20044    (match_operand 1 "comparison_operator" "")
20045    (match_operand:SWI 2 "register_operand" "")
20046    (match_operand:SWI 3 "const_int_operand" "")]
20047   ""
20048   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20051 ;; Misc patterns (?)
20053 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20054 ;; Otherwise there will be nothing to keep
20056 ;; [(set (reg ebp) (reg esp))]
20057 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20058 ;;  (clobber (eflags)]
20059 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20061 ;; in proper program order.
20062 (define_insn "pro_epilogue_adjust_stack_1"
20063   [(set (match_operand:SI 0 "register_operand" "=r,r")
20064         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20065                  (match_operand:SI 2 "immediate_operand" "i,i")))
20066    (clobber (reg:CC FLAGS_REG))
20067    (clobber (mem:BLK (scratch)))]
20068   "!TARGET_64BIT"
20070   switch (get_attr_type (insn))
20071     {
20072     case TYPE_IMOV:
20073       return "mov{l}\t{%1, %0|%0, %1}";
20075     case TYPE_ALU:
20076       if (CONST_INT_P (operands[2])
20077           && (INTVAL (operands[2]) == 128
20078               || (INTVAL (operands[2]) < 0
20079                   && INTVAL (operands[2]) != -128)))
20080         {
20081           operands[2] = GEN_INT (-INTVAL (operands[2]));
20082           return "sub{l}\t{%2, %0|%0, %2}";
20083         }
20084       return "add{l}\t{%2, %0|%0, %2}";
20086     case TYPE_LEA:
20087       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20088       return "lea{l}\t{%a2, %0|%0, %a2}";
20090     default:
20091       gcc_unreachable ();
20092     }
20094   [(set (attr "type")
20095         (cond [(eq_attr "alternative" "0")
20096                  (const_string "alu")
20097                (match_operand:SI 2 "const0_operand" "")
20098                  (const_string "imov")
20099               ]
20100               (const_string "lea")))
20101    (set_attr "mode" "SI")])
20103 (define_insn "pro_epilogue_adjust_stack_rex64"
20104   [(set (match_operand:DI 0 "register_operand" "=r,r")
20105         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20106                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20107    (clobber (reg:CC FLAGS_REG))
20108    (clobber (mem:BLK (scratch)))]
20109   "TARGET_64BIT"
20111   switch (get_attr_type (insn))
20112     {
20113     case TYPE_IMOV:
20114       return "mov{q}\t{%1, %0|%0, %1}";
20116     case TYPE_ALU:
20117       if (CONST_INT_P (operands[2])
20118           /* Avoid overflows.  */
20119           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20120           && (INTVAL (operands[2]) == 128
20121               || (INTVAL (operands[2]) < 0
20122                   && INTVAL (operands[2]) != -128)))
20123         {
20124           operands[2] = GEN_INT (-INTVAL (operands[2]));
20125           return "sub{q}\t{%2, %0|%0, %2}";
20126         }
20127       return "add{q}\t{%2, %0|%0, %2}";
20129     case TYPE_LEA:
20130       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20131       return "lea{q}\t{%a2, %0|%0, %a2}";
20133     default:
20134       gcc_unreachable ();
20135     }
20137   [(set (attr "type")
20138         (cond [(eq_attr "alternative" "0")
20139                  (const_string "alu")
20140                (match_operand:DI 2 "const0_operand" "")
20141                  (const_string "imov")
20142               ]
20143               (const_string "lea")))
20144    (set_attr "mode" "DI")])
20146 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20147   [(set (match_operand:DI 0 "register_operand" "=r,r")
20148         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20149                  (match_operand:DI 3 "immediate_operand" "i,i")))
20150    (use (match_operand:DI 2 "register_operand" "r,r"))
20151    (clobber (reg:CC FLAGS_REG))
20152    (clobber (mem:BLK (scratch)))]
20153   "TARGET_64BIT"
20155   switch (get_attr_type (insn))
20156     {
20157     case TYPE_ALU:
20158       return "add{q}\t{%2, %0|%0, %2}";
20160     case TYPE_LEA:
20161       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20162       return "lea{q}\t{%a2, %0|%0, %a2}";
20164     default:
20165       gcc_unreachable ();
20166     }
20168   [(set_attr "type" "alu,lea")
20169    (set_attr "mode" "DI")])
20171 (define_insn "allocate_stack_worker_32"
20172   [(set (match_operand:SI 0 "register_operand" "=a")
20173         (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20174                             UNSPECV_STACK_PROBE))
20175    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20176    (clobber (reg:CC FLAGS_REG))]
20177   "!TARGET_64BIT && TARGET_STACK_PROBE"
20178   "call\t___chkstk"
20179   [(set_attr "type" "multi")
20180    (set_attr "length" "5")])
20182 (define_insn "allocate_stack_worker_64"
20183   [(set (match_operand:DI 0 "register_operand" "=a")
20184         (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20185                             UNSPECV_STACK_PROBE))
20186    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20187    (clobber (reg:DI R10_REG))
20188    (clobber (reg:DI R11_REG))
20189    (clobber (reg:CC FLAGS_REG))]
20190   "TARGET_64BIT && TARGET_STACK_PROBE"
20191   "call\t___chkstk"
20192   [(set_attr "type" "multi")
20193    (set_attr "length" "5")])
20195 (define_expand "allocate_stack"
20196   [(match_operand 0 "register_operand" "")
20197    (match_operand 1 "general_operand" "")]
20198   "TARGET_STACK_PROBE"
20200   rtx x;
20202 #ifndef CHECK_STACK_LIMIT
20203 #define CHECK_STACK_LIMIT 0
20204 #endif
20206   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20207       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20208     {
20209       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20210                                stack_pointer_rtx, 0, OPTAB_DIRECT);
20211       if (x != stack_pointer_rtx)
20212         emit_move_insn (stack_pointer_rtx, x);
20213     }
20214   else
20215     {
20216       x = copy_to_mode_reg (Pmode, operands[1]);
20217       if (TARGET_64BIT)
20218         x = gen_allocate_stack_worker_64 (x, x);
20219       else
20220         x = gen_allocate_stack_worker_32 (x, x);
20221       emit_insn (x);
20222     }
20224   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20225   DONE;
20228 (define_expand "builtin_setjmp_receiver"
20229   [(label_ref (match_operand 0 "" ""))]
20230   "!TARGET_64BIT && flag_pic"
20232 #if TARGET_MACHO
20233   if (TARGET_MACHO)
20234     {
20235       rtx xops[3];
20236       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20237       rtx label_rtx = gen_label_rtx ();
20238       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20239       xops[0] = xops[1] = picreg;
20240       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20241       ix86_expand_binary_operator (MINUS, SImode, xops);
20242     }
20243   else
20244 #endif
20245     emit_insn (gen_set_got (pic_offset_table_rtx));
20246   DONE;
20249 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20251 (define_split
20252   [(set (match_operand 0 "register_operand" "")
20253         (match_operator 3 "promotable_binary_operator"
20254            [(match_operand 1 "register_operand" "")
20255             (match_operand 2 "aligned_operand" "")]))
20256    (clobber (reg:CC FLAGS_REG))]
20257   "! TARGET_PARTIAL_REG_STALL && reload_completed
20258    && ((GET_MODE (operands[0]) == HImode
20259         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20260             /* ??? next two lines just !satisfies_constraint_K (...) */
20261             || !CONST_INT_P (operands[2])
20262             || satisfies_constraint_K (operands[2])))
20263        || (GET_MODE (operands[0]) == QImode
20264            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20265   [(parallel [(set (match_dup 0)
20266                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20267               (clobber (reg:CC FLAGS_REG))])]
20268   "operands[0] = gen_lowpart (SImode, operands[0]);
20269    operands[1] = gen_lowpart (SImode, operands[1]);
20270    if (GET_CODE (operands[3]) != ASHIFT)
20271      operands[2] = gen_lowpart (SImode, operands[2]);
20272    PUT_MODE (operands[3], SImode);")
20274 ; Promote the QImode tests, as i386 has encoding of the AND
20275 ; instruction with 32-bit sign-extended immediate and thus the
20276 ; instruction size is unchanged, except in the %eax case for
20277 ; which it is increased by one byte, hence the ! optimize_size.
20278 (define_split
20279   [(set (match_operand 0 "flags_reg_operand" "")
20280         (match_operator 2 "compare_operator"
20281           [(and (match_operand 3 "aligned_operand" "")
20282                 (match_operand 4 "const_int_operand" ""))
20283            (const_int 0)]))
20284    (set (match_operand 1 "register_operand" "")
20285         (and (match_dup 3) (match_dup 4)))]
20286   "! TARGET_PARTIAL_REG_STALL && reload_completed
20287    && optimize_insn_for_speed_p ()
20288    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20289        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20290    /* Ensure that the operand will remain sign-extended immediate.  */
20291    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20292   [(parallel [(set (match_dup 0)
20293                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20294                                     (const_int 0)]))
20295               (set (match_dup 1)
20296                    (and:SI (match_dup 3) (match_dup 4)))])]
20298   operands[4]
20299     = gen_int_mode (INTVAL (operands[4])
20300                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20301   operands[1] = gen_lowpart (SImode, operands[1]);
20302   operands[3] = gen_lowpart (SImode, operands[3]);
20305 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20306 ; the TEST instruction with 32-bit sign-extended immediate and thus
20307 ; the instruction size would at least double, which is not what we
20308 ; want even with ! optimize_size.
20309 (define_split
20310   [(set (match_operand 0 "flags_reg_operand" "")
20311         (match_operator 1 "compare_operator"
20312           [(and (match_operand:HI 2 "aligned_operand" "")
20313                 (match_operand:HI 3 "const_int_operand" ""))
20314            (const_int 0)]))]
20315   "! TARGET_PARTIAL_REG_STALL && reload_completed
20316    && ! TARGET_FAST_PREFIX
20317    && optimize_insn_for_speed_p ()
20318    /* Ensure that the operand will remain sign-extended immediate.  */
20319    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20320   [(set (match_dup 0)
20321         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20322                          (const_int 0)]))]
20324   operands[3]
20325     = gen_int_mode (INTVAL (operands[3])
20326                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20327   operands[2] = gen_lowpart (SImode, operands[2]);
20330 (define_split
20331   [(set (match_operand 0 "register_operand" "")
20332         (neg (match_operand 1 "register_operand" "")))
20333    (clobber (reg:CC FLAGS_REG))]
20334   "! TARGET_PARTIAL_REG_STALL && reload_completed
20335    && (GET_MODE (operands[0]) == HImode
20336        || (GET_MODE (operands[0]) == QImode
20337            && (TARGET_PROMOTE_QImode
20338                || optimize_insn_for_size_p ())))"
20339   [(parallel [(set (match_dup 0)
20340                    (neg:SI (match_dup 1)))
20341               (clobber (reg:CC FLAGS_REG))])]
20342   "operands[0] = gen_lowpart (SImode, operands[0]);
20343    operands[1] = gen_lowpart (SImode, operands[1]);")
20345 (define_split
20346   [(set (match_operand 0 "register_operand" "")
20347         (not (match_operand 1 "register_operand" "")))]
20348   "! TARGET_PARTIAL_REG_STALL && reload_completed
20349    && (GET_MODE (operands[0]) == HImode
20350        || (GET_MODE (operands[0]) == QImode
20351            && (TARGET_PROMOTE_QImode
20352                || optimize_insn_for_size_p ())))"
20353   [(set (match_dup 0)
20354         (not:SI (match_dup 1)))]
20355   "operands[0] = gen_lowpart (SImode, operands[0]);
20356    operands[1] = gen_lowpart (SImode, operands[1]);")
20358 (define_split
20359   [(set (match_operand 0 "register_operand" "")
20360         (if_then_else (match_operator 1 "comparison_operator"
20361                                 [(reg FLAGS_REG) (const_int 0)])
20362                       (match_operand 2 "register_operand" "")
20363                       (match_operand 3 "register_operand" "")))]
20364   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20365    && (GET_MODE (operands[0]) == HImode
20366        || (GET_MODE (operands[0]) == QImode
20367            && (TARGET_PROMOTE_QImode
20368                || optimize_insn_for_size_p ())))"
20369   [(set (match_dup 0)
20370         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20371   "operands[0] = gen_lowpart (SImode, operands[0]);
20372    operands[2] = gen_lowpart (SImode, operands[2]);
20373    operands[3] = gen_lowpart (SImode, operands[3]);")
20376 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20377 ;; transform a complex memory operation into two memory to register operations.
20379 ;; Don't push memory operands
20380 (define_peephole2
20381   [(set (match_operand:SI 0 "push_operand" "")
20382         (match_operand:SI 1 "memory_operand" ""))
20383    (match_scratch:SI 2 "r")]
20384   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20385    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20386   [(set (match_dup 2) (match_dup 1))
20387    (set (match_dup 0) (match_dup 2))]
20388   "")
20390 (define_peephole2
20391   [(set (match_operand:DI 0 "push_operand" "")
20392         (match_operand:DI 1 "memory_operand" ""))
20393    (match_scratch:DI 2 "r")]
20394   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20395    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20396   [(set (match_dup 2) (match_dup 1))
20397    (set (match_dup 0) (match_dup 2))]
20398   "")
20400 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20401 ;; SImode pushes.
20402 (define_peephole2
20403   [(set (match_operand:SF 0 "push_operand" "")
20404         (match_operand:SF 1 "memory_operand" ""))
20405    (match_scratch:SF 2 "r")]
20406   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20407    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20408   [(set (match_dup 2) (match_dup 1))
20409    (set (match_dup 0) (match_dup 2))]
20410   "")
20412 (define_peephole2
20413   [(set (match_operand:HI 0 "push_operand" "")
20414         (match_operand:HI 1 "memory_operand" ""))
20415    (match_scratch:HI 2 "r")]
20416   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20417    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20418   [(set (match_dup 2) (match_dup 1))
20419    (set (match_dup 0) (match_dup 2))]
20420   "")
20422 (define_peephole2
20423   [(set (match_operand:QI 0 "push_operand" "")
20424         (match_operand:QI 1 "memory_operand" ""))
20425    (match_scratch:QI 2 "q")]
20426   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20427    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20428   [(set (match_dup 2) (match_dup 1))
20429    (set (match_dup 0) (match_dup 2))]
20430   "")
20432 ;; Don't move an immediate directly to memory when the instruction
20433 ;; gets too big.
20434 (define_peephole2
20435   [(match_scratch:SI 1 "r")
20436    (set (match_operand:SI 0 "memory_operand" "")
20437         (const_int 0))]
20438   "optimize_insn_for_speed_p ()
20439    && ! TARGET_USE_MOV0
20440    && TARGET_SPLIT_LONG_MOVES
20441    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20442    && peep2_regno_dead_p (0, FLAGS_REG)"
20443   [(parallel [(set (match_dup 1) (const_int 0))
20444               (clobber (reg:CC FLAGS_REG))])
20445    (set (match_dup 0) (match_dup 1))]
20446   "")
20448 (define_peephole2
20449   [(match_scratch:HI 1 "r")
20450    (set (match_operand:HI 0 "memory_operand" "")
20451         (const_int 0))]
20452   "optimize_insn_for_speed_p ()
20453    && ! TARGET_USE_MOV0
20454    && TARGET_SPLIT_LONG_MOVES
20455    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20456    && peep2_regno_dead_p (0, FLAGS_REG)"
20457   [(parallel [(set (match_dup 2) (const_int 0))
20458               (clobber (reg:CC FLAGS_REG))])
20459    (set (match_dup 0) (match_dup 1))]
20460   "operands[2] = gen_lowpart (SImode, operands[1]);")
20462 (define_peephole2
20463   [(match_scratch:QI 1 "q")
20464    (set (match_operand:QI 0 "memory_operand" "")
20465         (const_int 0))]
20466   "optimize_insn_for_speed_p ()
20467    && ! TARGET_USE_MOV0
20468    && TARGET_SPLIT_LONG_MOVES
20469    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20470    && peep2_regno_dead_p (0, FLAGS_REG)"
20471   [(parallel [(set (match_dup 2) (const_int 0))
20472               (clobber (reg:CC FLAGS_REG))])
20473    (set (match_dup 0) (match_dup 1))]
20474   "operands[2] = gen_lowpart (SImode, operands[1]);")
20476 (define_peephole2
20477   [(match_scratch:SI 2 "r")
20478    (set (match_operand:SI 0 "memory_operand" "")
20479         (match_operand:SI 1 "immediate_operand" ""))]
20480   "optimize_insn_for_speed_p ()
20481    && TARGET_SPLIT_LONG_MOVES
20482    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20483   [(set (match_dup 2) (match_dup 1))
20484    (set (match_dup 0) (match_dup 2))]
20485   "")
20487 (define_peephole2
20488   [(match_scratch:HI 2 "r")
20489    (set (match_operand:HI 0 "memory_operand" "")
20490         (match_operand:HI 1 "immediate_operand" ""))]
20491   "optimize_insn_for_speed_p ()
20492    && TARGET_SPLIT_LONG_MOVES
20493    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20494   [(set (match_dup 2) (match_dup 1))
20495    (set (match_dup 0) (match_dup 2))]
20496   "")
20498 (define_peephole2
20499   [(match_scratch:QI 2 "q")
20500    (set (match_operand:QI 0 "memory_operand" "")
20501         (match_operand:QI 1 "immediate_operand" ""))]
20502   "optimize_insn_for_speed_p ()
20503    && TARGET_SPLIT_LONG_MOVES
20504    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20505   [(set (match_dup 2) (match_dup 1))
20506    (set (match_dup 0) (match_dup 2))]
20507   "")
20509 ;; Don't compare memory with zero, load and use a test instead.
20510 (define_peephole2
20511   [(set (match_operand 0 "flags_reg_operand" "")
20512         (match_operator 1 "compare_operator"
20513           [(match_operand:SI 2 "memory_operand" "")
20514            (const_int 0)]))
20515    (match_scratch:SI 3 "r")]
20516   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20517   [(set (match_dup 3) (match_dup 2))
20518    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20519   "")
20521 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20522 ;; Don't split NOTs with a displacement operand, because resulting XOR
20523 ;; will not be pairable anyway.
20525 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20526 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20527 ;; so this split helps here as well.
20529 ;; Note: Can't do this as a regular split because we can't get proper
20530 ;; lifetime information then.
20532 (define_peephole2
20533   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20534         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20535   "optimize_insn_for_speed_p ()
20536    && ((TARGET_NOT_UNPAIRABLE
20537         && (!MEM_P (operands[0])
20538             || !memory_displacement_operand (operands[0], SImode)))
20539        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20540    && peep2_regno_dead_p (0, FLAGS_REG)"
20541   [(parallel [(set (match_dup 0)
20542                    (xor:SI (match_dup 1) (const_int -1)))
20543               (clobber (reg:CC FLAGS_REG))])]
20544   "")
20546 (define_peephole2
20547   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20548         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20549   "optimize_insn_for_speed_p ()
20550    && ((TARGET_NOT_UNPAIRABLE
20551         && (!MEM_P (operands[0])
20552             || !memory_displacement_operand (operands[0], HImode)))
20553        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20554    && peep2_regno_dead_p (0, FLAGS_REG)"
20555   [(parallel [(set (match_dup 0)
20556                    (xor:HI (match_dup 1) (const_int -1)))
20557               (clobber (reg:CC FLAGS_REG))])]
20558   "")
20560 (define_peephole2
20561   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20562         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20563   "optimize_insn_for_speed_p ()
20564    && ((TARGET_NOT_UNPAIRABLE
20565         && (!MEM_P (operands[0])
20566             || !memory_displacement_operand (operands[0], QImode)))
20567        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20568    && peep2_regno_dead_p (0, FLAGS_REG)"
20569   [(parallel [(set (match_dup 0)
20570                    (xor:QI (match_dup 1) (const_int -1)))
20571               (clobber (reg:CC FLAGS_REG))])]
20572   "")
20574 ;; Non pairable "test imm, reg" instructions can be translated to
20575 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20576 ;; byte opcode instead of two, have a short form for byte operands),
20577 ;; so do it for other CPUs as well.  Given that the value was dead,
20578 ;; this should not create any new dependencies.  Pass on the sub-word
20579 ;; versions if we're concerned about partial register stalls.
20581 (define_peephole2
20582   [(set (match_operand 0 "flags_reg_operand" "")
20583         (match_operator 1 "compare_operator"
20584           [(and:SI (match_operand:SI 2 "register_operand" "")
20585                    (match_operand:SI 3 "immediate_operand" ""))
20586            (const_int 0)]))]
20587   "ix86_match_ccmode (insn, CCNOmode)
20588    && (true_regnum (operands[2]) != AX_REG
20589        || satisfies_constraint_K (operands[3]))
20590    && peep2_reg_dead_p (1, operands[2])"
20591   [(parallel
20592      [(set (match_dup 0)
20593            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20594                             (const_int 0)]))
20595       (set (match_dup 2)
20596            (and:SI (match_dup 2) (match_dup 3)))])]
20597   "")
20599 ;; We don't need to handle HImode case, because it will be promoted to SImode
20600 ;; on ! TARGET_PARTIAL_REG_STALL
20602 (define_peephole2
20603   [(set (match_operand 0 "flags_reg_operand" "")
20604         (match_operator 1 "compare_operator"
20605           [(and:QI (match_operand:QI 2 "register_operand" "")
20606                    (match_operand:QI 3 "immediate_operand" ""))
20607            (const_int 0)]))]
20608   "! TARGET_PARTIAL_REG_STALL
20609    && ix86_match_ccmode (insn, CCNOmode)
20610    && true_regnum (operands[2]) != AX_REG
20611    && peep2_reg_dead_p (1, operands[2])"
20612   [(parallel
20613      [(set (match_dup 0)
20614            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20615                             (const_int 0)]))
20616       (set (match_dup 2)
20617            (and:QI (match_dup 2) (match_dup 3)))])]
20618   "")
20620 (define_peephole2
20621   [(set (match_operand 0 "flags_reg_operand" "")
20622         (match_operator 1 "compare_operator"
20623           [(and:SI
20624              (zero_extract:SI
20625                (match_operand 2 "ext_register_operand" "")
20626                (const_int 8)
20627                (const_int 8))
20628              (match_operand 3 "const_int_operand" ""))
20629            (const_int 0)]))]
20630   "! TARGET_PARTIAL_REG_STALL
20631    && ix86_match_ccmode (insn, CCNOmode)
20632    && true_regnum (operands[2]) != AX_REG
20633    && peep2_reg_dead_p (1, operands[2])"
20634   [(parallel [(set (match_dup 0)
20635                    (match_op_dup 1
20636                      [(and:SI
20637                         (zero_extract:SI
20638                           (match_dup 2)
20639                           (const_int 8)
20640                           (const_int 8))
20641                         (match_dup 3))
20642                       (const_int 0)]))
20643               (set (zero_extract:SI (match_dup 2)
20644                                     (const_int 8)
20645                                     (const_int 8))
20646                    (and:SI
20647                      (zero_extract:SI
20648                        (match_dup 2)
20649                        (const_int 8)
20650                        (const_int 8))
20651                      (match_dup 3)))])]
20652   "")
20654 ;; Don't do logical operations with memory inputs.
20655 (define_peephole2
20656   [(match_scratch:SI 2 "r")
20657    (parallel [(set (match_operand:SI 0 "register_operand" "")
20658                    (match_operator:SI 3 "arith_or_logical_operator"
20659                      [(match_dup 0)
20660                       (match_operand:SI 1 "memory_operand" "")]))
20661               (clobber (reg:CC FLAGS_REG))])]
20662   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20663   [(set (match_dup 2) (match_dup 1))
20664    (parallel [(set (match_dup 0)
20665                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20666               (clobber (reg:CC FLAGS_REG))])]
20667   "")
20669 (define_peephole2
20670   [(match_scratch:SI 2 "r")
20671    (parallel [(set (match_operand:SI 0 "register_operand" "")
20672                    (match_operator:SI 3 "arith_or_logical_operator"
20673                      [(match_operand:SI 1 "memory_operand" "")
20674                       (match_dup 0)]))
20675               (clobber (reg:CC FLAGS_REG))])]
20676   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20677   [(set (match_dup 2) (match_dup 1))
20678    (parallel [(set (match_dup 0)
20679                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20680               (clobber (reg:CC FLAGS_REG))])]
20681   "")
20683 ; Don't do logical operations with memory outputs
20685 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20686 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20687 ; the same decoder scheduling characteristics as the original.
20689 (define_peephole2
20690   [(match_scratch:SI 2 "r")
20691    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20692                    (match_operator:SI 3 "arith_or_logical_operator"
20693                      [(match_dup 0)
20694                       (match_operand:SI 1 "nonmemory_operand" "")]))
20695               (clobber (reg:CC FLAGS_REG))])]
20696   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20697   [(set (match_dup 2) (match_dup 0))
20698    (parallel [(set (match_dup 2)
20699                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20700               (clobber (reg:CC FLAGS_REG))])
20701    (set (match_dup 0) (match_dup 2))]
20702   "")
20704 (define_peephole2
20705   [(match_scratch:SI 2 "r")
20706    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20707                    (match_operator:SI 3 "arith_or_logical_operator"
20708                      [(match_operand:SI 1 "nonmemory_operand" "")
20709                       (match_dup 0)]))
20710               (clobber (reg:CC FLAGS_REG))])]
20711   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20712   [(set (match_dup 2) (match_dup 0))
20713    (parallel [(set (match_dup 2)
20714                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20715               (clobber (reg:CC FLAGS_REG))])
20716    (set (match_dup 0) (match_dup 2))]
20717   "")
20719 ;; Attempt to always use XOR for zeroing registers.
20720 (define_peephole2
20721   [(set (match_operand 0 "register_operand" "")
20722         (match_operand 1 "const0_operand" ""))]
20723   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20724    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20725    && GENERAL_REG_P (operands[0])
20726    && peep2_regno_dead_p (0, FLAGS_REG)"
20727   [(parallel [(set (match_dup 0) (const_int 0))
20728               (clobber (reg:CC FLAGS_REG))])]
20730   operands[0] = gen_lowpart (word_mode, operands[0]);
20733 (define_peephole2
20734   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20735         (const_int 0))]
20736   "(GET_MODE (operands[0]) == QImode
20737     || GET_MODE (operands[0]) == HImode)
20738    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20739    && peep2_regno_dead_p (0, FLAGS_REG)"
20740   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20741               (clobber (reg:CC FLAGS_REG))])])
20743 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20744 (define_peephole2
20745   [(set (match_operand 0 "register_operand" "")
20746         (const_int -1))]
20747   "(GET_MODE (operands[0]) == HImode
20748     || GET_MODE (operands[0]) == SImode
20749     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20750    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20751    && peep2_regno_dead_p (0, FLAGS_REG)"
20752   [(parallel [(set (match_dup 0) (const_int -1))
20753               (clobber (reg:CC FLAGS_REG))])]
20754   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20755                               operands[0]);")
20757 ;; Attempt to convert simple leas to adds. These can be created by
20758 ;; move expanders.
20759 (define_peephole2
20760   [(set (match_operand:SI 0 "register_operand" "")
20761         (plus:SI (match_dup 0)
20762                  (match_operand:SI 1 "nonmemory_operand" "")))]
20763   "peep2_regno_dead_p (0, FLAGS_REG)"
20764   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20765               (clobber (reg:CC FLAGS_REG))])]
20766   "")
20768 (define_peephole2
20769   [(set (match_operand:SI 0 "register_operand" "")
20770         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20771                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20772   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20773   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20774               (clobber (reg:CC FLAGS_REG))])]
20775   "operands[2] = gen_lowpart (SImode, operands[2]);")
20777 (define_peephole2
20778   [(set (match_operand:DI 0 "register_operand" "")
20779         (plus:DI (match_dup 0)
20780                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20781   "peep2_regno_dead_p (0, FLAGS_REG)"
20782   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20783               (clobber (reg:CC FLAGS_REG))])]
20784   "")
20786 (define_peephole2
20787   [(set (match_operand:SI 0 "register_operand" "")
20788         (mult:SI (match_dup 0)
20789                  (match_operand:SI 1 "const_int_operand" "")))]
20790   "exact_log2 (INTVAL (operands[1])) >= 0
20791    && peep2_regno_dead_p (0, FLAGS_REG)"
20792   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20793               (clobber (reg:CC FLAGS_REG))])]
20794   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20796 (define_peephole2
20797   [(set (match_operand:DI 0 "register_operand" "")
20798         (mult:DI (match_dup 0)
20799                  (match_operand:DI 1 "const_int_operand" "")))]
20800   "exact_log2 (INTVAL (operands[1])) >= 0
20801    && peep2_regno_dead_p (0, FLAGS_REG)"
20802   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20803               (clobber (reg:CC FLAGS_REG))])]
20804   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20806 (define_peephole2
20807   [(set (match_operand:SI 0 "register_operand" "")
20808         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20809                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20810   "exact_log2 (INTVAL (operands[2])) >= 0
20811    && REGNO (operands[0]) == REGNO (operands[1])
20812    && peep2_regno_dead_p (0, FLAGS_REG)"
20813   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20814               (clobber (reg:CC FLAGS_REG))])]
20815   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20817 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20818 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20819 ;; many CPUs it is also faster, since special hardware to avoid esp
20820 ;; dependencies is present.
20822 ;; While some of these conversions may be done using splitters, we use peepholes
20823 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20825 ;; Convert prologue esp subtractions to push.
20826 ;; We need register to push.  In order to keep verify_flow_info happy we have
20827 ;; two choices
20828 ;; - use scratch and clobber it in order to avoid dependencies
20829 ;; - use already live register
20830 ;; We can't use the second way right now, since there is no reliable way how to
20831 ;; verify that given register is live.  First choice will also most likely in
20832 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20833 ;; call clobbered registers are dead.  We may want to use base pointer as an
20834 ;; alternative when no register is available later.
20836 (define_peephole2
20837   [(match_scratch:SI 0 "r")
20838    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20839               (clobber (reg:CC FLAGS_REG))
20840               (clobber (mem:BLK (scratch)))])]
20841   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20842   [(clobber (match_dup 0))
20843    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20844               (clobber (mem:BLK (scratch)))])])
20846 (define_peephole2
20847   [(match_scratch:SI 0 "r")
20848    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20849               (clobber (reg:CC FLAGS_REG))
20850               (clobber (mem:BLK (scratch)))])]
20851   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20852   [(clobber (match_dup 0))
20853    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20854    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20855               (clobber (mem:BLK (scratch)))])])
20857 ;; Convert esp subtractions to push.
20858 (define_peephole2
20859   [(match_scratch:SI 0 "r")
20860    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20861               (clobber (reg:CC FLAGS_REG))])]
20862   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20863   [(clobber (match_dup 0))
20864    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20866 (define_peephole2
20867   [(match_scratch:SI 0 "r")
20868    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20869               (clobber (reg:CC FLAGS_REG))])]
20870   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20871   [(clobber (match_dup 0))
20872    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20873    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20875 ;; Convert epilogue deallocator to pop.
20876 (define_peephole2
20877   [(match_scratch:SI 0 "r")
20878    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20879               (clobber (reg:CC FLAGS_REG))
20880               (clobber (mem:BLK (scratch)))])]
20881   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20882   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20883               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20884               (clobber (mem:BLK (scratch)))])]
20885   "")
20887 ;; Two pops case is tricky, since pop causes dependency on destination register.
20888 ;; We use two registers if available.
20889 (define_peephole2
20890   [(match_scratch:SI 0 "r")
20891    (match_scratch:SI 1 "r")
20892    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20893               (clobber (reg:CC FLAGS_REG))
20894               (clobber (mem:BLK (scratch)))])]
20895   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20896   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20897               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20898               (clobber (mem:BLK (scratch)))])
20899    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20900               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20901   "")
20903 (define_peephole2
20904   [(match_scratch:SI 0 "r")
20905    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20906               (clobber (reg:CC FLAGS_REG))
20907               (clobber (mem:BLK (scratch)))])]
20908   "optimize_insn_for_size_p ()"
20909   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20910               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20911               (clobber (mem:BLK (scratch)))])
20912    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20913               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20914   "")
20916 ;; Convert esp additions to pop.
20917 (define_peephole2
20918   [(match_scratch:SI 0 "r")
20919    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20920               (clobber (reg:CC FLAGS_REG))])]
20921   ""
20922   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20923               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20924   "")
20926 ;; Two pops case is tricky, since pop causes dependency on destination register.
20927 ;; We use two registers if available.
20928 (define_peephole2
20929   [(match_scratch:SI 0 "r")
20930    (match_scratch:SI 1 "r")
20931    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20932               (clobber (reg:CC FLAGS_REG))])]
20933   ""
20934   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20935               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20936    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20937               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20938   "")
20940 (define_peephole2
20941   [(match_scratch:SI 0 "r")
20942    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20943               (clobber (reg:CC FLAGS_REG))])]
20944   "optimize_insn_for_size_p ()"
20945   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20946               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20947    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20948               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20949   "")
20951 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20952 ;; required and register dies.  Similarly for 128 to -128.
20953 (define_peephole2
20954   [(set (match_operand 0 "flags_reg_operand" "")
20955         (match_operator 1 "compare_operator"
20956           [(match_operand 2 "register_operand" "")
20957            (match_operand 3 "const_int_operand" "")]))]
20958   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
20959      && incdec_operand (operands[3], GET_MODE (operands[3])))
20960     || (!TARGET_FUSE_CMP_AND_BRANCH
20961         && INTVAL (operands[3]) == 128))
20962    && ix86_match_ccmode (insn, CCGCmode)
20963    && peep2_reg_dead_p (1, operands[2])"
20964   [(parallel [(set (match_dup 0)
20965                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20966               (clobber (match_dup 2))])]
20967   "")
20969 (define_peephole2
20970   [(match_scratch:DI 0 "r")
20971    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20972               (clobber (reg:CC FLAGS_REG))
20973               (clobber (mem:BLK (scratch)))])]
20974   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20975   [(clobber (match_dup 0))
20976    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20977               (clobber (mem:BLK (scratch)))])])
20979 (define_peephole2
20980   [(match_scratch:DI 0 "r")
20981    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20982               (clobber (reg:CC FLAGS_REG))
20983               (clobber (mem:BLK (scratch)))])]
20984   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20985   [(clobber (match_dup 0))
20986    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20987    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20988               (clobber (mem:BLK (scratch)))])])
20990 ;; Convert esp subtractions to push.
20991 (define_peephole2
20992   [(match_scratch:DI 0 "r")
20993    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20994               (clobber (reg:CC FLAGS_REG))])]
20995   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20996   [(clobber (match_dup 0))
20997    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20999 (define_peephole2
21000   [(match_scratch:DI 0 "r")
21001    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21002               (clobber (reg:CC FLAGS_REG))])]
21003   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21004   [(clobber (match_dup 0))
21005    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21006    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21008 ;; Convert epilogue deallocator to pop.
21009 (define_peephole2
21010   [(match_scratch:DI 0 "r")
21011    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21012               (clobber (reg:CC FLAGS_REG))
21013               (clobber (mem:BLK (scratch)))])]
21014   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21015   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21016               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21017               (clobber (mem:BLK (scratch)))])]
21018   "")
21020 ;; Two pops case is tricky, since pop causes dependency on destination register.
21021 ;; We use two registers if available.
21022 (define_peephole2
21023   [(match_scratch:DI 0 "r")
21024    (match_scratch:DI 1 "r")
21025    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21026               (clobber (reg:CC FLAGS_REG))
21027               (clobber (mem:BLK (scratch)))])]
21028   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21029   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21030               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21031               (clobber (mem:BLK (scratch)))])
21032    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21033               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21034   "")
21036 (define_peephole2
21037   [(match_scratch:DI 0 "r")
21038    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21039               (clobber (reg:CC FLAGS_REG))
21040               (clobber (mem:BLK (scratch)))])]
21041   "optimize_insn_for_size_p ()"
21042   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21043               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21044               (clobber (mem:BLK (scratch)))])
21045    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21046               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21047   "")
21049 ;; Convert esp additions to pop.
21050 (define_peephole2
21051   [(match_scratch:DI 0 "r")
21052    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21053               (clobber (reg:CC FLAGS_REG))])]
21054   ""
21055   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21056               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21057   "")
21059 ;; Two pops case is tricky, since pop causes dependency on destination register.
21060 ;; We use two registers if available.
21061 (define_peephole2
21062   [(match_scratch:DI 0 "r")
21063    (match_scratch:DI 1 "r")
21064    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21065               (clobber (reg:CC FLAGS_REG))])]
21066   ""
21067   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21068               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21069    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21070               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21071   "")
21073 (define_peephole2
21074   [(match_scratch:DI 0 "r")
21075    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21076               (clobber (reg:CC FLAGS_REG))])]
21077   "optimize_insn_for_size_p ()"
21078   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21079               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21080    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21081               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21082   "")
21084 ;; Convert imul by three, five and nine into lea
21085 (define_peephole2
21086   [(parallel
21087     [(set (match_operand:SI 0 "register_operand" "")
21088           (mult:SI (match_operand:SI 1 "register_operand" "")
21089                    (match_operand:SI 2 "const_int_operand" "")))
21090      (clobber (reg:CC FLAGS_REG))])]
21091   "INTVAL (operands[2]) == 3
21092    || INTVAL (operands[2]) == 5
21093    || INTVAL (operands[2]) == 9"
21094   [(set (match_dup 0)
21095         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21096                  (match_dup 1)))]
21097   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21099 (define_peephole2
21100   [(parallel
21101     [(set (match_operand:SI 0 "register_operand" "")
21102           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21103                    (match_operand:SI 2 "const_int_operand" "")))
21104      (clobber (reg:CC FLAGS_REG))])]
21105   "optimize_insn_for_speed_p ()
21106    && (INTVAL (operands[2]) == 3
21107        || INTVAL (operands[2]) == 5
21108        || INTVAL (operands[2]) == 9)"
21109   [(set (match_dup 0) (match_dup 1))
21110    (set (match_dup 0)
21111         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21112                  (match_dup 0)))]
21113   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21115 (define_peephole2
21116   [(parallel
21117     [(set (match_operand:DI 0 "register_operand" "")
21118           (mult:DI (match_operand:DI 1 "register_operand" "")
21119                    (match_operand:DI 2 "const_int_operand" "")))
21120      (clobber (reg:CC FLAGS_REG))])]
21121   "TARGET_64BIT
21122    && (INTVAL (operands[2]) == 3
21123        || INTVAL (operands[2]) == 5
21124        || INTVAL (operands[2]) == 9)"
21125   [(set (match_dup 0)
21126         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21127                  (match_dup 1)))]
21128   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21130 (define_peephole2
21131   [(parallel
21132     [(set (match_operand:DI 0 "register_operand" "")
21133           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21134                    (match_operand:DI 2 "const_int_operand" "")))
21135      (clobber (reg:CC FLAGS_REG))])]
21136   "TARGET_64BIT
21137    && optimize_insn_for_speed_p ()
21138    && (INTVAL (operands[2]) == 3
21139        || INTVAL (operands[2]) == 5
21140        || INTVAL (operands[2]) == 9)"
21141   [(set (match_dup 0) (match_dup 1))
21142    (set (match_dup 0)
21143         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21144                  (match_dup 0)))]
21145   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21147 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21148 ;; imul $32bit_imm, reg, reg is direct decoded.
21149 (define_peephole2
21150   [(match_scratch:DI 3 "r")
21151    (parallel [(set (match_operand:DI 0 "register_operand" "")
21152                    (mult:DI (match_operand:DI 1 "memory_operand" "")
21153                             (match_operand:DI 2 "immediate_operand" "")))
21154               (clobber (reg:CC FLAGS_REG))])]
21155   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21156    && !satisfies_constraint_K (operands[2])"
21157   [(set (match_dup 3) (match_dup 1))
21158    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21159               (clobber (reg:CC FLAGS_REG))])]
21162 (define_peephole2
21163   [(match_scratch:SI 3 "r")
21164    (parallel [(set (match_operand:SI 0 "register_operand" "")
21165                    (mult:SI (match_operand:SI 1 "memory_operand" "")
21166                             (match_operand:SI 2 "immediate_operand" "")))
21167               (clobber (reg:CC FLAGS_REG))])]
21168   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21169    && !satisfies_constraint_K (operands[2])"
21170   [(set (match_dup 3) (match_dup 1))
21171    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21172               (clobber (reg:CC FLAGS_REG))])]
21175 (define_peephole2
21176   [(match_scratch:SI 3 "r")
21177    (parallel [(set (match_operand:DI 0 "register_operand" "")
21178                    (zero_extend:DI
21179                      (mult:SI (match_operand:SI 1 "memory_operand" "")
21180                               (match_operand:SI 2 "immediate_operand" ""))))
21181               (clobber (reg:CC FLAGS_REG))])]
21182   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21183    && !satisfies_constraint_K (operands[2])"
21184   [(set (match_dup 3) (match_dup 1))
21185    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21186               (clobber (reg:CC FLAGS_REG))])]
21189 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21190 ;; Convert it into imul reg, reg
21191 ;; It would be better to force assembler to encode instruction using long
21192 ;; immediate, but there is apparently no way to do so.
21193 (define_peephole2
21194   [(parallel [(set (match_operand:DI 0 "register_operand" "")
21195                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21196                             (match_operand:DI 2 "const_int_operand" "")))
21197               (clobber (reg:CC FLAGS_REG))])
21198    (match_scratch:DI 3 "r")]
21199   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21200    && satisfies_constraint_K (operands[2])"
21201   [(set (match_dup 3) (match_dup 2))
21202    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21203               (clobber (reg:CC FLAGS_REG))])]
21205   if (!rtx_equal_p (operands[0], operands[1]))
21206     emit_move_insn (operands[0], operands[1]);
21209 (define_peephole2
21210   [(parallel [(set (match_operand:SI 0 "register_operand" "")
21211                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21212                             (match_operand:SI 2 "const_int_operand" "")))
21213               (clobber (reg:CC FLAGS_REG))])
21214    (match_scratch:SI 3 "r")]
21215   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21216    && satisfies_constraint_K (operands[2])"
21217   [(set (match_dup 3) (match_dup 2))
21218    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21219               (clobber (reg:CC FLAGS_REG))])]
21221   if (!rtx_equal_p (operands[0], operands[1]))
21222     emit_move_insn (operands[0], operands[1]);
21225 (define_peephole2
21226   [(parallel [(set (match_operand:HI 0 "register_operand" "")
21227                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21228                             (match_operand:HI 2 "immediate_operand" "")))
21229               (clobber (reg:CC FLAGS_REG))])
21230    (match_scratch:HI 3 "r")]
21231   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21232   [(set (match_dup 3) (match_dup 2))
21233    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21234               (clobber (reg:CC FLAGS_REG))])]
21236   if (!rtx_equal_p (operands[0], operands[1]))
21237     emit_move_insn (operands[0], operands[1]);
21240 ;; After splitting up read-modify operations, array accesses with memory
21241 ;; operands might end up in form:
21242 ;;  sall    $2, %eax
21243 ;;  movl    4(%esp), %edx
21244 ;;  addl    %edx, %eax
21245 ;; instead of pre-splitting:
21246 ;;  sall    $2, %eax
21247 ;;  addl    4(%esp), %eax
21248 ;; Turn it into:
21249 ;;  movl    4(%esp), %edx
21250 ;;  leal    (%edx,%eax,4), %eax
21252 (define_peephole2
21253   [(parallel [(set (match_operand 0 "register_operand" "")
21254                    (ashift (match_operand 1 "register_operand" "")
21255                            (match_operand 2 "const_int_operand" "")))
21256                (clobber (reg:CC FLAGS_REG))])
21257    (set (match_operand 3 "register_operand")
21258         (match_operand 4 "x86_64_general_operand" ""))
21259    (parallel [(set (match_operand 5 "register_operand" "")
21260                    (plus (match_operand 6 "register_operand" "")
21261                          (match_operand 7 "register_operand" "")))
21262                    (clobber (reg:CC FLAGS_REG))])]
21263   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21264    /* Validate MODE for lea.  */
21265    && ((!TARGET_PARTIAL_REG_STALL
21266         && (GET_MODE (operands[0]) == QImode
21267             || GET_MODE (operands[0]) == HImode))
21268        || GET_MODE (operands[0]) == SImode
21269        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21270    /* We reorder load and the shift.  */
21271    && !rtx_equal_p (operands[1], operands[3])
21272    && !reg_overlap_mentioned_p (operands[0], operands[4])
21273    /* Last PLUS must consist of operand 0 and 3.  */
21274    && !rtx_equal_p (operands[0], operands[3])
21275    && (rtx_equal_p (operands[3], operands[6])
21276        || rtx_equal_p (operands[3], operands[7]))
21277    && (rtx_equal_p (operands[0], operands[6])
21278        || rtx_equal_p (operands[0], operands[7]))
21279    /* The intermediate operand 0 must die or be same as output.  */
21280    && (rtx_equal_p (operands[0], operands[5])
21281        || peep2_reg_dead_p (3, operands[0]))"
21282   [(set (match_dup 3) (match_dup 4))
21283    (set (match_dup 0) (match_dup 1))]
21285   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21286   int scale = 1 << INTVAL (operands[2]);
21287   rtx index = gen_lowpart (Pmode, operands[1]);
21288   rtx base = gen_lowpart (Pmode, operands[3]);
21289   rtx dest = gen_lowpart (mode, operands[5]);
21291   operands[1] = gen_rtx_PLUS (Pmode, base,
21292                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21293   if (mode != Pmode)
21294     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21295   operands[0] = dest;
21298 ;; Call-value patterns last so that the wildcard operand does not
21299 ;; disrupt insn-recog's switch tables.
21301 (define_insn "*call_value_pop_0"
21302   [(set (match_operand 0 "" "")
21303         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21304               (match_operand:SI 2 "" "")))
21305    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21306                             (match_operand:SI 3 "immediate_operand" "")))]
21307   "!TARGET_64BIT"
21309   if (SIBLING_CALL_P (insn))
21310     return "jmp\t%P1";
21311   else
21312     return "call\t%P1";
21314   [(set_attr "type" "callv")])
21316 (define_insn "*call_value_pop_1"
21317   [(set (match_operand 0 "" "")
21318         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21319               (match_operand:SI 2 "" "")))
21320    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21321                             (match_operand:SI 3 "immediate_operand" "i")))]
21322   "!TARGET_64BIT"
21324   if (constant_call_address_operand (operands[1], Pmode))
21325     {
21326       if (SIBLING_CALL_P (insn))
21327         return "jmp\t%P1";
21328       else
21329         return "call\t%P1";
21330     }
21331   if (SIBLING_CALL_P (insn))
21332     return "jmp\t%A1";
21333   else
21334     return "call\t%A1";
21336   [(set_attr "type" "callv")])
21338 (define_insn "*call_value_0"
21339   [(set (match_operand 0 "" "")
21340         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21341               (match_operand:SI 2 "" "")))]
21342   "!TARGET_64BIT"
21344   if (SIBLING_CALL_P (insn))
21345     return "jmp\t%P1";
21346   else
21347     return "call\t%P1";
21349   [(set_attr "type" "callv")])
21351 (define_insn "*call_value_0_rex64"
21352   [(set (match_operand 0 "" "")
21353         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21354               (match_operand:DI 2 "const_int_operand" "")))]
21355   "TARGET_64BIT"
21357   if (SIBLING_CALL_P (insn))
21358     return "jmp\t%P1";
21359   else
21360     return "call\t%P1";
21362   [(set_attr "type" "callv")])
21364 (define_insn "*call_value_1"
21365   [(set (match_operand 0 "" "")
21366         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21367               (match_operand:SI 2 "" "")))]
21368   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
21370   if (constant_call_address_operand (operands[1], Pmode))
21371     return "call\t%P1";
21372   return "call\t%A1";
21374   [(set_attr "type" "callv")])
21376 (define_insn "*sibcall_value_1"
21377   [(set (match_operand 0 "" "")
21378         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21379               (match_operand:SI 2 "" "")))]
21380   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21382   if (constant_call_address_operand (operands[1], Pmode))
21383     return "jmp\t%P1";
21384   return "jmp\t%A1";
21386   [(set_attr "type" "callv")])
21388 (define_insn "*call_value_1_rex64"
21389   [(set (match_operand 0 "" "")
21390         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21391               (match_operand:DI 2 "" "")))]
21392   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21393    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21395   if (constant_call_address_operand (operands[1], Pmode))
21396     return "call\t%P1";
21397   return "call\t%A1";
21399   [(set_attr "type" "callv")])
21401 (define_insn "*call_value_1_rex64_large"
21402   [(set (match_operand 0 "" "")
21403         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21404               (match_operand:DI 2 "" "")))]
21405   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21406   "call\t%A1"
21407   [(set_attr "type" "callv")])
21409 (define_insn "*sibcall_value_1_rex64"
21410   [(set (match_operand 0 "" "")
21411         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21412               (match_operand:DI 2 "" "")))]
21413   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21414   "jmp\t%P1"
21415   [(set_attr "type" "callv")])
21417 (define_insn "*sibcall_value_1_rex64_v"
21418   [(set (match_operand 0 "" "")
21419         (call (mem:QI (reg:DI R11_REG))
21420               (match_operand:DI 1 "" "")))]
21421   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21422   "jmp\t{*%%}r11"
21423   [(set_attr "type" "callv")])
21425 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21426 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21427 ;; caught for use by garbage collectors and the like.  Using an insn that
21428 ;; maps to SIGILL makes it more likely the program will rightfully die.
21429 ;; Keeping with tradition, "6" is in honor of #UD.
21430 (define_insn "trap"
21431   [(trap_if (const_int 1) (const_int 6))]
21432   ""
21433   { return ASM_SHORT "0x0b0f"; }
21434   [(set_attr "length" "2")])
21436 (define_expand "sse_prologue_save"
21437   [(parallel [(set (match_operand:BLK 0 "" "")
21438                    (unspec:BLK [(reg:DI 21)
21439                                 (reg:DI 22)
21440                                 (reg:DI 23)
21441                                 (reg:DI 24)
21442                                 (reg:DI 25)
21443                                 (reg:DI 26)
21444                                 (reg:DI 27)
21445                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21446               (use (match_operand:DI 1 "register_operand" ""))
21447               (use (match_operand:DI 2 "immediate_operand" ""))
21448               (use (label_ref:DI (match_operand 3 "" "")))])]
21449   "TARGET_64BIT"
21450   "")
21452 (define_insn "*sse_prologue_save_insn"
21453   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21454                           (match_operand:DI 4 "const_int_operand" "n")))
21455         (unspec:BLK [(reg:DI 21)
21456                      (reg:DI 22)
21457                      (reg:DI 23)
21458                      (reg:DI 24)
21459                      (reg:DI 25)
21460                      (reg:DI 26)
21461                      (reg:DI 27)
21462                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21463    (use (match_operand:DI 1 "register_operand" "r"))
21464    (use (match_operand:DI 2 "const_int_operand" "i"))
21465    (use (label_ref:DI (match_operand 3 "" "X")))]
21466   "TARGET_64BIT
21467    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21468    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21470   int i;
21471   operands[0] = gen_rtx_MEM (Pmode,
21472                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21473   /* VEX instruction with a REX prefix will #UD.  */
21474   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21475     gcc_unreachable ();
21477   output_asm_insn ("jmp\t%A1", operands);
21478   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21479     {
21480       operands[4] = adjust_address (operands[0], DImode, i*16);
21481       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21482       PUT_MODE (operands[4], TImode);
21483       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21484         output_asm_insn ("rex", operands);
21485       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21486     }
21487   (*targetm.asm_out.internal_label) (asm_out_file, "L",
21488                                      CODE_LABEL_NUMBER (operands[3]));
21489   return "";
21491   [(set_attr "type" "other")
21492    (set_attr "length_immediate" "0")
21493    (set_attr "length_address" "0")
21494    (set (attr "length")
21495      (if_then_else
21496        (eq (symbol_ref "TARGET_AVX") (const_int 0))
21497        (const_string "34")
21498        (const_string "42")))
21499    (set_attr "memory" "store")
21500    (set_attr "modrm" "0")
21501    (set_attr "prefix" "maybe_vex")
21502    (set_attr "mode" "DI")])
21504 (define_expand "prefetch"
21505   [(prefetch (match_operand 0 "address_operand" "")
21506              (match_operand:SI 1 "const_int_operand" "")
21507              (match_operand:SI 2 "const_int_operand" ""))]
21508   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21510   int rw = INTVAL (operands[1]);
21511   int locality = INTVAL (operands[2]);
21513   gcc_assert (rw == 0 || rw == 1);
21514   gcc_assert (locality >= 0 && locality <= 3);
21515   gcc_assert (GET_MODE (operands[0]) == Pmode
21516               || GET_MODE (operands[0]) == VOIDmode);
21518   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21519      supported by SSE counterpart or the SSE prefetch is not available
21520      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21521      of locality.  */
21522   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21523     operands[2] = GEN_INT (3);
21524   else
21525     operands[1] = const0_rtx;
21528 (define_insn "*prefetch_sse"
21529   [(prefetch (match_operand:SI 0 "address_operand" "p")
21530              (const_int 0)
21531              (match_operand:SI 1 "const_int_operand" ""))]
21532   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21534   static const char * const patterns[4] = {
21535    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21536   };
21538   int locality = INTVAL (operands[1]);
21539   gcc_assert (locality >= 0 && locality <= 3);
21541   return patterns[locality];
21543   [(set_attr "type" "sse")
21544    (set_attr "memory" "none")])
21546 (define_insn "*prefetch_sse_rex"
21547   [(prefetch (match_operand:DI 0 "address_operand" "p")
21548              (const_int 0)
21549              (match_operand:SI 1 "const_int_operand" ""))]
21550   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21552   static const char * const patterns[4] = {
21553    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21554   };
21556   int locality = INTVAL (operands[1]);
21557   gcc_assert (locality >= 0 && locality <= 3);
21559   return patterns[locality];
21561   [(set_attr "type" "sse")
21562    (set_attr "memory" "none")])
21564 (define_insn "*prefetch_3dnow"
21565   [(prefetch (match_operand:SI 0 "address_operand" "p")
21566              (match_operand:SI 1 "const_int_operand" "n")
21567              (const_int 3))]
21568   "TARGET_3DNOW && !TARGET_64BIT"
21570   if (INTVAL (operands[1]) == 0)
21571     return "prefetch\t%a0";
21572   else
21573     return "prefetchw\t%a0";
21575   [(set_attr "type" "mmx")
21576    (set_attr "memory" "none")])
21578 (define_insn "*prefetch_3dnow_rex"
21579   [(prefetch (match_operand:DI 0 "address_operand" "p")
21580              (match_operand:SI 1 "const_int_operand" "n")
21581              (const_int 3))]
21582   "TARGET_3DNOW && TARGET_64BIT"
21584   if (INTVAL (operands[1]) == 0)
21585     return "prefetch\t%a0";
21586   else
21587     return "prefetchw\t%a0";
21589   [(set_attr "type" "mmx")
21590    (set_attr "memory" "none")])
21592 (define_expand "stack_protect_set"
21593   [(match_operand 0 "memory_operand" "")
21594    (match_operand 1 "memory_operand" "")]
21595   ""
21597 #ifdef TARGET_THREAD_SSP_OFFSET
21598   if (TARGET_64BIT)
21599     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21600                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21601   else
21602     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21603                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21604 #else
21605   if (TARGET_64BIT)
21606     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21607   else
21608     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21609 #endif
21610   DONE;
21613 (define_insn "stack_protect_set_si"
21614   [(set (match_operand:SI 0 "memory_operand" "=m")
21615         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21616    (set (match_scratch:SI 2 "=&r") (const_int 0))
21617    (clobber (reg:CC FLAGS_REG))]
21618   ""
21619   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21620   [(set_attr "type" "multi")])
21622 (define_insn "stack_protect_set_di"
21623   [(set (match_operand:DI 0 "memory_operand" "=m")
21624         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21625    (set (match_scratch:DI 2 "=&r") (const_int 0))
21626    (clobber (reg:CC FLAGS_REG))]
21627   "TARGET_64BIT"
21628   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21629   [(set_attr "type" "multi")])
21631 (define_insn "stack_tls_protect_set_si"
21632   [(set (match_operand:SI 0 "memory_operand" "=m")
21633         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21634    (set (match_scratch:SI 2 "=&r") (const_int 0))
21635    (clobber (reg:CC FLAGS_REG))]
21636   ""
21637   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21638   [(set_attr "type" "multi")])
21640 (define_insn "stack_tls_protect_set_di"
21641   [(set (match_operand:DI 0 "memory_operand" "=m")
21642         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21643    (set (match_scratch:DI 2 "=&r") (const_int 0))
21644    (clobber (reg:CC FLAGS_REG))]
21645   "TARGET_64BIT"
21646   {
21647      /* The kernel uses a different segment register for performance reasons; a
21648         system call would not have to trash the userspace segment register,
21649         which would be expensive */
21650      if (ix86_cmodel != CM_KERNEL)
21651         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21652      else
21653         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21654   }
21655   [(set_attr "type" "multi")])
21657 (define_expand "stack_protect_test"
21658   [(match_operand 0 "memory_operand" "")
21659    (match_operand 1 "memory_operand" "")
21660    (match_operand 2 "" "")]
21661   ""
21663   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21664   ix86_compare_op0 = operands[0];
21665   ix86_compare_op1 = operands[1];
21666   ix86_compare_emitted = flags;
21668 #ifdef TARGET_THREAD_SSP_OFFSET
21669   if (TARGET_64BIT)
21670     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21671                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21672   else
21673     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21674                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21675 #else
21676   if (TARGET_64BIT)
21677     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21678   else
21679     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21680 #endif
21681   emit_jump_insn (gen_beq (operands[2]));
21682   DONE;
21685 (define_insn "stack_protect_test_si"
21686   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21687         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21688                      (match_operand:SI 2 "memory_operand" "m")]
21689                     UNSPEC_SP_TEST))
21690    (clobber (match_scratch:SI 3 "=&r"))]
21691   ""
21692   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21693   [(set_attr "type" "multi")])
21695 (define_insn "stack_protect_test_di"
21696   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21697         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21698                      (match_operand:DI 2 "memory_operand" "m")]
21699                     UNSPEC_SP_TEST))
21700    (clobber (match_scratch:DI 3 "=&r"))]
21701   "TARGET_64BIT"
21702   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21703   [(set_attr "type" "multi")])
21705 (define_insn "stack_tls_protect_test_si"
21706   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21707         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21708                      (match_operand:SI 2 "const_int_operand" "i")]
21709                     UNSPEC_SP_TLS_TEST))
21710    (clobber (match_scratch:SI 3 "=r"))]
21711   ""
21712   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21713   [(set_attr "type" "multi")])
21715 (define_insn "stack_tls_protect_test_di"
21716   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21717         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21718                      (match_operand:DI 2 "const_int_operand" "i")]
21719                     UNSPEC_SP_TLS_TEST))
21720    (clobber (match_scratch:DI 3 "=r"))]
21721   "TARGET_64BIT"
21722   {
21723      /* The kernel uses a different segment register for performance reasons; a
21724         system call would not have to trash the userspace segment register,
21725         which would be expensive */
21726      if (ix86_cmodel != CM_KERNEL)
21727         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21728      else
21729         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21730   }
21731   [(set_attr "type" "multi")])
21733 (define_mode_iterator CRC32MODE [QI HI SI])
21734 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21735 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21737 (define_insn "sse4_2_crc32<mode>"
21738   [(set (match_operand:SI 0 "register_operand" "=r")
21739         (unspec:SI
21740           [(match_operand:SI 1 "register_operand" "0")
21741            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21742           UNSPEC_CRC32))]
21743   "TARGET_SSE4_2"
21744   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21745   [(set_attr "type" "sselog1")
21746    (set_attr "prefix_rep" "1")
21747    (set_attr "prefix_extra" "1")
21748    (set_attr "mode" "SI")])
21750 (define_insn "sse4_2_crc32di"
21751   [(set (match_operand:DI 0 "register_operand" "=r")
21752         (unspec:DI
21753           [(match_operand:DI 1 "register_operand" "0")
21754            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21755           UNSPEC_CRC32))]
21756   "TARGET_SSE4_2 && TARGET_64BIT"
21757   "crc32q\t{%2, %0|%0, %2}"
21758   [(set_attr "type" "sselog1")
21759    (set_attr "prefix_rep" "1")
21760    (set_attr "prefix_extra" "1")
21761    (set_attr "mode" "DI")])
21763 (include "mmx.md")
21764 (include "sse.md")
21765 (include "sync.md")