2008-11-18 Kai Tietz <kai.tietz@onevision.com>
[official-gcc.git] / gcc / config / i386 / i386.md
blob055add495feb16ef6b16dadd8c9b11f62e1dcb83
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_1           10)
223    (UNSPECV_CMPXCHG_2           11)
224    (UNSPECV_XCHG                12)
225    (UNSPECV_LOCK                13)
226    (UNSPECV_PROLOGUE_USE        14)
227    (UNSPECV_CLD                 15)
228    (UNSPECV_VZEROALL            16)
229    (UNSPECV_VZEROUPPER          17)
230   ])
232 ;; Constants to represent pcomtrue/pcomfalse variants
233 (define_constants
234   [(PCOM_FALSE                  0)
235    (PCOM_TRUE                   1)
236    (COM_FALSE_S                 2)
237    (COM_FALSE_P                 3)
238    (COM_TRUE_S                  4)
239    (COM_TRUE_P                  5)
240   ])
242 ;; Constants used in the SSE5 pperm instruction
243 (define_constants
244   [(PPERM_SRC                   0x00)   /* copy source */
245    (PPERM_INVERT                0x20)   /* invert source */
246    (PPERM_REVERSE               0x40)   /* bit reverse source */
247    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
248    (PPERM_ZERO                  0x80)   /* all 0's */
249    (PPERM_ONES                  0xa0)   /* all 1's */
250    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
251    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
252    (PPERM_SRC1                  0x00)   /* use first source byte */
253    (PPERM_SRC2                  0x10)   /* use second source byte */
254    ])
256 ;; Registers by name.
257 (define_constants
258   [(AX_REG                       0)
259    (DX_REG                       1)
260    (CX_REG                       2)
261    (BX_REG                       3)
262    (SI_REG                       4)
263    (DI_REG                       5)
264    (BP_REG                       6)
265    (SP_REG                       7)
266    (FLAGS_REG                   17)
267    (FPSR_REG                    18)
268    (FPCR_REG                    19)
269    (XMM0_REG                    21)
270    (XMM1_REG                    22)
271    (XMM2_REG                    23)
272    (XMM3_REG                    24)
273    (XMM4_REG                    25)
274    (XMM5_REG                    26)
275    (XMM6_REG                    27)
276    (XMM7_REG                    28)
277    (R10_REG                     39)
278    (R11_REG                     40)
279    (R13_REG                     42)
280    (XMM8_REG                    45)
281    (XMM9_REG                    46)
282    (XMM10_REG                   47)
283    (XMM11_REG                   48)
284    (XMM12_REG                   49)
285    (XMM13_REG                   50)
286    (XMM14_REG                   51)
287    (XMM15_REG                   52)
288   ])
290 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
291 ;; from i386.c.
293 ;; In C guard expressions, put expressions which may be compile-time
294 ;; constants first.  This allows for better optimization.  For
295 ;; example, write "TARGET_64BIT && reload_completed", not
296 ;; "reload_completed && TARGET_64BIT".
299 ;; Processor type.
300 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,
301                     generic64,amdfam10"
302   (const (symbol_ref "ix86_schedule")))
304 ;; A basic instruction type.  Refinements due to arguments to be
305 ;; provided in other attributes.
306 (define_attr "type"
307   "other,multi,
308    alu,alu1,negnot,imov,imovx,lea,
309    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
310    icmp,test,ibr,setcc,icmov,
311    push,pop,call,callv,leave,
312    str,bitmanip,
313    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
314    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
315    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
316    ssemuladd,sse4arg,
317    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
318   (const_string "other"))
320 ;; Main data type used by the insn
321 (define_attr "mode"
322   "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
323   (const_string "unknown"))
325 ;; The CPU unit operations uses.
326 (define_attr "unit" "integer,i387,sse,mmx,unknown"
327   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
328            (const_string "i387")
329          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
330                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
331                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
332            (const_string "sse")
333          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
334            (const_string "mmx")
335          (eq_attr "type" "other")
336            (const_string "unknown")]
337          (const_string "integer")))
339 ;; The (bounding maximum) length of an instruction immediate.
340 (define_attr "length_immediate" ""
341   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
342                           bitmanip")
343            (const_int 0)
344          (eq_attr "unit" "i387,sse,mmx")
345            (const_int 0)
346          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
347                           imul,icmp,push,pop")
348            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
349          (eq_attr "type" "imov,test")
350            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
351          (eq_attr "type" "call")
352            (if_then_else (match_operand 0 "constant_call_address_operand" "")
353              (const_int 4)
354              (const_int 0))
355          (eq_attr "type" "callv")
356            (if_then_else (match_operand 1 "constant_call_address_operand" "")
357              (const_int 4)
358              (const_int 0))
359          ;; We don't know the size before shorten_branches.  Expect
360          ;; the instruction to fit for better scheduling.
361          (eq_attr "type" "ibr")
362            (const_int 1)
363          ]
364          (symbol_ref "/* Update immediate_length and other attributes! */
365                       gcc_unreachable (),1")))
367 ;; The (bounding maximum) length of an instruction address.
368 (define_attr "length_address" ""
369   (cond [(eq_attr "type" "str,other,multi,fxch")
370            (const_int 0)
371          (and (eq_attr "type" "call")
372               (match_operand 0 "constant_call_address_operand" ""))
373              (const_int 0)
374          (and (eq_attr "type" "callv")
375               (match_operand 1 "constant_call_address_operand" ""))
376              (const_int 0)
377          ]
378          (symbol_ref "ix86_attr_length_address_default (insn)")))
380 ;; Set when length prefix is used.
381 (define_attr "prefix_data16" ""
382   (if_then_else (ior (eq_attr "mode" "HI")
383                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
384     (const_int 1)
385     (const_int 0)))
387 ;; Set when string REP prefix is used.
388 (define_attr "prefix_rep" ""
389   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
390     (const_int 1)
391     (const_int 0)))
393 ;; Set when 0f opcode prefix is used.
394 (define_attr "prefix_0f" ""
395   (if_then_else
396     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
397          (eq_attr "unit" "sse,mmx"))
398     (const_int 1)
399     (const_int 0)))
401 ;; Set when REX opcode prefix is used.
402 (define_attr "prefix_rex" ""
403   (cond [(and (eq_attr "mode" "DI")
404               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
405            (const_int 1)
406          (and (eq_attr "mode" "QI")
407               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
408                   (const_int 0)))
409            (const_int 1)
410          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
411              (const_int 0))
412            (const_int 1)
413         ]
414         (const_int 0)))
416 ;; There are also additional prefixes in SSSE3.
417 (define_attr "prefix_extra" "" (const_int 0))
419 ;; Prefix used: original, VEX or maybe VEX.
420 (define_attr "prefix" "orig,vex,maybe_vex"
421   (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
422     (const_string "vex")
423     (const_string "orig")))
425 ;; There is a 8bit immediate for VEX.
426 (define_attr "prefix_vex_imm8" "" (const_int 0))
428 ;; VEX W bit is used.
429 (define_attr "prefix_vex_w" "" (const_int 0))
431 ;; The length of VEX prefix
432 (define_attr "length_vex" ""
433   (if_then_else (eq_attr "prefix_0f" "1")
434     (if_then_else (eq_attr "prefix_vex_w" "1")
435       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
436       (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
437     (if_then_else (eq_attr "prefix_vex_w" "1")
438       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
439       (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
441 ;; Set when modrm byte is used.
442 (define_attr "modrm" ""
443   (cond [(eq_attr "type" "str,leave")
444            (const_int 0)
445          (eq_attr "unit" "i387")
446            (const_int 0)
447          (and (eq_attr "type" "incdec")
448               (ior (match_operand:SI 1 "register_operand" "")
449                    (match_operand:HI 1 "register_operand" "")))
450            (const_int 0)
451          (and (eq_attr "type" "push")
452               (not (match_operand 1 "memory_operand" "")))
453            (const_int 0)
454          (and (eq_attr "type" "pop")
455               (not (match_operand 0 "memory_operand" "")))
456            (const_int 0)
457          (and (eq_attr "type" "imov")
458               (ior (and (match_operand 0 "register_operand" "")
459                         (match_operand 1 "immediate_operand" ""))
460                    (ior (and (match_operand 0 "ax_reg_operand" "")
461                              (match_operand 1 "memory_displacement_only_operand" ""))
462                         (and (match_operand 0 "memory_displacement_only_operand" "")
463                              (match_operand 1 "ax_reg_operand" "")))))
464            (const_int 0)
465          (and (eq_attr "type" "call")
466               (match_operand 0 "constant_call_address_operand" ""))
467              (const_int 0)
468          (and (eq_attr "type" "callv")
469               (match_operand 1 "constant_call_address_operand" ""))
470              (const_int 0)
471          ]
472          (const_int 1)))
474 ;; The (bounding maximum) length of an instruction in bytes.
475 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
476 ;; Later we may want to split them and compute proper length as for
477 ;; other insns.
478 (define_attr "length" ""
479   (cond [(eq_attr "type" "other,multi,fistp,frndint")
480            (const_int 16)
481          (eq_attr "type" "fcmp")
482            (const_int 4)
483          (eq_attr "unit" "i387")
484            (plus (const_int 2)
485                  (plus (attr "prefix_data16")
486                        (attr "length_address")))
487          (ior (eq_attr "prefix" "vex")
488               (and (eq_attr "prefix" "maybe_vex")
489                     (ne (symbol_ref "TARGET_AVX") (const_int 0))))
490            (plus (attr "length_vex")
491                  (plus (attr "prefix_vex_imm8")
492                        (plus (attr "modrm")
493                              (attr "length_address"))))]
494          (plus (plus (attr "modrm")
495                      (plus (attr "prefix_0f")
496                            (plus (attr "prefix_rex")
497                                  (plus (attr "prefix_extra")
498                                        (const_int 1)))))
499                (plus (attr "prefix_rep")
500                      (plus (attr "prefix_data16")
501                            (plus (attr "length_immediate")
502                                  (attr "length_address")))))))
504 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
505 ;; `store' if there is a simple memory reference therein, or `unknown'
506 ;; if the instruction is complex.
508 (define_attr "memory" "none,load,store,both,unknown"
509   (cond [(eq_attr "type" "other,multi,str")
510            (const_string "unknown")
511          (eq_attr "type" "lea,fcmov,fpspc")
512            (const_string "none")
513          (eq_attr "type" "fistp,leave")
514            (const_string "both")
515          (eq_attr "type" "frndint")
516            (const_string "load")
517          (eq_attr "type" "push")
518            (if_then_else (match_operand 1 "memory_operand" "")
519              (const_string "both")
520              (const_string "store"))
521          (eq_attr "type" "pop")
522            (if_then_else (match_operand 0 "memory_operand" "")
523              (const_string "both")
524              (const_string "load"))
525          (eq_attr "type" "setcc")
526            (if_then_else (match_operand 0 "memory_operand" "")
527              (const_string "store")
528              (const_string "none"))
529          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
530            (if_then_else (ior (match_operand 0 "memory_operand" "")
531                               (match_operand 1 "memory_operand" ""))
532              (const_string "load")
533              (const_string "none"))
534          (eq_attr "type" "ibr")
535            (if_then_else (match_operand 0 "memory_operand" "")
536              (const_string "load")
537              (const_string "none"))
538          (eq_attr "type" "call")
539            (if_then_else (match_operand 0 "constant_call_address_operand" "")
540              (const_string "none")
541              (const_string "load"))
542          (eq_attr "type" "callv")
543            (if_then_else (match_operand 1 "constant_call_address_operand" "")
544              (const_string "none")
545              (const_string "load"))
546          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
547               (match_operand 1 "memory_operand" ""))
548            (const_string "both")
549          (and (match_operand 0 "memory_operand" "")
550               (match_operand 1 "memory_operand" ""))
551            (const_string "both")
552          (match_operand 0 "memory_operand" "")
553            (const_string "store")
554          (match_operand 1 "memory_operand" "")
555            (const_string "load")
556          (and (eq_attr "type"
557                  "!alu1,negnot,ishift1,
558                    imov,imovx,icmp,test,bitmanip,
559                    fmov,fcmp,fsgn,
560                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
561                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
562               (match_operand 2 "memory_operand" ""))
563            (const_string "load")
564          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
565               (match_operand 3 "memory_operand" ""))
566            (const_string "load")
567         ]
568         (const_string "none")))
570 ;; Indicates if an instruction has both an immediate and a displacement.
572 (define_attr "imm_disp" "false,true,unknown"
573   (cond [(eq_attr "type" "other,multi")
574            (const_string "unknown")
575          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
576               (and (match_operand 0 "memory_displacement_operand" "")
577                    (match_operand 1 "immediate_operand" "")))
578            (const_string "true")
579          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
580               (and (match_operand 0 "memory_displacement_operand" "")
581                    (match_operand 2 "immediate_operand" "")))
582            (const_string "true")
583         ]
584         (const_string "false")))
586 ;; Indicates if an FP operation has an integer source.
588 (define_attr "fp_int_src" "false,true"
589   (const_string "false"))
591 ;; Defines rounding mode of an FP operation.
593 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
594   (const_string "any"))
596 ;; Describe a user's asm statement.
597 (define_asm_attributes
598   [(set_attr "length" "128")
599    (set_attr "type" "multi")])
601 ;; All integer comparison codes.
602 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
604 ;; All floating-point comparison codes.
605 (define_code_iterator fp_cond [unordered ordered
606                                uneq unge ungt unle unlt ltgt ])
608 (define_code_iterator plusminus [plus minus])
610 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
612 ;; Base name for define_insn
613 (define_code_attr plusminus_insn
614   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
615    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
617 ;; Base name for insn mnemonic.
618 (define_code_attr plusminus_mnemonic
619   [(plus "add") (ss_plus "adds") (us_plus "addus")
620    (minus "sub") (ss_minus "subs") (us_minus "subus")])
622 ;; Mark commutative operators as such in constraints.
623 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
624                         (minus "") (ss_minus "") (us_minus "")])
626 ;; Mapping of signed max and min
627 (define_code_iterator smaxmin [smax smin])
629 ;; Mapping of unsigned max and min
630 (define_code_iterator umaxmin [umax umin])
632 ;; Mapping of signed/unsigned max and min
633 (define_code_iterator maxmin [smax smin umax umin])
635 ;; Base name for integer and FP insn mnemonic
636 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
637                                  (umax "maxu") (umin "minu")])
638 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
640 ;; Mapping of parallel logic operators
641 (define_code_iterator plogic [and ior xor])
643 ;; Base name for insn mnemonic.
644 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
646 ;; Mapping of abs neg operators
647 (define_code_iterator absneg [abs neg])
649 ;; Base name for x87 insn mnemonic.
650 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
652 ;; All single word integer modes.
653 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
655 ;; Single word integer modes up to SImode.
656 (define_mode_iterator SWI32 [QI HI SI])
658 ;; Instruction suffix for integer modes.
659 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
661 ;; Register class for integer modes.
662 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
664 ;; Immediate operand constraint for integer modes.
665 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
667 ;; General operand predicate for integer modes.
668 (define_mode_attr general_operand
669         [(QI "general_operand")
670          (HI "general_operand")
671          (SI "general_operand")
672          (DI "x86_64_general_operand")])
674 ;; SSE and x87 SFmode and DFmode floating point modes
675 (define_mode_iterator MODEF [SF DF])
677 ;; All x87 floating point modes
678 (define_mode_iterator X87MODEF [SF DF XF])
680 ;; All integer modes handled by x87 fisttp operator.
681 (define_mode_iterator X87MODEI [HI SI DI])
683 ;; All integer modes handled by integer x87 operators.
684 (define_mode_iterator X87MODEI12 [HI SI])
686 ;; All integer modes handled by SSE cvtts?2si* operators.
687 (define_mode_iterator SSEMODEI24 [SI DI])
689 ;; SSE asm suffix for floating point modes
690 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
692 ;; SSE vector mode corresponding to a scalar mode
693 (define_mode_attr ssevecmode
694   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
696 ;; Instruction suffix for REX 64bit operators.
697 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
699 ;; This mode iterator allows :P to be used for patterns that operate on
700 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
701 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
704 ;; Scheduling descriptions
706 (include "pentium.md")
707 (include "ppro.md")
708 (include "k6.md")
709 (include "athlon.md")
710 (include "geode.md")
713 ;; Operand and operator predicates and constraints
715 (include "predicates.md")
716 (include "constraints.md")
719 ;; Compare instructions.
721 ;; All compare insns have expanders that save the operands away without
722 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
723 ;; after the cmp) will actually emit the cmpM.
725 (define_expand "cmpti"
726   [(set (reg:CC FLAGS_REG)
727         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
728                     (match_operand:TI 1 "x86_64_general_operand" "")))]
729   "TARGET_64BIT"
731   if (MEM_P (operands[0]) && MEM_P (operands[1]))
732     operands[0] = force_reg (TImode, operands[0]);
733   ix86_compare_op0 = operands[0];
734   ix86_compare_op1 = operands[1];
735   DONE;
738 (define_expand "cmpdi"
739   [(set (reg:CC FLAGS_REG)
740         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
741                     (match_operand:DI 1 "x86_64_general_operand" "")))]
742   ""
744   if (MEM_P (operands[0]) && MEM_P (operands[1]))
745     operands[0] = force_reg (DImode, operands[0]);
746   ix86_compare_op0 = operands[0];
747   ix86_compare_op1 = operands[1];
748   DONE;
751 (define_expand "cmpsi"
752   [(set (reg:CC FLAGS_REG)
753         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
754                     (match_operand:SI 1 "general_operand" "")))]
755   ""
757   if (MEM_P (operands[0]) && MEM_P (operands[1]))
758     operands[0] = force_reg (SImode, operands[0]);
759   ix86_compare_op0 = operands[0];
760   ix86_compare_op1 = operands[1];
761   DONE;
764 (define_expand "cmphi"
765   [(set (reg:CC FLAGS_REG)
766         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
767                     (match_operand:HI 1 "general_operand" "")))]
768   ""
770   if (MEM_P (operands[0]) && MEM_P (operands[1]))
771     operands[0] = force_reg (HImode, operands[0]);
772   ix86_compare_op0 = operands[0];
773   ix86_compare_op1 = operands[1];
774   DONE;
777 (define_expand "cmpqi"
778   [(set (reg:CC FLAGS_REG)
779         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
780                     (match_operand:QI 1 "general_operand" "")))]
781   "TARGET_QIMODE_MATH"
783   if (MEM_P (operands[0]) && MEM_P (operands[1]))
784     operands[0] = force_reg (QImode, operands[0]);
785   ix86_compare_op0 = operands[0];
786   ix86_compare_op1 = operands[1];
787   DONE;
790 (define_insn "cmpdi_ccno_1_rex64"
791   [(set (reg FLAGS_REG)
792         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
793                  (match_operand:DI 1 "const0_operand" "")))]
794   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
795   "@
796    test{q}\t%0, %0
797    cmp{q}\t{%1, %0|%0, %1}"
798   [(set_attr "type" "test,icmp")
799    (set_attr "length_immediate" "0,1")
800    (set_attr "mode" "DI")])
802 (define_insn "*cmpdi_minus_1_rex64"
803   [(set (reg FLAGS_REG)
804         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
805                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
806                  (const_int 0)))]
807   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
808   "cmp{q}\t{%1, %0|%0, %1}"
809   [(set_attr "type" "icmp")
810    (set_attr "mode" "DI")])
812 (define_expand "cmpdi_1_rex64"
813   [(set (reg:CC FLAGS_REG)
814         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
815                     (match_operand:DI 1 "general_operand" "")))]
816   "TARGET_64BIT"
817   "")
819 (define_insn "cmpdi_1_insn_rex64"
820   [(set (reg FLAGS_REG)
821         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
822                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
823   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
824   "cmp{q}\t{%1, %0|%0, %1}"
825   [(set_attr "type" "icmp")
826    (set_attr "mode" "DI")])
829 (define_insn "*cmpsi_ccno_1"
830   [(set (reg FLAGS_REG)
831         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
832                  (match_operand:SI 1 "const0_operand" "")))]
833   "ix86_match_ccmode (insn, CCNOmode)"
834   "@
835    test{l}\t%0, %0
836    cmp{l}\t{%1, %0|%0, %1}"
837   [(set_attr "type" "test,icmp")
838    (set_attr "length_immediate" "0,1")
839    (set_attr "mode" "SI")])
841 (define_insn "*cmpsi_minus_1"
842   [(set (reg FLAGS_REG)
843         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
844                            (match_operand:SI 1 "general_operand" "ri,mr"))
845                  (const_int 0)))]
846   "ix86_match_ccmode (insn, CCGOCmode)"
847   "cmp{l}\t{%1, %0|%0, %1}"
848   [(set_attr "type" "icmp")
849    (set_attr "mode" "SI")])
851 (define_expand "cmpsi_1"
852   [(set (reg:CC FLAGS_REG)
853         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
854                     (match_operand:SI 1 "general_operand" "")))]
855   ""
856   "")
858 (define_insn "*cmpsi_1_insn"
859   [(set (reg FLAGS_REG)
860         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
861                  (match_operand:SI 1 "general_operand" "ri,mr")))]
862   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
863     && ix86_match_ccmode (insn, CCmode)"
864   "cmp{l}\t{%1, %0|%0, %1}"
865   [(set_attr "type" "icmp")
866    (set_attr "mode" "SI")])
868 (define_insn "*cmphi_ccno_1"
869   [(set (reg FLAGS_REG)
870         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
871                  (match_operand:HI 1 "const0_operand" "")))]
872   "ix86_match_ccmode (insn, CCNOmode)"
873   "@
874    test{w}\t%0, %0
875    cmp{w}\t{%1, %0|%0, %1}"
876   [(set_attr "type" "test,icmp")
877    (set_attr "length_immediate" "0,1")
878    (set_attr "mode" "HI")])
880 (define_insn "*cmphi_minus_1"
881   [(set (reg FLAGS_REG)
882         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
883                            (match_operand:HI 1 "general_operand" "rn,mr"))
884                  (const_int 0)))]
885   "ix86_match_ccmode (insn, CCGOCmode)"
886   "cmp{w}\t{%1, %0|%0, %1}"
887   [(set_attr "type" "icmp")
888    (set_attr "mode" "HI")])
890 (define_insn "*cmphi_1"
891   [(set (reg FLAGS_REG)
892         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
893                  (match_operand:HI 1 "general_operand" "rn,mr")))]
894   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
895    && ix86_match_ccmode (insn, CCmode)"
896   "cmp{w}\t{%1, %0|%0, %1}"
897   [(set_attr "type" "icmp")
898    (set_attr "mode" "HI")])
900 (define_insn "*cmpqi_ccno_1"
901   [(set (reg FLAGS_REG)
902         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
903                  (match_operand:QI 1 "const0_operand" "")))]
904   "ix86_match_ccmode (insn, CCNOmode)"
905   "@
906    test{b}\t%0, %0
907    cmp{b}\t{$0, %0|%0, 0}"
908   [(set_attr "type" "test,icmp")
909    (set_attr "length_immediate" "0,1")
910    (set_attr "mode" "QI")])
912 (define_insn "*cmpqi_1"
913   [(set (reg FLAGS_REG)
914         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
915                  (match_operand:QI 1 "general_operand" "qn,mq")))]
916   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
917     && ix86_match_ccmode (insn, CCmode)"
918   "cmp{b}\t{%1, %0|%0, %1}"
919   [(set_attr "type" "icmp")
920    (set_attr "mode" "QI")])
922 (define_insn "*cmpqi_minus_1"
923   [(set (reg FLAGS_REG)
924         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
925                            (match_operand:QI 1 "general_operand" "qn,mq"))
926                  (const_int 0)))]
927   "ix86_match_ccmode (insn, CCGOCmode)"
928   "cmp{b}\t{%1, %0|%0, %1}"
929   [(set_attr "type" "icmp")
930    (set_attr "mode" "QI")])
932 (define_insn "*cmpqi_ext_1"
933   [(set (reg FLAGS_REG)
934         (compare
935           (match_operand:QI 0 "general_operand" "Qm")
936           (subreg:QI
937             (zero_extract:SI
938               (match_operand 1 "ext_register_operand" "Q")
939               (const_int 8)
940               (const_int 8)) 0)))]
941   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
942   "cmp{b}\t{%h1, %0|%0, %h1}"
943   [(set_attr "type" "icmp")
944    (set_attr "mode" "QI")])
946 (define_insn "*cmpqi_ext_1_rex64"
947   [(set (reg FLAGS_REG)
948         (compare
949           (match_operand:QI 0 "register_operand" "Q")
950           (subreg:QI
951             (zero_extract:SI
952               (match_operand 1 "ext_register_operand" "Q")
953               (const_int 8)
954               (const_int 8)) 0)))]
955   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
956   "cmp{b}\t{%h1, %0|%0, %h1}"
957   [(set_attr "type" "icmp")
958    (set_attr "mode" "QI")])
960 (define_insn "*cmpqi_ext_2"
961   [(set (reg FLAGS_REG)
962         (compare
963           (subreg:QI
964             (zero_extract:SI
965               (match_operand 0 "ext_register_operand" "Q")
966               (const_int 8)
967               (const_int 8)) 0)
968           (match_operand:QI 1 "const0_operand" "")))]
969   "ix86_match_ccmode (insn, CCNOmode)"
970   "test{b}\t%h0, %h0"
971   [(set_attr "type" "test")
972    (set_attr "length_immediate" "0")
973    (set_attr "mode" "QI")])
975 (define_expand "cmpqi_ext_3"
976   [(set (reg:CC FLAGS_REG)
977         (compare:CC
978           (subreg:QI
979             (zero_extract:SI
980               (match_operand 0 "ext_register_operand" "")
981               (const_int 8)
982               (const_int 8)) 0)
983           (match_operand:QI 1 "general_operand" "")))]
984   ""
985   "")
987 (define_insn "cmpqi_ext_3_insn"
988   [(set (reg FLAGS_REG)
989         (compare
990           (subreg:QI
991             (zero_extract:SI
992               (match_operand 0 "ext_register_operand" "Q")
993               (const_int 8)
994               (const_int 8)) 0)
995           (match_operand:QI 1 "general_operand" "Qmn")))]
996   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
997   "cmp{b}\t{%1, %h0|%h0, %1}"
998   [(set_attr "type" "icmp")
999    (set_attr "mode" "QI")])
1001 (define_insn "cmpqi_ext_3_insn_rex64"
1002   [(set (reg FLAGS_REG)
1003         (compare
1004           (subreg:QI
1005             (zero_extract:SI
1006               (match_operand 0 "ext_register_operand" "Q")
1007               (const_int 8)
1008               (const_int 8)) 0)
1009           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1010   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1011   "cmp{b}\t{%1, %h0|%h0, %1}"
1012   [(set_attr "type" "icmp")
1013    (set_attr "mode" "QI")])
1015 (define_insn "*cmpqi_ext_4"
1016   [(set (reg FLAGS_REG)
1017         (compare
1018           (subreg:QI
1019             (zero_extract:SI
1020               (match_operand 0 "ext_register_operand" "Q")
1021               (const_int 8)
1022               (const_int 8)) 0)
1023           (subreg:QI
1024             (zero_extract:SI
1025               (match_operand 1 "ext_register_operand" "Q")
1026               (const_int 8)
1027               (const_int 8)) 0)))]
1028   "ix86_match_ccmode (insn, CCmode)"
1029   "cmp{b}\t{%h1, %h0|%h0, %h1}"
1030   [(set_attr "type" "icmp")
1031    (set_attr "mode" "QI")])
1033 ;; These implement float point compares.
1034 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1035 ;; which would allow mix and match FP modes on the compares.  Which is what
1036 ;; the old patterns did, but with many more of them.
1038 (define_expand "cmpxf"
1039   [(set (reg:CC FLAGS_REG)
1040         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
1041                     (match_operand:XF 1 "nonmemory_operand" "")))]
1042   "TARGET_80387"
1044   ix86_compare_op0 = operands[0];
1045   ix86_compare_op1 = operands[1];
1046   DONE;
1049 (define_expand "cmp<mode>"
1050   [(set (reg:CC FLAGS_REG)
1051         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
1052                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
1053   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1055   ix86_compare_op0 = operands[0];
1056   ix86_compare_op1 = operands[1];
1057   DONE;
1060 ;; FP compares, step 1:
1061 ;; Set the FP condition codes.
1063 ;; CCFPmode     compare with exceptions
1064 ;; CCFPUmode    compare with no exceptions
1066 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1067 ;; used to manage the reg stack popping would not be preserved.
1069 (define_insn "*cmpfp_0"
1070   [(set (match_operand:HI 0 "register_operand" "=a")
1071         (unspec:HI
1072           [(compare:CCFP
1073              (match_operand 1 "register_operand" "f")
1074              (match_operand 2 "const0_operand" ""))]
1075         UNSPEC_FNSTSW))]
1076   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1077    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1078   "* return output_fp_compare (insn, operands, 0, 0);"
1079   [(set_attr "type" "multi")
1080    (set_attr "unit" "i387")
1081    (set (attr "mode")
1082      (cond [(match_operand:SF 1 "" "")
1083               (const_string "SF")
1084             (match_operand:DF 1 "" "")
1085               (const_string "DF")
1086            ]
1087            (const_string "XF")))])
1089 (define_insn_and_split "*cmpfp_0_cc"
1090   [(set (reg:CCFP FLAGS_REG)
1091         (compare:CCFP
1092           (match_operand 1 "register_operand" "f")
1093           (match_operand 2 "const0_operand" "")))
1094    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1095   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1096    && TARGET_SAHF && !TARGET_CMOVE
1097    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1098   "#"
1099   "&& reload_completed"
1100   [(set (match_dup 0)
1101         (unspec:HI
1102           [(compare:CCFP (match_dup 1)(match_dup 2))]
1103         UNSPEC_FNSTSW))
1104    (set (reg:CC FLAGS_REG)
1105         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1106   ""
1107   [(set_attr "type" "multi")
1108    (set_attr "unit" "i387")
1109    (set (attr "mode")
1110      (cond [(match_operand:SF 1 "" "")
1111               (const_string "SF")
1112             (match_operand:DF 1 "" "")
1113               (const_string "DF")
1114            ]
1115            (const_string "XF")))])
1117 (define_insn "*cmpfp_xf"
1118   [(set (match_operand:HI 0 "register_operand" "=a")
1119         (unspec:HI
1120           [(compare:CCFP
1121              (match_operand:XF 1 "register_operand" "f")
1122              (match_operand:XF 2 "register_operand" "f"))]
1123           UNSPEC_FNSTSW))]
1124   "TARGET_80387"
1125   "* return output_fp_compare (insn, operands, 0, 0);"
1126   [(set_attr "type" "multi")
1127    (set_attr "unit" "i387")
1128    (set_attr "mode" "XF")])
1130 (define_insn_and_split "*cmpfp_xf_cc"
1131   [(set (reg:CCFP FLAGS_REG)
1132         (compare:CCFP
1133           (match_operand:XF 1 "register_operand" "f")
1134           (match_operand:XF 2 "register_operand" "f")))
1135    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1136   "TARGET_80387
1137    && TARGET_SAHF && !TARGET_CMOVE"
1138   "#"
1139   "&& reload_completed"
1140   [(set (match_dup 0)
1141         (unspec:HI
1142           [(compare:CCFP (match_dup 1)(match_dup 2))]
1143         UNSPEC_FNSTSW))
1144    (set (reg:CC FLAGS_REG)
1145         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1146   ""
1147   [(set_attr "type" "multi")
1148    (set_attr "unit" "i387")
1149    (set_attr "mode" "XF")])
1151 (define_insn "*cmpfp_<mode>"
1152   [(set (match_operand:HI 0 "register_operand" "=a")
1153         (unspec:HI
1154           [(compare:CCFP
1155              (match_operand:MODEF 1 "register_operand" "f")
1156              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1157           UNSPEC_FNSTSW))]
1158   "TARGET_80387"
1159   "* return output_fp_compare (insn, operands, 0, 0);"
1160   [(set_attr "type" "multi")
1161    (set_attr "unit" "i387")
1162    (set_attr "mode" "<MODE>")])
1164 (define_insn_and_split "*cmpfp_<mode>_cc"
1165   [(set (reg:CCFP FLAGS_REG)
1166         (compare:CCFP
1167           (match_operand:MODEF 1 "register_operand" "f")
1168           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1169    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1170   "TARGET_80387
1171    && TARGET_SAHF && !TARGET_CMOVE"
1172   "#"
1173   "&& reload_completed"
1174   [(set (match_dup 0)
1175         (unspec:HI
1176           [(compare:CCFP (match_dup 1)(match_dup 2))]
1177         UNSPEC_FNSTSW))
1178    (set (reg:CC FLAGS_REG)
1179         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1180   ""
1181   [(set_attr "type" "multi")
1182    (set_attr "unit" "i387")
1183    (set_attr "mode" "<MODE>")])
1185 (define_insn "*cmpfp_u"
1186   [(set (match_operand:HI 0 "register_operand" "=a")
1187         (unspec:HI
1188           [(compare:CCFPU
1189              (match_operand 1 "register_operand" "f")
1190              (match_operand 2 "register_operand" "f"))]
1191           UNSPEC_FNSTSW))]
1192   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1193    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1194   "* return output_fp_compare (insn, operands, 0, 1);"
1195   [(set_attr "type" "multi")
1196    (set_attr "unit" "i387")
1197    (set (attr "mode")
1198      (cond [(match_operand:SF 1 "" "")
1199               (const_string "SF")
1200             (match_operand:DF 1 "" "")
1201               (const_string "DF")
1202            ]
1203            (const_string "XF")))])
1205 (define_insn_and_split "*cmpfp_u_cc"
1206   [(set (reg:CCFPU FLAGS_REG)
1207         (compare:CCFPU
1208           (match_operand 1 "register_operand" "f")
1209           (match_operand 2 "register_operand" "f")))
1210    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1211   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1212    && TARGET_SAHF && !TARGET_CMOVE
1213    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1214   "#"
1215   "&& reload_completed"
1216   [(set (match_dup 0)
1217         (unspec:HI
1218           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1219         UNSPEC_FNSTSW))
1220    (set (reg:CC FLAGS_REG)
1221         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1222   ""
1223   [(set_attr "type" "multi")
1224    (set_attr "unit" "i387")
1225    (set (attr "mode")
1226      (cond [(match_operand:SF 1 "" "")
1227               (const_string "SF")
1228             (match_operand:DF 1 "" "")
1229               (const_string "DF")
1230            ]
1231            (const_string "XF")))])
1233 (define_insn "*cmpfp_<mode>"
1234   [(set (match_operand:HI 0 "register_operand" "=a")
1235         (unspec:HI
1236           [(compare:CCFP
1237              (match_operand 1 "register_operand" "f")
1238              (match_operator 3 "float_operator"
1239                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1240           UNSPEC_FNSTSW))]
1241   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1242    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1243    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1244   "* return output_fp_compare (insn, operands, 0, 0);"
1245   [(set_attr "type" "multi")
1246    (set_attr "unit" "i387")
1247    (set_attr "fp_int_src" "true")
1248    (set_attr "mode" "<MODE>")])
1250 (define_insn_and_split "*cmpfp_<mode>_cc"
1251   [(set (reg:CCFP FLAGS_REG)
1252         (compare:CCFP
1253           (match_operand 1 "register_operand" "f")
1254           (match_operator 3 "float_operator"
1255             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1256    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1257   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1258    && TARGET_SAHF && !TARGET_CMOVE
1259    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1260    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1261   "#"
1262   "&& reload_completed"
1263   [(set (match_dup 0)
1264         (unspec:HI
1265           [(compare:CCFP
1266              (match_dup 1)
1267              (match_op_dup 3 [(match_dup 2)]))]
1268         UNSPEC_FNSTSW))
1269    (set (reg:CC FLAGS_REG)
1270         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1271   ""
1272   [(set_attr "type" "multi")
1273    (set_attr "unit" "i387")
1274    (set_attr "fp_int_src" "true")
1275    (set_attr "mode" "<MODE>")])
1277 ;; FP compares, step 2
1278 ;; Move the fpsw to ax.
1280 (define_insn "x86_fnstsw_1"
1281   [(set (match_operand:HI 0 "register_operand" "=a")
1282         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1283   "TARGET_80387"
1284   "fnstsw\t%0"
1285   [(set_attr "length" "2")
1286    (set_attr "mode" "SI")
1287    (set_attr "unit" "i387")])
1289 ;; FP compares, step 3
1290 ;; Get ax into flags, general case.
1292 (define_insn "x86_sahf_1"
1293   [(set (reg:CC FLAGS_REG)
1294         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1295                    UNSPEC_SAHF))]
1296   "TARGET_SAHF"
1298 #ifdef HAVE_AS_IX86_SAHF
1299   return "sahf";
1300 #else
1301   return ".byte\t0x9e";
1302 #endif
1304   [(set_attr "length" "1")
1305    (set_attr "athlon_decode" "vector")
1306    (set_attr "amdfam10_decode" "direct")
1307    (set_attr "mode" "SI")])
1309 ;; Pentium Pro can do steps 1 through 3 in one go.
1310 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1311 (define_insn "*cmpfp_i_mixed"
1312   [(set (reg:CCFP FLAGS_REG)
1313         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1314                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1315   "TARGET_MIX_SSE_I387
1316    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1317    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1318   "* return output_fp_compare (insn, operands, 1, 0);"
1319   [(set_attr "type" "fcmp,ssecomi")
1320    (set_attr "prefix" "orig,maybe_vex")
1321    (set (attr "mode")
1322      (if_then_else (match_operand:SF 1 "" "")
1323         (const_string "SF")
1324         (const_string "DF")))
1325    (set_attr "athlon_decode" "vector")
1326    (set_attr "amdfam10_decode" "direct")])
1328 (define_insn "*cmpfp_i_sse"
1329   [(set (reg:CCFP FLAGS_REG)
1330         (compare:CCFP (match_operand 0 "register_operand" "x")
1331                       (match_operand 1 "nonimmediate_operand" "xm")))]
1332   "TARGET_SSE_MATH
1333    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1334    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1335   "* return output_fp_compare (insn, operands, 1, 0);"
1336   [(set_attr "type" "ssecomi")
1337    (set_attr "prefix" "maybe_vex")
1338    (set (attr "mode")
1339      (if_then_else (match_operand:SF 1 "" "")
1340         (const_string "SF")
1341         (const_string "DF")))
1342    (set_attr "athlon_decode" "vector")
1343    (set_attr "amdfam10_decode" "direct")])
1345 (define_insn "*cmpfp_i_i387"
1346   [(set (reg:CCFP FLAGS_REG)
1347         (compare:CCFP (match_operand 0 "register_operand" "f")
1348                       (match_operand 1 "register_operand" "f")))]
1349   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1350    && TARGET_CMOVE
1351    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1352    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1353   "* return output_fp_compare (insn, operands, 1, 0);"
1354   [(set_attr "type" "fcmp")
1355    (set (attr "mode")
1356      (cond [(match_operand:SF 1 "" "")
1357               (const_string "SF")
1358             (match_operand:DF 1 "" "")
1359               (const_string "DF")
1360            ]
1361            (const_string "XF")))
1362    (set_attr "athlon_decode" "vector")
1363    (set_attr "amdfam10_decode" "direct")])
1365 (define_insn "*cmpfp_iu_mixed"
1366   [(set (reg:CCFPU FLAGS_REG)
1367         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1368                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1369   "TARGET_MIX_SSE_I387
1370    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1371    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1372   "* return output_fp_compare (insn, operands, 1, 1);"
1373   [(set_attr "type" "fcmp,ssecomi")
1374    (set_attr "prefix" "orig,maybe_vex")
1375    (set (attr "mode")
1376      (if_then_else (match_operand:SF 1 "" "")
1377         (const_string "SF")
1378         (const_string "DF")))
1379    (set_attr "athlon_decode" "vector")
1380    (set_attr "amdfam10_decode" "direct")])
1382 (define_insn "*cmpfp_iu_sse"
1383   [(set (reg:CCFPU FLAGS_REG)
1384         (compare:CCFPU (match_operand 0 "register_operand" "x")
1385                        (match_operand 1 "nonimmediate_operand" "xm")))]
1386   "TARGET_SSE_MATH
1387    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1388    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1389   "* return output_fp_compare (insn, operands, 1, 1);"
1390   [(set_attr "type" "ssecomi")
1391    (set_attr "prefix" "maybe_vex")
1392    (set (attr "mode")
1393      (if_then_else (match_operand:SF 1 "" "")
1394         (const_string "SF")
1395         (const_string "DF")))
1396    (set_attr "athlon_decode" "vector")
1397    (set_attr "amdfam10_decode" "direct")])
1399 (define_insn "*cmpfp_iu_387"
1400   [(set (reg:CCFPU FLAGS_REG)
1401         (compare:CCFPU (match_operand 0 "register_operand" "f")
1402                        (match_operand 1 "register_operand" "f")))]
1403   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1404    && TARGET_CMOVE
1405    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1406    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1407   "* return output_fp_compare (insn, operands, 1, 1);"
1408   [(set_attr "type" "fcmp")
1409    (set (attr "mode")
1410      (cond [(match_operand:SF 1 "" "")
1411               (const_string "SF")
1412             (match_operand:DF 1 "" "")
1413               (const_string "DF")
1414            ]
1415            (const_string "XF")))
1416    (set_attr "athlon_decode" "vector")
1417    (set_attr "amdfam10_decode" "direct")])
1419 ;; Move instructions.
1421 ;; General case of fullword move.
1423 (define_expand "movsi"
1424   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1425         (match_operand:SI 1 "general_operand" ""))]
1426   ""
1427   "ix86_expand_move (SImode, operands); DONE;")
1429 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1430 ;; general_operand.
1432 ;; %%% We don't use a post-inc memory reference because x86 is not a
1433 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1434 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1435 ;; targets without our curiosities, and it is just as easy to represent
1436 ;; this differently.
1438 (define_insn "*pushsi2"
1439   [(set (match_operand:SI 0 "push_operand" "=<")
1440         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1441   "!TARGET_64BIT"
1442   "push{l}\t%1"
1443   [(set_attr "type" "push")
1444    (set_attr "mode" "SI")])
1446 ;; For 64BIT abi we always round up to 8 bytes.
1447 (define_insn "*pushsi2_rex64"
1448   [(set (match_operand:SI 0 "push_operand" "=X")
1449         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1450   "TARGET_64BIT"
1451   "push{q}\t%q1"
1452   [(set_attr "type" "push")
1453    (set_attr "mode" "SI")])
1455 (define_insn "*pushsi2_prologue"
1456   [(set (match_operand:SI 0 "push_operand" "=<")
1457         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1458    (clobber (mem:BLK (scratch)))]
1459   "!TARGET_64BIT"
1460   "push{l}\t%1"
1461   [(set_attr "type" "push")
1462    (set_attr "mode" "SI")])
1464 (define_insn "*popsi1_epilogue"
1465   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1466         (mem:SI (reg:SI SP_REG)))
1467    (set (reg:SI SP_REG)
1468         (plus:SI (reg:SI SP_REG) (const_int 4)))
1469    (clobber (mem:BLK (scratch)))]
1470   "!TARGET_64BIT"
1471   "pop{l}\t%0"
1472   [(set_attr "type" "pop")
1473    (set_attr "mode" "SI")])
1475 (define_insn "popsi1"
1476   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1477         (mem:SI (reg:SI SP_REG)))
1478    (set (reg:SI SP_REG)
1479         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1480   "!TARGET_64BIT"
1481   "pop{l}\t%0"
1482   [(set_attr "type" "pop")
1483    (set_attr "mode" "SI")])
1485 (define_insn "*movsi_xor"
1486   [(set (match_operand:SI 0 "register_operand" "=r")
1487         (match_operand:SI 1 "const0_operand" ""))
1488    (clobber (reg:CC FLAGS_REG))]
1489   "reload_completed"
1490   "xor{l}\t%0, %0"
1491   [(set_attr "type" "alu1")
1492    (set_attr "mode" "SI")
1493    (set_attr "length_immediate" "0")])
1495 (define_insn "*movsi_or"
1496   [(set (match_operand:SI 0 "register_operand" "=r")
1497         (match_operand:SI 1 "immediate_operand" "i"))
1498    (clobber (reg:CC FLAGS_REG))]
1499   "reload_completed
1500    && operands[1] == constm1_rtx"
1502   operands[1] = constm1_rtx;
1503   return "or{l}\t{%1, %0|%0, %1}";
1505   [(set_attr "type" "alu1")
1506    (set_attr "mode" "SI")
1507    (set_attr "length_immediate" "1")])
1509 (define_insn "*movsi_1"
1510   [(set (match_operand:SI 0 "nonimmediate_operand"
1511                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1512         (match_operand:SI 1 "general_operand"
1513                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1514   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1516   switch (get_attr_type (insn))
1517     {
1518     case TYPE_SSELOG1:
1519       if (get_attr_mode (insn) == MODE_TI)
1520         return "%vpxor\t%0, %d0";
1521       return "%vxorps\t%0, %d0";
1523     case TYPE_SSEMOV:
1524       switch (get_attr_mode (insn))
1525         {
1526         case MODE_TI:
1527           return "%vmovdqa\t{%1, %0|%0, %1}";
1528         case MODE_V4SF:
1529           return "%vmovaps\t{%1, %0|%0, %1}";
1530         case MODE_SI:
1531           return "%vmovd\t{%1, %0|%0, %1}";
1532         case MODE_SF:
1533           return "%vmovss\t{%1, %0|%0, %1}";
1534         default:
1535           gcc_unreachable ();
1536         }
1538     case TYPE_MMXADD:
1539       return "pxor\t%0, %0";
1541     case TYPE_MMXMOV:
1542       if (get_attr_mode (insn) == MODE_DI)
1543         return "movq\t{%1, %0|%0, %1}";
1544       return "movd\t{%1, %0|%0, %1}";
1546     case TYPE_LEA:
1547       return "lea{l}\t{%1, %0|%0, %1}";
1549     default:
1550       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1551       return "mov{l}\t{%1, %0|%0, %1}";
1552     }
1554   [(set (attr "type")
1555      (cond [(eq_attr "alternative" "2")
1556               (const_string "mmxadd")
1557             (eq_attr "alternative" "3,4,5")
1558               (const_string "mmxmov")
1559             (eq_attr "alternative" "6")
1560               (const_string "sselog1")
1561             (eq_attr "alternative" "7,8,9,10,11")
1562               (const_string "ssemov")
1563             (match_operand:DI 1 "pic_32bit_operand" "")
1564               (const_string "lea")
1565            ]
1566            (const_string "imov")))
1567    (set (attr "prefix")
1568      (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1569        (const_string "orig")
1570        (const_string "maybe_vex")))
1571    (set (attr "mode")
1572      (cond [(eq_attr "alternative" "2,3")
1573               (const_string "DI")
1574             (eq_attr "alternative" "6,7")
1575               (if_then_else
1576                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1577                 (const_string "V4SF")
1578                 (const_string "TI"))
1579             (and (eq_attr "alternative" "8,9,10,11")
1580                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1581               (const_string "SF")
1582            ]
1583            (const_string "SI")))])
1585 ;; Stores and loads of ax to arbitrary constant address.
1586 ;; We fake an second form of instruction to force reload to load address
1587 ;; into register when rax is not available
1588 (define_insn "*movabssi_1_rex64"
1589   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1590         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1591   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1592   "@
1593    movabs{l}\t{%1, %P0|%P0, %1}
1594    mov{l}\t{%1, %a0|%a0, %1}"
1595   [(set_attr "type" "imov")
1596    (set_attr "modrm" "0,*")
1597    (set_attr "length_address" "8,0")
1598    (set_attr "length_immediate" "0,*")
1599    (set_attr "memory" "store")
1600    (set_attr "mode" "SI")])
1602 (define_insn "*movabssi_2_rex64"
1603   [(set (match_operand:SI 0 "register_operand" "=a,r")
1604         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1605   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1606   "@
1607    movabs{l}\t{%P1, %0|%0, %P1}
1608    mov{l}\t{%a1, %0|%0, %a1}"
1609   [(set_attr "type" "imov")
1610    (set_attr "modrm" "0,*")
1611    (set_attr "length_address" "8,0")
1612    (set_attr "length_immediate" "0")
1613    (set_attr "memory" "load")
1614    (set_attr "mode" "SI")])
1616 (define_insn "*swapsi"
1617   [(set (match_operand:SI 0 "register_operand" "+r")
1618         (match_operand:SI 1 "register_operand" "+r"))
1619    (set (match_dup 1)
1620         (match_dup 0))]
1621   ""
1622   "xchg{l}\t%1, %0"
1623   [(set_attr "type" "imov")
1624    (set_attr "mode" "SI")
1625    (set_attr "pent_pair" "np")
1626    (set_attr "athlon_decode" "vector")
1627    (set_attr "amdfam10_decode" "double")])
1629 (define_expand "movhi"
1630   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1631         (match_operand:HI 1 "general_operand" ""))]
1632   ""
1633   "ix86_expand_move (HImode, operands); DONE;")
1635 (define_insn "*pushhi2"
1636   [(set (match_operand:HI 0 "push_operand" "=X")
1637         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1638   "!TARGET_64BIT"
1639   "push{l}\t%k1"
1640   [(set_attr "type" "push")
1641    (set_attr "mode" "SI")])
1643 ;; For 64BIT abi we always round up to 8 bytes.
1644 (define_insn "*pushhi2_rex64"
1645   [(set (match_operand:HI 0 "push_operand" "=X")
1646         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1647   "TARGET_64BIT"
1648   "push{q}\t%q1"
1649   [(set_attr "type" "push")
1650    (set_attr "mode" "DI")])
1652 (define_insn "*movhi_1"
1653   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1654         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1655   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1657   switch (get_attr_type (insn))
1658     {
1659     case TYPE_IMOVX:
1660       /* movzwl is faster than movw on p2 due to partial word stalls,
1661          though not as fast as an aligned movl.  */
1662       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1663     default:
1664       if (get_attr_mode (insn) == MODE_SI)
1665         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1666       else
1667         return "mov{w}\t{%1, %0|%0, %1}";
1668     }
1670   [(set (attr "type")
1671      (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1672               (const_string "imov")
1673             (and (eq_attr "alternative" "0")
1674                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1675                           (const_int 0))
1676                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1677                           (const_int 0))))
1678               (const_string "imov")
1679             (and (eq_attr "alternative" "1,2")
1680                  (match_operand:HI 1 "aligned_operand" ""))
1681               (const_string "imov")
1682             (and (ne (symbol_ref "TARGET_MOVX")
1683                      (const_int 0))
1684                  (eq_attr "alternative" "0,2"))
1685               (const_string "imovx")
1686            ]
1687            (const_string "imov")))
1688     (set (attr "mode")
1689       (cond [(eq_attr "type" "imovx")
1690                (const_string "SI")
1691              (and (eq_attr "alternative" "1,2")
1692                   (match_operand:HI 1 "aligned_operand" ""))
1693                (const_string "SI")
1694              (and (eq_attr "alternative" "0")
1695                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1696                            (const_int 0))
1697                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1698                            (const_int 0))))
1699                (const_string "SI")
1700             ]
1701             (const_string "HI")))])
1703 ;; Stores and loads of ax to arbitrary constant address.
1704 ;; We fake an second form of instruction to force reload to load address
1705 ;; into register when rax is not available
1706 (define_insn "*movabshi_1_rex64"
1707   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1708         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1709   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1710   "@
1711    movabs{w}\t{%1, %P0|%P0, %1}
1712    mov{w}\t{%1, %a0|%a0, %1}"
1713   [(set_attr "type" "imov")
1714    (set_attr "modrm" "0,*")
1715    (set_attr "length_address" "8,0")
1716    (set_attr "length_immediate" "0,*")
1717    (set_attr "memory" "store")
1718    (set_attr "mode" "HI")])
1720 (define_insn "*movabshi_2_rex64"
1721   [(set (match_operand:HI 0 "register_operand" "=a,r")
1722         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1723   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1724   "@
1725    movabs{w}\t{%P1, %0|%0, %P1}
1726    mov{w}\t{%a1, %0|%0, %a1}"
1727   [(set_attr "type" "imov")
1728    (set_attr "modrm" "0,*")
1729    (set_attr "length_address" "8,0")
1730    (set_attr "length_immediate" "0")
1731    (set_attr "memory" "load")
1732    (set_attr "mode" "HI")])
1734 (define_insn "*swaphi_1"
1735   [(set (match_operand:HI 0 "register_operand" "+r")
1736         (match_operand:HI 1 "register_operand" "+r"))
1737    (set (match_dup 1)
1738         (match_dup 0))]
1739   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1740   "xchg{l}\t%k1, %k0"
1741   [(set_attr "type" "imov")
1742    (set_attr "mode" "SI")
1743    (set_attr "pent_pair" "np")
1744    (set_attr "athlon_decode" "vector")
1745    (set_attr "amdfam10_decode" "double")])
1747 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1748 (define_insn "*swaphi_2"
1749   [(set (match_operand:HI 0 "register_operand" "+r")
1750         (match_operand:HI 1 "register_operand" "+r"))
1751    (set (match_dup 1)
1752         (match_dup 0))]
1753   "TARGET_PARTIAL_REG_STALL"
1754   "xchg{w}\t%1, %0"
1755   [(set_attr "type" "imov")
1756    (set_attr "mode" "HI")
1757    (set_attr "pent_pair" "np")
1758    (set_attr "athlon_decode" "vector")])
1760 (define_expand "movstricthi"
1761   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1762         (match_operand:HI 1 "general_operand" ""))]
1763   ""
1765   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1766     FAIL;
1767   /* Don't generate memory->memory moves, go through a register */
1768   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1769     operands[1] = force_reg (HImode, operands[1]);
1772 (define_insn "*movstricthi_1"
1773   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1774         (match_operand:HI 1 "general_operand" "rn,m"))]
1775   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1776    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1777   "mov{w}\t{%1, %0|%0, %1}"
1778   [(set_attr "type" "imov")
1779    (set_attr "mode" "HI")])
1781 (define_insn "*movstricthi_xor"
1782   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1783         (match_operand:HI 1 "const0_operand" ""))
1784    (clobber (reg:CC FLAGS_REG))]
1785   "reload_completed"
1786   "xor{w}\t%0, %0"
1787   [(set_attr "type" "alu1")
1788    (set_attr "mode" "HI")
1789    (set_attr "length_immediate" "0")])
1791 (define_expand "movqi"
1792   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1793         (match_operand:QI 1 "general_operand" ""))]
1794   ""
1795   "ix86_expand_move (QImode, operands); DONE;")
1797 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1798 ;; "push a byte".  But actually we use pushl, which has the effect
1799 ;; of rounding the amount pushed up to a word.
1801 (define_insn "*pushqi2"
1802   [(set (match_operand:QI 0 "push_operand" "=X")
1803         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1804   "!TARGET_64BIT"
1805   "push{l}\t%k1"
1806   [(set_attr "type" "push")
1807    (set_attr "mode" "SI")])
1809 ;; For 64BIT abi we always round up to 8 bytes.
1810 (define_insn "*pushqi2_rex64"
1811   [(set (match_operand:QI 0 "push_operand" "=X")
1812         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1813   "TARGET_64BIT"
1814   "push{q}\t%q1"
1815   [(set_attr "type" "push")
1816    (set_attr "mode" "DI")])
1818 ;; Situation is quite tricky about when to choose full sized (SImode) move
1819 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1820 ;; partial register dependency machines (such as AMD Athlon), where QImode
1821 ;; moves issue extra dependency and for partial register stalls machines
1822 ;; that don't use QImode patterns (and QImode move cause stall on the next
1823 ;; instruction).
1825 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1826 ;; register stall machines with, where we use QImode instructions, since
1827 ;; partial register stall can be caused there.  Then we use movzx.
1828 (define_insn "*movqi_1"
1829   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1830         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1831   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1833   switch (get_attr_type (insn))
1834     {
1835     case TYPE_IMOVX:
1836       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1837       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1838     default:
1839       if (get_attr_mode (insn) == MODE_SI)
1840         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1841       else
1842         return "mov{b}\t{%1, %0|%0, %1}";
1843     }
1845   [(set (attr "type")
1846      (cond [(and (eq_attr "alternative" "5")
1847                  (not (match_operand:QI 1 "aligned_operand" "")))
1848               (const_string "imovx")
1849             (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1850               (const_string "imov")
1851             (and (eq_attr "alternative" "3")
1852                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1853                           (const_int 0))
1854                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1855                           (const_int 0))))
1856               (const_string "imov")
1857             (eq_attr "alternative" "3,5")
1858               (const_string "imovx")
1859             (and (ne (symbol_ref "TARGET_MOVX")
1860                      (const_int 0))
1861                  (eq_attr "alternative" "2"))
1862               (const_string "imovx")
1863            ]
1864            (const_string "imov")))
1865    (set (attr "mode")
1866       (cond [(eq_attr "alternative" "3,4,5")
1867                (const_string "SI")
1868              (eq_attr "alternative" "6")
1869                (const_string "QI")
1870              (eq_attr "type" "imovx")
1871                (const_string "SI")
1872              (and (eq_attr "type" "imov")
1873                   (and (eq_attr "alternative" "0,1")
1874                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1875                                 (const_int 0))
1876                             (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1877                                      (const_int 0))
1878                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1879                                      (const_int 0))))))
1880                (const_string "SI")
1881              ;; Avoid partial register stalls when not using QImode arithmetic
1882              (and (eq_attr "type" "imov")
1883                   (and (eq_attr "alternative" "0,1")
1884                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1885                                 (const_int 0))
1886                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1887                                 (const_int 0)))))
1888                (const_string "SI")
1889            ]
1890            (const_string "QI")))])
1892 (define_insn "*swapqi_1"
1893   [(set (match_operand:QI 0 "register_operand" "+r")
1894         (match_operand:QI 1 "register_operand" "+r"))
1895    (set (match_dup 1)
1896         (match_dup 0))]
1897   "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1898   "xchg{l}\t%k1, %k0"
1899   [(set_attr "type" "imov")
1900    (set_attr "mode" "SI")
1901    (set_attr "pent_pair" "np")
1902    (set_attr "athlon_decode" "vector")
1903    (set_attr "amdfam10_decode" "vector")])
1905 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1906 (define_insn "*swapqi_2"
1907   [(set (match_operand:QI 0 "register_operand" "+q")
1908         (match_operand:QI 1 "register_operand" "+q"))
1909    (set (match_dup 1)
1910         (match_dup 0))]
1911   "TARGET_PARTIAL_REG_STALL"
1912   "xchg{b}\t%1, %0"
1913   [(set_attr "type" "imov")
1914    (set_attr "mode" "QI")
1915    (set_attr "pent_pair" "np")
1916    (set_attr "athlon_decode" "vector")])
1918 (define_expand "movstrictqi"
1919   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1920         (match_operand:QI 1 "general_operand" ""))]
1921   ""
1923   if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1924     FAIL;
1925   /* Don't generate memory->memory moves, go through a register.  */
1926   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1927     operands[1] = force_reg (QImode, operands[1]);
1930 (define_insn "*movstrictqi_1"
1931   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1932         (match_operand:QI 1 "general_operand" "*qn,m"))]
1933   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1934    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1935   "mov{b}\t{%1, %0|%0, %1}"
1936   [(set_attr "type" "imov")
1937    (set_attr "mode" "QI")])
1939 (define_insn "*movstrictqi_xor"
1940   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1941         (match_operand:QI 1 "const0_operand" ""))
1942    (clobber (reg:CC FLAGS_REG))]
1943   "reload_completed"
1944   "xor{b}\t%0, %0"
1945   [(set_attr "type" "alu1")
1946    (set_attr "mode" "QI")
1947    (set_attr "length_immediate" "0")])
1949 (define_insn "*movsi_extv_1"
1950   [(set (match_operand:SI 0 "register_operand" "=R")
1951         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1952                          (const_int 8)
1953                          (const_int 8)))]
1954   ""
1955   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1956   [(set_attr "type" "imovx")
1957    (set_attr "mode" "SI")])
1959 (define_insn "*movhi_extv_1"
1960   [(set (match_operand:HI 0 "register_operand" "=R")
1961         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1962                          (const_int 8)
1963                          (const_int 8)))]
1964   ""
1965   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1966   [(set_attr "type" "imovx")
1967    (set_attr "mode" "SI")])
1969 (define_insn "*movqi_extv_1"
1970   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1971         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1972                          (const_int 8)
1973                          (const_int 8)))]
1974   "!TARGET_64BIT"
1976   switch (get_attr_type (insn))
1977     {
1978     case TYPE_IMOVX:
1979       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1980     default:
1981       return "mov{b}\t{%h1, %0|%0, %h1}";
1982     }
1984   [(set (attr "type")
1985      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1986                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1987                              (ne (symbol_ref "TARGET_MOVX")
1988                                  (const_int 0))))
1989         (const_string "imovx")
1990         (const_string "imov")))
1991    (set (attr "mode")
1992      (if_then_else (eq_attr "type" "imovx")
1993         (const_string "SI")
1994         (const_string "QI")))])
1996 (define_insn "*movqi_extv_1_rex64"
1997   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1998         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1999                          (const_int 8)
2000                          (const_int 8)))]
2001   "TARGET_64BIT"
2003   switch (get_attr_type (insn))
2004     {
2005     case TYPE_IMOVX:
2006       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2007     default:
2008       return "mov{b}\t{%h1, %0|%0, %h1}";
2009     }
2011   [(set (attr "type")
2012      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2013                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2014                              (ne (symbol_ref "TARGET_MOVX")
2015                                  (const_int 0))))
2016         (const_string "imovx")
2017         (const_string "imov")))
2018    (set (attr "mode")
2019      (if_then_else (eq_attr "type" "imovx")
2020         (const_string "SI")
2021         (const_string "QI")))])
2023 ;; Stores and loads of ax to arbitrary constant address.
2024 ;; We fake an second form of instruction to force reload to load address
2025 ;; into register when rax is not available
2026 (define_insn "*movabsqi_1_rex64"
2027   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2028         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2029   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2030   "@
2031    movabs{b}\t{%1, %P0|%P0, %1}
2032    mov{b}\t{%1, %a0|%a0, %1}"
2033   [(set_attr "type" "imov")
2034    (set_attr "modrm" "0,*")
2035    (set_attr "length_address" "8,0")
2036    (set_attr "length_immediate" "0,*")
2037    (set_attr "memory" "store")
2038    (set_attr "mode" "QI")])
2040 (define_insn "*movabsqi_2_rex64"
2041   [(set (match_operand:QI 0 "register_operand" "=a,r")
2042         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2043   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2044   "@
2045    movabs{b}\t{%P1, %0|%0, %P1}
2046    mov{b}\t{%a1, %0|%0, %a1}"
2047   [(set_attr "type" "imov")
2048    (set_attr "modrm" "0,*")
2049    (set_attr "length_address" "8,0")
2050    (set_attr "length_immediate" "0")
2051    (set_attr "memory" "load")
2052    (set_attr "mode" "QI")])
2054 (define_insn "*movdi_extzv_1"
2055   [(set (match_operand:DI 0 "register_operand" "=R")
2056         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2057                          (const_int 8)
2058                          (const_int 8)))]
2059   "TARGET_64BIT"
2060   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2061   [(set_attr "type" "imovx")
2062    (set_attr "mode" "DI")])
2064 (define_insn "*movsi_extzv_1"
2065   [(set (match_operand:SI 0 "register_operand" "=R")
2066         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2067                          (const_int 8)
2068                          (const_int 8)))]
2069   ""
2070   "movz{bl|x}\t{%h1, %0|%0, %h1}"
2071   [(set_attr "type" "imovx")
2072    (set_attr "mode" "SI")])
2074 (define_insn "*movqi_extzv_2"
2075   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2076         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2077                                     (const_int 8)
2078                                     (const_int 8)) 0))]
2079   "!TARGET_64BIT"
2081   switch (get_attr_type (insn))
2082     {
2083     case TYPE_IMOVX:
2084       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2085     default:
2086       return "mov{b}\t{%h1, %0|%0, %h1}";
2087     }
2089   [(set (attr "type")
2090      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2091                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2092                              (ne (symbol_ref "TARGET_MOVX")
2093                                  (const_int 0))))
2094         (const_string "imovx")
2095         (const_string "imov")))
2096    (set (attr "mode")
2097      (if_then_else (eq_attr "type" "imovx")
2098         (const_string "SI")
2099         (const_string "QI")))])
2101 (define_insn "*movqi_extzv_2_rex64"
2102   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2103         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2104                                     (const_int 8)
2105                                     (const_int 8)) 0))]
2106   "TARGET_64BIT"
2108   switch (get_attr_type (insn))
2109     {
2110     case TYPE_IMOVX:
2111       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2112     default:
2113       return "mov{b}\t{%h1, %0|%0, %h1}";
2114     }
2116   [(set (attr "type")
2117      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2118                         (ne (symbol_ref "TARGET_MOVX")
2119                             (const_int 0)))
2120         (const_string "imovx")
2121         (const_string "imov")))
2122    (set (attr "mode")
2123      (if_then_else (eq_attr "type" "imovx")
2124         (const_string "SI")
2125         (const_string "QI")))])
2127 (define_insn "movsi_insv_1"
2128   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2129                          (const_int 8)
2130                          (const_int 8))
2131         (match_operand:SI 1 "general_operand" "Qmn"))]
2132   "!TARGET_64BIT"
2133   "mov{b}\t{%b1, %h0|%h0, %b1}"
2134   [(set_attr "type" "imov")
2135    (set_attr "mode" "QI")])
2137 (define_insn "*movsi_insv_1_rex64"
2138   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2139                          (const_int 8)
2140                          (const_int 8))
2141         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2142   "TARGET_64BIT"
2143   "mov{b}\t{%b1, %h0|%h0, %b1}"
2144   [(set_attr "type" "imov")
2145    (set_attr "mode" "QI")])
2147 (define_insn "movdi_insv_1_rex64"
2148   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2149                          (const_int 8)
2150                          (const_int 8))
2151         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2152   "TARGET_64BIT"
2153   "mov{b}\t{%b1, %h0|%h0, %b1}"
2154   [(set_attr "type" "imov")
2155    (set_attr "mode" "QI")])
2157 (define_insn "*movqi_insv_2"
2158   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2159                          (const_int 8)
2160                          (const_int 8))
2161         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2162                      (const_int 8)))]
2163   ""
2164   "mov{b}\t{%h1, %h0|%h0, %h1}"
2165   [(set_attr "type" "imov")
2166    (set_attr "mode" "QI")])
2168 (define_expand "movdi"
2169   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2170         (match_operand:DI 1 "general_operand" ""))]
2171   ""
2172   "ix86_expand_move (DImode, operands); DONE;")
2174 (define_insn "*pushdi"
2175   [(set (match_operand:DI 0 "push_operand" "=<")
2176         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2177   "!TARGET_64BIT"
2178   "#")
2180 (define_insn "*pushdi2_rex64"
2181   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2182         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2183   "TARGET_64BIT"
2184   "@
2185    push{q}\t%1
2186    #"
2187   [(set_attr "type" "push,multi")
2188    (set_attr "mode" "DI")])
2190 ;; Convert impossible pushes of immediate to existing instructions.
2191 ;; First try to get scratch register and go through it.  In case this
2192 ;; fails, push sign extended lower part first and then overwrite
2193 ;; upper part by 32bit move.
2194 (define_peephole2
2195   [(match_scratch:DI 2 "r")
2196    (set (match_operand:DI 0 "push_operand" "")
2197         (match_operand:DI 1 "immediate_operand" ""))]
2198   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2199    && !x86_64_immediate_operand (operands[1], DImode)"
2200   [(set (match_dup 2) (match_dup 1))
2201    (set (match_dup 0) (match_dup 2))]
2202   "")
2204 ;; We need to define this as both peepholer and splitter for case
2205 ;; peephole2 pass is not run.
2206 ;; "&& 1" is needed to keep it from matching the previous pattern.
2207 (define_peephole2
2208   [(set (match_operand:DI 0 "push_operand" "")
2209         (match_operand:DI 1 "immediate_operand" ""))]
2210   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2211    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2212   [(set (match_dup 0) (match_dup 1))
2213    (set (match_dup 2) (match_dup 3))]
2214   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2215    operands[1] = gen_lowpart (DImode, operands[2]);
2216    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2217                                                     GEN_INT (4)));
2218   ")
2220 (define_split
2221   [(set (match_operand:DI 0 "push_operand" "")
2222         (match_operand:DI 1 "immediate_operand" ""))]
2223   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2224                     ? epilogue_completed : reload_completed)
2225    && !symbolic_operand (operands[1], DImode)
2226    && !x86_64_immediate_operand (operands[1], DImode)"
2227   [(set (match_dup 0) (match_dup 1))
2228    (set (match_dup 2) (match_dup 3))]
2229   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2230    operands[1] = gen_lowpart (DImode, operands[2]);
2231    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2232                                                     GEN_INT (4)));
2233   ")
2235 (define_insn "*pushdi2_prologue_rex64"
2236   [(set (match_operand:DI 0 "push_operand" "=<")
2237         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2238    (clobber (mem:BLK (scratch)))]
2239   "TARGET_64BIT"
2240   "push{q}\t%1"
2241   [(set_attr "type" "push")
2242    (set_attr "mode" "DI")])
2244 (define_insn "*popdi1_epilogue_rex64"
2245   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2246         (mem:DI (reg:DI SP_REG)))
2247    (set (reg:DI SP_REG)
2248         (plus:DI (reg:DI SP_REG) (const_int 8)))
2249    (clobber (mem:BLK (scratch)))]
2250   "TARGET_64BIT"
2251   "pop{q}\t%0"
2252   [(set_attr "type" "pop")
2253    (set_attr "mode" "DI")])
2255 (define_insn "popdi1"
2256   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2257         (mem:DI (reg:DI SP_REG)))
2258    (set (reg:DI SP_REG)
2259         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2260   "TARGET_64BIT"
2261   "pop{q}\t%0"
2262   [(set_attr "type" "pop")
2263    (set_attr "mode" "DI")])
2265 (define_insn "*movdi_xor_rex64"
2266   [(set (match_operand:DI 0 "register_operand" "=r")
2267         (match_operand:DI 1 "const0_operand" ""))
2268    (clobber (reg:CC FLAGS_REG))]
2269   "TARGET_64BIT
2270    && reload_completed"
2271   "xor{l}\t%k0, %k0";
2272   [(set_attr "type" "alu1")
2273    (set_attr "mode" "SI")
2274    (set_attr "length_immediate" "0")])
2276 (define_insn "*movdi_or_rex64"
2277   [(set (match_operand:DI 0 "register_operand" "=r")
2278         (match_operand:DI 1 "const_int_operand" "i"))
2279    (clobber (reg:CC FLAGS_REG))]
2280   "TARGET_64BIT
2281    && reload_completed
2282    && operands[1] == constm1_rtx"
2284   operands[1] = constm1_rtx;
2285   return "or{q}\t{%1, %0|%0, %1}";
2287   [(set_attr "type" "alu1")
2288    (set_attr "mode" "DI")
2289    (set_attr "length_immediate" "1")])
2291 (define_insn "*movdi_2"
2292   [(set (match_operand:DI 0 "nonimmediate_operand"
2293                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2294         (match_operand:DI 1 "general_operand"
2295                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2296   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2297   "@
2298    #
2299    #
2300    pxor\t%0, %0
2301    movq\t{%1, %0|%0, %1}
2302    movq\t{%1, %0|%0, %1}
2303    %vpxor\t%0, %d0
2304    %vmovq\t{%1, %0|%0, %1}
2305    %vmovdqa\t{%1, %0|%0, %1}
2306    %vmovq\t{%1, %0|%0, %1}
2307    xorps\t%0, %0
2308    movlps\t{%1, %0|%0, %1}
2309    movaps\t{%1, %0|%0, %1}
2310    movlps\t{%1, %0|%0, %1}"
2311   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2312    (set (attr "prefix")
2313      (if_then_else (eq_attr "alternative" "5,6,7,8")
2314        (const_string "vex")
2315        (const_string "orig")))
2316    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2318 (define_split
2319   [(set (match_operand:DI 0 "push_operand" "")
2320         (match_operand:DI 1 "general_operand" ""))]
2321   "!TARGET_64BIT && reload_completed
2322    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2323   [(const_int 0)]
2324   "ix86_split_long_move (operands); DONE;")
2326 ;; %%% This multiword shite has got to go.
2327 (define_split
2328   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2329         (match_operand:DI 1 "general_operand" ""))]
2330   "!TARGET_64BIT && reload_completed
2331    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2332    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2333   [(const_int 0)]
2334   "ix86_split_long_move (operands); DONE;")
2336 (define_insn "*movdi_1_rex64"
2337   [(set (match_operand:DI 0 "nonimmediate_operand"
2338           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2339         (match_operand:DI 1 "general_operand"
2340           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2341   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2343   switch (get_attr_type (insn))
2344     {
2345     case TYPE_SSECVT:
2346       if (SSE_REG_P (operands[0]))
2347         return "movq2dq\t{%1, %0|%0, %1}";
2348       else
2349         return "movdq2q\t{%1, %0|%0, %1}";
2351     case TYPE_SSEMOV:
2352       if (TARGET_AVX)
2353         {
2354           if (get_attr_mode (insn) == MODE_TI)
2355             return "vmovdqa\t{%1, %0|%0, %1}";
2356           else
2357             return "vmovq\t{%1, %0|%0, %1}";
2358         }
2360       if (get_attr_mode (insn) == MODE_TI)
2361         return "movdqa\t{%1, %0|%0, %1}";
2362       /* FALLTHRU */
2364     case TYPE_MMXMOV:
2365       /* Moves from and into integer register is done using movd
2366          opcode with REX prefix.  */
2367       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2368         return "movd\t{%1, %0|%0, %1}";
2369       return "movq\t{%1, %0|%0, %1}";
2371     case TYPE_SSELOG1:
2372       return "%vpxor\t%0, %d0";
2374     case TYPE_MMXADD:
2375       return "pxor\t%0, %0";
2377     case TYPE_MULTI:
2378       return "#";
2380     case TYPE_LEA:
2381       return "lea{q}\t{%a1, %0|%0, %a1}";
2383     default:
2384       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2385       if (get_attr_mode (insn) == MODE_SI)
2386         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2387       else if (which_alternative == 2)
2388         return "movabs{q}\t{%1, %0|%0, %1}";
2389       else
2390         return "mov{q}\t{%1, %0|%0, %1}";
2391     }
2393   [(set (attr "type")
2394      (cond [(eq_attr "alternative" "5")
2395               (const_string "mmxadd")
2396             (eq_attr "alternative" "6,7,8,9,10")
2397               (const_string "mmxmov")
2398             (eq_attr "alternative" "11")
2399               (const_string "sselog1")
2400             (eq_attr "alternative" "12,13,14,15,16")
2401               (const_string "ssemov")
2402             (eq_attr "alternative" "17,18")
2403               (const_string "ssecvt")
2404             (eq_attr "alternative" "4")
2405               (const_string "multi")
2406             (match_operand:DI 1 "pic_32bit_operand" "")
2407               (const_string "lea")
2408            ]
2409            (const_string "imov")))
2410    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2411    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2412    (set (attr "prefix")
2413      (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2414        (const_string "maybe_vex")
2415        (const_string "orig")))
2416    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2418 ;; Stores and loads of ax to arbitrary constant address.
2419 ;; We fake an second form of instruction to force reload to load address
2420 ;; into register when rax is not available
2421 (define_insn "*movabsdi_1_rex64"
2422   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2423         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2424   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2425   "@
2426    movabs{q}\t{%1, %P0|%P0, %1}
2427    mov{q}\t{%1, %a0|%a0, %1}"
2428   [(set_attr "type" "imov")
2429    (set_attr "modrm" "0,*")
2430    (set_attr "length_address" "8,0")
2431    (set_attr "length_immediate" "0,*")
2432    (set_attr "memory" "store")
2433    (set_attr "mode" "DI")])
2435 (define_insn "*movabsdi_2_rex64"
2436   [(set (match_operand:DI 0 "register_operand" "=a,r")
2437         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2438   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2439   "@
2440    movabs{q}\t{%P1, %0|%0, %P1}
2441    mov{q}\t{%a1, %0|%0, %a1}"
2442   [(set_attr "type" "imov")
2443    (set_attr "modrm" "0,*")
2444    (set_attr "length_address" "8,0")
2445    (set_attr "length_immediate" "0")
2446    (set_attr "memory" "load")
2447    (set_attr "mode" "DI")])
2449 ;; Convert impossible stores of immediate to existing instructions.
2450 ;; First try to get scratch register and go through it.  In case this
2451 ;; fails, move by 32bit parts.
2452 (define_peephole2
2453   [(match_scratch:DI 2 "r")
2454    (set (match_operand:DI 0 "memory_operand" "")
2455         (match_operand:DI 1 "immediate_operand" ""))]
2456   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2457    && !x86_64_immediate_operand (operands[1], DImode)"
2458   [(set (match_dup 2) (match_dup 1))
2459    (set (match_dup 0) (match_dup 2))]
2460   "")
2462 ;; We need to define this as both peepholer and splitter for case
2463 ;; peephole2 pass is not run.
2464 ;; "&& 1" is needed to keep it from matching the previous pattern.
2465 (define_peephole2
2466   [(set (match_operand:DI 0 "memory_operand" "")
2467         (match_operand:DI 1 "immediate_operand" ""))]
2468   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2469    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2470   [(set (match_dup 2) (match_dup 3))
2471    (set (match_dup 4) (match_dup 5))]
2472   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2474 (define_split
2475   [(set (match_operand:DI 0 "memory_operand" "")
2476         (match_operand:DI 1 "immediate_operand" ""))]
2477   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2478                     ? epilogue_completed : reload_completed)
2479    && !symbolic_operand (operands[1], DImode)
2480    && !x86_64_immediate_operand (operands[1], DImode)"
2481   [(set (match_dup 2) (match_dup 3))
2482    (set (match_dup 4) (match_dup 5))]
2483   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2485 (define_insn "*swapdi_rex64"
2486   [(set (match_operand:DI 0 "register_operand" "+r")
2487         (match_operand:DI 1 "register_operand" "+r"))
2488    (set (match_dup 1)
2489         (match_dup 0))]
2490   "TARGET_64BIT"
2491   "xchg{q}\t%1, %0"
2492   [(set_attr "type" "imov")
2493    (set_attr "mode" "DI")
2494    (set_attr "pent_pair" "np")
2495    (set_attr "athlon_decode" "vector")
2496    (set_attr "amdfam10_decode" "double")])
2498 (define_expand "movoi"
2499   [(set (match_operand:OI 0 "nonimmediate_operand" "")
2500         (match_operand:OI 1 "general_operand" ""))]
2501   "TARGET_AVX"
2502   "ix86_expand_move (OImode, operands); DONE;")
2504 (define_insn "*movoi_internal"
2505   [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2506         (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2507   "TARGET_AVX
2508    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2510   switch (which_alternative)
2511     {
2512     case 0:
2513       return "vxorps\t%0, %0, %0";
2514     case 1:
2515     case 2:
2516       if (misaligned_operand (operands[0], OImode)
2517           || misaligned_operand (operands[1], OImode))
2518         return "vmovdqu\t{%1, %0|%0, %1}";
2519       else
2520         return "vmovdqa\t{%1, %0|%0, %1}";
2521     default:
2522       gcc_unreachable ();
2523     }
2525   [(set_attr "type" "sselog1,ssemov,ssemov")
2526    (set_attr "prefix" "vex")
2527    (set_attr "mode" "OI")])
2529 (define_expand "movti"
2530   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2531         (match_operand:TI 1 "nonimmediate_operand" ""))]
2532   "TARGET_SSE || TARGET_64BIT"
2534   if (TARGET_64BIT)
2535     ix86_expand_move (TImode, operands);
2536   else if (push_operand (operands[0], TImode))
2537     ix86_expand_push (TImode, operands[1]);
2538   else
2539     ix86_expand_vector_move (TImode, operands);
2540   DONE;
2543 (define_insn "*movti_internal"
2544   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2545         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2546   "TARGET_SSE && !TARGET_64BIT
2547    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2549   switch (which_alternative)
2550     {
2551     case 0:
2552       if (get_attr_mode (insn) == MODE_V4SF)
2553         return "%vxorps\t%0, %d0";
2554       else
2555         return "%vpxor\t%0, %d0";
2556     case 1:
2557     case 2:
2558       /* TDmode values are passed as TImode on the stack.  Moving them
2559          to stack may result in unaligned memory access.  */
2560       if (misaligned_operand (operands[0], TImode)
2561           || misaligned_operand (operands[1], TImode))
2562         {
2563           if (get_attr_mode (insn) == MODE_V4SF)
2564             return "%vmovups\t{%1, %0|%0, %1}";
2565          else
2566            return "%vmovdqu\t{%1, %0|%0, %1}";
2567         }
2568       else
2569         {
2570           if (get_attr_mode (insn) == MODE_V4SF)
2571             return "%vmovaps\t{%1, %0|%0, %1}";
2572          else
2573            return "%vmovdqa\t{%1, %0|%0, %1}";
2574         }
2575     default:
2576       gcc_unreachable ();
2577     }
2579   [(set_attr "type" "sselog1,ssemov,ssemov")
2580    (set_attr "prefix" "maybe_vex")
2581    (set (attr "mode")
2582         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2583                     (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2584                  (const_string "V4SF")
2585                (and (eq_attr "alternative" "2")
2586                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2587                         (const_int 0)))
2588                  (const_string "V4SF")]
2589               (const_string "TI")))])
2591 (define_insn "*movti_rex64"
2592   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2593         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2594   "TARGET_64BIT
2595    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2597   switch (which_alternative)
2598     {
2599     case 0:
2600     case 1:
2601       return "#";
2602     case 2:
2603       if (get_attr_mode (insn) == MODE_V4SF)
2604         return "%vxorps\t%0, %d0";
2605       else
2606         return "%vpxor\t%0, %d0";
2607     case 3:
2608     case 4:
2609       /* TDmode values are passed as TImode on the stack.  Moving them
2610          to stack may result in unaligned memory access.  */
2611       if (misaligned_operand (operands[0], TImode)
2612           || misaligned_operand (operands[1], TImode))
2613         {
2614           if (get_attr_mode (insn) == MODE_V4SF)
2615             return "%vmovups\t{%1, %0|%0, %1}";
2616          else
2617            return "%vmovdqu\t{%1, %0|%0, %1}";
2618         }
2619       else
2620         {
2621           if (get_attr_mode (insn) == MODE_V4SF)
2622             return "%vmovaps\t{%1, %0|%0, %1}";
2623          else
2624            return "%vmovdqa\t{%1, %0|%0, %1}";
2625         }
2626     default:
2627       gcc_unreachable ();
2628     }
2630   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2631    (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2632    (set (attr "mode")
2633         (cond [(eq_attr "alternative" "2,3")
2634                  (if_then_else
2635                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2636                        (const_int 0))
2637                    (const_string "V4SF")
2638                    (const_string "TI"))
2639                (eq_attr "alternative" "4")
2640                  (if_then_else
2641                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2642                             (const_int 0))
2643                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2644                             (const_int 0)))
2645                    (const_string "V4SF")
2646                    (const_string "TI"))]
2647                (const_string "DI")))])
2649 (define_split
2650   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2651         (match_operand:TI 1 "general_operand" ""))]
2652   "reload_completed && !SSE_REG_P (operands[0])
2653    && !SSE_REG_P (operands[1])"
2654   [(const_int 0)]
2655   "ix86_split_long_move (operands); DONE;")
2657 ;; This expands to what emit_move_complex would generate if we didn't
2658 ;; have a movti pattern.  Having this avoids problems with reload on
2659 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2660 ;; to have around all the time.
2661 (define_expand "movcdi"
2662   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2663         (match_operand:CDI 1 "general_operand" ""))]
2664   ""
2666   if (push_operand (operands[0], CDImode))
2667     emit_move_complex_push (CDImode, operands[0], operands[1]);
2668   else
2669     emit_move_complex_parts (operands[0], operands[1]);
2670   DONE;
2673 (define_expand "movsf"
2674   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2675         (match_operand:SF 1 "general_operand" ""))]
2676   ""
2677   "ix86_expand_move (SFmode, operands); DONE;")
2679 (define_insn "*pushsf"
2680   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2681         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2682   "!TARGET_64BIT"
2684   /* Anything else should be already split before reg-stack.  */
2685   gcc_assert (which_alternative == 1);
2686   return "push{l}\t%1";
2688   [(set_attr "type" "multi,push,multi")
2689    (set_attr "unit" "i387,*,*")
2690    (set_attr "mode" "SF,SI,SF")])
2692 (define_insn "*pushsf_rex64"
2693   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2694         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2695   "TARGET_64BIT"
2697   /* Anything else should be already split before reg-stack.  */
2698   gcc_assert (which_alternative == 1);
2699   return "push{q}\t%q1";
2701   [(set_attr "type" "multi,push,multi")
2702    (set_attr "unit" "i387,*,*")
2703    (set_attr "mode" "SF,DI,SF")])
2705 (define_split
2706   [(set (match_operand:SF 0 "push_operand" "")
2707         (match_operand:SF 1 "memory_operand" ""))]
2708   "reload_completed
2709    && MEM_P (operands[1])
2710    && (operands[2] = find_constant_src (insn))"
2711   [(set (match_dup 0)
2712         (match_dup 2))])
2715 ;; %%% Kill this when call knows how to work this out.
2716 (define_split
2717   [(set (match_operand:SF 0 "push_operand" "")
2718         (match_operand:SF 1 "any_fp_register_operand" ""))]
2719   "!TARGET_64BIT"
2720   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2721    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2723 (define_split
2724   [(set (match_operand:SF 0 "push_operand" "")
2725         (match_operand:SF 1 "any_fp_register_operand" ""))]
2726   "TARGET_64BIT"
2727   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2728    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2730 (define_insn "*movsf_1"
2731   [(set (match_operand:SF 0 "nonimmediate_operand"
2732           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2733         (match_operand:SF 1 "general_operand"
2734           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2735   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2736    && (reload_in_progress || reload_completed
2737        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2738        || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2739            && standard_80387_constant_p (operands[1]))
2740        || GET_CODE (operands[1]) != CONST_DOUBLE
2741        || memory_operand (operands[0], SFmode))"
2743   switch (which_alternative)
2744     {
2745     case 0:
2746     case 1:
2747       return output_387_reg_move (insn, operands);
2749     case 2:
2750       return standard_80387_constant_opcode (operands[1]);
2752     case 3:
2753     case 4:
2754       return "mov{l}\t{%1, %0|%0, %1}";
2755     case 5:
2756       if (get_attr_mode (insn) == MODE_TI)
2757         return "%vpxor\t%0, %d0";
2758       else
2759         return "%vxorps\t%0, %d0";
2760     case 6:
2761       if (get_attr_mode (insn) == MODE_V4SF)
2762         return "%vmovaps\t{%1, %0|%0, %1}";
2763       else
2764         return "%vmovss\t{%1, %d0|%d0, %1}";
2765     case 7:
2766       if (TARGET_AVX)
2767         return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2768                                    : "vmovss\t{%1, %0|%0, %1}";
2769       else
2770         return "movss\t{%1, %0|%0, %1}";
2771     case 8:
2772       return "%vmovss\t{%1, %0|%0, %1}";
2774     case 9: case 10: case 14: case 15:
2775       return "movd\t{%1, %0|%0, %1}";
2776     case 12: case 13:
2777       return "%vmovd\t{%1, %0|%0, %1}";
2779     case 11:
2780       return "movq\t{%1, %0|%0, %1}";
2782     default:
2783       gcc_unreachable ();
2784     }
2786   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2787    (set (attr "prefix")
2788      (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2789        (const_string "maybe_vex")
2790        (const_string "orig")))
2791    (set (attr "mode")
2792         (cond [(eq_attr "alternative" "3,4,9,10")
2793                  (const_string "SI")
2794                (eq_attr "alternative" "5")
2795                  (if_then_else
2796                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2797                                  (const_int 0))
2798                              (ne (symbol_ref "TARGET_SSE2")
2799                                  (const_int 0)))
2800                         (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2801                             (const_int 0)))
2802                    (const_string "TI")
2803                    (const_string "V4SF"))
2804                /* For architectures resolving dependencies on
2805                   whole SSE registers use APS move to break dependency
2806                   chains, otherwise use short move to avoid extra work.
2808                   Do the same for architectures resolving dependencies on
2809                   the parts.  While in DF mode it is better to always handle
2810                   just register parts, the SF mode is different due to lack
2811                   of instructions to load just part of the register.  It is
2812                   better to maintain the whole registers in single format
2813                   to avoid problems on using packed logical operations.  */
2814                (eq_attr "alternative" "6")
2815                  (if_then_else
2816                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2817                             (const_int 0))
2818                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2819                             (const_int 0)))
2820                    (const_string "V4SF")
2821                    (const_string "SF"))
2822                (eq_attr "alternative" "11")
2823                  (const_string "DI")]
2824                (const_string "SF")))])
2826 (define_insn "*swapsf"
2827   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2828         (match_operand:SF 1 "fp_register_operand" "+f"))
2829    (set (match_dup 1)
2830         (match_dup 0))]
2831   "reload_completed || TARGET_80387"
2833   if (STACK_TOP_P (operands[0]))
2834     return "fxch\t%1";
2835   else
2836     return "fxch\t%0";
2838   [(set_attr "type" "fxch")
2839    (set_attr "mode" "SF")])
2841 (define_expand "movdf"
2842   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2843         (match_operand:DF 1 "general_operand" ""))]
2844   ""
2845   "ix86_expand_move (DFmode, operands); DONE;")
2847 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2848 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2849 ;; On the average, pushdf using integers can be still shorter.  Allow this
2850 ;; pattern for optimize_size too.
2852 (define_insn "*pushdf_nointeger"
2853   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2854         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2855   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2857   /* This insn should be already split before reg-stack.  */
2858   gcc_unreachable ();
2860   [(set_attr "type" "multi")
2861    (set_attr "unit" "i387,*,*,*")
2862    (set_attr "mode" "DF,SI,SI,DF")])
2864 (define_insn "*pushdf_integer"
2865   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2866         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2867   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2869   /* This insn should be already split before reg-stack.  */
2870   gcc_unreachable ();
2872   [(set_attr "type" "multi")
2873    (set_attr "unit" "i387,*,*")
2874    (set_attr "mode" "DF,SI,DF")])
2876 ;; %%% Kill this when call knows how to work this out.
2877 (define_split
2878   [(set (match_operand:DF 0 "push_operand" "")
2879         (match_operand:DF 1 "any_fp_register_operand" ""))]
2880   "reload_completed"
2881   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2882    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2883   "")
2885 (define_split
2886   [(set (match_operand:DF 0 "push_operand" "")
2887         (match_operand:DF 1 "general_operand" ""))]
2888   "reload_completed"
2889   [(const_int 0)]
2890   "ix86_split_long_move (operands); DONE;")
2892 ;; Moving is usually shorter when only FP registers are used. This separate
2893 ;; movdf pattern avoids the use of integer registers for FP operations
2894 ;; when optimizing for size.
2896 (define_insn "*movdf_nointeger"
2897   [(set (match_operand:DF 0 "nonimmediate_operand"
2898                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2899         (match_operand:DF 1 "general_operand"
2900                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2901   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2902    && ((optimize_function_for_size_p (cfun)
2903        || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2904    && (reload_in_progress || reload_completed
2905        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2906        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2907            && optimize_function_for_size_p (cfun)
2908            && !memory_operand (operands[0], DFmode)
2909            && standard_80387_constant_p (operands[1]))
2910        || GET_CODE (operands[1]) != CONST_DOUBLE
2911        || ((optimize_function_for_size_p (cfun)
2912             || !TARGET_MEMORY_MISMATCH_STALL
2913             || reload_in_progress || reload_completed)
2914            && memory_operand (operands[0], DFmode)))"
2916   switch (which_alternative)
2917     {
2918     case 0:
2919     case 1:
2920       return output_387_reg_move (insn, operands);
2922     case 2:
2923       return standard_80387_constant_opcode (operands[1]);
2925     case 3:
2926     case 4:
2927       return "#";
2928     case 5:
2929       switch (get_attr_mode (insn))
2930         {
2931         case MODE_V4SF:
2932           return "%vxorps\t%0, %d0";
2933         case MODE_V2DF:
2934           return "%vxorpd\t%0, %d0";
2935         case MODE_TI:
2936           return "%vpxor\t%0, %d0";
2937         default:
2938           gcc_unreachable ();
2939         }
2940     case 6:
2941     case 7:
2942     case 8:
2943       switch (get_attr_mode (insn))
2944         {
2945         case MODE_V4SF:
2946           return "%vmovaps\t{%1, %0|%0, %1}";
2947         case MODE_V2DF:
2948           return "%vmovapd\t{%1, %0|%0, %1}";
2949         case MODE_TI:
2950           return "%vmovdqa\t{%1, %0|%0, %1}";
2951         case MODE_DI:
2952           return "%vmovq\t{%1, %0|%0, %1}";
2953         case MODE_DF:
2954           if (TARGET_AVX)
2955             {
2956               if (REG_P (operands[0]) && REG_P (operands[1]))
2957                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2958               else
2959                 return "vmovsd\t{%1, %0|%0, %1}";
2960             }
2961           else
2962             return "movsd\t{%1, %0|%0, %1}";
2963         case MODE_V1DF:
2964           if (TARGET_AVX)
2965             {
2966               if (REG_P (operands[0]))
2967                 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
2968               else
2969                 return "vmovlpd\t{%1, %0|%0, %1}";
2970             }
2971           else
2972             return "movlpd\t{%1, %0|%0, %1}";
2973         case MODE_V2SF:
2974           if (TARGET_AVX)
2975             {
2976               if (REG_P (operands[0]))
2977                 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
2978               else
2979                 return "vmovlps\t{%1, %0|%0, %1}";
2980             }
2981           else
2982             return "movlps\t{%1, %0|%0, %1}";
2983         default:
2984           gcc_unreachable ();
2985         }
2987     default:
2988       gcc_unreachable ();
2989     }
2991   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2992    (set (attr "prefix")
2993      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2994        (const_string "orig")
2995        (const_string "maybe_vex")))
2996    (set (attr "mode")
2997         (cond [(eq_attr "alternative" "0,1,2")
2998                  (const_string "DF")
2999                (eq_attr "alternative" "3,4")
3000                  (const_string "SI")
3002                /* For SSE1, we have many fewer alternatives.  */
3003                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3004                  (cond [(eq_attr "alternative" "5,6")
3005                           (const_string "V4SF")
3006                        ]
3007                    (const_string "V2SF"))
3009                /* xorps is one byte shorter.  */
3010                (eq_attr "alternative" "5")
3011                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3012                             (const_int 0))
3013                           (const_string "V4SF")
3014                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3015                             (const_int 0))
3016                           (const_string "TI")
3017                        ]
3018                        (const_string "V2DF"))
3020                /* For architectures resolving dependencies on
3021                   whole SSE registers use APD move to break dependency
3022                   chains, otherwise use short move to avoid extra work.
3024                   movaps encodes one byte shorter.  */
3025                (eq_attr "alternative" "6")
3026                  (cond
3027                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3028                         (const_int 0))
3029                       (const_string "V4SF")
3030                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3031                         (const_int 0))
3032                       (const_string "V2DF")
3033                    ]
3034                    (const_string "DF"))
3035                /* For architectures resolving dependencies on register
3036                   parts we may avoid extra work to zero out upper part
3037                   of register.  */
3038                (eq_attr "alternative" "7")
3039                  (if_then_else
3040                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3041                        (const_int 0))
3042                    (const_string "V1DF")
3043                    (const_string "DF"))
3044               ]
3045               (const_string "DF")))])
3047 (define_insn "*movdf_integer_rex64"
3048   [(set (match_operand:DF 0 "nonimmediate_operand"
3049                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
3050         (match_operand:DF 1 "general_operand"
3051                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
3052   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3053    && (reload_in_progress || reload_completed
3054        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3055        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3056            && optimize_function_for_size_p (cfun)
3057            && standard_80387_constant_p (operands[1]))
3058        || GET_CODE (operands[1]) != CONST_DOUBLE
3059        || memory_operand (operands[0], DFmode))"
3061   switch (which_alternative)
3062     {
3063     case 0:
3064     case 1:
3065       return output_387_reg_move (insn, operands);
3067     case 2:
3068       return standard_80387_constant_opcode (operands[1]);
3070     case 3:
3071     case 4:
3072       return "#";
3074     case 5:
3075       switch (get_attr_mode (insn))
3076         {
3077         case MODE_V4SF:
3078           return "%vxorps\t%0, %d0";
3079         case MODE_V2DF:
3080           return "%vxorpd\t%0, %d0";
3081         case MODE_TI:
3082           return "%vpxor\t%0, %d0";
3083         default:
3084           gcc_unreachable ();
3085         }
3086     case 6:
3087     case 7:
3088     case 8:
3089       switch (get_attr_mode (insn))
3090         {
3091         case MODE_V4SF:
3092           return "%vmovaps\t{%1, %0|%0, %1}";
3093         case MODE_V2DF:
3094           return "%vmovapd\t{%1, %0|%0, %1}";
3095         case MODE_TI:
3096           return "%vmovdqa\t{%1, %0|%0, %1}";
3097         case MODE_DI:
3098           return "%vmovq\t{%1, %0|%0, %1}";
3099         case MODE_DF:
3100           if (TARGET_AVX)
3101             {
3102               if (REG_P (operands[0]) && REG_P (operands[1]))
3103                 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3104               else
3105                 return "vmovsd\t{%1, %0|%0, %1}";
3106             }
3107           else
3108             return "movsd\t{%1, %0|%0, %1}";
3109         case MODE_V1DF:
3110           return "%vmovlpd\t{%1, %d0|%d0, %1}";
3111         case MODE_V2SF:
3112           return "%vmovlps\t{%1, %d0|%d0, %1}";
3113         default:
3114           gcc_unreachable ();
3115         }
3117     case 9:
3118     case 10:
3119     return "%vmovd\t{%1, %0|%0, %1}";
3121     default:
3122       gcc_unreachable();
3123     }
3125   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3126    (set (attr "prefix")
3127      (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3128        (const_string "orig")
3129        (const_string "maybe_vex")))
3130    (set (attr "mode")
3131         (cond [(eq_attr "alternative" "0,1,2")
3132                  (const_string "DF")
3133                (eq_attr "alternative" "3,4,9,10")
3134                  (const_string "DI")
3136                /* For SSE1, we have many fewer alternatives.  */
3137                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3138                  (cond [(eq_attr "alternative" "5,6")
3139                           (const_string "V4SF")
3140                        ]
3141                    (const_string "V2SF"))
3143                /* xorps is one byte shorter.  */
3144                (eq_attr "alternative" "5")
3145                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3146                             (const_int 0))
3147                           (const_string "V4SF")
3148                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3149                             (const_int 0))
3150                           (const_string "TI")
3151                        ]
3152                        (const_string "V2DF"))
3154                /* For architectures resolving dependencies on
3155                   whole SSE registers use APD move to break dependency
3156                   chains, otherwise use short move to avoid extra work.
3158                   movaps encodes one byte shorter.  */
3159                (eq_attr "alternative" "6")
3160                  (cond
3161                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3162                         (const_int 0))
3163                       (const_string "V4SF")
3164                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3165                         (const_int 0))
3166                       (const_string "V2DF")
3167                    ]
3168                    (const_string "DF"))
3169                /* For architectures resolving dependencies on register
3170                   parts we may avoid extra work to zero out upper part
3171                   of register.  */
3172                (eq_attr "alternative" "7")
3173                  (if_then_else
3174                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3175                        (const_int 0))
3176                    (const_string "V1DF")
3177                    (const_string "DF"))
3178               ]
3179               (const_string "DF")))])
3181 (define_insn "*movdf_integer"
3182   [(set (match_operand:DF 0 "nonimmediate_operand"
3183                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3184         (match_operand:DF 1 "general_operand"
3185                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3186   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3187    && optimize_function_for_speed_p (cfun)
3188    && TARGET_INTEGER_DFMODE_MOVES
3189    && (reload_in_progress || reload_completed
3190        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3191        || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3192            && optimize_function_for_size_p (cfun)
3193            && standard_80387_constant_p (operands[1]))
3194        || GET_CODE (operands[1]) != CONST_DOUBLE
3195        || memory_operand (operands[0], DFmode))"
3197   switch (which_alternative)
3198     {
3199     case 0:
3200     case 1:
3201       return output_387_reg_move (insn, operands);
3203     case 2:
3204       return standard_80387_constant_opcode (operands[1]);
3206     case 3:
3207     case 4:
3208       return "#";
3210     case 5:
3211       switch (get_attr_mode (insn))
3212         {
3213         case MODE_V4SF:
3214           return "xorps\t%0, %0";
3215         case MODE_V2DF:
3216           return "xorpd\t%0, %0";
3217         case MODE_TI:
3218           return "pxor\t%0, %0";
3219         default:
3220           gcc_unreachable ();
3221         }
3222     case 6:
3223     case 7:
3224     case 8:
3225       switch (get_attr_mode (insn))
3226         {
3227         case MODE_V4SF:
3228           return "movaps\t{%1, %0|%0, %1}";
3229         case MODE_V2DF:
3230           return "movapd\t{%1, %0|%0, %1}";
3231         case MODE_TI:
3232           return "movdqa\t{%1, %0|%0, %1}";
3233         case MODE_DI:
3234           return "movq\t{%1, %0|%0, %1}";
3235         case MODE_DF:
3236           return "movsd\t{%1, %0|%0, %1}";
3237         case MODE_V1DF:
3238           return "movlpd\t{%1, %0|%0, %1}";
3239         case MODE_V2SF:
3240           return "movlps\t{%1, %0|%0, %1}";
3241         default:
3242           gcc_unreachable ();
3243         }
3245     default:
3246       gcc_unreachable();
3247     }
3249   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3250    (set (attr "mode")
3251         (cond [(eq_attr "alternative" "0,1,2")
3252                  (const_string "DF")
3253                (eq_attr "alternative" "3,4")
3254                  (const_string "SI")
3256                /* For SSE1, we have many fewer alternatives.  */
3257                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3258                  (cond [(eq_attr "alternative" "5,6")
3259                           (const_string "V4SF")
3260                        ]
3261                    (const_string "V2SF"))
3263                /* xorps is one byte shorter.  */
3264                (eq_attr "alternative" "5")
3265                  (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3266                             (const_int 0))
3267                           (const_string "V4SF")
3268                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3269                             (const_int 0))
3270                           (const_string "TI")
3271                        ]
3272                        (const_string "V2DF"))
3274                /* For architectures resolving dependencies on
3275                   whole SSE registers use APD move to break dependency
3276                   chains, otherwise use short move to avoid extra work.
3278                   movaps encodes one byte shorter.  */
3279                (eq_attr "alternative" "6")
3280                  (cond
3281                    [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3282                         (const_int 0))
3283                       (const_string "V4SF")
3284                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3285                         (const_int 0))
3286                       (const_string "V2DF")
3287                    ]
3288                    (const_string "DF"))
3289                /* For architectures resolving dependencies on register
3290                   parts we may avoid extra work to zero out upper part
3291                   of register.  */
3292                (eq_attr "alternative" "7")
3293                  (if_then_else
3294                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3295                        (const_int 0))
3296                    (const_string "V1DF")
3297                    (const_string "DF"))
3298               ]
3299               (const_string "DF")))])
3301 (define_split
3302   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3303         (match_operand:DF 1 "general_operand" ""))]
3304   "reload_completed
3305    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3306    && ! (ANY_FP_REG_P (operands[0]) ||
3307          (GET_CODE (operands[0]) == SUBREG
3308           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3309    && ! (ANY_FP_REG_P (operands[1]) ||
3310          (GET_CODE (operands[1]) == SUBREG
3311           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3312   [(const_int 0)]
3313   "ix86_split_long_move (operands); DONE;")
3315 (define_insn "*swapdf"
3316   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3317         (match_operand:DF 1 "fp_register_operand" "+f"))
3318    (set (match_dup 1)
3319         (match_dup 0))]
3320   "reload_completed || TARGET_80387"
3322   if (STACK_TOP_P (operands[0]))
3323     return "fxch\t%1";
3324   else
3325     return "fxch\t%0";
3327   [(set_attr "type" "fxch")
3328    (set_attr "mode" "DF")])
3330 (define_expand "movxf"
3331   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3332         (match_operand:XF 1 "general_operand" ""))]
3333   ""
3334   "ix86_expand_move (XFmode, operands); DONE;")
3336 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3337 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3338 ;; Pushing using integer instructions is longer except for constants
3339 ;; and direct memory references.
3340 ;; (assuming that any given constant is pushed only once, but this ought to be
3341 ;;  handled elsewhere).
3343 (define_insn "*pushxf_nointeger"
3344   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3345         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3346   "optimize_function_for_size_p (cfun)"
3348   /* This insn should be already split before reg-stack.  */
3349   gcc_unreachable ();
3351   [(set_attr "type" "multi")
3352    (set_attr "unit" "i387,*,*")
3353    (set_attr "mode" "XF,SI,SI")])
3355 (define_insn "*pushxf_integer"
3356   [(set (match_operand:XF 0 "push_operand" "=<,<")
3357         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3358   "optimize_function_for_speed_p (cfun)"
3360   /* This insn should be already split before reg-stack.  */
3361   gcc_unreachable ();
3363   [(set_attr "type" "multi")
3364    (set_attr "unit" "i387,*")
3365    (set_attr "mode" "XF,SI")])
3367 (define_split
3368   [(set (match_operand 0 "push_operand" "")
3369         (match_operand 1 "general_operand" ""))]
3370   "reload_completed
3371    && (GET_MODE (operands[0]) == XFmode
3372        || GET_MODE (operands[0]) == DFmode)
3373    && !ANY_FP_REG_P (operands[1])"
3374   [(const_int 0)]
3375   "ix86_split_long_move (operands); DONE;")
3377 (define_split
3378   [(set (match_operand:XF 0 "push_operand" "")
3379         (match_operand:XF 1 "any_fp_register_operand" ""))]
3380   ""
3381   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3382    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3383   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3385 ;; Do not use integer registers when optimizing for size
3386 (define_insn "*movxf_nointeger"
3387   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3388         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3389   "optimize_function_for_size_p (cfun)
3390    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3391    && (reload_in_progress || reload_completed
3392        || standard_80387_constant_p (operands[1])
3393        || GET_CODE (operands[1]) != CONST_DOUBLE
3394        || memory_operand (operands[0], XFmode))"
3396   switch (which_alternative)
3397     {
3398     case 0:
3399     case 1:
3400       return output_387_reg_move (insn, operands);
3402     case 2:
3403       return standard_80387_constant_opcode (operands[1]);
3405     case 3: case 4:
3406       return "#";
3407     default:
3408       gcc_unreachable ();
3409     }
3411   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3412    (set_attr "mode" "XF,XF,XF,SI,SI")])
3414 (define_insn "*movxf_integer"
3415   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3416         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3417   "optimize_function_for_speed_p (cfun)
3418    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3419    && (reload_in_progress || reload_completed
3420        || GET_CODE (operands[1]) != CONST_DOUBLE
3421        || memory_operand (operands[0], XFmode))"
3423   switch (which_alternative)
3424     {
3425     case 0:
3426     case 1:
3427       return output_387_reg_move (insn, operands);
3429     case 2:
3430       return standard_80387_constant_opcode (operands[1]);
3432     case 3: case 4:
3433       return "#";
3435     default:
3436       gcc_unreachable ();
3437     }
3439   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3440    (set_attr "mode" "XF,XF,XF,SI,SI")])
3442 (define_expand "movtf"
3443   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3444         (match_operand:TF 1 "nonimmediate_operand" ""))]
3445   "TARGET_SSE2"
3447   ix86_expand_move (TFmode, operands);
3448   DONE;
3451 (define_insn "*movtf_internal"
3452   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3453         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3454   "TARGET_SSE2
3455    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3457   switch (which_alternative)
3458     {
3459     case 0:
3460     case 1:
3461       if (get_attr_mode (insn) == MODE_V4SF)
3462         return "%vmovaps\t{%1, %0|%0, %1}";
3463       else
3464         return "%vmovdqa\t{%1, %0|%0, %1}";
3465     case 2:
3466       if (get_attr_mode (insn) == MODE_V4SF)
3467         return "%vxorps\t%0, %d0";
3468       else
3469         return "%vpxor\t%0, %d0";
3470     case 3:
3471     case 4:
3472         return "#";
3473     default:
3474       gcc_unreachable ();
3475     }
3477   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3478    (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3479    (set (attr "mode")
3480         (cond [(eq_attr "alternative" "0,2")
3481                  (if_then_else
3482                    (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3483                        (const_int 0))
3484                    (const_string "V4SF")
3485                    (const_string "TI"))
3486                (eq_attr "alternative" "1")
3487                  (if_then_else
3488                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3489                             (const_int 0))
3490                         (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3491                             (const_int 0)))
3492                    (const_string "V4SF")
3493                    (const_string "TI"))]
3494                (const_string "DI")))])
3496 (define_insn "*pushtf_sse"
3497   [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3498         (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3499   "TARGET_SSE2"
3501   /* This insn should be already split before reg-stack.  */
3502   gcc_unreachable ();
3504   [(set_attr "type" "multi")
3505    (set_attr "unit" "sse,*,*")
3506    (set_attr "mode" "TF,SI,SI")])
3508 (define_split
3509   [(set (match_operand:TF 0 "push_operand" "")
3510         (match_operand:TF 1 "general_operand" ""))]
3511   "TARGET_SSE2 && reload_completed
3512    && !SSE_REG_P (operands[1])"
3513   [(const_int 0)]
3514   "ix86_split_long_move (operands); DONE;")
3516 (define_split
3517   [(set (match_operand:TF 0 "push_operand" "")
3518         (match_operand:TF 1 "any_fp_register_operand" ""))]
3519   "TARGET_SSE2"
3520   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3521    (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3522   "")
3524 (define_split
3525   [(set (match_operand 0 "nonimmediate_operand" "")
3526         (match_operand 1 "general_operand" ""))]
3527   "reload_completed
3528    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3529    && GET_MODE (operands[0]) == XFmode
3530    && ! (ANY_FP_REG_P (operands[0]) ||
3531          (GET_CODE (operands[0]) == SUBREG
3532           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3533    && ! (ANY_FP_REG_P (operands[1]) ||
3534          (GET_CODE (operands[1]) == SUBREG
3535           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3536   [(const_int 0)]
3537   "ix86_split_long_move (operands); DONE;")
3539 (define_split
3540   [(set (match_operand 0 "register_operand" "")
3541         (match_operand 1 "memory_operand" ""))]
3542   "reload_completed
3543    && MEM_P (operands[1])
3544    && (GET_MODE (operands[0]) == TFmode
3545        || GET_MODE (operands[0]) == XFmode
3546        || GET_MODE (operands[0]) == SFmode
3547        || GET_MODE (operands[0]) == DFmode)
3548    && (operands[2] = find_constant_src (insn))"
3549   [(set (match_dup 0) (match_dup 2))]
3551   rtx c = operands[2];
3552   rtx r = operands[0];
3554   if (GET_CODE (r) == SUBREG)
3555     r = SUBREG_REG (r);
3557   if (SSE_REG_P (r))
3558     {
3559       if (!standard_sse_constant_p (c))
3560         FAIL;
3561     }
3562   else if (FP_REG_P (r))
3563     {
3564       if (!standard_80387_constant_p (c))
3565         FAIL;
3566     }
3567   else if (MMX_REG_P (r))
3568     FAIL;
3571 (define_split
3572   [(set (match_operand 0 "register_operand" "")
3573         (float_extend (match_operand 1 "memory_operand" "")))]
3574   "reload_completed
3575    && MEM_P (operands[1])
3576    && (GET_MODE (operands[0]) == TFmode
3577        || GET_MODE (operands[0]) == XFmode
3578        || GET_MODE (operands[0]) == SFmode
3579        || GET_MODE (operands[0]) == DFmode)
3580    && (operands[2] = find_constant_src (insn))"
3581   [(set (match_dup 0) (match_dup 2))]
3583   rtx c = operands[2];
3584   rtx r = operands[0];
3586   if (GET_CODE (r) == SUBREG)
3587     r = SUBREG_REG (r);
3589   if (SSE_REG_P (r))
3590     {
3591       if (!standard_sse_constant_p (c))
3592         FAIL;
3593     }
3594   else if (FP_REG_P (r))
3595     {
3596       if (!standard_80387_constant_p (c))
3597         FAIL;
3598     }
3599   else if (MMX_REG_P (r))
3600     FAIL;
3603 (define_insn "swapxf"
3604   [(set (match_operand:XF 0 "register_operand" "+f")
3605         (match_operand:XF 1 "register_operand" "+f"))
3606    (set (match_dup 1)
3607         (match_dup 0))]
3608   "TARGET_80387"
3610   if (STACK_TOP_P (operands[0]))
3611     return "fxch\t%1";
3612   else
3613     return "fxch\t%0";
3615   [(set_attr "type" "fxch")
3616    (set_attr "mode" "XF")])
3618 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3619 (define_split
3620   [(set (match_operand:X87MODEF 0 "register_operand" "")
3621         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3622   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3623    && (standard_80387_constant_p (operands[1]) == 8
3624        || standard_80387_constant_p (operands[1]) == 9)"
3625   [(set (match_dup 0)(match_dup 1))
3626    (set (match_dup 0)
3627         (neg:X87MODEF (match_dup 0)))]
3629   REAL_VALUE_TYPE r;
3631   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3632   if (real_isnegzero (&r))
3633     operands[1] = CONST0_RTX (<MODE>mode);
3634   else
3635     operands[1] = CONST1_RTX (<MODE>mode);
3638 (define_split
3639   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3640         (match_operand:TF 1 "general_operand" ""))]
3641   "reload_completed
3642    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3643   [(const_int 0)]
3644   "ix86_split_long_move (operands); DONE;")
3646 ;; Zero extension instructions
3648 (define_expand "zero_extendhisi2"
3649   [(set (match_operand:SI 0 "register_operand" "")
3650      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3651   ""
3653   if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3654     {
3655       operands[1] = force_reg (HImode, operands[1]);
3656       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3657       DONE;
3658     }
3661 (define_insn "zero_extendhisi2_and"
3662   [(set (match_operand:SI 0 "register_operand" "=r")
3663      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3664    (clobber (reg:CC FLAGS_REG))]
3665   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3666   "#"
3667   [(set_attr "type" "alu1")
3668    (set_attr "mode" "SI")])
3670 (define_split
3671   [(set (match_operand:SI 0 "register_operand" "")
3672         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3673    (clobber (reg:CC FLAGS_REG))]
3674   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3675    && optimize_function_for_speed_p (cfun)"
3676   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3677               (clobber (reg:CC FLAGS_REG))])]
3678   "")
3680 (define_insn "*zero_extendhisi2_movzwl"
3681   [(set (match_operand:SI 0 "register_operand" "=r")
3682      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3683   "!TARGET_ZERO_EXTEND_WITH_AND
3684    || optimize_function_for_size_p (cfun)"
3685   "movz{wl|x}\t{%1, %0|%0, %1}"
3686   [(set_attr "type" "imovx")
3687    (set_attr "mode" "SI")])
3689 (define_expand "zero_extendqihi2"
3690   [(parallel
3691     [(set (match_operand:HI 0 "register_operand" "")
3692        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3693      (clobber (reg:CC FLAGS_REG))])]
3694   ""
3695   "")
3697 (define_insn "*zero_extendqihi2_and"
3698   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3699      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3700    (clobber (reg:CC FLAGS_REG))]
3701   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3702   "#"
3703   [(set_attr "type" "alu1")
3704    (set_attr "mode" "HI")])
3706 (define_insn "*zero_extendqihi2_movzbw_and"
3707   [(set (match_operand:HI 0 "register_operand" "=r,r")
3708      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3709    (clobber (reg:CC FLAGS_REG))]
3710   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3711   "#"
3712   [(set_attr "type" "imovx,alu1")
3713    (set_attr "mode" "HI")])
3715 ; zero extend to SImode here to avoid partial register stalls
3716 (define_insn "*zero_extendqihi2_movzbl"
3717   [(set (match_operand:HI 0 "register_operand" "=r")
3718      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3719   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3720    && reload_completed"
3721   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3722   [(set_attr "type" "imovx")
3723    (set_attr "mode" "SI")])
3725 ;; For the movzbw case strip only the clobber
3726 (define_split
3727   [(set (match_operand:HI 0 "register_operand" "")
3728         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3729    (clobber (reg:CC FLAGS_REG))]
3730   "reload_completed
3731    && (!TARGET_ZERO_EXTEND_WITH_AND
3732        || optimize_function_for_size_p (cfun))
3733    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3734   [(set (match_operand:HI 0 "register_operand" "")
3735         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3737 ;; When source and destination does not overlap, clear destination
3738 ;; first and then do the movb
3739 (define_split
3740   [(set (match_operand:HI 0 "register_operand" "")
3741         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3742    (clobber (reg:CC FLAGS_REG))]
3743   "reload_completed
3744    && ANY_QI_REG_P (operands[0])
3745    && (TARGET_ZERO_EXTEND_WITH_AND
3746        && optimize_function_for_speed_p (cfun))
3747    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3748   [(set (match_dup 0) (const_int 0))
3749    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3750   "operands[2] = gen_lowpart (QImode, operands[0]);")
3752 ;; Rest is handled by single and.
3753 (define_split
3754   [(set (match_operand:HI 0 "register_operand" "")
3755         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3756    (clobber (reg:CC FLAGS_REG))]
3757   "reload_completed
3758    && true_regnum (operands[0]) == true_regnum (operands[1])"
3759   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3760               (clobber (reg:CC FLAGS_REG))])]
3761   "")
3763 (define_expand "zero_extendqisi2"
3764   [(parallel
3765     [(set (match_operand:SI 0 "register_operand" "")
3766        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3767      (clobber (reg:CC FLAGS_REG))])]
3768   ""
3769   "")
3771 (define_insn "*zero_extendqisi2_and"
3772   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3773      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3774    (clobber (reg:CC FLAGS_REG))]
3775   "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3776   "#"
3777   [(set_attr "type" "alu1")
3778    (set_attr "mode" "SI")])
3780 (define_insn "*zero_extendqisi2_movzbw_and"
3781   [(set (match_operand:SI 0 "register_operand" "=r,r")
3782      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3783    (clobber (reg:CC FLAGS_REG))]
3784   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3785   "#"
3786   [(set_attr "type" "imovx,alu1")
3787    (set_attr "mode" "SI")])
3789 (define_insn "*zero_extendqisi2_movzbw"
3790   [(set (match_operand:SI 0 "register_operand" "=r")
3791      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3792   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3793    && reload_completed"
3794   "movz{bl|x}\t{%1, %0|%0, %1}"
3795   [(set_attr "type" "imovx")
3796    (set_attr "mode" "SI")])
3798 ;; For the movzbl case strip only the clobber
3799 (define_split
3800   [(set (match_operand:SI 0 "register_operand" "")
3801         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3802    (clobber (reg:CC FLAGS_REG))]
3803   "reload_completed
3804    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3805    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3806   [(set (match_dup 0)
3807         (zero_extend:SI (match_dup 1)))])
3809 ;; When source and destination does not overlap, clear destination
3810 ;; first and then do the movb
3811 (define_split
3812   [(set (match_operand:SI 0 "register_operand" "")
3813         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3814    (clobber (reg:CC FLAGS_REG))]
3815   "reload_completed
3816    && ANY_QI_REG_P (operands[0])
3817    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3818    && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3819    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3820   [(set (match_dup 0) (const_int 0))
3821    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3822   "operands[2] = gen_lowpart (QImode, operands[0]);")
3824 ;; Rest is handled by single and.
3825 (define_split
3826   [(set (match_operand:SI 0 "register_operand" "")
3827         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3828    (clobber (reg:CC FLAGS_REG))]
3829   "reload_completed
3830    && true_regnum (operands[0]) == true_regnum (operands[1])"
3831   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3832               (clobber (reg:CC FLAGS_REG))])]
3833   "")
3835 ;; %%% Kill me once multi-word ops are sane.
3836 (define_expand "zero_extendsidi2"
3837   [(set (match_operand:DI 0 "register_operand" "")
3838      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3839   ""
3841   if (!TARGET_64BIT)
3842     {
3843       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3844       DONE;
3845     }
3848 (define_insn "zero_extendsidi2_32"
3849   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3850         (zero_extend:DI
3851          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3852    (clobber (reg:CC FLAGS_REG))]
3853   "!TARGET_64BIT"
3854   "@
3855    #
3856    #
3857    #
3858    movd\t{%1, %0|%0, %1}
3859    movd\t{%1, %0|%0, %1}
3860    %vmovd\t{%1, %0|%0, %1}
3861    %vmovd\t{%1, %0|%0, %1}"
3862   [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3863    (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3864    (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3866 (define_insn "zero_extendsidi2_rex64"
3867   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3868      (zero_extend:DI
3869        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3870   "TARGET_64BIT"
3871   "@
3872    mov\t{%k1, %k0|%k0, %k1}
3873    #
3874    movd\t{%1, %0|%0, %1}
3875    movd\t{%1, %0|%0, %1}
3876    %vmovd\t{%1, %0|%0, %1}
3877    %vmovd\t{%1, %0|%0, %1}"
3878   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3879    (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3880    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3882 (define_split
3883   [(set (match_operand:DI 0 "memory_operand" "")
3884      (zero_extend:DI (match_dup 0)))]
3885   "TARGET_64BIT"
3886   [(set (match_dup 4) (const_int 0))]
3887   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3889 (define_split
3890   [(set (match_operand:DI 0 "register_operand" "")
3891         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3892    (clobber (reg:CC FLAGS_REG))]
3893   "!TARGET_64BIT && reload_completed
3894    && true_regnum (operands[0]) == true_regnum (operands[1])"
3895   [(set (match_dup 4) (const_int 0))]
3896   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3898 (define_split
3899   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3900         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3901    (clobber (reg:CC FLAGS_REG))]
3902   "!TARGET_64BIT && reload_completed
3903    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3904   [(set (match_dup 3) (match_dup 1))
3905    (set (match_dup 4) (const_int 0))]
3906   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3908 (define_insn "zero_extendhidi2"
3909   [(set (match_operand:DI 0 "register_operand" "=r")
3910      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3911   "TARGET_64BIT"
3912   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3913   [(set_attr "type" "imovx")
3914    (set_attr "mode" "DI")])
3916 (define_insn "zero_extendqidi2"
3917   [(set (match_operand:DI 0 "register_operand" "=r")
3918      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3919   "TARGET_64BIT"
3920   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3921   [(set_attr "type" "imovx")
3922    (set_attr "mode" "DI")])
3924 ;; Sign extension instructions
3926 (define_expand "extendsidi2"
3927   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3928                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3929               (clobber (reg:CC FLAGS_REG))
3930               (clobber (match_scratch:SI 2 ""))])]
3931   ""
3933   if (TARGET_64BIT)
3934     {
3935       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3936       DONE;
3937     }
3940 (define_insn "*extendsidi2_1"
3941   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3942         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3943    (clobber (reg:CC FLAGS_REG))
3944    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3945   "!TARGET_64BIT"
3946   "#")
3948 (define_insn "extendsidi2_rex64"
3949   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3950         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3951   "TARGET_64BIT"
3952   "@
3953    {cltq|cdqe}
3954    movs{lq|x}\t{%1,%0|%0, %1}"
3955   [(set_attr "type" "imovx")
3956    (set_attr "mode" "DI")
3957    (set_attr "prefix_0f" "0")
3958    (set_attr "modrm" "0,1")])
3960 (define_insn "extendhidi2"
3961   [(set (match_operand:DI 0 "register_operand" "=r")
3962         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3963   "TARGET_64BIT"
3964   "movs{wq|x}\t{%1,%0|%0, %1}"
3965   [(set_attr "type" "imovx")
3966    (set_attr "mode" "DI")])
3968 (define_insn "extendqidi2"
3969   [(set (match_operand:DI 0 "register_operand" "=r")
3970         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3971   "TARGET_64BIT"
3972   "movs{bq|x}\t{%1,%0|%0, %1}"
3973    [(set_attr "type" "imovx")
3974     (set_attr "mode" "DI")])
3976 ;; Extend to memory case when source register does die.
3977 (define_split
3978   [(set (match_operand:DI 0 "memory_operand" "")
3979         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3980    (clobber (reg:CC FLAGS_REG))
3981    (clobber (match_operand:SI 2 "register_operand" ""))]
3982   "(reload_completed
3983     && dead_or_set_p (insn, operands[1])
3984     && !reg_mentioned_p (operands[1], operands[0]))"
3985   [(set (match_dup 3) (match_dup 1))
3986    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3987               (clobber (reg:CC FLAGS_REG))])
3988    (set (match_dup 4) (match_dup 1))]
3989   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3991 ;; Extend to memory case when source register does not die.
3992 (define_split
3993   [(set (match_operand:DI 0 "memory_operand" "")
3994         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3995    (clobber (reg:CC FLAGS_REG))
3996    (clobber (match_operand:SI 2 "register_operand" ""))]
3997   "reload_completed"
3998   [(const_int 0)]
4000   split_di (&operands[0], 1, &operands[3], &operands[4]);
4002   emit_move_insn (operands[3], operands[1]);
4004   /* Generate a cltd if possible and doing so it profitable.  */
4005   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4006       && true_regnum (operands[1]) == AX_REG
4007       && true_regnum (operands[2]) == DX_REG)
4008     {
4009       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4010     }
4011   else
4012     {
4013       emit_move_insn (operands[2], operands[1]);
4014       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4015     }
4016   emit_move_insn (operands[4], operands[2]);
4017   DONE;
4020 ;; Extend to register case.  Optimize case where source and destination
4021 ;; registers match and cases where we can use cltd.
4022 (define_split
4023   [(set (match_operand:DI 0 "register_operand" "")
4024         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4025    (clobber (reg:CC FLAGS_REG))
4026    (clobber (match_scratch:SI 2 ""))]
4027   "reload_completed"
4028   [(const_int 0)]
4030   split_di (&operands[0], 1, &operands[3], &operands[4]);
4032   if (true_regnum (operands[3]) != true_regnum (operands[1]))
4033     emit_move_insn (operands[3], operands[1]);
4035   /* Generate a cltd if possible and doing so it profitable.  */
4036   if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4037       && true_regnum (operands[3]) == AX_REG)
4038     {
4039       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4040       DONE;
4041     }
4043   if (true_regnum (operands[4]) != true_regnum (operands[1]))
4044     emit_move_insn (operands[4], operands[1]);
4046   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4047   DONE;
4050 (define_insn "extendhisi2"
4051   [(set (match_operand:SI 0 "register_operand" "=*a,r")
4052         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4053   ""
4055   switch (get_attr_prefix_0f (insn))
4056     {
4057     case 0:
4058       return "{cwtl|cwde}";
4059     default:
4060       return "movs{wl|x}\t{%1,%0|%0, %1}";
4061     }
4063   [(set_attr "type" "imovx")
4064    (set_attr "mode" "SI")
4065    (set (attr "prefix_0f")
4066      ;; movsx is short decodable while cwtl is vector decoded.
4067      (if_then_else (and (eq_attr "cpu" "!k6")
4068                         (eq_attr "alternative" "0"))
4069         (const_string "0")
4070         (const_string "1")))
4071    (set (attr "modrm")
4072      (if_then_else (eq_attr "prefix_0f" "0")
4073         (const_string "0")
4074         (const_string "1")))])
4076 (define_insn "*extendhisi2_zext"
4077   [(set (match_operand:DI 0 "register_operand" "=*a,r")
4078         (zero_extend:DI
4079           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4080   "TARGET_64BIT"
4082   switch (get_attr_prefix_0f (insn))
4083     {
4084     case 0:
4085       return "{cwtl|cwde}";
4086     default:
4087       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
4088     }
4090   [(set_attr "type" "imovx")
4091    (set_attr "mode" "SI")
4092    (set (attr "prefix_0f")
4093      ;; movsx is short decodable while cwtl is vector decoded.
4094      (if_then_else (and (eq_attr "cpu" "!k6")
4095                         (eq_attr "alternative" "0"))
4096         (const_string "0")
4097         (const_string "1")))
4098    (set (attr "modrm")
4099      (if_then_else (eq_attr "prefix_0f" "0")
4100         (const_string "0")
4101         (const_string "1")))])
4103 (define_insn "extendqihi2"
4104   [(set (match_operand:HI 0 "register_operand" "=*a,r")
4105         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4106   ""
4108   switch (get_attr_prefix_0f (insn))
4109     {
4110     case 0:
4111       return "{cbtw|cbw}";
4112     default:
4113       return "movs{bw|x}\t{%1,%0|%0, %1}";
4114     }
4116   [(set_attr "type" "imovx")
4117    (set_attr "mode" "HI")
4118    (set (attr "prefix_0f")
4119      ;; movsx is short decodable while cwtl is vector decoded.
4120      (if_then_else (and (eq_attr "cpu" "!k6")
4121                         (eq_attr "alternative" "0"))
4122         (const_string "0")
4123         (const_string "1")))
4124    (set (attr "modrm")
4125      (if_then_else (eq_attr "prefix_0f" "0")
4126         (const_string "0")
4127         (const_string "1")))])
4129 (define_insn "extendqisi2"
4130   [(set (match_operand:SI 0 "register_operand" "=r")
4131         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4132   ""
4133   "movs{bl|x}\t{%1,%0|%0, %1}"
4134    [(set_attr "type" "imovx")
4135     (set_attr "mode" "SI")])
4137 (define_insn "*extendqisi2_zext"
4138   [(set (match_operand:DI 0 "register_operand" "=r")
4139         (zero_extend:DI
4140           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4141   "TARGET_64BIT"
4142   "movs{bl|x}\t{%1,%k0|%k0, %1}"
4143    [(set_attr "type" "imovx")
4144     (set_attr "mode" "SI")])
4146 ;; Conversions between float and double.
4148 ;; These are all no-ops in the model used for the 80387.  So just
4149 ;; emit moves.
4151 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4152 (define_insn "*dummy_extendsfdf2"
4153   [(set (match_operand:DF 0 "push_operand" "=<")
4154         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4155   "0"
4156   "#")
4158 (define_split
4159   [(set (match_operand:DF 0 "push_operand" "")
4160         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4161   ""
4162   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4163    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4165 (define_insn "*dummy_extendsfxf2"
4166   [(set (match_operand:XF 0 "push_operand" "=<")
4167         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4168   "0"
4169   "#")
4171 (define_split
4172   [(set (match_operand:XF 0 "push_operand" "")
4173         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4174   ""
4175   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4176    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4177   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4179 (define_split
4180   [(set (match_operand:XF 0 "push_operand" "")
4181         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4182   ""
4183   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4184    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4185   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4187 (define_expand "extendsfdf2"
4188   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4189         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4190   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4192   /* ??? Needed for compress_float_constant since all fp constants
4193      are LEGITIMATE_CONSTANT_P.  */
4194   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4195     {
4196       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4197           && standard_80387_constant_p (operands[1]) > 0)
4198         {
4199           operands[1] = simplify_const_unary_operation
4200             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4201           emit_move_insn_1 (operands[0], operands[1]);
4202           DONE;
4203         }
4204       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4205     }
4208 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4209    cvtss2sd:
4210       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4211       cvtps2pd xmm2,xmm1
4212    We do the conversion post reload to avoid producing of 128bit spills
4213    that might lead to ICE on 32bit target.  The sequence unlikely combine
4214    anyway.  */
4215 (define_split
4216   [(set (match_operand:DF 0 "register_operand" "")
4217         (float_extend:DF
4218           (match_operand:SF 1 "nonimmediate_operand" "")))]
4219   "TARGET_USE_VECTOR_FP_CONVERTS
4220    && optimize_insn_for_speed_p ()
4221    && reload_completed && SSE_REG_P (operands[0])"
4222    [(set (match_dup 2)
4223          (float_extend:V2DF
4224            (vec_select:V2SF
4225              (match_dup 3)
4226              (parallel [(const_int 0) (const_int 1)]))))]
4228   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4229   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4230   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4231      Try to avoid move when unpacking can be done in source.  */
4232   if (REG_P (operands[1]))
4233     {
4234       /* If it is unsafe to overwrite upper half of source, we need
4235          to move to destination and unpack there.  */
4236       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4237            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4238           && true_regnum (operands[0]) != true_regnum (operands[1]))
4239         {
4240           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4241           emit_move_insn (tmp, operands[1]);
4242         }
4243       else
4244         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4245       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4246     }
4247   else
4248     emit_insn (gen_vec_setv4sf_0 (operands[3],
4249                                   CONST0_RTX (V4SFmode), operands[1]));
4252 (define_insn "*extendsfdf2_mixed"
4253   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4254         (float_extend:DF
4255           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4256   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4258   switch (which_alternative)
4259     {
4260     case 0:
4261     case 1:
4262       return output_387_reg_move (insn, operands);
4264     case 2:
4265       return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4267     default:
4268       gcc_unreachable ();
4269     }
4271   [(set_attr "type" "fmov,fmov,ssecvt")
4272    (set_attr "prefix" "orig,orig,maybe_vex")
4273    (set_attr "mode" "SF,XF,DF")])
4275 (define_insn "*extendsfdf2_sse"
4276   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4277         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4278   "TARGET_SSE2 && TARGET_SSE_MATH"
4279   "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4280   [(set_attr "type" "ssecvt")
4281    (set_attr "prefix" "maybe_vex")
4282    (set_attr "mode" "DF")])
4284 (define_insn "*extendsfdf2_i387"
4285   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4286         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4287   "TARGET_80387"
4288   "* return output_387_reg_move (insn, operands);"
4289   [(set_attr "type" "fmov")
4290    (set_attr "mode" "SF,XF")])
4292 (define_expand "extend<mode>xf2"
4293   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4294         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4295   "TARGET_80387"
4297   /* ??? Needed for compress_float_constant since all fp constants
4298      are LEGITIMATE_CONSTANT_P.  */
4299   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4300     {
4301       if (standard_80387_constant_p (operands[1]) > 0)
4302         {
4303           operands[1] = simplify_const_unary_operation
4304             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4305           emit_move_insn_1 (operands[0], operands[1]);
4306           DONE;
4307         }
4308       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4309     }
4312 (define_insn "*extend<mode>xf2_i387"
4313   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4314         (float_extend:XF
4315           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4316   "TARGET_80387"
4317   "* return output_387_reg_move (insn, operands);"
4318   [(set_attr "type" "fmov")
4319    (set_attr "mode" "<MODE>,XF")])
4321 ;; %%% This seems bad bad news.
4322 ;; This cannot output into an f-reg because there is no way to be sure
4323 ;; of truncating in that case.  Otherwise this is just like a simple move
4324 ;; insn.  So we pretend we can output to a reg in order to get better
4325 ;; register preferencing, but we really use a stack slot.
4327 ;; Conversion from DFmode to SFmode.
4329 (define_expand "truncdfsf2"
4330   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4331         (float_truncate:SF
4332           (match_operand:DF 1 "nonimmediate_operand" "")))]
4333   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4335   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4336     ;
4337   else if (flag_unsafe_math_optimizations)
4338     ;
4339   else
4340     {
4341       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4342       rtx temp = assign_386_stack_local (SFmode, slot);
4343       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4344       DONE;
4345     }
4348 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4349    cvtsd2ss:
4350       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4351       cvtpd2ps xmm2,xmm1
4352    We do the conversion post reload to avoid producing of 128bit spills
4353    that might lead to ICE on 32bit target.  The sequence unlikely combine
4354    anyway.  */
4355 (define_split
4356   [(set (match_operand:SF 0 "register_operand" "")
4357         (float_truncate:SF
4358           (match_operand:DF 1 "nonimmediate_operand" "")))]
4359   "TARGET_USE_VECTOR_FP_CONVERTS
4360    && optimize_insn_for_speed_p ()
4361    && reload_completed && SSE_REG_P (operands[0])"
4362    [(set (match_dup 2)
4363          (vec_concat:V4SF
4364            (float_truncate:V2SF
4365              (match_dup 4))
4366            (match_dup 3)))]
4368   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4369   operands[3] = CONST0_RTX (V2SFmode);
4370   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4371   /* Use movsd for loading from memory, unpcklpd for registers.
4372      Try to avoid move when unpacking can be done in source, or SSE3
4373      movddup is available.  */
4374   if (REG_P (operands[1]))
4375     {
4376       if (!TARGET_SSE3
4377           && true_regnum (operands[0]) != true_regnum (operands[1])
4378           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4379               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4380         {
4381           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4382           emit_move_insn (tmp, operands[1]);
4383           operands[1] = tmp;
4384         }
4385       else if (!TARGET_SSE3)
4386         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4387       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4388     }
4389   else
4390     emit_insn (gen_sse2_loadlpd (operands[4],
4391                                  CONST0_RTX (V2DFmode), operands[1]));
4394 (define_expand "truncdfsf2_with_temp"
4395   [(parallel [(set (match_operand:SF 0 "" "")
4396                    (float_truncate:SF (match_operand:DF 1 "" "")))
4397               (clobber (match_operand:SF 2 "" ""))])]
4398   "")
4400 (define_insn "*truncdfsf_fast_mixed"
4401   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4402         (float_truncate:SF
4403           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4404   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4406   switch (which_alternative)
4407     {
4408     case 0:
4409       return output_387_reg_move (insn, operands);
4410     case 1:
4411       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4412     default:
4413       gcc_unreachable ();
4414     }
4416   [(set_attr "type" "fmov,ssecvt")
4417    (set_attr "prefix" "orig,maybe_vex")
4418    (set_attr "mode" "SF")])
4420 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4421 ;; because nothing we do here is unsafe.
4422 (define_insn "*truncdfsf_fast_sse"
4423   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4424         (float_truncate:SF
4425           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4426   "TARGET_SSE2 && TARGET_SSE_MATH"
4427   "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4428   [(set_attr "type" "ssecvt")
4429    (set_attr "prefix" "maybe_vex")
4430    (set_attr "mode" "SF")])
4432 (define_insn "*truncdfsf_fast_i387"
4433   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4434         (float_truncate:SF
4435           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4436   "TARGET_80387 && flag_unsafe_math_optimizations"
4437   "* return output_387_reg_move (insn, operands);"
4438   [(set_attr "type" "fmov")
4439    (set_attr "mode" "SF")])
4441 (define_insn "*truncdfsf_mixed"
4442   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4443         (float_truncate:SF
4444           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4445    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4446   "TARGET_MIX_SSE_I387"
4448   switch (which_alternative)
4449     {
4450     case 0:
4451       return output_387_reg_move (insn, operands);
4453     case 1:
4454       return "#";
4455     case 2:
4456       return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4457     default:
4458       gcc_unreachable ();
4459     }
4461   [(set_attr "type" "fmov,multi,ssecvt")
4462    (set_attr "unit" "*,i387,*")
4463    (set_attr "prefix" "orig,orig,maybe_vex")
4464    (set_attr "mode" "SF")])
4466 (define_insn "*truncdfsf_i387"
4467   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4468         (float_truncate:SF
4469           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4470    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4471   "TARGET_80387"
4473   switch (which_alternative)
4474     {
4475     case 0:
4476       return output_387_reg_move (insn, operands);
4478     case 1:
4479       return "#";
4480     default:
4481       gcc_unreachable ();
4482     }
4484   [(set_attr "type" "fmov,multi")
4485    (set_attr "unit" "*,i387")
4486    (set_attr "mode" "SF")])
4488 (define_insn "*truncdfsf2_i387_1"
4489   [(set (match_operand:SF 0 "memory_operand" "=m")
4490         (float_truncate:SF
4491           (match_operand:DF 1 "register_operand" "f")))]
4492   "TARGET_80387
4493    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4494    && !TARGET_MIX_SSE_I387"
4495   "* return output_387_reg_move (insn, operands);"
4496   [(set_attr "type" "fmov")
4497    (set_attr "mode" "SF")])
4499 (define_split
4500   [(set (match_operand:SF 0 "register_operand" "")
4501         (float_truncate:SF
4502          (match_operand:DF 1 "fp_register_operand" "")))
4503    (clobber (match_operand 2 "" ""))]
4504   "reload_completed"
4505   [(set (match_dup 2) (match_dup 1))
4506    (set (match_dup 0) (match_dup 2))]
4508   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4511 ;; Conversion from XFmode to {SF,DF}mode
4513 (define_expand "truncxf<mode>2"
4514   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4515                    (float_truncate:MODEF
4516                      (match_operand:XF 1 "register_operand" "")))
4517               (clobber (match_dup 2))])]
4518   "TARGET_80387"
4520   if (flag_unsafe_math_optimizations)
4521     {
4522       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4523       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4524       if (reg != operands[0])
4525         emit_move_insn (operands[0], reg);
4526       DONE;
4527     }
4528   else
4529     {
4530       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4531       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4532     }
4535 (define_insn "*truncxfsf2_mixed"
4536   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4537         (float_truncate:SF
4538           (match_operand:XF 1 "register_operand" "f,f")))
4539    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4540   "TARGET_80387"
4542   gcc_assert (!which_alternative);
4543   return output_387_reg_move (insn, operands);
4545   [(set_attr "type" "fmov,multi")
4546    (set_attr "unit" "*,i387")
4547    (set_attr "mode" "SF")])
4549 (define_insn "*truncxfdf2_mixed"
4550   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4551         (float_truncate:DF
4552           (match_operand:XF 1 "register_operand" "f,f")))
4553    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4554   "TARGET_80387"
4556   gcc_assert (!which_alternative);
4557   return output_387_reg_move (insn, operands);
4559   [(set_attr "type" "fmov,multi")
4560    (set_attr "unit" "*,i387")
4561    (set_attr "mode" "DF")])
4563 (define_insn "truncxf<mode>2_i387_noop"
4564   [(set (match_operand:MODEF 0 "register_operand" "=f")
4565         (float_truncate:MODEF
4566           (match_operand:XF 1 "register_operand" "f")))]
4567   "TARGET_80387 && flag_unsafe_math_optimizations"
4568   "* return output_387_reg_move (insn, operands);"
4569   [(set_attr "type" "fmov")
4570    (set_attr "mode" "<MODE>")])
4572 (define_insn "*truncxf<mode>2_i387"
4573   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4574         (float_truncate:MODEF
4575           (match_operand:XF 1 "register_operand" "f")))]
4576   "TARGET_80387"
4577   "* return output_387_reg_move (insn, operands);"
4578   [(set_attr "type" "fmov")
4579    (set_attr "mode" "<MODE>")])
4581 (define_split
4582   [(set (match_operand:MODEF 0 "register_operand" "")
4583         (float_truncate:MODEF
4584           (match_operand:XF 1 "register_operand" "")))
4585    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4586   "TARGET_80387 && reload_completed"
4587   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4588    (set (match_dup 0) (match_dup 2))]
4589   "")
4591 (define_split
4592   [(set (match_operand:MODEF 0 "memory_operand" "")
4593         (float_truncate:MODEF
4594           (match_operand:XF 1 "register_operand" "")))
4595    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4596   "TARGET_80387"
4597   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4598   "")
4600 ;; Signed conversion to DImode.
4602 (define_expand "fix_truncxfdi2"
4603   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4604                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4605               (clobber (reg:CC FLAGS_REG))])]
4606   "TARGET_80387"
4608   if (TARGET_FISTTP)
4609    {
4610      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4611      DONE;
4612    }
4615 (define_expand "fix_trunc<mode>di2"
4616   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4617                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4618               (clobber (reg:CC FLAGS_REG))])]
4619   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4621   if (TARGET_FISTTP
4622       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4623    {
4624      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4625      DONE;
4626    }
4627   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4628    {
4629      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4630      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4631      if (out != operands[0])
4632         emit_move_insn (operands[0], out);
4633      DONE;
4634    }
4637 ;; Signed conversion to SImode.
4639 (define_expand "fix_truncxfsi2"
4640   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4641                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4642               (clobber (reg:CC FLAGS_REG))])]
4643   "TARGET_80387"
4645   if (TARGET_FISTTP)
4646    {
4647      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4648      DONE;
4649    }
4652 (define_expand "fix_trunc<mode>si2"
4653   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4654                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4655               (clobber (reg:CC FLAGS_REG))])]
4656   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4658   if (TARGET_FISTTP
4659       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4660    {
4661      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4662      DONE;
4663    }
4664   if (SSE_FLOAT_MODE_P (<MODE>mode))
4665    {
4666      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4667      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4668      if (out != operands[0])
4669         emit_move_insn (operands[0], out);
4670      DONE;
4671    }
4674 ;; Signed conversion to HImode.
4676 (define_expand "fix_trunc<mode>hi2"
4677   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4678                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4679               (clobber (reg:CC FLAGS_REG))])]
4680   "TARGET_80387
4681    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4683   if (TARGET_FISTTP)
4684    {
4685      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4686      DONE;
4687    }
4690 ;; Unsigned conversion to SImode.
4692 (define_expand "fixuns_trunc<mode>si2"
4693   [(parallel
4694     [(set (match_operand:SI 0 "register_operand" "")
4695           (unsigned_fix:SI
4696             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4697      (use (match_dup 2))
4698      (clobber (match_scratch:<ssevecmode> 3 ""))
4699      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4700   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4702   enum machine_mode mode = <MODE>mode;
4703   enum machine_mode vecmode = <ssevecmode>mode;
4704   REAL_VALUE_TYPE TWO31r;
4705   rtx two31;
4707   if (optimize_insn_for_size_p ())
4708     FAIL;
4710   real_ldexp (&TWO31r, &dconst1, 31);
4711   two31 = const_double_from_real_value (TWO31r, mode);
4712   two31 = ix86_build_const_vector (mode, true, two31);
4713   operands[2] = force_reg (vecmode, two31);
4716 (define_insn_and_split "*fixuns_trunc<mode>_1"
4717   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4718         (unsigned_fix:SI
4719           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4720    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4721    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4722    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4723   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4724    && optimize_function_for_speed_p (cfun)"
4725   "#"
4726   "&& reload_completed"
4727   [(const_int 0)]
4729   ix86_split_convert_uns_si_sse (operands);
4730   DONE;
4733 ;; Unsigned conversion to HImode.
4734 ;; Without these patterns, we'll try the unsigned SI conversion which
4735 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4737 (define_expand "fixuns_trunc<mode>hi2"
4738   [(set (match_dup 2)
4739         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4740    (set (match_operand:HI 0 "nonimmediate_operand" "")
4741         (subreg:HI (match_dup 2) 0))]
4742   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4743   "operands[2] = gen_reg_rtx (SImode);")
4745 ;; When SSE is available, it is always faster to use it!
4746 (define_insn "fix_trunc<mode>di_sse"
4747   [(set (match_operand:DI 0 "register_operand" "=r,r")
4748         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4749   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4750    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4751   "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4752   [(set_attr "type" "sseicvt")
4753    (set_attr "prefix" "maybe_vex")
4754    (set_attr "mode" "<MODE>")
4755    (set_attr "athlon_decode" "double,vector")
4756    (set_attr "amdfam10_decode" "double,double")])
4758 (define_insn "fix_trunc<mode>si_sse"
4759   [(set (match_operand:SI 0 "register_operand" "=r,r")
4760         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4761   "SSE_FLOAT_MODE_P (<MODE>mode)
4762    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4763   "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4764   [(set_attr "type" "sseicvt")
4765    (set_attr "prefix" "maybe_vex")
4766    (set_attr "mode" "<MODE>")
4767    (set_attr "athlon_decode" "double,vector")
4768    (set_attr "amdfam10_decode" "double,double")])
4770 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4771 (define_peephole2
4772   [(set (match_operand:MODEF 0 "register_operand" "")
4773         (match_operand:MODEF 1 "memory_operand" ""))
4774    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4775         (fix:SSEMODEI24 (match_dup 0)))]
4776   "TARGET_SHORTEN_X87_SSE
4777    && peep2_reg_dead_p (2, operands[0])"
4778   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4779   "")
4781 ;; Avoid vector decoded forms of the instruction.
4782 (define_peephole2
4783   [(match_scratch:DF 2 "Y2")
4784    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4785         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4786   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4787   [(set (match_dup 2) (match_dup 1))
4788    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4789   "")
4791 (define_peephole2
4792   [(match_scratch:SF 2 "x")
4793    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4794         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4795   "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4796   [(set (match_dup 2) (match_dup 1))
4797    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4798   "")
4800 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4801   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4802         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4803   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4804    && TARGET_FISTTP
4805    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4806          && (TARGET_64BIT || <MODE>mode != DImode))
4807         && TARGET_SSE_MATH)
4808    && !(reload_completed || reload_in_progress)"
4809   "#"
4810   "&& 1"
4811   [(const_int 0)]
4813   if (memory_operand (operands[0], VOIDmode))
4814     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4815   else
4816     {
4817       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4818       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4819                                                             operands[1],
4820                                                             operands[2]));
4821     }
4822   DONE;
4824   [(set_attr "type" "fisttp")
4825    (set_attr "mode" "<MODE>")])
4827 (define_insn "fix_trunc<mode>_i387_fisttp"
4828   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4829         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4830    (clobber (match_scratch:XF 2 "=&1f"))]
4831   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4832    && TARGET_FISTTP
4833    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4834          && (TARGET_64BIT || <MODE>mode != DImode))
4835         && TARGET_SSE_MATH)"
4836   "* return output_fix_trunc (insn, operands, 1);"
4837   [(set_attr "type" "fisttp")
4838    (set_attr "mode" "<MODE>")])
4840 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4841   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4842         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4843    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4844    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4845   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4846    && TARGET_FISTTP
4847    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4848         && (TARGET_64BIT || <MODE>mode != DImode))
4849         && TARGET_SSE_MATH)"
4850   "#"
4851   [(set_attr "type" "fisttp")
4852    (set_attr "mode" "<MODE>")])
4854 (define_split
4855   [(set (match_operand:X87MODEI 0 "register_operand" "")
4856         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4857    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4858    (clobber (match_scratch 3 ""))]
4859   "reload_completed"
4860   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4861               (clobber (match_dup 3))])
4862    (set (match_dup 0) (match_dup 2))]
4863   "")
4865 (define_split
4866   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4867         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4868    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4869    (clobber (match_scratch 3 ""))]
4870   "reload_completed"
4871   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4872               (clobber (match_dup 3))])]
4873   "")
4875 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4876 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4877 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4878 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4879 ;; function in i386.c.
4880 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4881   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4882         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4883    (clobber (reg:CC FLAGS_REG))]
4884   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4885    && !TARGET_FISTTP
4886    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4887          && (TARGET_64BIT || <MODE>mode != DImode))
4888    && !(reload_completed || reload_in_progress)"
4889   "#"
4890   "&& 1"
4891   [(const_int 0)]
4893   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4895   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4896   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4897   if (memory_operand (operands[0], VOIDmode))
4898     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4899                                          operands[2], operands[3]));
4900   else
4901     {
4902       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4903       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4904                                                      operands[2], operands[3],
4905                                                      operands[4]));
4906     }
4907   DONE;
4909   [(set_attr "type" "fistp")
4910    (set_attr "i387_cw" "trunc")
4911    (set_attr "mode" "<MODE>")])
4913 (define_insn "fix_truncdi_i387"
4914   [(set (match_operand:DI 0 "memory_operand" "=m")
4915         (fix:DI (match_operand 1 "register_operand" "f")))
4916    (use (match_operand:HI 2 "memory_operand" "m"))
4917    (use (match_operand:HI 3 "memory_operand" "m"))
4918    (clobber (match_scratch:XF 4 "=&1f"))]
4919   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4920    && !TARGET_FISTTP
4921    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4922   "* return output_fix_trunc (insn, operands, 0);"
4923   [(set_attr "type" "fistp")
4924    (set_attr "i387_cw" "trunc")
4925    (set_attr "mode" "DI")])
4927 (define_insn "fix_truncdi_i387_with_temp"
4928   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4929         (fix:DI (match_operand 1 "register_operand" "f,f")))
4930    (use (match_operand:HI 2 "memory_operand" "m,m"))
4931    (use (match_operand:HI 3 "memory_operand" "m,m"))
4932    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4933    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4934   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4935    && !TARGET_FISTTP
4936    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4937   "#"
4938   [(set_attr "type" "fistp")
4939    (set_attr "i387_cw" "trunc")
4940    (set_attr "mode" "DI")])
4942 (define_split
4943   [(set (match_operand:DI 0 "register_operand" "")
4944         (fix:DI (match_operand 1 "register_operand" "")))
4945    (use (match_operand:HI 2 "memory_operand" ""))
4946    (use (match_operand:HI 3 "memory_operand" ""))
4947    (clobber (match_operand:DI 4 "memory_operand" ""))
4948    (clobber (match_scratch 5 ""))]
4949   "reload_completed"
4950   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4951               (use (match_dup 2))
4952               (use (match_dup 3))
4953               (clobber (match_dup 5))])
4954    (set (match_dup 0) (match_dup 4))]
4955   "")
4957 (define_split
4958   [(set (match_operand:DI 0 "memory_operand" "")
4959         (fix:DI (match_operand 1 "register_operand" "")))
4960    (use (match_operand:HI 2 "memory_operand" ""))
4961    (use (match_operand:HI 3 "memory_operand" ""))
4962    (clobber (match_operand:DI 4 "memory_operand" ""))
4963    (clobber (match_scratch 5 ""))]
4964   "reload_completed"
4965   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4966               (use (match_dup 2))
4967               (use (match_dup 3))
4968               (clobber (match_dup 5))])]
4969   "")
4971 (define_insn "fix_trunc<mode>_i387"
4972   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4973         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4974    (use (match_operand:HI 2 "memory_operand" "m"))
4975    (use (match_operand:HI 3 "memory_operand" "m"))]
4976   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4977    && !TARGET_FISTTP
4978    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4979   "* return output_fix_trunc (insn, operands, 0);"
4980   [(set_attr "type" "fistp")
4981    (set_attr "i387_cw" "trunc")
4982    (set_attr "mode" "<MODE>")])
4984 (define_insn "fix_trunc<mode>_i387_with_temp"
4985   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4986         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4987    (use (match_operand:HI 2 "memory_operand" "m,m"))
4988    (use (match_operand:HI 3 "memory_operand" "m,m"))
4989    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4990   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4991    && !TARGET_FISTTP
4992    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4993   "#"
4994   [(set_attr "type" "fistp")
4995    (set_attr "i387_cw" "trunc")
4996    (set_attr "mode" "<MODE>")])
4998 (define_split
4999   [(set (match_operand:X87MODEI12 0 "register_operand" "")
5000         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5001    (use (match_operand:HI 2 "memory_operand" ""))
5002    (use (match_operand:HI 3 "memory_operand" ""))
5003    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5004   "reload_completed"
5005   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5006               (use (match_dup 2))
5007               (use (match_dup 3))])
5008    (set (match_dup 0) (match_dup 4))]
5009   "")
5011 (define_split
5012   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5013         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5014    (use (match_operand:HI 2 "memory_operand" ""))
5015    (use (match_operand:HI 3 "memory_operand" ""))
5016    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5017   "reload_completed"
5018   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5019               (use (match_dup 2))
5020               (use (match_dup 3))])]
5021   "")
5023 (define_insn "x86_fnstcw_1"
5024   [(set (match_operand:HI 0 "memory_operand" "=m")
5025         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5026   "TARGET_80387"
5027   "fnstcw\t%0"
5028   [(set_attr "length" "2")
5029    (set_attr "mode" "HI")
5030    (set_attr "unit" "i387")])
5032 (define_insn "x86_fldcw_1"
5033   [(set (reg:HI FPCR_REG)
5034         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5035   "TARGET_80387"
5036   "fldcw\t%0"
5037   [(set_attr "length" "2")
5038    (set_attr "mode" "HI")
5039    (set_attr "unit" "i387")
5040    (set_attr "athlon_decode" "vector")
5041    (set_attr "amdfam10_decode" "vector")])
5043 ;; Conversion between fixed point and floating point.
5045 ;; Even though we only accept memory inputs, the backend _really_
5046 ;; wants to be able to do this between registers.
5048 (define_expand "floathi<mode>2"
5049   [(set (match_operand:X87MODEF 0 "register_operand" "")
5050         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5051   "TARGET_80387
5052    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5053        || TARGET_MIX_SSE_I387)"
5054   "")
5056 ;; Pre-reload splitter to add memory clobber to the pattern.
5057 (define_insn_and_split "*floathi<mode>2_1"
5058   [(set (match_operand:X87MODEF 0 "register_operand" "")
5059         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5060   "TARGET_80387
5061    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5062        || TARGET_MIX_SSE_I387)
5063    && !(reload_completed || reload_in_progress)"
5064   "#"
5065   "&& 1"
5066   [(parallel [(set (match_dup 0)
5067               (float:X87MODEF (match_dup 1)))
5068    (clobber (match_dup 2))])]
5069   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5071 (define_insn "*floathi<mode>2_i387_with_temp"
5072   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5073         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5074   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5075   "TARGET_80387
5076    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5077        || TARGET_MIX_SSE_I387)"
5078   "#"
5079   [(set_attr "type" "fmov,multi")
5080    (set_attr "mode" "<MODE>")
5081    (set_attr "unit" "*,i387")
5082    (set_attr "fp_int_src" "true")])
5084 (define_insn "*floathi<mode>2_i387"
5085   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5086         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5087   "TARGET_80387
5088    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5089        || TARGET_MIX_SSE_I387)"
5090   "fild%z1\t%1"
5091   [(set_attr "type" "fmov")
5092    (set_attr "mode" "<MODE>")
5093    (set_attr "fp_int_src" "true")])
5095 (define_split
5096   [(set (match_operand:X87MODEF 0 "register_operand" "")
5097         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5098    (clobber (match_operand:HI 2 "memory_operand" ""))]
5099   "TARGET_80387
5100    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5101        || TARGET_MIX_SSE_I387)
5102    && reload_completed"
5103   [(set (match_dup 2) (match_dup 1))
5104    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5105   "")
5107 (define_split
5108   [(set (match_operand:X87MODEF 0 "register_operand" "")
5109         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5110    (clobber (match_operand:HI 2 "memory_operand" ""))]
5111    "TARGET_80387
5112     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5113         || TARGET_MIX_SSE_I387)
5114     && reload_completed"
5115   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5116   "")
5118 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5119   [(set (match_operand:X87MODEF 0 "register_operand" "")
5120         (float:X87MODEF
5121           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5122   "TARGET_80387
5123    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5124        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5125   "")
5127 ;; Pre-reload splitter to add memory clobber to the pattern.
5128 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5129   [(set (match_operand:X87MODEF 0 "register_operand" "")
5130         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5131   "((TARGET_80387
5132      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5133            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5134          || TARGET_MIX_SSE_I387))
5135     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5136         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5137         && ((<SSEMODEI24:MODE>mode == SImode
5138              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5139              && optimize_function_for_speed_p (cfun)
5140              && flag_trapping_math)
5141             || !(TARGET_INTER_UNIT_CONVERSIONS
5142                  || optimize_function_for_size_p (cfun)))))
5143    && !(reload_completed || reload_in_progress)"
5144   "#"
5145   "&& 1"
5146   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5147               (clobber (match_dup 2))])]
5149   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5151   /* Avoid store forwarding (partial memory) stall penalty
5152      by passing DImode value through XMM registers.  */
5153   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5154       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5155       && optimize_function_for_speed_p (cfun))
5156     {
5157       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5158                                                             operands[1],
5159                                                             operands[2]));
5160       DONE;
5161     }
5164 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5165   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5166         (float:MODEF
5167           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5168    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5169   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5170    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5171   "#"
5172   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5173    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5174    (set_attr "unit" "*,i387,*,*,*")
5175    (set_attr "athlon_decode" "*,*,double,direct,double")
5176    (set_attr "amdfam10_decode" "*,*,vector,double,double")
5177    (set_attr "fp_int_src" "true")])
5179 (define_insn "*floatsi<mode>2_vector_mixed"
5180   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5181         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5182   "TARGET_SSE2 && TARGET_MIX_SSE_I387
5183    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5184   "@
5185    fild%z1\t%1
5186    #"
5187   [(set_attr "type" "fmov,sseicvt")
5188    (set_attr "mode" "<MODE>,<ssevecmode>")
5189    (set_attr "unit" "i387,*")
5190    (set_attr "athlon_decode" "*,direct")
5191    (set_attr "amdfam10_decode" "*,double")
5192    (set_attr "fp_int_src" "true")])
5194 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5195   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5196         (float:MODEF
5197           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5198   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5199   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5200    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5201   "#"
5202   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5203    (set_attr "mode" "<MODEF:MODE>")
5204    (set_attr "unit" "*,i387,*,*")
5205    (set_attr "athlon_decode" "*,*,double,direct")
5206    (set_attr "amdfam10_decode" "*,*,vector,double")
5207    (set_attr "fp_int_src" "true")])
5209 (define_split
5210   [(set (match_operand:MODEF 0 "register_operand" "")
5211         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5212    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5213   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5214    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5215    && TARGET_INTER_UNIT_CONVERSIONS
5216    && reload_completed
5217    && (SSE_REG_P (operands[0])
5218        || (GET_CODE (operands[0]) == SUBREG
5219            && SSE_REG_P (operands[0])))"
5220   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5221   "")
5223 (define_split
5224   [(set (match_operand:MODEF 0 "register_operand" "")
5225         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5226    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5227   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5228    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5229    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5230    && reload_completed
5231    && (SSE_REG_P (operands[0])
5232        || (GET_CODE (operands[0]) == SUBREG
5233            && SSE_REG_P (operands[0])))"
5234   [(set (match_dup 2) (match_dup 1))
5235    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5236   "")
5238 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5239   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5240         (float:MODEF
5241           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5242   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5243    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5244    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5245   "@
5246    fild%z1\t%1
5247    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5248    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5249   [(set_attr "type" "fmov,sseicvt,sseicvt")
5250    (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5251    (set_attr "mode" "<MODEF:MODE>")
5252    (set_attr "unit" "i387,*,*")
5253    (set_attr "athlon_decode" "*,double,direct")
5254    (set_attr "amdfam10_decode" "*,vector,double")
5255    (set_attr "fp_int_src" "true")])
5257 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5258   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5259         (float:MODEF
5260           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5261   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5262    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5263    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5264   "@
5265    fild%z1\t%1
5266    %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5267   [(set_attr "type" "fmov,sseicvt")
5268    (set_attr "prefix" "orig,maybe_vex")
5269    (set_attr "mode" "<MODEF:MODE>")
5270    (set_attr "athlon_decode" "*,direct")
5271    (set_attr "amdfam10_decode" "*,double")
5272    (set_attr "fp_int_src" "true")])
5274 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5275   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5276         (float:MODEF
5277           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5278    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5279   "TARGET_SSE2 && TARGET_SSE_MATH
5280    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5281   "#"
5282   [(set_attr "type" "sseicvt")
5283    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5284    (set_attr "athlon_decode" "double,direct,double")
5285    (set_attr "amdfam10_decode" "vector,double,double")
5286    (set_attr "fp_int_src" "true")])
5288 (define_insn "*floatsi<mode>2_vector_sse"
5289   [(set (match_operand:MODEF 0 "register_operand" "=x")
5290         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5291   "TARGET_SSE2 && TARGET_SSE_MATH
5292    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5293   "#"
5294   [(set_attr "type" "sseicvt")
5295    (set_attr "mode" "<MODE>")
5296    (set_attr "athlon_decode" "direct")
5297    (set_attr "amdfam10_decode" "double")
5298    (set_attr "fp_int_src" "true")])
5300 (define_split
5301   [(set (match_operand:MODEF 0 "register_operand" "")
5302         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5303    (clobber (match_operand:SI 2 "memory_operand" ""))]
5304   "TARGET_SSE2 && TARGET_SSE_MATH
5305    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5306    && reload_completed
5307    && (SSE_REG_P (operands[0])
5308        || (GET_CODE (operands[0]) == SUBREG
5309            && SSE_REG_P (operands[0])))"
5310   [(const_int 0)]
5312   rtx op1 = operands[1];
5314   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5315                                      <MODE>mode, 0);
5316   if (GET_CODE (op1) == SUBREG)
5317     op1 = SUBREG_REG (op1);
5319   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5320     {
5321       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5322       emit_insn (gen_sse2_loadld (operands[4],
5323                                   CONST0_RTX (V4SImode), operands[1]));
5324     }
5325   /* We can ignore possible trapping value in the
5326      high part of SSE register for non-trapping math. */
5327   else if (SSE_REG_P (op1) && !flag_trapping_math)
5328     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5329   else
5330     {
5331       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5332       emit_move_insn (operands[2], operands[1]);
5333       emit_insn (gen_sse2_loadld (operands[4],
5334                                   CONST0_RTX (V4SImode), operands[2]));
5335     }
5336   emit_insn
5337     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5338   DONE;
5341 (define_split
5342   [(set (match_operand:MODEF 0 "register_operand" "")
5343         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5344    (clobber (match_operand:SI 2 "memory_operand" ""))]
5345   "TARGET_SSE2 && TARGET_SSE_MATH
5346    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5347    && reload_completed
5348    && (SSE_REG_P (operands[0])
5349        || (GET_CODE (operands[0]) == SUBREG
5350            && SSE_REG_P (operands[0])))"
5351   [(const_int 0)]
5353   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5354                                      <MODE>mode, 0);
5355   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5357   emit_insn (gen_sse2_loadld (operands[4],
5358                               CONST0_RTX (V4SImode), operands[1]));
5359   emit_insn
5360     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5361   DONE;
5364 (define_split
5365   [(set (match_operand:MODEF 0 "register_operand" "")
5366         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5367   "TARGET_SSE2 && TARGET_SSE_MATH
5368    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5369    && reload_completed
5370    && (SSE_REG_P (operands[0])
5371        || (GET_CODE (operands[0]) == SUBREG
5372            && SSE_REG_P (operands[0])))"
5373   [(const_int 0)]
5375   rtx op1 = operands[1];
5377   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5378                                      <MODE>mode, 0);
5379   if (GET_CODE (op1) == SUBREG)
5380     op1 = SUBREG_REG (op1);
5382   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5383     {
5384       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5385       emit_insn (gen_sse2_loadld (operands[4],
5386                                   CONST0_RTX (V4SImode), operands[1]));
5387     }
5388   /* We can ignore possible trapping value in the
5389      high part of SSE register for non-trapping math. */
5390   else if (SSE_REG_P (op1) && !flag_trapping_math)
5391     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5392   else
5393     gcc_unreachable ();
5394   emit_insn
5395     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5396   DONE;
5399 (define_split
5400   [(set (match_operand:MODEF 0 "register_operand" "")
5401         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5402   "TARGET_SSE2 && TARGET_SSE_MATH
5403    && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5404    && reload_completed
5405    && (SSE_REG_P (operands[0])
5406        || (GET_CODE (operands[0]) == SUBREG
5407            && SSE_REG_P (operands[0])))"
5408   [(const_int 0)]
5410   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5411                                      <MODE>mode, 0);
5412   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5414   emit_insn (gen_sse2_loadld (operands[4],
5415                               CONST0_RTX (V4SImode), operands[1]));
5416   emit_insn
5417     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5418   DONE;
5421 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5422   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5423         (float:MODEF
5424           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5425   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5426   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5427    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5428   "#"
5429   [(set_attr "type" "sseicvt")
5430    (set_attr "mode" "<MODEF:MODE>")
5431    (set_attr "athlon_decode" "double,direct")
5432    (set_attr "amdfam10_decode" "vector,double")
5433    (set_attr "fp_int_src" "true")])
5435 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5436   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5437         (float:MODEF
5438           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5439   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5440    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5441    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5442   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5443   [(set_attr "type" "sseicvt")
5444    (set_attr "prefix" "maybe_vex")
5445    (set_attr "mode" "<MODEF:MODE>")
5446    (set_attr "athlon_decode" "double,direct")
5447    (set_attr "amdfam10_decode" "vector,double")
5448    (set_attr "fp_int_src" "true")])
5450 (define_split
5451   [(set (match_operand:MODEF 0 "register_operand" "")
5452         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5453    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5454   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5455    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5456    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5457    && reload_completed
5458    && (SSE_REG_P (operands[0])
5459        || (GET_CODE (operands[0]) == SUBREG
5460            && SSE_REG_P (operands[0])))"
5461   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5462   "")
5464 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5465   [(set (match_operand:MODEF 0 "register_operand" "=x")
5466         (float:MODEF
5467           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5468   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5469    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5470    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5471   "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5472   [(set_attr "type" "sseicvt")
5473    (set_attr "prefix" "maybe_vex")
5474    (set_attr "mode" "<MODEF:MODE>")
5475    (set_attr "athlon_decode" "direct")
5476    (set_attr "amdfam10_decode" "double")
5477    (set_attr "fp_int_src" "true")])
5479 (define_split
5480   [(set (match_operand:MODEF 0 "register_operand" "")
5481         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5482    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5483   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5484    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5485    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5486    && reload_completed
5487    && (SSE_REG_P (operands[0])
5488        || (GET_CODE (operands[0]) == SUBREG
5489            && SSE_REG_P (operands[0])))"
5490   [(set (match_dup 2) (match_dup 1))
5491    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5492   "")
5494 (define_split
5495   [(set (match_operand:MODEF 0 "register_operand" "")
5496         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5497    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5498   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5499    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5500    && reload_completed
5501    && (SSE_REG_P (operands[0])
5502        || (GET_CODE (operands[0]) == SUBREG
5503            && SSE_REG_P (operands[0])))"
5504   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5505   "")
5507 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5508   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5509         (float:X87MODEF
5510           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5511   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5512   "TARGET_80387"
5513   "@
5514    fild%z1\t%1
5515    #"
5516   [(set_attr "type" "fmov,multi")
5517    (set_attr "mode" "<X87MODEF:MODE>")
5518    (set_attr "unit" "*,i387")
5519    (set_attr "fp_int_src" "true")])
5521 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5522   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5523         (float:X87MODEF
5524           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5525   "TARGET_80387"
5526   "fild%z1\t%1"
5527   [(set_attr "type" "fmov")
5528    (set_attr "mode" "<X87MODEF:MODE>")
5529    (set_attr "fp_int_src" "true")])
5531 (define_split
5532   [(set (match_operand:X87MODEF 0 "register_operand" "")
5533         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5534    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5535   "TARGET_80387
5536    && reload_completed
5537    && FP_REG_P (operands[0])"
5538   [(set (match_dup 2) (match_dup 1))
5539    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5540   "")
5542 (define_split
5543   [(set (match_operand:X87MODEF 0 "register_operand" "")
5544         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5545    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5546   "TARGET_80387
5547    && reload_completed
5548    && FP_REG_P (operands[0])"
5549   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5550   "")
5552 ;; Avoid store forwarding (partial memory) stall penalty
5553 ;; by passing DImode value through XMM registers.  */
5555 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5556   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5557         (float:X87MODEF
5558           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5559    (clobber (match_scratch:V4SI 3 "=X,x"))
5560    (clobber (match_scratch:V4SI 4 "=X,x"))
5561    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5562   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5563    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5564   "#"
5565   [(set_attr "type" "multi")
5566    (set_attr "mode" "<X87MODEF:MODE>")
5567    (set_attr "unit" "i387")
5568    (set_attr "fp_int_src" "true")])
5570 (define_split
5571   [(set (match_operand:X87MODEF 0 "register_operand" "")
5572         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5573    (clobber (match_scratch:V4SI 3 ""))
5574    (clobber (match_scratch:V4SI 4 ""))
5575    (clobber (match_operand:DI 2 "memory_operand" ""))]
5576   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5577    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5578    && reload_completed
5579    && FP_REG_P (operands[0])"
5580   [(set (match_dup 2) (match_dup 3))
5581    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5583   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5584      Assemble the 64-bit DImode value in an xmm register.  */
5585   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5586                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5587   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5588                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5589   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5591   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5594 (define_split
5595   [(set (match_operand:X87MODEF 0 "register_operand" "")
5596         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5597    (clobber (match_scratch:V4SI 3 ""))
5598    (clobber (match_scratch:V4SI 4 ""))
5599    (clobber (match_operand:DI 2 "memory_operand" ""))]
5600   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5601    && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5602    && reload_completed
5603    && FP_REG_P (operands[0])"
5604   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5605   "")
5607 ;; Avoid store forwarding (partial memory) stall penalty by extending
5608 ;; SImode value to DImode through XMM register instead of pushing two
5609 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5610 ;; targets benefit from this optimization. Also note that fild
5611 ;; loads from memory only.
5613 (define_insn "*floatunssi<mode>2_1"
5614   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5615         (unsigned_float:X87MODEF
5616           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5617    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5618    (clobber (match_scratch:SI 3 "=X,x"))]
5619   "!TARGET_64BIT
5620    && TARGET_80387 && TARGET_SSE"
5621   "#"
5622   [(set_attr "type" "multi")
5623    (set_attr "mode" "<MODE>")])
5625 (define_split
5626   [(set (match_operand:X87MODEF 0 "register_operand" "")
5627         (unsigned_float:X87MODEF
5628           (match_operand:SI 1 "register_operand" "")))
5629    (clobber (match_operand:DI 2 "memory_operand" ""))
5630    (clobber (match_scratch:SI 3 ""))]
5631   "!TARGET_64BIT
5632    && TARGET_80387 && TARGET_SSE
5633    && reload_completed"
5634   [(set (match_dup 2) (match_dup 1))
5635    (set (match_dup 0)
5636         (float:X87MODEF (match_dup 2)))]
5637   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5639 (define_split
5640   [(set (match_operand:X87MODEF 0 "register_operand" "")
5641         (unsigned_float:X87MODEF
5642           (match_operand:SI 1 "memory_operand" "")))
5643    (clobber (match_operand:DI 2 "memory_operand" ""))
5644    (clobber (match_scratch:SI 3 ""))]
5645   "!TARGET_64BIT
5646    && TARGET_80387 && TARGET_SSE
5647    && reload_completed"
5648   [(set (match_dup 2) (match_dup 3))
5649    (set (match_dup 0)
5650         (float:X87MODEF (match_dup 2)))]
5652   emit_move_insn (operands[3], operands[1]);
5653   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5656 (define_expand "floatunssi<mode>2"
5657   [(parallel
5658      [(set (match_operand:X87MODEF 0 "register_operand" "")
5659            (unsigned_float:X87MODEF
5660              (match_operand:SI 1 "nonimmediate_operand" "")))
5661       (clobber (match_dup 2))
5662       (clobber (match_scratch:SI 3 ""))])]
5663   "!TARGET_64BIT
5664    && ((TARGET_80387 && TARGET_SSE)
5665        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5667   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5668     {
5669       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5670       DONE;
5671     }
5672   else
5673     {
5674       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5675       operands[2] = assign_386_stack_local (DImode, slot);
5676     }
5679 (define_expand "floatunsdisf2"
5680   [(use (match_operand:SF 0 "register_operand" ""))
5681    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5682   "TARGET_64BIT && TARGET_SSE_MATH"
5683   "x86_emit_floatuns (operands); DONE;")
5685 (define_expand "floatunsdidf2"
5686   [(use (match_operand:DF 0 "register_operand" ""))
5687    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5688   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5689    && TARGET_SSE2 && TARGET_SSE_MATH"
5691   if (TARGET_64BIT)
5692     x86_emit_floatuns (operands);
5693   else
5694     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5695   DONE;
5698 ;; Add instructions
5700 ;; %%% splits for addditi3
5702 (define_expand "addti3"
5703   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5704         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5705                  (match_operand:TI 2 "x86_64_general_operand" "")))]
5706   "TARGET_64BIT"
5707   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5709 (define_insn "*addti3_1"
5710   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5711         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5712                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5713    (clobber (reg:CC FLAGS_REG))]
5714   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5715   "#")
5717 (define_split
5718   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5719         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5720                  (match_operand:TI 2 "x86_64_general_operand" "")))
5721    (clobber (reg:CC FLAGS_REG))]
5722   "TARGET_64BIT && reload_completed"
5723   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5724                                           UNSPEC_ADD_CARRY))
5725               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5726    (parallel [(set (match_dup 3)
5727                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5728                                      (match_dup 4))
5729                             (match_dup 5)))
5730               (clobber (reg:CC FLAGS_REG))])]
5731   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5733 ;; %%% splits for addsidi3
5734 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5735 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5736 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5738 (define_expand "adddi3"
5739   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5740         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5741                  (match_operand:DI 2 "x86_64_general_operand" "")))]
5742   ""
5743   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5745 (define_insn "*adddi3_1"
5746   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5747         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5748                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5749    (clobber (reg:CC FLAGS_REG))]
5750   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5751   "#")
5753 (define_split
5754   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5755         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5756                  (match_operand:DI 2 "general_operand" "")))
5757    (clobber (reg:CC FLAGS_REG))]
5758   "!TARGET_64BIT && reload_completed"
5759   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5760                                           UNSPEC_ADD_CARRY))
5761               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5762    (parallel [(set (match_dup 3)
5763                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5764                                      (match_dup 4))
5765                             (match_dup 5)))
5766               (clobber (reg:CC FLAGS_REG))])]
5767   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5769 (define_insn "adddi3_carry_rex64"
5770   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5771           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5772                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5773                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5774    (clobber (reg:CC FLAGS_REG))]
5775   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5776   "adc{q}\t{%2, %0|%0, %2}"
5777   [(set_attr "type" "alu")
5778    (set_attr "pent_pair" "pu")
5779    (set_attr "mode" "DI")])
5781 (define_insn "*adddi3_cc_rex64"
5782   [(set (reg:CC FLAGS_REG)
5783         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5784                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5785                    UNSPEC_ADD_CARRY))
5786    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5787         (plus:DI (match_dup 1) (match_dup 2)))]
5788   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5789   "add{q}\t{%2, %0|%0, %2}"
5790   [(set_attr "type" "alu")
5791    (set_attr "mode" "DI")])
5793 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5794   [(set (reg:CCC FLAGS_REG)
5795         (compare:CCC
5796             (plusminus:SWI
5797                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5798                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5799             (match_dup 1)))
5800    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5801         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5802   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5803   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5804   [(set_attr "type" "alu")
5805    (set_attr "mode" "<MODE>")])
5807 (define_insn "*add<mode>3_cconly_overflow"
5808   [(set (reg:CCC FLAGS_REG)
5809         (compare:CCC
5810                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5811                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5812                 (match_dup 1)))
5813    (clobber (match_scratch:SWI 0 "=<r>"))]
5814   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5815   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5816   [(set_attr "type" "alu")
5817    (set_attr "mode" "<MODE>")])
5819 (define_insn "*sub<mode>3_cconly_overflow"
5820   [(set (reg:CCC FLAGS_REG)
5821         (compare:CCC
5822              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5823                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5824              (match_dup 0)))]
5825   ""
5826   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5827   [(set_attr "type" "icmp")
5828    (set_attr "mode" "<MODE>")])
5830 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5831   [(set (reg:CCC FLAGS_REG)
5832         (compare:CCC
5833             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5834                           (match_operand:SI 2 "general_operand" "g"))
5835             (match_dup 1)))
5836    (set (match_operand:DI 0 "register_operand" "=r")
5837         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5838   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5839   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5840   [(set_attr "type" "alu")
5841    (set_attr "mode" "SI")])
5843 (define_insn "addqi3_carry"
5844   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5845           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5846                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5847                    (match_operand:QI 2 "general_operand" "qn,qm")))
5848    (clobber (reg:CC FLAGS_REG))]
5849   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5850   "adc{b}\t{%2, %0|%0, %2}"
5851   [(set_attr "type" "alu")
5852    (set_attr "pent_pair" "pu")
5853    (set_attr "mode" "QI")])
5855 (define_insn "addhi3_carry"
5856   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5857           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5858                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5859                    (match_operand:HI 2 "general_operand" "rn,rm")))
5860    (clobber (reg:CC FLAGS_REG))]
5861   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5862   "adc{w}\t{%2, %0|%0, %2}"
5863   [(set_attr "type" "alu")
5864    (set_attr "pent_pair" "pu")
5865    (set_attr "mode" "HI")])
5867 (define_insn "addsi3_carry"
5868   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5869           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5870                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5871                    (match_operand:SI 2 "general_operand" "ri,rm")))
5872    (clobber (reg:CC FLAGS_REG))]
5873   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5874   "adc{l}\t{%2, %0|%0, %2}"
5875   [(set_attr "type" "alu")
5876    (set_attr "pent_pair" "pu")
5877    (set_attr "mode" "SI")])
5879 (define_insn "*addsi3_carry_zext"
5880   [(set (match_operand:DI 0 "register_operand" "=r")
5881           (zero_extend:DI
5882             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5883                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5884                      (match_operand:SI 2 "general_operand" "g"))))
5885    (clobber (reg:CC FLAGS_REG))]
5886   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5887   "adc{l}\t{%2, %k0|%k0, %2}"
5888   [(set_attr "type" "alu")
5889    (set_attr "pent_pair" "pu")
5890    (set_attr "mode" "SI")])
5892 (define_insn "*addsi3_cc"
5893   [(set (reg:CC FLAGS_REG)
5894         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5895                     (match_operand:SI 2 "general_operand" "ri,rm")]
5896                    UNSPEC_ADD_CARRY))
5897    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5898         (plus:SI (match_dup 1) (match_dup 2)))]
5899   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5900   "add{l}\t{%2, %0|%0, %2}"
5901   [(set_attr "type" "alu")
5902    (set_attr "mode" "SI")])
5904 (define_insn "addqi3_cc"
5905   [(set (reg:CC FLAGS_REG)
5906         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5907                     (match_operand:QI 2 "general_operand" "qn,qm")]
5908                    UNSPEC_ADD_CARRY))
5909    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5910         (plus:QI (match_dup 1) (match_dup 2)))]
5911   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5912   "add{b}\t{%2, %0|%0, %2}"
5913   [(set_attr "type" "alu")
5914    (set_attr "mode" "QI")])
5916 (define_expand "addsi3"
5917   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5918         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5919                  (match_operand:SI 2 "general_operand" "")))]
5920   ""
5921   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5923 (define_insn "*lea_1"
5924   [(set (match_operand:SI 0 "register_operand" "=r")
5925         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5926   "!TARGET_64BIT"
5927   "lea{l}\t{%a1, %0|%0, %a1}"
5928   [(set_attr "type" "lea")
5929    (set_attr "mode" "SI")])
5931 (define_insn "*lea_1_rex64"
5932   [(set (match_operand:SI 0 "register_operand" "=r")
5933         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5934   "TARGET_64BIT"
5935   "lea{l}\t{%a1, %0|%0, %a1}"
5936   [(set_attr "type" "lea")
5937    (set_attr "mode" "SI")])
5939 (define_insn "*lea_1_zext"
5940   [(set (match_operand:DI 0 "register_operand" "=r")
5941         (zero_extend:DI
5942          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5943   "TARGET_64BIT"
5944   "lea{l}\t{%a1, %k0|%k0, %a1}"
5945   [(set_attr "type" "lea")
5946    (set_attr "mode" "SI")])
5948 (define_insn "*lea_2_rex64"
5949   [(set (match_operand:DI 0 "register_operand" "=r")
5950         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5951   "TARGET_64BIT"
5952   "lea{q}\t{%a1, %0|%0, %a1}"
5953   [(set_attr "type" "lea")
5954    (set_attr "mode" "DI")])
5956 ;; The lea patterns for non-Pmodes needs to be matched by several
5957 ;; insns converted to real lea by splitters.
5959 (define_insn_and_split "*lea_general_1"
5960   [(set (match_operand 0 "register_operand" "=r")
5961         (plus (plus (match_operand 1 "index_register_operand" "l")
5962                     (match_operand 2 "register_operand" "r"))
5963               (match_operand 3 "immediate_operand" "i")))]
5964   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5965     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5966    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5967    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5968    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5969    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5970        || GET_MODE (operands[3]) == VOIDmode)"
5971   "#"
5972   "&& reload_completed"
5973   [(const_int 0)]
5975   rtx pat;
5976   operands[0] = gen_lowpart (SImode, operands[0]);
5977   operands[1] = gen_lowpart (Pmode, operands[1]);
5978   operands[2] = gen_lowpart (Pmode, operands[2]);
5979   operands[3] = gen_lowpart (Pmode, operands[3]);
5980   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5981                       operands[3]);
5982   if (Pmode != SImode)
5983     pat = gen_rtx_SUBREG (SImode, pat, 0);
5984   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5985   DONE;
5987   [(set_attr "type" "lea")
5988    (set_attr "mode" "SI")])
5990 (define_insn_and_split "*lea_general_1_zext"
5991   [(set (match_operand:DI 0 "register_operand" "=r")
5992         (zero_extend:DI
5993           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5994                             (match_operand:SI 2 "register_operand" "r"))
5995                    (match_operand:SI 3 "immediate_operand" "i"))))]
5996   "TARGET_64BIT"
5997   "#"
5998   "&& reload_completed"
5999   [(set (match_dup 0)
6000         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6001                                                      (match_dup 2))
6002                                             (match_dup 3)) 0)))]
6004   operands[1] = gen_lowpart (Pmode, operands[1]);
6005   operands[2] = gen_lowpart (Pmode, operands[2]);
6006   operands[3] = gen_lowpart (Pmode, operands[3]);
6008   [(set_attr "type" "lea")
6009    (set_attr "mode" "SI")])
6011 (define_insn_and_split "*lea_general_2"
6012   [(set (match_operand 0 "register_operand" "=r")
6013         (plus (mult (match_operand 1 "index_register_operand" "l")
6014                     (match_operand 2 "const248_operand" "i"))
6015               (match_operand 3 "nonmemory_operand" "ri")))]
6016   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6017     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6018    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6019    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6020    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6021        || GET_MODE (operands[3]) == VOIDmode)"
6022   "#"
6023   "&& reload_completed"
6024   [(const_int 0)]
6026   rtx pat;
6027   operands[0] = gen_lowpart (SImode, operands[0]);
6028   operands[1] = gen_lowpart (Pmode, operands[1]);
6029   operands[3] = gen_lowpart (Pmode, operands[3]);
6030   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6031                       operands[3]);
6032   if (Pmode != SImode)
6033     pat = gen_rtx_SUBREG (SImode, pat, 0);
6034   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6035   DONE;
6037   [(set_attr "type" "lea")
6038    (set_attr "mode" "SI")])
6040 (define_insn_and_split "*lea_general_2_zext"
6041   [(set (match_operand:DI 0 "register_operand" "=r")
6042         (zero_extend:DI
6043           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6044                             (match_operand:SI 2 "const248_operand" "n"))
6045                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6046   "TARGET_64BIT"
6047   "#"
6048   "&& reload_completed"
6049   [(set (match_dup 0)
6050         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6051                                                      (match_dup 2))
6052                                             (match_dup 3)) 0)))]
6054   operands[1] = gen_lowpart (Pmode, operands[1]);
6055   operands[3] = gen_lowpart (Pmode, operands[3]);
6057   [(set_attr "type" "lea")
6058    (set_attr "mode" "SI")])
6060 (define_insn_and_split "*lea_general_3"
6061   [(set (match_operand 0 "register_operand" "=r")
6062         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6063                           (match_operand 2 "const248_operand" "i"))
6064                     (match_operand 3 "register_operand" "r"))
6065               (match_operand 4 "immediate_operand" "i")))]
6066   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6067     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6068    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6069    && GET_MODE (operands[0]) == GET_MODE (operands[1])
6070    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6071   "#"
6072   "&& reload_completed"
6073   [(const_int 0)]
6075   rtx pat;
6076   operands[0] = gen_lowpart (SImode, operands[0]);
6077   operands[1] = gen_lowpart (Pmode, operands[1]);
6078   operands[3] = gen_lowpart (Pmode, operands[3]);
6079   operands[4] = gen_lowpart (Pmode, operands[4]);
6080   pat = gen_rtx_PLUS (Pmode,
6081                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6082                                                          operands[2]),
6083                                     operands[3]),
6084                       operands[4]);
6085   if (Pmode != SImode)
6086     pat = gen_rtx_SUBREG (SImode, pat, 0);
6087   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6088   DONE;
6090   [(set_attr "type" "lea")
6091    (set_attr "mode" "SI")])
6093 (define_insn_and_split "*lea_general_3_zext"
6094   [(set (match_operand:DI 0 "register_operand" "=r")
6095         (zero_extend:DI
6096           (plus:SI (plus:SI (mult:SI
6097                               (match_operand:SI 1 "index_register_operand" "l")
6098                               (match_operand:SI 2 "const248_operand" "n"))
6099                             (match_operand:SI 3 "register_operand" "r"))
6100                    (match_operand:SI 4 "immediate_operand" "i"))))]
6101   "TARGET_64BIT"
6102   "#"
6103   "&& reload_completed"
6104   [(set (match_dup 0)
6105         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6106                                                               (match_dup 2))
6107                                                      (match_dup 3))
6108                                             (match_dup 4)) 0)))]
6110   operands[1] = gen_lowpart (Pmode, operands[1]);
6111   operands[3] = gen_lowpart (Pmode, operands[3]);
6112   operands[4] = gen_lowpart (Pmode, operands[4]);
6114   [(set_attr "type" "lea")
6115    (set_attr "mode" "SI")])
6117 (define_insn "*adddi_1_rex64"
6118   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
6119         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
6120                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
6121    (clobber (reg:CC FLAGS_REG))]
6122   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6124   switch (get_attr_type (insn))
6125     {
6126     case TYPE_LEA:
6127       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6128       return "lea{q}\t{%a2, %0|%0, %a2}";
6130     case TYPE_INCDEC:
6131       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6132       if (operands[2] == const1_rtx)
6133         return "inc{q}\t%0";
6134       else
6135         {
6136           gcc_assert (operands[2] == constm1_rtx);
6137           return "dec{q}\t%0";
6138         }
6140     default:
6141       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6143       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6144          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6145       if (CONST_INT_P (operands[2])
6146           /* Avoid overflows.  */
6147           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6148           && (INTVAL (operands[2]) == 128
6149               || (INTVAL (operands[2]) < 0
6150                   && INTVAL (operands[2]) != -128)))
6151         {
6152           operands[2] = GEN_INT (-INTVAL (operands[2]));
6153           return "sub{q}\t{%2, %0|%0, %2}";
6154         }
6155       return "add{q}\t{%2, %0|%0, %2}";
6156     }
6158   [(set (attr "type")
6159      (cond [(eq_attr "alternative" "2")
6160               (const_string "lea")
6161             ; Current assemblers are broken and do not allow @GOTOFF in
6162             ; ought but a memory context.
6163             (match_operand:DI 2 "pic_symbolic_operand" "")
6164               (const_string "lea")
6165             (match_operand:DI 2 "incdec_operand" "")
6166               (const_string "incdec")
6167            ]
6168            (const_string "alu")))
6169    (set_attr "mode" "DI")])
6171 ;; Convert lea to the lea pattern to avoid flags dependency.
6172 (define_split
6173   [(set (match_operand:DI 0 "register_operand" "")
6174         (plus:DI (match_operand:DI 1 "register_operand" "")
6175                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6176    (clobber (reg:CC FLAGS_REG))]
6177   "TARGET_64BIT && reload_completed
6178    && true_regnum (operands[0]) != true_regnum (operands[1])"
6179   [(set (match_dup 0)
6180         (plus:DI (match_dup 1)
6181                  (match_dup 2)))]
6182   "")
6184 (define_insn "*adddi_2_rex64"
6185   [(set (reg FLAGS_REG)
6186         (compare
6187           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6188                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6189           (const_int 0)))
6190    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6191         (plus:DI (match_dup 1) (match_dup 2)))]
6192   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6193    && ix86_binary_operator_ok (PLUS, DImode, operands)
6194    /* Current assemblers are broken and do not allow @GOTOFF in
6195       ought but a memory context.  */
6196    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6198   switch (get_attr_type (insn))
6199     {
6200     case TYPE_INCDEC:
6201       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6202       if (operands[2] == const1_rtx)
6203         return "inc{q}\t%0";
6204       else
6205         {
6206           gcc_assert (operands[2] == constm1_rtx);
6207           return "dec{q}\t%0";
6208         }
6210     default:
6211       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6212       /* ???? We ought to handle there the 32bit case too
6213          - do we need new constraint?  */
6214       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6215          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6216       if (CONST_INT_P (operands[2])
6217           /* Avoid overflows.  */
6218           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6219           && (INTVAL (operands[2]) == 128
6220               || (INTVAL (operands[2]) < 0
6221                   && INTVAL (operands[2]) != -128)))
6222         {
6223           operands[2] = GEN_INT (-INTVAL (operands[2]));
6224           return "sub{q}\t{%2, %0|%0, %2}";
6225         }
6226       return "add{q}\t{%2, %0|%0, %2}";
6227     }
6229   [(set (attr "type")
6230      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6231         (const_string "incdec")
6232         (const_string "alu")))
6233    (set_attr "mode" "DI")])
6235 (define_insn "*adddi_3_rex64"
6236   [(set (reg FLAGS_REG)
6237         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6238                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6239    (clobber (match_scratch:DI 0 "=r"))]
6240   "TARGET_64BIT
6241    && ix86_match_ccmode (insn, CCZmode)
6242    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6243    /* Current assemblers are broken and do not allow @GOTOFF in
6244       ought but a memory context.  */
6245    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6247   switch (get_attr_type (insn))
6248     {
6249     case TYPE_INCDEC:
6250       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6251       if (operands[2] == const1_rtx)
6252         return "inc{q}\t%0";
6253       else
6254         {
6255           gcc_assert (operands[2] == constm1_rtx);
6256           return "dec{q}\t%0";
6257         }
6259     default:
6260       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6261       /* ???? We ought to handle there the 32bit case too
6262          - do we need new constraint?  */
6263       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6264          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6265       if (CONST_INT_P (operands[2])
6266           /* Avoid overflows.  */
6267           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6268           && (INTVAL (operands[2]) == 128
6269               || (INTVAL (operands[2]) < 0
6270                   && INTVAL (operands[2]) != -128)))
6271         {
6272           operands[2] = GEN_INT (-INTVAL (operands[2]));
6273           return "sub{q}\t{%2, %0|%0, %2}";
6274         }
6275       return "add{q}\t{%2, %0|%0, %2}";
6276     }
6278   [(set (attr "type")
6279      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6280         (const_string "incdec")
6281         (const_string "alu")))
6282    (set_attr "mode" "DI")])
6284 ; For comparisons against 1, -1 and 128, we may generate better code
6285 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6286 ; is matched then.  We can't accept general immediate, because for
6287 ; case of overflows,  the result is messed up.
6288 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6289 ; when negated.
6290 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6291 ; only for comparisons not depending on it.
6292 (define_insn "*adddi_4_rex64"
6293   [(set (reg FLAGS_REG)
6294         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6295                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6296    (clobber (match_scratch:DI 0 "=rm"))]
6297   "TARGET_64BIT
6298    &&  ix86_match_ccmode (insn, CCGCmode)"
6300   switch (get_attr_type (insn))
6301     {
6302     case TYPE_INCDEC:
6303       if (operands[2] == constm1_rtx)
6304         return "inc{q}\t%0";
6305       else
6306         {
6307           gcc_assert (operands[2] == const1_rtx);
6308           return "dec{q}\t%0";
6309         }
6311     default:
6312       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6313       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6314          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6315       if ((INTVAL (operands[2]) == -128
6316            || (INTVAL (operands[2]) > 0
6317                && INTVAL (operands[2]) != 128))
6318           /* Avoid overflows.  */
6319           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6320         return "sub{q}\t{%2, %0|%0, %2}";
6321       operands[2] = GEN_INT (-INTVAL (operands[2]));
6322       return "add{q}\t{%2, %0|%0, %2}";
6323     }
6325   [(set (attr "type")
6326      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6327         (const_string "incdec")
6328         (const_string "alu")))
6329    (set_attr "mode" "DI")])
6331 (define_insn "*adddi_5_rex64"
6332   [(set (reg FLAGS_REG)
6333         (compare
6334           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6335                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6336           (const_int 0)))
6337    (clobber (match_scratch:DI 0 "=r"))]
6338   "TARGET_64BIT
6339    && ix86_match_ccmode (insn, CCGOCmode)
6340    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6341    /* Current assemblers are broken and do not allow @GOTOFF in
6342       ought but a memory context.  */
6343    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6345   switch (get_attr_type (insn))
6346     {
6347     case TYPE_INCDEC:
6348       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6349       if (operands[2] == const1_rtx)
6350         return "inc{q}\t%0";
6351       else
6352         {
6353           gcc_assert (operands[2] == constm1_rtx);
6354           return "dec{q}\t%0";
6355         }
6357     default:
6358       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6359       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6360          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6361       if (CONST_INT_P (operands[2])
6362           /* Avoid overflows.  */
6363           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6364           && (INTVAL (operands[2]) == 128
6365               || (INTVAL (operands[2]) < 0
6366                   && INTVAL (operands[2]) != -128)))
6367         {
6368           operands[2] = GEN_INT (-INTVAL (operands[2]));
6369           return "sub{q}\t{%2, %0|%0, %2}";
6370         }
6371       return "add{q}\t{%2, %0|%0, %2}";
6372     }
6374   [(set (attr "type")
6375      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6376         (const_string "incdec")
6377         (const_string "alu")))
6378    (set_attr "mode" "DI")])
6381 (define_insn "*addsi_1"
6382   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6383         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6384                  (match_operand:SI 2 "general_operand" "g,ri,li")))
6385    (clobber (reg:CC FLAGS_REG))]
6386   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6388   switch (get_attr_type (insn))
6389     {
6390     case TYPE_LEA:
6391       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6392       return "lea{l}\t{%a2, %0|%0, %a2}";
6394     case TYPE_INCDEC:
6395       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6396       if (operands[2] == const1_rtx)
6397         return "inc{l}\t%0";
6398       else
6399         {
6400           gcc_assert (operands[2] == constm1_rtx);
6401           return "dec{l}\t%0";
6402         }
6404     default:
6405       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6407       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6408          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6409       if (CONST_INT_P (operands[2])
6410           && (INTVAL (operands[2]) == 128
6411               || (INTVAL (operands[2]) < 0
6412                   && INTVAL (operands[2]) != -128)))
6413         {
6414           operands[2] = GEN_INT (-INTVAL (operands[2]));
6415           return "sub{l}\t{%2, %0|%0, %2}";
6416         }
6417       return "add{l}\t{%2, %0|%0, %2}";
6418     }
6420   [(set (attr "type")
6421      (cond [(eq_attr "alternative" "2")
6422               (const_string "lea")
6423             ; Current assemblers are broken and do not allow @GOTOFF in
6424             ; ought but a memory context.
6425             (match_operand:SI 2 "pic_symbolic_operand" "")
6426               (const_string "lea")
6427             (match_operand:SI 2 "incdec_operand" "")
6428               (const_string "incdec")
6429            ]
6430            (const_string "alu")))
6431    (set_attr "mode" "SI")])
6433 ;; Convert lea to the lea pattern to avoid flags dependency.
6434 (define_split
6435   [(set (match_operand 0 "register_operand" "")
6436         (plus (match_operand 1 "register_operand" "")
6437               (match_operand 2 "nonmemory_operand" "")))
6438    (clobber (reg:CC FLAGS_REG))]
6439   "reload_completed
6440    && true_regnum (operands[0]) != true_regnum (operands[1])"
6441   [(const_int 0)]
6443   rtx pat;
6444   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6445      may confuse gen_lowpart.  */
6446   if (GET_MODE (operands[0]) != Pmode)
6447     {
6448       operands[1] = gen_lowpart (Pmode, operands[1]);
6449       operands[2] = gen_lowpart (Pmode, operands[2]);
6450     }
6451   operands[0] = gen_lowpart (SImode, operands[0]);
6452   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6453   if (Pmode != SImode)
6454     pat = gen_rtx_SUBREG (SImode, pat, 0);
6455   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6456   DONE;
6459 ;; It may seem that nonimmediate operand is proper one for operand 1.
6460 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6461 ;; we take care in ix86_binary_operator_ok to not allow two memory
6462 ;; operands so proper swapping will be done in reload.  This allow
6463 ;; patterns constructed from addsi_1 to match.
6464 (define_insn "addsi_1_zext"
6465   [(set (match_operand:DI 0 "register_operand" "=r,r")
6466         (zero_extend:DI
6467           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6468                    (match_operand:SI 2 "general_operand" "g,li"))))
6469    (clobber (reg:CC FLAGS_REG))]
6470   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6472   switch (get_attr_type (insn))
6473     {
6474     case TYPE_LEA:
6475       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6476       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6478     case TYPE_INCDEC:
6479       if (operands[2] == const1_rtx)
6480         return "inc{l}\t%k0";
6481       else
6482         {
6483           gcc_assert (operands[2] == constm1_rtx);
6484           return "dec{l}\t%k0";
6485         }
6487     default:
6488       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6489          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6490       if (CONST_INT_P (operands[2])
6491           && (INTVAL (operands[2]) == 128
6492               || (INTVAL (operands[2]) < 0
6493                   && INTVAL (operands[2]) != -128)))
6494         {
6495           operands[2] = GEN_INT (-INTVAL (operands[2]));
6496           return "sub{l}\t{%2, %k0|%k0, %2}";
6497         }
6498       return "add{l}\t{%2, %k0|%k0, %2}";
6499     }
6501   [(set (attr "type")
6502      (cond [(eq_attr "alternative" "1")
6503               (const_string "lea")
6504             ; Current assemblers are broken and do not allow @GOTOFF in
6505             ; ought but a memory context.
6506             (match_operand:SI 2 "pic_symbolic_operand" "")
6507               (const_string "lea")
6508             (match_operand:SI 2 "incdec_operand" "")
6509               (const_string "incdec")
6510            ]
6511            (const_string "alu")))
6512    (set_attr "mode" "SI")])
6514 ;; Convert lea to the lea pattern to avoid flags dependency.
6515 (define_split
6516   [(set (match_operand:DI 0 "register_operand" "")
6517         (zero_extend:DI
6518           (plus:SI (match_operand:SI 1 "register_operand" "")
6519                    (match_operand:SI 2 "nonmemory_operand" ""))))
6520    (clobber (reg:CC FLAGS_REG))]
6521   "TARGET_64BIT && reload_completed
6522    && true_regnum (operands[0]) != true_regnum (operands[1])"
6523   [(set (match_dup 0)
6524         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6526   operands[1] = gen_lowpart (Pmode, operands[1]);
6527   operands[2] = gen_lowpart (Pmode, operands[2]);
6530 (define_insn "*addsi_2"
6531   [(set (reg FLAGS_REG)
6532         (compare
6533           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6534                    (match_operand:SI 2 "general_operand" "g,ri"))
6535           (const_int 0)))
6536    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6537         (plus:SI (match_dup 1) (match_dup 2)))]
6538   "ix86_match_ccmode (insn, CCGOCmode)
6539    && ix86_binary_operator_ok (PLUS, SImode, operands)
6540    /* Current assemblers are broken and do not allow @GOTOFF in
6541       ought but a memory context.  */
6542    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6544   switch (get_attr_type (insn))
6545     {
6546     case TYPE_INCDEC:
6547       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6548       if (operands[2] == const1_rtx)
6549         return "inc{l}\t%0";
6550       else
6551         {
6552           gcc_assert (operands[2] == constm1_rtx);
6553           return "dec{l}\t%0";
6554         }
6556     default:
6557       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6558       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6559          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6560       if (CONST_INT_P (operands[2])
6561           && (INTVAL (operands[2]) == 128
6562               || (INTVAL (operands[2]) < 0
6563                   && INTVAL (operands[2]) != -128)))
6564         {
6565           operands[2] = GEN_INT (-INTVAL (operands[2]));
6566           return "sub{l}\t{%2, %0|%0, %2}";
6567         }
6568       return "add{l}\t{%2, %0|%0, %2}";
6569     }
6571   [(set (attr "type")
6572      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6573         (const_string "incdec")
6574         (const_string "alu")))
6575    (set_attr "mode" "SI")])
6577 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6578 (define_insn "*addsi_2_zext"
6579   [(set (reg FLAGS_REG)
6580         (compare
6581           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6582                    (match_operand:SI 2 "general_operand" "g"))
6583           (const_int 0)))
6584    (set (match_operand:DI 0 "register_operand" "=r")
6585         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6586   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6587    && ix86_binary_operator_ok (PLUS, SImode, operands)
6588    /* Current assemblers are broken and do not allow @GOTOFF in
6589       ought but a memory context.  */
6590    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6592   switch (get_attr_type (insn))
6593     {
6594     case TYPE_INCDEC:
6595       if (operands[2] == const1_rtx)
6596         return "inc{l}\t%k0";
6597       else
6598         {
6599           gcc_assert (operands[2] == constm1_rtx);
6600           return "dec{l}\t%k0";
6601         }
6603     default:
6604       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6605          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6606       if (CONST_INT_P (operands[2])
6607           && (INTVAL (operands[2]) == 128
6608               || (INTVAL (operands[2]) < 0
6609                   && INTVAL (operands[2]) != -128)))
6610         {
6611           operands[2] = GEN_INT (-INTVAL (operands[2]));
6612           return "sub{l}\t{%2, %k0|%k0, %2}";
6613         }
6614       return "add{l}\t{%2, %k0|%k0, %2}";
6615     }
6617   [(set (attr "type")
6618      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6619         (const_string "incdec")
6620         (const_string "alu")))
6621    (set_attr "mode" "SI")])
6623 (define_insn "*addsi_3"
6624   [(set (reg FLAGS_REG)
6625         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6626                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6627    (clobber (match_scratch:SI 0 "=r"))]
6628   "ix86_match_ccmode (insn, CCZmode)
6629    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6630    /* Current assemblers are broken and do not allow @GOTOFF in
6631       ought but a memory context.  */
6632    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6634   switch (get_attr_type (insn))
6635     {
6636     case TYPE_INCDEC:
6637       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6638       if (operands[2] == const1_rtx)
6639         return "inc{l}\t%0";
6640       else
6641         {
6642           gcc_assert (operands[2] == constm1_rtx);
6643           return "dec{l}\t%0";
6644         }
6646     default:
6647       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6648       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6649          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6650       if (CONST_INT_P (operands[2])
6651           && (INTVAL (operands[2]) == 128
6652               || (INTVAL (operands[2]) < 0
6653                   && INTVAL (operands[2]) != -128)))
6654         {
6655           operands[2] = GEN_INT (-INTVAL (operands[2]));
6656           return "sub{l}\t{%2, %0|%0, %2}";
6657         }
6658       return "add{l}\t{%2, %0|%0, %2}";
6659     }
6661   [(set (attr "type")
6662      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6663         (const_string "incdec")
6664         (const_string "alu")))
6665    (set_attr "mode" "SI")])
6667 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6668 (define_insn "*addsi_3_zext"
6669   [(set (reg FLAGS_REG)
6670         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6671                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6672    (set (match_operand:DI 0 "register_operand" "=r")
6673         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6674   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6675    && ix86_binary_operator_ok (PLUS, SImode, operands)
6676    /* Current assemblers are broken and do not allow @GOTOFF in
6677       ought but a memory context.  */
6678    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6680   switch (get_attr_type (insn))
6681     {
6682     case TYPE_INCDEC:
6683       if (operands[2] == const1_rtx)
6684         return "inc{l}\t%k0";
6685       else
6686         {
6687           gcc_assert (operands[2] == constm1_rtx);
6688           return "dec{l}\t%k0";
6689         }
6691     default:
6692       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6693          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6694       if (CONST_INT_P (operands[2])
6695           && (INTVAL (operands[2]) == 128
6696               || (INTVAL (operands[2]) < 0
6697                   && INTVAL (operands[2]) != -128)))
6698         {
6699           operands[2] = GEN_INT (-INTVAL (operands[2]));
6700           return "sub{l}\t{%2, %k0|%k0, %2}";
6701         }
6702       return "add{l}\t{%2, %k0|%k0, %2}";
6703     }
6705   [(set (attr "type")
6706      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6707         (const_string "incdec")
6708         (const_string "alu")))
6709    (set_attr "mode" "SI")])
6711 ; For comparisons against 1, -1 and 128, we may generate better code
6712 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6713 ; is matched then.  We can't accept general immediate, because for
6714 ; case of overflows,  the result is messed up.
6715 ; This pattern also don't hold of 0x80000000, since the value overflows
6716 ; when negated.
6717 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6718 ; only for comparisons not depending on it.
6719 (define_insn "*addsi_4"
6720   [(set (reg FLAGS_REG)
6721         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6722                  (match_operand:SI 2 "const_int_operand" "n")))
6723    (clobber (match_scratch:SI 0 "=rm"))]
6724   "ix86_match_ccmode (insn, CCGCmode)
6725    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6727   switch (get_attr_type (insn))
6728     {
6729     case TYPE_INCDEC:
6730       if (operands[2] == constm1_rtx)
6731         return "inc{l}\t%0";
6732       else
6733         {
6734           gcc_assert (operands[2] == const1_rtx);
6735           return "dec{l}\t%0";
6736         }
6738     default:
6739       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6740       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6741          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6742       if ((INTVAL (operands[2]) == -128
6743            || (INTVAL (operands[2]) > 0
6744                && INTVAL (operands[2]) != 128)))
6745         return "sub{l}\t{%2, %0|%0, %2}";
6746       operands[2] = GEN_INT (-INTVAL (operands[2]));
6747       return "add{l}\t{%2, %0|%0, %2}";
6748     }
6750   [(set (attr "type")
6751      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6752         (const_string "incdec")
6753         (const_string "alu")))
6754    (set_attr "mode" "SI")])
6756 (define_insn "*addsi_5"
6757   [(set (reg FLAGS_REG)
6758         (compare
6759           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6760                    (match_operand:SI 2 "general_operand" "g"))
6761           (const_int 0)))
6762    (clobber (match_scratch:SI 0 "=r"))]
6763   "ix86_match_ccmode (insn, CCGOCmode)
6764    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6765    /* Current assemblers are broken and do not allow @GOTOFF in
6766       ought but a memory context.  */
6767    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6769   switch (get_attr_type (insn))
6770     {
6771     case TYPE_INCDEC:
6772       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6773       if (operands[2] == const1_rtx)
6774         return "inc{l}\t%0";
6775       else
6776         {
6777           gcc_assert (operands[2] == constm1_rtx);
6778           return "dec{l}\t%0";
6779         }
6781     default:
6782       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6783       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6784          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6785       if (CONST_INT_P (operands[2])
6786           && (INTVAL (operands[2]) == 128
6787               || (INTVAL (operands[2]) < 0
6788                   && INTVAL (operands[2]) != -128)))
6789         {
6790           operands[2] = GEN_INT (-INTVAL (operands[2]));
6791           return "sub{l}\t{%2, %0|%0, %2}";
6792         }
6793       return "add{l}\t{%2, %0|%0, %2}";
6794     }
6796   [(set (attr "type")
6797      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6798         (const_string "incdec")
6799         (const_string "alu")))
6800    (set_attr "mode" "SI")])
6802 (define_expand "addhi3"
6803   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6804         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6805                  (match_operand:HI 2 "general_operand" "")))]
6806   "TARGET_HIMODE_MATH"
6807   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6809 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6810 ;; type optimizations enabled by define-splits.  This is not important
6811 ;; for PII, and in fact harmful because of partial register stalls.
6813 (define_insn "*addhi_1_lea"
6814   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6815         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6816                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6817    (clobber (reg:CC FLAGS_REG))]
6818   "!TARGET_PARTIAL_REG_STALL
6819    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6821   switch (get_attr_type (insn))
6822     {
6823     case TYPE_LEA:
6824       return "#";
6825     case TYPE_INCDEC:
6826       if (operands[2] == const1_rtx)
6827         return "inc{w}\t%0";
6828       else
6829         {
6830           gcc_assert (operands[2] == constm1_rtx);
6831           return "dec{w}\t%0";
6832         }
6834     default:
6835       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6836          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6837       if (CONST_INT_P (operands[2])
6838           && (INTVAL (operands[2]) == 128
6839               || (INTVAL (operands[2]) < 0
6840                   && INTVAL (operands[2]) != -128)))
6841         {
6842           operands[2] = GEN_INT (-INTVAL (operands[2]));
6843           return "sub{w}\t{%2, %0|%0, %2}";
6844         }
6845       return "add{w}\t{%2, %0|%0, %2}";
6846     }
6848   [(set (attr "type")
6849      (if_then_else (eq_attr "alternative" "2")
6850         (const_string "lea")
6851         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6852            (const_string "incdec")
6853            (const_string "alu"))))
6854    (set_attr "mode" "HI,HI,SI")])
6856 (define_insn "*addhi_1"
6857   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6858         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6859                  (match_operand:HI 2 "general_operand" "rn,rm")))
6860    (clobber (reg:CC FLAGS_REG))]
6861   "TARGET_PARTIAL_REG_STALL
6862    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6864   switch (get_attr_type (insn))
6865     {
6866     case TYPE_INCDEC:
6867       if (operands[2] == const1_rtx)
6868         return "inc{w}\t%0";
6869       else
6870         {
6871           gcc_assert (operands[2] == constm1_rtx);
6872           return "dec{w}\t%0";
6873         }
6875     default:
6876       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6877          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6878       if (CONST_INT_P (operands[2])
6879           && (INTVAL (operands[2]) == 128
6880               || (INTVAL (operands[2]) < 0
6881                   && INTVAL (operands[2]) != -128)))
6882         {
6883           operands[2] = GEN_INT (-INTVAL (operands[2]));
6884           return "sub{w}\t{%2, %0|%0, %2}";
6885         }
6886       return "add{w}\t{%2, %0|%0, %2}";
6887     }
6889   [(set (attr "type")
6890      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6891         (const_string "incdec")
6892         (const_string "alu")))
6893    (set_attr "mode" "HI")])
6895 (define_insn "*addhi_2"
6896   [(set (reg FLAGS_REG)
6897         (compare
6898           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6899                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6900           (const_int 0)))
6901    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6902         (plus:HI (match_dup 1) (match_dup 2)))]
6903   "ix86_match_ccmode (insn, CCGOCmode)
6904    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6906   switch (get_attr_type (insn))
6907     {
6908     case TYPE_INCDEC:
6909       if (operands[2] == const1_rtx)
6910         return "inc{w}\t%0";
6911       else
6912         {
6913           gcc_assert (operands[2] == constm1_rtx);
6914           return "dec{w}\t%0";
6915         }
6917     default:
6918       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6919          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6920       if (CONST_INT_P (operands[2])
6921           && (INTVAL (operands[2]) == 128
6922               || (INTVAL (operands[2]) < 0
6923                   && INTVAL (operands[2]) != -128)))
6924         {
6925           operands[2] = GEN_INT (-INTVAL (operands[2]));
6926           return "sub{w}\t{%2, %0|%0, %2}";
6927         }
6928       return "add{w}\t{%2, %0|%0, %2}";
6929     }
6931   [(set (attr "type")
6932      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6933         (const_string "incdec")
6934         (const_string "alu")))
6935    (set_attr "mode" "HI")])
6937 (define_insn "*addhi_3"
6938   [(set (reg FLAGS_REG)
6939         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6940                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6941    (clobber (match_scratch:HI 0 "=r"))]
6942   "ix86_match_ccmode (insn, CCZmode)
6943    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6945   switch (get_attr_type (insn))
6946     {
6947     case TYPE_INCDEC:
6948       if (operands[2] == const1_rtx)
6949         return "inc{w}\t%0";
6950       else
6951         {
6952           gcc_assert (operands[2] == constm1_rtx);
6953           return "dec{w}\t%0";
6954         }
6956     default:
6957       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6958          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6959       if (CONST_INT_P (operands[2])
6960           && (INTVAL (operands[2]) == 128
6961               || (INTVAL (operands[2]) < 0
6962                   && INTVAL (operands[2]) != -128)))
6963         {
6964           operands[2] = GEN_INT (-INTVAL (operands[2]));
6965           return "sub{w}\t{%2, %0|%0, %2}";
6966         }
6967       return "add{w}\t{%2, %0|%0, %2}";
6968     }
6970   [(set (attr "type")
6971      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6972         (const_string "incdec")
6973         (const_string "alu")))
6974    (set_attr "mode" "HI")])
6976 ; See comments above addsi_4 for details.
6977 (define_insn "*addhi_4"
6978   [(set (reg FLAGS_REG)
6979         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6980                  (match_operand:HI 2 "const_int_operand" "n")))
6981    (clobber (match_scratch:HI 0 "=rm"))]
6982   "ix86_match_ccmode (insn, CCGCmode)
6983    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6985   switch (get_attr_type (insn))
6986     {
6987     case TYPE_INCDEC:
6988       if (operands[2] == constm1_rtx)
6989         return "inc{w}\t%0";
6990       else
6991         {
6992           gcc_assert (operands[2] == const1_rtx);
6993           return "dec{w}\t%0";
6994         }
6996     default:
6997       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6998       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6999          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7000       if ((INTVAL (operands[2]) == -128
7001            || (INTVAL (operands[2]) > 0
7002                && INTVAL (operands[2]) != 128)))
7003         return "sub{w}\t{%2, %0|%0, %2}";
7004       operands[2] = GEN_INT (-INTVAL (operands[2]));
7005       return "add{w}\t{%2, %0|%0, %2}";
7006     }
7008   [(set (attr "type")
7009      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7010         (const_string "incdec")
7011         (const_string "alu")))
7012    (set_attr "mode" "SI")])
7015 (define_insn "*addhi_5"
7016   [(set (reg FLAGS_REG)
7017         (compare
7018           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7019                    (match_operand:HI 2 "general_operand" "rmn"))
7020           (const_int 0)))
7021    (clobber (match_scratch:HI 0 "=r"))]
7022   "ix86_match_ccmode (insn, CCGOCmode)
7023    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7025   switch (get_attr_type (insn))
7026     {
7027     case TYPE_INCDEC:
7028       if (operands[2] == const1_rtx)
7029         return "inc{w}\t%0";
7030       else
7031         {
7032           gcc_assert (operands[2] == constm1_rtx);
7033           return "dec{w}\t%0";
7034         }
7036     default:
7037       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7038          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7039       if (CONST_INT_P (operands[2])
7040           && (INTVAL (operands[2]) == 128
7041               || (INTVAL (operands[2]) < 0
7042                   && INTVAL (operands[2]) != -128)))
7043         {
7044           operands[2] = GEN_INT (-INTVAL (operands[2]));
7045           return "sub{w}\t{%2, %0|%0, %2}";
7046         }
7047       return "add{w}\t{%2, %0|%0, %2}";
7048     }
7050   [(set (attr "type")
7051      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7052         (const_string "incdec")
7053         (const_string "alu")))
7054    (set_attr "mode" "HI")])
7056 (define_expand "addqi3"
7057   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7058         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7059                  (match_operand:QI 2 "general_operand" "")))]
7060   "TARGET_QIMODE_MATH"
7061   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7063 ;; %%% Potential partial reg stall on alternative 2.  What to do?
7064 (define_insn "*addqi_1_lea"
7065   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7066         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7067                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7068    (clobber (reg:CC FLAGS_REG))]
7069   "!TARGET_PARTIAL_REG_STALL
7070    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7072   int widen = (which_alternative == 2);
7073   switch (get_attr_type (insn))
7074     {
7075     case TYPE_LEA:
7076       return "#";
7077     case TYPE_INCDEC:
7078       if (operands[2] == const1_rtx)
7079         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7080       else
7081         {
7082           gcc_assert (operands[2] == constm1_rtx);
7083           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7084         }
7086     default:
7087       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7088          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7089       if (CONST_INT_P (operands[2])
7090           && (INTVAL (operands[2]) == 128
7091               || (INTVAL (operands[2]) < 0
7092                   && INTVAL (operands[2]) != -128)))
7093         {
7094           operands[2] = GEN_INT (-INTVAL (operands[2]));
7095           if (widen)
7096             return "sub{l}\t{%2, %k0|%k0, %2}";
7097           else
7098             return "sub{b}\t{%2, %0|%0, %2}";
7099         }
7100       if (widen)
7101         return "add{l}\t{%k2, %k0|%k0, %k2}";
7102       else
7103         return "add{b}\t{%2, %0|%0, %2}";
7104     }
7106   [(set (attr "type")
7107      (if_then_else (eq_attr "alternative" "3")
7108         (const_string "lea")
7109         (if_then_else (match_operand:QI 2 "incdec_operand" "")
7110            (const_string "incdec")
7111            (const_string "alu"))))
7112    (set_attr "mode" "QI,QI,SI,SI")])
7114 (define_insn "*addqi_1"
7115   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7116         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7117                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7118    (clobber (reg:CC FLAGS_REG))]
7119   "TARGET_PARTIAL_REG_STALL
7120    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7122   int widen = (which_alternative == 2);
7123   switch (get_attr_type (insn))
7124     {
7125     case TYPE_INCDEC:
7126       if (operands[2] == const1_rtx)
7127         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7128       else
7129         {
7130           gcc_assert (operands[2] == constm1_rtx);
7131           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7132         }
7134     default:
7135       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7136          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
7137       if (CONST_INT_P (operands[2])
7138           && (INTVAL (operands[2]) == 128
7139               || (INTVAL (operands[2]) < 0
7140                   && INTVAL (operands[2]) != -128)))
7141         {
7142           operands[2] = GEN_INT (-INTVAL (operands[2]));
7143           if (widen)
7144             return "sub{l}\t{%2, %k0|%k0, %2}";
7145           else
7146             return "sub{b}\t{%2, %0|%0, %2}";
7147         }
7148       if (widen)
7149         return "add{l}\t{%k2, %k0|%k0, %k2}";
7150       else
7151         return "add{b}\t{%2, %0|%0, %2}";
7152     }
7154   [(set (attr "type")
7155      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7156         (const_string "incdec")
7157         (const_string "alu")))
7158    (set_attr "mode" "QI,QI,SI")])
7160 (define_insn "*addqi_1_slp"
7161   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7162         (plus:QI (match_dup 0)
7163                  (match_operand:QI 1 "general_operand" "qn,qnm")))
7164    (clobber (reg:CC FLAGS_REG))]
7165   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7166    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7168   switch (get_attr_type (insn))
7169     {
7170     case TYPE_INCDEC:
7171       if (operands[1] == const1_rtx)
7172         return "inc{b}\t%0";
7173       else
7174         {
7175           gcc_assert (operands[1] == constm1_rtx);
7176           return "dec{b}\t%0";
7177         }
7179     default:
7180       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
7181       if (CONST_INT_P (operands[1])
7182           && INTVAL (operands[1]) < 0)
7183         {
7184           operands[1] = GEN_INT (-INTVAL (operands[1]));
7185           return "sub{b}\t{%1, %0|%0, %1}";
7186         }
7187       return "add{b}\t{%1, %0|%0, %1}";
7188     }
7190   [(set (attr "type")
7191      (if_then_else (match_operand:QI 1 "incdec_operand" "")
7192         (const_string "incdec")
7193         (const_string "alu1")))
7194    (set (attr "memory")
7195      (if_then_else (match_operand 1 "memory_operand" "")
7196         (const_string "load")
7197         (const_string "none")))
7198    (set_attr "mode" "QI")])
7200 (define_insn "*addqi_2"
7201   [(set (reg FLAGS_REG)
7202         (compare
7203           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7204                    (match_operand:QI 2 "general_operand" "qmn,qn"))
7205           (const_int 0)))
7206    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7207         (plus:QI (match_dup 1) (match_dup 2)))]
7208   "ix86_match_ccmode (insn, CCGOCmode)
7209    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7211   switch (get_attr_type (insn))
7212     {
7213     case TYPE_INCDEC:
7214       if (operands[2] == const1_rtx)
7215         return "inc{b}\t%0";
7216       else
7217         {
7218           gcc_assert (operands[2] == constm1_rtx
7219                       || (CONST_INT_P (operands[2])
7220                           && INTVAL (operands[2]) == 255));
7221           return "dec{b}\t%0";
7222         }
7224     default:
7225       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7226       if (CONST_INT_P (operands[2])
7227           && INTVAL (operands[2]) < 0)
7228         {
7229           operands[2] = GEN_INT (-INTVAL (operands[2]));
7230           return "sub{b}\t{%2, %0|%0, %2}";
7231         }
7232       return "add{b}\t{%2, %0|%0, %2}";
7233     }
7235   [(set (attr "type")
7236      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7237         (const_string "incdec")
7238         (const_string "alu")))
7239    (set_attr "mode" "QI")])
7241 (define_insn "*addqi_3"
7242   [(set (reg FLAGS_REG)
7243         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7244                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7245    (clobber (match_scratch:QI 0 "=q"))]
7246   "ix86_match_ccmode (insn, CCZmode)
7247    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7249   switch (get_attr_type (insn))
7250     {
7251     case TYPE_INCDEC:
7252       if (operands[2] == const1_rtx)
7253         return "inc{b}\t%0";
7254       else
7255         {
7256           gcc_assert (operands[2] == constm1_rtx
7257                       || (CONST_INT_P (operands[2])
7258                           && INTVAL (operands[2]) == 255));
7259           return "dec{b}\t%0";
7260         }
7262     default:
7263       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7264       if (CONST_INT_P (operands[2])
7265           && INTVAL (operands[2]) < 0)
7266         {
7267           operands[2] = GEN_INT (-INTVAL (operands[2]));
7268           return "sub{b}\t{%2, %0|%0, %2}";
7269         }
7270       return "add{b}\t{%2, %0|%0, %2}";
7271     }
7273   [(set (attr "type")
7274      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7275         (const_string "incdec")
7276         (const_string "alu")))
7277    (set_attr "mode" "QI")])
7279 ; See comments above addsi_4 for details.
7280 (define_insn "*addqi_4"
7281   [(set (reg FLAGS_REG)
7282         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7283                  (match_operand:QI 2 "const_int_operand" "n")))
7284    (clobber (match_scratch:QI 0 "=qm"))]
7285   "ix86_match_ccmode (insn, CCGCmode)
7286    && (INTVAL (operands[2]) & 0xff) != 0x80"
7288   switch (get_attr_type (insn))
7289     {
7290     case TYPE_INCDEC:
7291       if (operands[2] == constm1_rtx
7292           || (CONST_INT_P (operands[2])
7293               && INTVAL (operands[2]) == 255))
7294         return "inc{b}\t%0";
7295       else
7296         {
7297           gcc_assert (operands[2] == const1_rtx);
7298           return "dec{b}\t%0";
7299         }
7301     default:
7302       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7303       if (INTVAL (operands[2]) < 0)
7304         {
7305           operands[2] = GEN_INT (-INTVAL (operands[2]));
7306           return "add{b}\t{%2, %0|%0, %2}";
7307         }
7308       return "sub{b}\t{%2, %0|%0, %2}";
7309     }
7311   [(set (attr "type")
7312      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7313         (const_string "incdec")
7314         (const_string "alu")))
7315    (set_attr "mode" "QI")])
7318 (define_insn "*addqi_5"
7319   [(set (reg FLAGS_REG)
7320         (compare
7321           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7322                    (match_operand:QI 2 "general_operand" "qmn"))
7323           (const_int 0)))
7324    (clobber (match_scratch:QI 0 "=q"))]
7325   "ix86_match_ccmode (insn, CCGOCmode)
7326    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7328   switch (get_attr_type (insn))
7329     {
7330     case TYPE_INCDEC:
7331       if (operands[2] == const1_rtx)
7332         return "inc{b}\t%0";
7333       else
7334         {
7335           gcc_assert (operands[2] == constm1_rtx
7336                       || (CONST_INT_P (operands[2])
7337                           && INTVAL (operands[2]) == 255));
7338           return "dec{b}\t%0";
7339         }
7341     default:
7342       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7343       if (CONST_INT_P (operands[2])
7344           && INTVAL (operands[2]) < 0)
7345         {
7346           operands[2] = GEN_INT (-INTVAL (operands[2]));
7347           return "sub{b}\t{%2, %0|%0, %2}";
7348         }
7349       return "add{b}\t{%2, %0|%0, %2}";
7350     }
7352   [(set (attr "type")
7353      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7354         (const_string "incdec")
7355         (const_string "alu")))
7356    (set_attr "mode" "QI")])
7359 (define_insn "addqi_ext_1"
7360   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7361                          (const_int 8)
7362                          (const_int 8))
7363         (plus:SI
7364           (zero_extract:SI
7365             (match_operand 1 "ext_register_operand" "0")
7366             (const_int 8)
7367             (const_int 8))
7368           (match_operand:QI 2 "general_operand" "Qmn")))
7369    (clobber (reg:CC FLAGS_REG))]
7370   "!TARGET_64BIT"
7372   switch (get_attr_type (insn))
7373     {
7374     case TYPE_INCDEC:
7375       if (operands[2] == const1_rtx)
7376         return "inc{b}\t%h0";
7377       else
7378         {
7379           gcc_assert (operands[2] == constm1_rtx
7380                       || (CONST_INT_P (operands[2])
7381                           && INTVAL (operands[2]) == 255));
7382           return "dec{b}\t%h0";
7383         }
7385     default:
7386       return "add{b}\t{%2, %h0|%h0, %2}";
7387     }
7389   [(set (attr "type")
7390      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7391         (const_string "incdec")
7392         (const_string "alu")))
7393    (set_attr "mode" "QI")])
7395 (define_insn "*addqi_ext_1_rex64"
7396   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7397                          (const_int 8)
7398                          (const_int 8))
7399         (plus:SI
7400           (zero_extract:SI
7401             (match_operand 1 "ext_register_operand" "0")
7402             (const_int 8)
7403             (const_int 8))
7404           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7405    (clobber (reg:CC FLAGS_REG))]
7406   "TARGET_64BIT"
7408   switch (get_attr_type (insn))
7409     {
7410     case TYPE_INCDEC:
7411       if (operands[2] == const1_rtx)
7412         return "inc{b}\t%h0";
7413       else
7414         {
7415           gcc_assert (operands[2] == constm1_rtx
7416                       || (CONST_INT_P (operands[2])
7417                           && INTVAL (operands[2]) == 255));
7418           return "dec{b}\t%h0";
7419         }
7421     default:
7422       return "add{b}\t{%2, %h0|%h0, %2}";
7423     }
7425   [(set (attr "type")
7426      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7427         (const_string "incdec")
7428         (const_string "alu")))
7429    (set_attr "mode" "QI")])
7431 (define_insn "*addqi_ext_2"
7432   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7433                          (const_int 8)
7434                          (const_int 8))
7435         (plus:SI
7436           (zero_extract:SI
7437             (match_operand 1 "ext_register_operand" "%0")
7438             (const_int 8)
7439             (const_int 8))
7440           (zero_extract:SI
7441             (match_operand 2 "ext_register_operand" "Q")
7442             (const_int 8)
7443             (const_int 8))))
7444    (clobber (reg:CC FLAGS_REG))]
7445   ""
7446   "add{b}\t{%h2, %h0|%h0, %h2}"
7447   [(set_attr "type" "alu")
7448    (set_attr "mode" "QI")])
7450 ;; The patterns that match these are at the end of this file.
7452 (define_expand "addxf3"
7453   [(set (match_operand:XF 0 "register_operand" "")
7454         (plus:XF (match_operand:XF 1 "register_operand" "")
7455                  (match_operand:XF 2 "register_operand" "")))]
7456   "TARGET_80387"
7457   "")
7459 (define_expand "add<mode>3"
7460   [(set (match_operand:MODEF 0 "register_operand" "")
7461         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7462                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7463   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7464   "")
7466 ;; Subtract instructions
7468 ;; %%% splits for subditi3
7470 (define_expand "subti3"
7471   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7472         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7473                   (match_operand:TI 2 "x86_64_general_operand" "")))]
7474   "TARGET_64BIT"
7475   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7477 (define_insn "*subti3_1"
7478   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7479         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7480                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7481    (clobber (reg:CC FLAGS_REG))]
7482   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7483   "#")
7485 (define_split
7486   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7487         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7488                   (match_operand:TI 2 "x86_64_general_operand" "")))
7489    (clobber (reg:CC FLAGS_REG))]
7490   "TARGET_64BIT && reload_completed"
7491   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7492               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7493    (parallel [(set (match_dup 3)
7494                    (minus:DI (match_dup 4)
7495                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7496                                       (match_dup 5))))
7497               (clobber (reg:CC FLAGS_REG))])]
7498   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7500 ;; %%% splits for subsidi3
7502 (define_expand "subdi3"
7503   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7504         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7505                   (match_operand:DI 2 "x86_64_general_operand" "")))]
7506   ""
7507   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7509 (define_insn "*subdi3_1"
7510   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7511         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7512                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7513    (clobber (reg:CC FLAGS_REG))]
7514   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7515   "#")
7517 (define_split
7518   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7519         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7520                   (match_operand:DI 2 "general_operand" "")))
7521    (clobber (reg:CC FLAGS_REG))]
7522   "!TARGET_64BIT && reload_completed"
7523   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7524               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7525    (parallel [(set (match_dup 3)
7526                    (minus:SI (match_dup 4)
7527                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7528                                       (match_dup 5))))
7529               (clobber (reg:CC FLAGS_REG))])]
7530   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7532 (define_insn "subdi3_carry_rex64"
7533   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7534           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7535             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7536                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7537    (clobber (reg:CC FLAGS_REG))]
7538   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7539   "sbb{q}\t{%2, %0|%0, %2}"
7540   [(set_attr "type" "alu")
7541    (set_attr "pent_pair" "pu")
7542    (set_attr "mode" "DI")])
7544 (define_insn "*subdi_1_rex64"
7545   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7546         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7547                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7548    (clobber (reg:CC FLAGS_REG))]
7549   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7550   "sub{q}\t{%2, %0|%0, %2}"
7551   [(set_attr "type" "alu")
7552    (set_attr "mode" "DI")])
7554 (define_insn "*subdi_2_rex64"
7555   [(set (reg FLAGS_REG)
7556         (compare
7557           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7558                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7559           (const_int 0)))
7560    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7561         (minus:DI (match_dup 1) (match_dup 2)))]
7562   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7563    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7564   "sub{q}\t{%2, %0|%0, %2}"
7565   [(set_attr "type" "alu")
7566    (set_attr "mode" "DI")])
7568 (define_insn "*subdi_3_rex63"
7569   [(set (reg FLAGS_REG)
7570         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7571                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7572    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7573         (minus:DI (match_dup 1) (match_dup 2)))]
7574   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7575    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7576   "sub{q}\t{%2, %0|%0, %2}"
7577   [(set_attr "type" "alu")
7578    (set_attr "mode" "DI")])
7580 (define_insn "subqi3_carry"
7581   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7582           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7583             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7584                (match_operand:QI 2 "general_operand" "qn,qm"))))
7585    (clobber (reg:CC FLAGS_REG))]
7586   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7587   "sbb{b}\t{%2, %0|%0, %2}"
7588   [(set_attr "type" "alu")
7589    (set_attr "pent_pair" "pu")
7590    (set_attr "mode" "QI")])
7592 (define_insn "subhi3_carry"
7593   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7594           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7595             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7596                (match_operand:HI 2 "general_operand" "rn,rm"))))
7597    (clobber (reg:CC FLAGS_REG))]
7598   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7599   "sbb{w}\t{%2, %0|%0, %2}"
7600   [(set_attr "type" "alu")
7601    (set_attr "pent_pair" "pu")
7602    (set_attr "mode" "HI")])
7604 (define_insn "subsi3_carry"
7605   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7606           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7607             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7608                (match_operand:SI 2 "general_operand" "ri,rm"))))
7609    (clobber (reg:CC FLAGS_REG))]
7610   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7611   "sbb{l}\t{%2, %0|%0, %2}"
7612   [(set_attr "type" "alu")
7613    (set_attr "pent_pair" "pu")
7614    (set_attr "mode" "SI")])
7616 (define_insn "subsi3_carry_zext"
7617   [(set (match_operand:DI 0 "register_operand" "=r")
7618           (zero_extend:DI
7619             (minus:SI (match_operand:SI 1 "register_operand" "0")
7620               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7621                  (match_operand:SI 2 "general_operand" "g")))))
7622    (clobber (reg:CC FLAGS_REG))]
7623   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7624   "sbb{l}\t{%2, %k0|%k0, %2}"
7625   [(set_attr "type" "alu")
7626    (set_attr "pent_pair" "pu")
7627    (set_attr "mode" "SI")])
7629 (define_expand "subsi3"
7630   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7631         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7632                   (match_operand:SI 2 "general_operand" "")))]
7633   ""
7634   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7636 (define_insn "*subsi_1"
7637   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7638         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7639                   (match_operand:SI 2 "general_operand" "ri,rm")))
7640    (clobber (reg:CC FLAGS_REG))]
7641   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7642   "sub{l}\t{%2, %0|%0, %2}"
7643   [(set_attr "type" "alu")
7644    (set_attr "mode" "SI")])
7646 (define_insn "*subsi_1_zext"
7647   [(set (match_operand:DI 0 "register_operand" "=r")
7648         (zero_extend:DI
7649           (minus:SI (match_operand:SI 1 "register_operand" "0")
7650                     (match_operand:SI 2 "general_operand" "g"))))
7651    (clobber (reg:CC FLAGS_REG))]
7652   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7653   "sub{l}\t{%2, %k0|%k0, %2}"
7654   [(set_attr "type" "alu")
7655    (set_attr "mode" "SI")])
7657 (define_insn "*subsi_2"
7658   [(set (reg FLAGS_REG)
7659         (compare
7660           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7661                     (match_operand:SI 2 "general_operand" "ri,rm"))
7662           (const_int 0)))
7663    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7664         (minus:SI (match_dup 1) (match_dup 2)))]
7665   "ix86_match_ccmode (insn, CCGOCmode)
7666    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7667   "sub{l}\t{%2, %0|%0, %2}"
7668   [(set_attr "type" "alu")
7669    (set_attr "mode" "SI")])
7671 (define_insn "*subsi_2_zext"
7672   [(set (reg FLAGS_REG)
7673         (compare
7674           (minus:SI (match_operand:SI 1 "register_operand" "0")
7675                     (match_operand:SI 2 "general_operand" "g"))
7676           (const_int 0)))
7677    (set (match_operand:DI 0 "register_operand" "=r")
7678         (zero_extend:DI
7679           (minus:SI (match_dup 1)
7680                     (match_dup 2))))]
7681   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7682    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7683   "sub{l}\t{%2, %k0|%k0, %2}"
7684   [(set_attr "type" "alu")
7685    (set_attr "mode" "SI")])
7687 (define_insn "*subsi_3"
7688   [(set (reg FLAGS_REG)
7689         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7690                  (match_operand:SI 2 "general_operand" "ri,rm")))
7691    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7692         (minus:SI (match_dup 1) (match_dup 2)))]
7693   "ix86_match_ccmode (insn, CCmode)
7694    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7695   "sub{l}\t{%2, %0|%0, %2}"
7696   [(set_attr "type" "alu")
7697    (set_attr "mode" "SI")])
7699 (define_insn "*subsi_3_zext"
7700   [(set (reg FLAGS_REG)
7701         (compare (match_operand:SI 1 "register_operand" "0")
7702                  (match_operand:SI 2 "general_operand" "g")))
7703    (set (match_operand:DI 0 "register_operand" "=r")
7704         (zero_extend:DI
7705           (minus:SI (match_dup 1)
7706                     (match_dup 2))))]
7707   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7708    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7709   "sub{l}\t{%2, %1|%1, %2}"
7710   [(set_attr "type" "alu")
7711    (set_attr "mode" "DI")])
7713 (define_expand "subhi3"
7714   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7715         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7716                   (match_operand:HI 2 "general_operand" "")))]
7717   "TARGET_HIMODE_MATH"
7718   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7720 (define_insn "*subhi_1"
7721   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7722         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7723                   (match_operand:HI 2 "general_operand" "rn,rm")))
7724    (clobber (reg:CC FLAGS_REG))]
7725   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7726   "sub{w}\t{%2, %0|%0, %2}"
7727   [(set_attr "type" "alu")
7728    (set_attr "mode" "HI")])
7730 (define_insn "*subhi_2"
7731   [(set (reg FLAGS_REG)
7732         (compare
7733           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7734                     (match_operand:HI 2 "general_operand" "rn,rm"))
7735           (const_int 0)))
7736    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7737         (minus:HI (match_dup 1) (match_dup 2)))]
7738   "ix86_match_ccmode (insn, CCGOCmode)
7739    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7740   "sub{w}\t{%2, %0|%0, %2}"
7741   [(set_attr "type" "alu")
7742    (set_attr "mode" "HI")])
7744 (define_insn "*subhi_3"
7745   [(set (reg FLAGS_REG)
7746         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7747                  (match_operand:HI 2 "general_operand" "rn,rm")))
7748    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7749         (minus:HI (match_dup 1) (match_dup 2)))]
7750   "ix86_match_ccmode (insn, CCmode)
7751    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7752   "sub{w}\t{%2, %0|%0, %2}"
7753   [(set_attr "type" "alu")
7754    (set_attr "mode" "HI")])
7756 (define_expand "subqi3"
7757   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7758         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7759                   (match_operand:QI 2 "general_operand" "")))]
7760   "TARGET_QIMODE_MATH"
7761   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7763 (define_insn "*subqi_1"
7764   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7765         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7766                   (match_operand:QI 2 "general_operand" "qn,qm")))
7767    (clobber (reg:CC FLAGS_REG))]
7768   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7769   "sub{b}\t{%2, %0|%0, %2}"
7770   [(set_attr "type" "alu")
7771    (set_attr "mode" "QI")])
7773 (define_insn "*subqi_1_slp"
7774   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7775         (minus:QI (match_dup 0)
7776                   (match_operand:QI 1 "general_operand" "qn,qm")))
7777    (clobber (reg:CC FLAGS_REG))]
7778   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7779    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7780   "sub{b}\t{%1, %0|%0, %1}"
7781   [(set_attr "type" "alu1")
7782    (set_attr "mode" "QI")])
7784 (define_insn "*subqi_2"
7785   [(set (reg FLAGS_REG)
7786         (compare
7787           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7788                     (match_operand:QI 2 "general_operand" "qn,qm"))
7789           (const_int 0)))
7790    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7791         (minus:QI (match_dup 1) (match_dup 2)))]
7792   "ix86_match_ccmode (insn, CCGOCmode)
7793    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7794   "sub{b}\t{%2, %0|%0, %2}"
7795   [(set_attr "type" "alu")
7796    (set_attr "mode" "QI")])
7798 (define_insn "*subqi_3"
7799   [(set (reg FLAGS_REG)
7800         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7801                  (match_operand:QI 2 "general_operand" "qn,qm")))
7802    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7803         (minus:QI (match_dup 1) (match_dup 2)))]
7804   "ix86_match_ccmode (insn, CCmode)
7805    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7806   "sub{b}\t{%2, %0|%0, %2}"
7807   [(set_attr "type" "alu")
7808    (set_attr "mode" "QI")])
7810 ;; The patterns that match these are at the end of this file.
7812 (define_expand "subxf3"
7813   [(set (match_operand:XF 0 "register_operand" "")
7814         (minus:XF (match_operand:XF 1 "register_operand" "")
7815                   (match_operand:XF 2 "register_operand" "")))]
7816   "TARGET_80387"
7817   "")
7819 (define_expand "sub<mode>3"
7820   [(set (match_operand:MODEF 0 "register_operand" "")
7821         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7822                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7823   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7824   "")
7826 ;; Multiply instructions
7828 (define_expand "muldi3"
7829   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7830                    (mult:DI (match_operand:DI 1 "register_operand" "")
7831                             (match_operand:DI 2 "x86_64_general_operand" "")))
7832               (clobber (reg:CC FLAGS_REG))])]
7833   "TARGET_64BIT"
7834   "")
7836 ;; On AMDFAM10
7837 ;; IMUL reg64, reg64, imm8      Direct
7838 ;; IMUL reg64, mem64, imm8      VectorPath
7839 ;; IMUL reg64, reg64, imm32     Direct
7840 ;; IMUL reg64, mem64, imm32     VectorPath
7841 ;; IMUL reg64, reg64            Direct
7842 ;; IMUL reg64, mem64            Direct
7844 (define_insn "*muldi3_1_rex64"
7845   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7846         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7847                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7848    (clobber (reg:CC FLAGS_REG))]
7849   "TARGET_64BIT
7850    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7851   "@
7852    imul{q}\t{%2, %1, %0|%0, %1, %2}
7853    imul{q}\t{%2, %1, %0|%0, %1, %2}
7854    imul{q}\t{%2, %0|%0, %2}"
7855   [(set_attr "type" "imul")
7856    (set_attr "prefix_0f" "0,0,1")
7857    (set (attr "athlon_decode")
7858         (cond [(eq_attr "cpu" "athlon")
7859                   (const_string "vector")
7860                (eq_attr "alternative" "1")
7861                   (const_string "vector")
7862                (and (eq_attr "alternative" "2")
7863                     (match_operand 1 "memory_operand" ""))
7864                   (const_string "vector")]
7865               (const_string "direct")))
7866    (set (attr "amdfam10_decode")
7867         (cond [(and (eq_attr "alternative" "0,1")
7868                     (match_operand 1 "memory_operand" ""))
7869                   (const_string "vector")]
7870               (const_string "direct")))
7871    (set_attr "mode" "DI")])
7873 (define_expand "mulsi3"
7874   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7875                    (mult:SI (match_operand:SI 1 "register_operand" "")
7876                             (match_operand:SI 2 "general_operand" "")))
7877               (clobber (reg:CC FLAGS_REG))])]
7878   ""
7879   "")
7881 ;; On AMDFAM10
7882 ;; IMUL reg32, reg32, imm8      Direct
7883 ;; IMUL reg32, mem32, imm8      VectorPath
7884 ;; IMUL reg32, reg32, imm32     Direct
7885 ;; IMUL reg32, mem32, imm32     VectorPath
7886 ;; IMUL reg32, reg32            Direct
7887 ;; IMUL reg32, mem32            Direct
7889 (define_insn "*mulsi3_1"
7890   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7891         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7892                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7893    (clobber (reg:CC FLAGS_REG))]
7894   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7895   "@
7896    imul{l}\t{%2, %1, %0|%0, %1, %2}
7897    imul{l}\t{%2, %1, %0|%0, %1, %2}
7898    imul{l}\t{%2, %0|%0, %2}"
7899   [(set_attr "type" "imul")
7900    (set_attr "prefix_0f" "0,0,1")
7901    (set (attr "athlon_decode")
7902         (cond [(eq_attr "cpu" "athlon")
7903                   (const_string "vector")
7904                (eq_attr "alternative" "1")
7905                   (const_string "vector")
7906                (and (eq_attr "alternative" "2")
7907                     (match_operand 1 "memory_operand" ""))
7908                   (const_string "vector")]
7909               (const_string "direct")))
7910    (set (attr "amdfam10_decode")
7911         (cond [(and (eq_attr "alternative" "0,1")
7912                     (match_operand 1 "memory_operand" ""))
7913                   (const_string "vector")]
7914               (const_string "direct")))
7915    (set_attr "mode" "SI")])
7917 (define_insn "*mulsi3_1_zext"
7918   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7919         (zero_extend:DI
7920           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7921                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7922    (clobber (reg:CC FLAGS_REG))]
7923   "TARGET_64BIT
7924    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7925   "@
7926    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7927    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7928    imul{l}\t{%2, %k0|%k0, %2}"
7929   [(set_attr "type" "imul")
7930    (set_attr "prefix_0f" "0,0,1")
7931    (set (attr "athlon_decode")
7932         (cond [(eq_attr "cpu" "athlon")
7933                   (const_string "vector")
7934                (eq_attr "alternative" "1")
7935                   (const_string "vector")
7936                (and (eq_attr "alternative" "2")
7937                     (match_operand 1 "memory_operand" ""))
7938                   (const_string "vector")]
7939               (const_string "direct")))
7940    (set (attr "amdfam10_decode")
7941         (cond [(and (eq_attr "alternative" "0,1")
7942                     (match_operand 1 "memory_operand" ""))
7943                   (const_string "vector")]
7944               (const_string "direct")))
7945    (set_attr "mode" "SI")])
7947 (define_expand "mulhi3"
7948   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7949                    (mult:HI (match_operand:HI 1 "register_operand" "")
7950                             (match_operand:HI 2 "general_operand" "")))
7951               (clobber (reg:CC FLAGS_REG))])]
7952   "TARGET_HIMODE_MATH"
7953   "")
7955 ;; On AMDFAM10
7956 ;; IMUL reg16, reg16, imm8      VectorPath
7957 ;; IMUL reg16, mem16, imm8      VectorPath
7958 ;; IMUL reg16, reg16, imm16     VectorPath
7959 ;; IMUL reg16, mem16, imm16     VectorPath
7960 ;; IMUL reg16, reg16            Direct
7961 ;; IMUL reg16, mem16            Direct
7962 (define_insn "*mulhi3_1"
7963   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7964         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7965                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7966    (clobber (reg:CC FLAGS_REG))]
7967   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7968   "@
7969    imul{w}\t{%2, %1, %0|%0, %1, %2}
7970    imul{w}\t{%2, %1, %0|%0, %1, %2}
7971    imul{w}\t{%2, %0|%0, %2}"
7972   [(set_attr "type" "imul")
7973    (set_attr "prefix_0f" "0,0,1")
7974    (set (attr "athlon_decode")
7975         (cond [(eq_attr "cpu" "athlon")
7976                   (const_string "vector")
7977                (eq_attr "alternative" "1,2")
7978                   (const_string "vector")]
7979               (const_string "direct")))
7980    (set (attr "amdfam10_decode")
7981         (cond [(eq_attr "alternative" "0,1")
7982                   (const_string "vector")]
7983               (const_string "direct")))
7984    (set_attr "mode" "HI")])
7986 (define_expand "mulqi3"
7987   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7988                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7989                             (match_operand:QI 2 "register_operand" "")))
7990               (clobber (reg:CC FLAGS_REG))])]
7991   "TARGET_QIMODE_MATH"
7992   "")
7994 ;;On AMDFAM10
7995 ;; MUL reg8     Direct
7996 ;; MUL mem8     Direct
7998 (define_insn "*mulqi3_1"
7999   [(set (match_operand:QI 0 "register_operand" "=a")
8000         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8001                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8002    (clobber (reg:CC FLAGS_REG))]
8003   "TARGET_QIMODE_MATH
8004    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8005   "mul{b}\t%2"
8006   [(set_attr "type" "imul")
8007    (set_attr "length_immediate" "0")
8008    (set (attr "athlon_decode")
8009      (if_then_else (eq_attr "cpu" "athlon")
8010         (const_string "vector")
8011         (const_string "direct")))
8012    (set_attr "amdfam10_decode" "direct")
8013    (set_attr "mode" "QI")])
8015 (define_expand "umulqihi3"
8016   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8017                    (mult:HI (zero_extend:HI
8018                               (match_operand:QI 1 "nonimmediate_operand" ""))
8019                             (zero_extend:HI
8020                               (match_operand:QI 2 "register_operand" ""))))
8021               (clobber (reg:CC FLAGS_REG))])]
8022   "TARGET_QIMODE_MATH"
8023   "")
8025 (define_insn "*umulqihi3_1"
8026   [(set (match_operand:HI 0 "register_operand" "=a")
8027         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8028                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8029    (clobber (reg:CC FLAGS_REG))]
8030   "TARGET_QIMODE_MATH
8031    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8032   "mul{b}\t%2"
8033   [(set_attr "type" "imul")
8034    (set_attr "length_immediate" "0")
8035    (set (attr "athlon_decode")
8036      (if_then_else (eq_attr "cpu" "athlon")
8037         (const_string "vector")
8038         (const_string "direct")))
8039    (set_attr "amdfam10_decode" "direct")
8040    (set_attr "mode" "QI")])
8042 (define_expand "mulqihi3"
8043   [(parallel [(set (match_operand:HI 0 "register_operand" "")
8044                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8045                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8046               (clobber (reg:CC FLAGS_REG))])]
8047   "TARGET_QIMODE_MATH"
8048   "")
8050 (define_insn "*mulqihi3_insn"
8051   [(set (match_operand:HI 0 "register_operand" "=a")
8052         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8053                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8054    (clobber (reg:CC FLAGS_REG))]
8055   "TARGET_QIMODE_MATH
8056    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8057   "imul{b}\t%2"
8058   [(set_attr "type" "imul")
8059    (set_attr "length_immediate" "0")
8060    (set (attr "athlon_decode")
8061      (if_then_else (eq_attr "cpu" "athlon")
8062         (const_string "vector")
8063         (const_string "direct")))
8064    (set_attr "amdfam10_decode" "direct")
8065    (set_attr "mode" "QI")])
8067 (define_expand "umulditi3"
8068   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8069                    (mult:TI (zero_extend:TI
8070                               (match_operand:DI 1 "nonimmediate_operand" ""))
8071                             (zero_extend:TI
8072                               (match_operand:DI 2 "register_operand" ""))))
8073               (clobber (reg:CC FLAGS_REG))])]
8074   "TARGET_64BIT"
8075   "")
8077 (define_insn "*umulditi3_insn"
8078   [(set (match_operand:TI 0 "register_operand" "=A")
8079         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8080                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8081    (clobber (reg:CC FLAGS_REG))]
8082   "TARGET_64BIT
8083    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8084   "mul{q}\t%2"
8085   [(set_attr "type" "imul")
8086    (set_attr "length_immediate" "0")
8087    (set (attr "athlon_decode")
8088      (if_then_else (eq_attr "cpu" "athlon")
8089         (const_string "vector")
8090         (const_string "double")))
8091    (set_attr "amdfam10_decode" "double")
8092    (set_attr "mode" "DI")])
8094 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8095 (define_expand "umulsidi3"
8096   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8097                    (mult:DI (zero_extend:DI
8098                               (match_operand:SI 1 "nonimmediate_operand" ""))
8099                             (zero_extend:DI
8100                               (match_operand:SI 2 "register_operand" ""))))
8101               (clobber (reg:CC FLAGS_REG))])]
8102   "!TARGET_64BIT"
8103   "")
8105 (define_insn "*umulsidi3_insn"
8106   [(set (match_operand:DI 0 "register_operand" "=A")
8107         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8108                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8109    (clobber (reg:CC FLAGS_REG))]
8110   "!TARGET_64BIT
8111    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8112   "mul{l}\t%2"
8113   [(set_attr "type" "imul")
8114    (set_attr "length_immediate" "0")
8115    (set (attr "athlon_decode")
8116      (if_then_else (eq_attr "cpu" "athlon")
8117         (const_string "vector")
8118         (const_string "double")))
8119    (set_attr "amdfam10_decode" "double")
8120    (set_attr "mode" "SI")])
8122 (define_expand "mulditi3"
8123   [(parallel [(set (match_operand:TI 0 "register_operand" "")
8124                    (mult:TI (sign_extend:TI
8125                               (match_operand:DI 1 "nonimmediate_operand" ""))
8126                             (sign_extend:TI
8127                               (match_operand:DI 2 "register_operand" ""))))
8128               (clobber (reg:CC FLAGS_REG))])]
8129   "TARGET_64BIT"
8130   "")
8132 (define_insn "*mulditi3_insn"
8133   [(set (match_operand:TI 0 "register_operand" "=A")
8134         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8135                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8136    (clobber (reg:CC FLAGS_REG))]
8137   "TARGET_64BIT
8138    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8139   "imul{q}\t%2"
8140   [(set_attr "type" "imul")
8141    (set_attr "length_immediate" "0")
8142    (set (attr "athlon_decode")
8143      (if_then_else (eq_attr "cpu" "athlon")
8144         (const_string "vector")
8145         (const_string "double")))
8146    (set_attr "amdfam10_decode" "double")
8147    (set_attr "mode" "DI")])
8149 (define_expand "mulsidi3"
8150   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8151                    (mult:DI (sign_extend:DI
8152                               (match_operand:SI 1 "nonimmediate_operand" ""))
8153                             (sign_extend:DI
8154                               (match_operand:SI 2 "register_operand" ""))))
8155               (clobber (reg:CC FLAGS_REG))])]
8156   "!TARGET_64BIT"
8157   "")
8159 (define_insn "*mulsidi3_insn"
8160   [(set (match_operand:DI 0 "register_operand" "=A")
8161         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8162                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8163    (clobber (reg:CC FLAGS_REG))]
8164   "!TARGET_64BIT
8165    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8166   "imul{l}\t%2"
8167   [(set_attr "type" "imul")
8168    (set_attr "length_immediate" "0")
8169    (set (attr "athlon_decode")
8170      (if_then_else (eq_attr "cpu" "athlon")
8171         (const_string "vector")
8172         (const_string "double")))
8173    (set_attr "amdfam10_decode" "double")
8174    (set_attr "mode" "SI")])
8176 (define_expand "umuldi3_highpart"
8177   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8178                    (truncate:DI
8179                      (lshiftrt:TI
8180                        (mult:TI (zero_extend:TI
8181                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8182                                 (zero_extend:TI
8183                                   (match_operand:DI 2 "register_operand" "")))
8184                        (const_int 64))))
8185               (clobber (match_scratch:DI 3 ""))
8186               (clobber (reg:CC FLAGS_REG))])]
8187   "TARGET_64BIT"
8188   "")
8190 (define_insn "*umuldi3_highpart_rex64"
8191   [(set (match_operand:DI 0 "register_operand" "=d")
8192         (truncate:DI
8193           (lshiftrt:TI
8194             (mult:TI (zero_extend:TI
8195                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8196                      (zero_extend:TI
8197                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8198             (const_int 64))))
8199    (clobber (match_scratch:DI 3 "=1"))
8200    (clobber (reg:CC FLAGS_REG))]
8201   "TARGET_64BIT
8202    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8203   "mul{q}\t%2"
8204   [(set_attr "type" "imul")
8205    (set_attr "length_immediate" "0")
8206    (set (attr "athlon_decode")
8207      (if_then_else (eq_attr "cpu" "athlon")
8208         (const_string "vector")
8209         (const_string "double")))
8210    (set_attr "amdfam10_decode" "double")
8211    (set_attr "mode" "DI")])
8213 (define_expand "umulsi3_highpart"
8214   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8215                    (truncate:SI
8216                      (lshiftrt:DI
8217                        (mult:DI (zero_extend:DI
8218                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8219                                 (zero_extend:DI
8220                                   (match_operand:SI 2 "register_operand" "")))
8221                        (const_int 32))))
8222               (clobber (match_scratch:SI 3 ""))
8223               (clobber (reg:CC FLAGS_REG))])]
8224   ""
8225   "")
8227 (define_insn "*umulsi3_highpart_insn"
8228   [(set (match_operand:SI 0 "register_operand" "=d")
8229         (truncate:SI
8230           (lshiftrt:DI
8231             (mult:DI (zero_extend:DI
8232                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8233                      (zero_extend:DI
8234                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8235             (const_int 32))))
8236    (clobber (match_scratch:SI 3 "=1"))
8237    (clobber (reg:CC FLAGS_REG))]
8238   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8239   "mul{l}\t%2"
8240   [(set_attr "type" "imul")
8241    (set_attr "length_immediate" "0")
8242    (set (attr "athlon_decode")
8243      (if_then_else (eq_attr "cpu" "athlon")
8244         (const_string "vector")
8245         (const_string "double")))
8246    (set_attr "amdfam10_decode" "double")
8247    (set_attr "mode" "SI")])
8249 (define_insn "*umulsi3_highpart_zext"
8250   [(set (match_operand:DI 0 "register_operand" "=d")
8251         (zero_extend:DI (truncate:SI
8252           (lshiftrt:DI
8253             (mult:DI (zero_extend:DI
8254                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8255                      (zero_extend:DI
8256                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8257             (const_int 32)))))
8258    (clobber (match_scratch:SI 3 "=1"))
8259    (clobber (reg:CC FLAGS_REG))]
8260   "TARGET_64BIT
8261    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8262   "mul{l}\t%2"
8263   [(set_attr "type" "imul")
8264    (set_attr "length_immediate" "0")
8265    (set (attr "athlon_decode")
8266      (if_then_else (eq_attr "cpu" "athlon")
8267         (const_string "vector")
8268         (const_string "double")))
8269    (set_attr "amdfam10_decode" "double")
8270    (set_attr "mode" "SI")])
8272 (define_expand "smuldi3_highpart"
8273   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8274                    (truncate:DI
8275                      (lshiftrt:TI
8276                        (mult:TI (sign_extend:TI
8277                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8278                                 (sign_extend:TI
8279                                   (match_operand:DI 2 "register_operand" "")))
8280                        (const_int 64))))
8281               (clobber (match_scratch:DI 3 ""))
8282               (clobber (reg:CC FLAGS_REG))])]
8283   "TARGET_64BIT"
8284   "")
8286 (define_insn "*smuldi3_highpart_rex64"
8287   [(set (match_operand:DI 0 "register_operand" "=d")
8288         (truncate:DI
8289           (lshiftrt:TI
8290             (mult:TI (sign_extend:TI
8291                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8292                      (sign_extend:TI
8293                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8294             (const_int 64))))
8295    (clobber (match_scratch:DI 3 "=1"))
8296    (clobber (reg:CC FLAGS_REG))]
8297   "TARGET_64BIT
8298    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8299   "imul{q}\t%2"
8300   [(set_attr "type" "imul")
8301    (set (attr "athlon_decode")
8302      (if_then_else (eq_attr "cpu" "athlon")
8303         (const_string "vector")
8304         (const_string "double")))
8305    (set_attr "amdfam10_decode" "double")
8306    (set_attr "mode" "DI")])
8308 (define_expand "smulsi3_highpart"
8309   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8310                    (truncate:SI
8311                      (lshiftrt:DI
8312                        (mult:DI (sign_extend:DI
8313                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8314                                 (sign_extend:DI
8315                                   (match_operand:SI 2 "register_operand" "")))
8316                        (const_int 32))))
8317               (clobber (match_scratch:SI 3 ""))
8318               (clobber (reg:CC FLAGS_REG))])]
8319   ""
8320   "")
8322 (define_insn "*smulsi3_highpart_insn"
8323   [(set (match_operand:SI 0 "register_operand" "=d")
8324         (truncate:SI
8325           (lshiftrt:DI
8326             (mult:DI (sign_extend:DI
8327                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8328                      (sign_extend:DI
8329                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8330             (const_int 32))))
8331    (clobber (match_scratch:SI 3 "=1"))
8332    (clobber (reg:CC FLAGS_REG))]
8333   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8334   "imul{l}\t%2"
8335   [(set_attr "type" "imul")
8336    (set (attr "athlon_decode")
8337      (if_then_else (eq_attr "cpu" "athlon")
8338         (const_string "vector")
8339         (const_string "double")))
8340    (set_attr "amdfam10_decode" "double")
8341    (set_attr "mode" "SI")])
8343 (define_insn "*smulsi3_highpart_zext"
8344   [(set (match_operand:DI 0 "register_operand" "=d")
8345         (zero_extend:DI (truncate:SI
8346           (lshiftrt:DI
8347             (mult:DI (sign_extend:DI
8348                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8349                      (sign_extend:DI
8350                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8351             (const_int 32)))))
8352    (clobber (match_scratch:SI 3 "=1"))
8353    (clobber (reg:CC FLAGS_REG))]
8354   "TARGET_64BIT
8355    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8356   "imul{l}\t%2"
8357   [(set_attr "type" "imul")
8358    (set (attr "athlon_decode")
8359      (if_then_else (eq_attr "cpu" "athlon")
8360         (const_string "vector")
8361         (const_string "double")))
8362    (set_attr "amdfam10_decode" "double")
8363    (set_attr "mode" "SI")])
8365 ;; The patterns that match these are at the end of this file.
8367 (define_expand "mulxf3"
8368   [(set (match_operand:XF 0 "register_operand" "")
8369         (mult:XF (match_operand:XF 1 "register_operand" "")
8370                  (match_operand:XF 2 "register_operand" "")))]
8371   "TARGET_80387"
8372   "")
8374 (define_expand "mul<mode>3"
8375   [(set (match_operand:MODEF 0 "register_operand" "")
8376         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8377                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8378   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8379   "")
8381 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8384 ;; Divide instructions
8386 (define_insn "divqi3"
8387   [(set (match_operand:QI 0 "register_operand" "=a")
8388         (div:QI (match_operand:HI 1 "register_operand" "0")
8389                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8390    (clobber (reg:CC FLAGS_REG))]
8391   "TARGET_QIMODE_MATH"
8392   "idiv{b}\t%2"
8393   [(set_attr "type" "idiv")
8394    (set_attr "mode" "QI")])
8396 (define_insn "udivqi3"
8397   [(set (match_operand:QI 0 "register_operand" "=a")
8398         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8399                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8400    (clobber (reg:CC FLAGS_REG))]
8401   "TARGET_QIMODE_MATH"
8402   "div{b}\t%2"
8403   [(set_attr "type" "idiv")
8404    (set_attr "mode" "QI")])
8406 ;; The patterns that match these are at the end of this file.
8408 (define_expand "divxf3"
8409   [(set (match_operand:XF 0 "register_operand" "")
8410         (div:XF (match_operand:XF 1 "register_operand" "")
8411                 (match_operand:XF 2 "register_operand" "")))]
8412   "TARGET_80387"
8413   "")
8415 (define_expand "divdf3"
8416   [(set (match_operand:DF 0 "register_operand" "")
8417         (div:DF (match_operand:DF 1 "register_operand" "")
8418                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8419    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8420    "")
8422 (define_expand "divsf3"
8423   [(set (match_operand:SF 0 "register_operand" "")
8424         (div:SF (match_operand:SF 1 "register_operand" "")
8425                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8426   "TARGET_80387 || TARGET_SSE_MATH"
8428   if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8429       && flag_finite_math_only && !flag_trapping_math
8430       && flag_unsafe_math_optimizations)
8431     {
8432       ix86_emit_swdivsf (operands[0], operands[1],
8433                          operands[2], SFmode);
8434       DONE;
8435     }
8438 ;; Remainder instructions.
8440 (define_expand "divmoddi4"
8441   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8442                    (div:DI (match_operand:DI 1 "register_operand" "")
8443                            (match_operand:DI 2 "nonimmediate_operand" "")))
8444               (set (match_operand:DI 3 "register_operand" "")
8445                    (mod:DI (match_dup 1) (match_dup 2)))
8446               (clobber (reg:CC FLAGS_REG))])]
8447   "TARGET_64BIT"
8448   "")
8450 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8451 ;; Penalize eax case slightly because it results in worse scheduling
8452 ;; of code.
8453 (define_insn "*divmoddi4_nocltd_rex64"
8454   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8455         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8456                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8457    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8458         (mod:DI (match_dup 2) (match_dup 3)))
8459    (clobber (reg:CC FLAGS_REG))]
8460   "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8461   "#"
8462   [(set_attr "type" "multi")])
8464 (define_insn "*divmoddi4_cltd_rex64"
8465   [(set (match_operand:DI 0 "register_operand" "=a")
8466         (div:DI (match_operand:DI 2 "register_operand" "a")
8467                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8468    (set (match_operand:DI 1 "register_operand" "=&d")
8469         (mod:DI (match_dup 2) (match_dup 3)))
8470    (clobber (reg:CC FLAGS_REG))]
8471   "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8472   "#"
8473   [(set_attr "type" "multi")])
8475 (define_insn "*divmoddi_noext_rex64"
8476   [(set (match_operand:DI 0 "register_operand" "=a")
8477         (div:DI (match_operand:DI 1 "register_operand" "0")
8478                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8479    (set (match_operand:DI 3 "register_operand" "=d")
8480         (mod:DI (match_dup 1) (match_dup 2)))
8481    (use (match_operand:DI 4 "register_operand" "3"))
8482    (clobber (reg:CC FLAGS_REG))]
8483   "TARGET_64BIT"
8484   "idiv{q}\t%2"
8485   [(set_attr "type" "idiv")
8486    (set_attr "mode" "DI")])
8488 (define_split
8489   [(set (match_operand:DI 0 "register_operand" "")
8490         (div:DI (match_operand:DI 1 "register_operand" "")
8491                 (match_operand:DI 2 "nonimmediate_operand" "")))
8492    (set (match_operand:DI 3 "register_operand" "")
8493         (mod:DI (match_dup 1) (match_dup 2)))
8494    (clobber (reg:CC FLAGS_REG))]
8495   "TARGET_64BIT && reload_completed"
8496   [(parallel [(set (match_dup 3)
8497                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8498               (clobber (reg:CC FLAGS_REG))])
8499    (parallel [(set (match_dup 0)
8500                    (div:DI (reg:DI 0) (match_dup 2)))
8501               (set (match_dup 3)
8502                    (mod:DI (reg:DI 0) (match_dup 2)))
8503               (use (match_dup 3))
8504               (clobber (reg:CC FLAGS_REG))])]
8506   /* Avoid use of cltd in favor of a mov+shift.  */
8507   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8508     {
8509       if (true_regnum (operands[1]))
8510         emit_move_insn (operands[0], operands[1]);
8511       else
8512         emit_move_insn (operands[3], operands[1]);
8513       operands[4] = operands[3];
8514     }
8515   else
8516     {
8517       gcc_assert (!true_regnum (operands[1]));
8518       operands[4] = operands[1];
8519     }
8523 (define_expand "divmodsi4"
8524   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8525                    (div:SI (match_operand:SI 1 "register_operand" "")
8526                            (match_operand:SI 2 "nonimmediate_operand" "")))
8527               (set (match_operand:SI 3 "register_operand" "")
8528                    (mod:SI (match_dup 1) (match_dup 2)))
8529               (clobber (reg:CC FLAGS_REG))])]
8530   ""
8531   "")
8533 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8534 ;; Penalize eax case slightly because it results in worse scheduling
8535 ;; of code.
8536 (define_insn "*divmodsi4_nocltd"
8537   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8538         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8539                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8540    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8541         (mod:SI (match_dup 2) (match_dup 3)))
8542    (clobber (reg:CC FLAGS_REG))]
8543   "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8544   "#"
8545   [(set_attr "type" "multi")])
8547 (define_insn "*divmodsi4_cltd"
8548   [(set (match_operand:SI 0 "register_operand" "=a")
8549         (div:SI (match_operand:SI 2 "register_operand" "a")
8550                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8551    (set (match_operand:SI 1 "register_operand" "=&d")
8552         (mod:SI (match_dup 2) (match_dup 3)))
8553    (clobber (reg:CC FLAGS_REG))]
8554   "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
8555   "#"
8556   [(set_attr "type" "multi")])
8558 (define_insn "*divmodsi_noext"
8559   [(set (match_operand:SI 0 "register_operand" "=a")
8560         (div:SI (match_operand:SI 1 "register_operand" "0")
8561                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8562    (set (match_operand:SI 3 "register_operand" "=d")
8563         (mod:SI (match_dup 1) (match_dup 2)))
8564    (use (match_operand:SI 4 "register_operand" "3"))
8565    (clobber (reg:CC FLAGS_REG))]
8566   ""
8567   "idiv{l}\t%2"
8568   [(set_attr "type" "idiv")
8569    (set_attr "mode" "SI")])
8571 (define_split
8572   [(set (match_operand:SI 0 "register_operand" "")
8573         (div:SI (match_operand:SI 1 "register_operand" "")
8574                 (match_operand:SI 2 "nonimmediate_operand" "")))
8575    (set (match_operand:SI 3 "register_operand" "")
8576         (mod:SI (match_dup 1) (match_dup 2)))
8577    (clobber (reg:CC FLAGS_REG))]
8578   "reload_completed"
8579   [(parallel [(set (match_dup 3)
8580                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8581               (clobber (reg:CC FLAGS_REG))])
8582    (parallel [(set (match_dup 0)
8583                    (div:SI (reg:SI 0) (match_dup 2)))
8584               (set (match_dup 3)
8585                    (mod:SI (reg:SI 0) (match_dup 2)))
8586               (use (match_dup 3))
8587               (clobber (reg:CC FLAGS_REG))])]
8589   /* Avoid use of cltd in favor of a mov+shift.  */
8590   if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
8591     {
8592       if (true_regnum (operands[1]))
8593         emit_move_insn (operands[0], operands[1]);
8594       else
8595         emit_move_insn (operands[3], operands[1]);
8596       operands[4] = operands[3];
8597     }
8598   else
8599     {
8600       gcc_assert (!true_regnum (operands[1]));
8601       operands[4] = operands[1];
8602     }
8604 ;; %%% Split me.
8605 (define_insn "divmodhi4"
8606   [(set (match_operand:HI 0 "register_operand" "=a")
8607         (div:HI (match_operand:HI 1 "register_operand" "0")
8608                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8609    (set (match_operand:HI 3 "register_operand" "=&d")
8610         (mod:HI (match_dup 1) (match_dup 2)))
8611    (clobber (reg:CC FLAGS_REG))]
8612   "TARGET_HIMODE_MATH"
8613   "cwtd\;idiv{w}\t%2"
8614   [(set_attr "type" "multi")
8615    (set_attr "length_immediate" "0")
8616    (set_attr "mode" "SI")])
8618 (define_insn "udivmoddi4"
8619   [(set (match_operand:DI 0 "register_operand" "=a")
8620         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8621                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8622    (set (match_operand:DI 3 "register_operand" "=&d")
8623         (umod:DI (match_dup 1) (match_dup 2)))
8624    (clobber (reg:CC FLAGS_REG))]
8625   "TARGET_64BIT"
8626   "xor{q}\t%3, %3\;div{q}\t%2"
8627   [(set_attr "type" "multi")
8628    (set_attr "length_immediate" "0")
8629    (set_attr "mode" "DI")])
8631 (define_insn "*udivmoddi4_noext"
8632   [(set (match_operand:DI 0 "register_operand" "=a")
8633         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8634                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8635    (set (match_operand:DI 3 "register_operand" "=d")
8636         (umod:DI (match_dup 1) (match_dup 2)))
8637    (use (match_dup 3))
8638    (clobber (reg:CC FLAGS_REG))]
8639   "TARGET_64BIT"
8640   "div{q}\t%2"
8641   [(set_attr "type" "idiv")
8642    (set_attr "mode" "DI")])
8644 (define_split
8645   [(set (match_operand:DI 0 "register_operand" "")
8646         (udiv:DI (match_operand:DI 1 "register_operand" "")
8647                  (match_operand:DI 2 "nonimmediate_operand" "")))
8648    (set (match_operand:DI 3 "register_operand" "")
8649         (umod:DI (match_dup 1) (match_dup 2)))
8650    (clobber (reg:CC FLAGS_REG))]
8651   "TARGET_64BIT && reload_completed"
8652   [(set (match_dup 3) (const_int 0))
8653    (parallel [(set (match_dup 0)
8654                    (udiv:DI (match_dup 1) (match_dup 2)))
8655               (set (match_dup 3)
8656                    (umod:DI (match_dup 1) (match_dup 2)))
8657               (use (match_dup 3))
8658               (clobber (reg:CC FLAGS_REG))])]
8659   "")
8661 (define_insn "udivmodsi4"
8662   [(set (match_operand:SI 0 "register_operand" "=a")
8663         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8664                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8665    (set (match_operand:SI 3 "register_operand" "=&d")
8666         (umod:SI (match_dup 1) (match_dup 2)))
8667    (clobber (reg:CC FLAGS_REG))]
8668   ""
8669   "xor{l}\t%3, %3\;div{l}\t%2"
8670   [(set_attr "type" "multi")
8671    (set_attr "length_immediate" "0")
8672    (set_attr "mode" "SI")])
8674 (define_insn "*udivmodsi4_noext"
8675   [(set (match_operand:SI 0 "register_operand" "=a")
8676         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8677                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8678    (set (match_operand:SI 3 "register_operand" "=d")
8679         (umod:SI (match_dup 1) (match_dup 2)))
8680    (use (match_dup 3))
8681    (clobber (reg:CC FLAGS_REG))]
8682   ""
8683   "div{l}\t%2"
8684   [(set_attr "type" "idiv")
8685    (set_attr "mode" "SI")])
8687 (define_split
8688   [(set (match_operand:SI 0 "register_operand" "")
8689         (udiv:SI (match_operand:SI 1 "register_operand" "")
8690                  (match_operand:SI 2 "nonimmediate_operand" "")))
8691    (set (match_operand:SI 3 "register_operand" "")
8692         (umod:SI (match_dup 1) (match_dup 2)))
8693    (clobber (reg:CC FLAGS_REG))]
8694   "reload_completed"
8695   [(set (match_dup 3) (const_int 0))
8696    (parallel [(set (match_dup 0)
8697                    (udiv:SI (match_dup 1) (match_dup 2)))
8698               (set (match_dup 3)
8699                    (umod:SI (match_dup 1) (match_dup 2)))
8700               (use (match_dup 3))
8701               (clobber (reg:CC FLAGS_REG))])]
8702   "")
8704 (define_expand "udivmodhi4"
8705   [(set (match_dup 4) (const_int 0))
8706    (parallel [(set (match_operand:HI 0 "register_operand" "")
8707                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8708                             (match_operand:HI 2 "nonimmediate_operand" "")))
8709               (set (match_operand:HI 3 "register_operand" "")
8710                    (umod:HI (match_dup 1) (match_dup 2)))
8711               (use (match_dup 4))
8712               (clobber (reg:CC FLAGS_REG))])]
8713   "TARGET_HIMODE_MATH"
8714   "operands[4] = gen_reg_rtx (HImode);")
8716 (define_insn "*udivmodhi_noext"
8717   [(set (match_operand:HI 0 "register_operand" "=a")
8718         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8719                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8720    (set (match_operand:HI 3 "register_operand" "=d")
8721         (umod:HI (match_dup 1) (match_dup 2)))
8722    (use (match_operand:HI 4 "register_operand" "3"))
8723    (clobber (reg:CC FLAGS_REG))]
8724   ""
8725   "div{w}\t%2"
8726   [(set_attr "type" "idiv")
8727    (set_attr "mode" "HI")])
8729 ;; We cannot use div/idiv for double division, because it causes
8730 ;; "division by zero" on the overflow and that's not what we expect
8731 ;; from truncate.  Because true (non truncating) double division is
8732 ;; never generated, we can't create this insn anyway.
8734 ;(define_insn ""
8735 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8736 ;       (truncate:SI
8737 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8738 ;                  (zero_extend:DI
8739 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8740 ;   (set (match_operand:SI 3 "register_operand" "=d")
8741 ;       (truncate:SI
8742 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8743 ;   (clobber (reg:CC FLAGS_REG))]
8744 ;  ""
8745 ;  "div{l}\t{%2, %0|%0, %2}"
8746 ;  [(set_attr "type" "idiv")])
8748 ;;- Logical AND instructions
8750 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8751 ;; Note that this excludes ah.
8753 (define_insn "*testdi_1_rex64"
8754   [(set (reg FLAGS_REG)
8755         (compare
8756           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8757                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8758           (const_int 0)))]
8759   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8760    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8761   "@
8762    test{l}\t{%k1, %k0|%k0, %k1}
8763    test{l}\t{%k1, %k0|%k0, %k1}
8764    test{q}\t{%1, %0|%0, %1}
8765    test{q}\t{%1, %0|%0, %1}
8766    test{q}\t{%1, %0|%0, %1}"
8767   [(set_attr "type" "test")
8768    (set_attr "modrm" "0,1,0,1,1")
8769    (set_attr "mode" "SI,SI,DI,DI,DI")
8770    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8772 (define_insn "testsi_1"
8773   [(set (reg FLAGS_REG)
8774         (compare
8775           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8776                   (match_operand:SI 1 "general_operand" "i,i,ri"))
8777           (const_int 0)))]
8778   "ix86_match_ccmode (insn, CCNOmode)
8779    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8780   "test{l}\t{%1, %0|%0, %1}"
8781   [(set_attr "type" "test")
8782    (set_attr "modrm" "0,1,1")
8783    (set_attr "mode" "SI")
8784    (set_attr "pent_pair" "uv,np,uv")])
8786 (define_expand "testsi_ccno_1"
8787   [(set (reg:CCNO FLAGS_REG)
8788         (compare:CCNO
8789           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8790                   (match_operand:SI 1 "nonmemory_operand" ""))
8791           (const_int 0)))]
8792   ""
8793   "")
8795 (define_insn "*testhi_1"
8796   [(set (reg FLAGS_REG)
8797         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8798                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8799                  (const_int 0)))]
8800   "ix86_match_ccmode (insn, CCNOmode)
8801    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8802   "test{w}\t{%1, %0|%0, %1}"
8803   [(set_attr "type" "test")
8804    (set_attr "modrm" "0,1,1")
8805    (set_attr "mode" "HI")
8806    (set_attr "pent_pair" "uv,np,uv")])
8808 (define_expand "testqi_ccz_1"
8809   [(set (reg:CCZ FLAGS_REG)
8810         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8811                              (match_operand:QI 1 "nonmemory_operand" ""))
8812                  (const_int 0)))]
8813   ""
8814   "")
8816 (define_insn "*testqi_1_maybe_si"
8817   [(set (reg FLAGS_REG)
8818         (compare
8819           (and:QI
8820             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8821             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8822           (const_int 0)))]
8823    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8824     && ix86_match_ccmode (insn,
8825                          CONST_INT_P (operands[1])
8826                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8828   if (which_alternative == 3)
8829     {
8830       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8831         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8832       return "test{l}\t{%1, %k0|%k0, %1}";
8833     }
8834   return "test{b}\t{%1, %0|%0, %1}";
8836   [(set_attr "type" "test")
8837    (set_attr "modrm" "0,1,1,1")
8838    (set_attr "mode" "QI,QI,QI,SI")
8839    (set_attr "pent_pair" "uv,np,uv,np")])
8841 (define_insn "*testqi_1"
8842   [(set (reg FLAGS_REG)
8843         (compare
8844           (and:QI
8845             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8846             (match_operand:QI 1 "general_operand" "n,n,qn"))
8847           (const_int 0)))]
8848   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8849    && ix86_match_ccmode (insn, CCNOmode)"
8850   "test{b}\t{%1, %0|%0, %1}"
8851   [(set_attr "type" "test")
8852    (set_attr "modrm" "0,1,1")
8853    (set_attr "mode" "QI")
8854    (set_attr "pent_pair" "uv,np,uv")])
8856 (define_expand "testqi_ext_ccno_0"
8857   [(set (reg:CCNO FLAGS_REG)
8858         (compare:CCNO
8859           (and:SI
8860             (zero_extract:SI
8861               (match_operand 0 "ext_register_operand" "")
8862               (const_int 8)
8863               (const_int 8))
8864             (match_operand 1 "const_int_operand" ""))
8865           (const_int 0)))]
8866   ""
8867   "")
8869 (define_insn "*testqi_ext_0"
8870   [(set (reg FLAGS_REG)
8871         (compare
8872           (and:SI
8873             (zero_extract:SI
8874               (match_operand 0 "ext_register_operand" "Q")
8875               (const_int 8)
8876               (const_int 8))
8877             (match_operand 1 "const_int_operand" "n"))
8878           (const_int 0)))]
8879   "ix86_match_ccmode (insn, CCNOmode)"
8880   "test{b}\t{%1, %h0|%h0, %1}"
8881   [(set_attr "type" "test")
8882    (set_attr "mode" "QI")
8883    (set_attr "length_immediate" "1")
8884    (set_attr "pent_pair" "np")])
8886 (define_insn "*testqi_ext_1"
8887   [(set (reg FLAGS_REG)
8888         (compare
8889           (and:SI
8890             (zero_extract:SI
8891               (match_operand 0 "ext_register_operand" "Q")
8892               (const_int 8)
8893               (const_int 8))
8894             (zero_extend:SI
8895               (match_operand:QI 1 "general_operand" "Qm")))
8896           (const_int 0)))]
8897   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8898    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8899   "test{b}\t{%1, %h0|%h0, %1}"
8900   [(set_attr "type" "test")
8901    (set_attr "mode" "QI")])
8903 (define_insn "*testqi_ext_1_rex64"
8904   [(set (reg FLAGS_REG)
8905         (compare
8906           (and:SI
8907             (zero_extract:SI
8908               (match_operand 0 "ext_register_operand" "Q")
8909               (const_int 8)
8910               (const_int 8))
8911             (zero_extend:SI
8912               (match_operand:QI 1 "register_operand" "Q")))
8913           (const_int 0)))]
8914   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8915   "test{b}\t{%1, %h0|%h0, %1}"
8916   [(set_attr "type" "test")
8917    (set_attr "mode" "QI")])
8919 (define_insn "*testqi_ext_2"
8920   [(set (reg FLAGS_REG)
8921         (compare
8922           (and:SI
8923             (zero_extract:SI
8924               (match_operand 0 "ext_register_operand" "Q")
8925               (const_int 8)
8926               (const_int 8))
8927             (zero_extract:SI
8928               (match_operand 1 "ext_register_operand" "Q")
8929               (const_int 8)
8930               (const_int 8)))
8931           (const_int 0)))]
8932   "ix86_match_ccmode (insn, CCNOmode)"
8933   "test{b}\t{%h1, %h0|%h0, %h1}"
8934   [(set_attr "type" "test")
8935    (set_attr "mode" "QI")])
8937 ;; Combine likes to form bit extractions for some tests.  Humor it.
8938 (define_insn "*testqi_ext_3"
8939   [(set (reg FLAGS_REG)
8940         (compare (zero_extract:SI
8941                    (match_operand 0 "nonimmediate_operand" "rm")
8942                    (match_operand:SI 1 "const_int_operand" "")
8943                    (match_operand:SI 2 "const_int_operand" ""))
8944                  (const_int 0)))]
8945   "ix86_match_ccmode (insn, CCNOmode)
8946    && INTVAL (operands[1]) > 0
8947    && INTVAL (operands[2]) >= 0
8948    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8949    && (GET_MODE (operands[0]) == SImode
8950        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8951        || GET_MODE (operands[0]) == HImode
8952        || GET_MODE (operands[0]) == QImode)"
8953   "#")
8955 (define_insn "*testqi_ext_3_rex64"
8956   [(set (reg FLAGS_REG)
8957         (compare (zero_extract:DI
8958                    (match_operand 0 "nonimmediate_operand" "rm")
8959                    (match_operand:DI 1 "const_int_operand" "")
8960                    (match_operand:DI 2 "const_int_operand" ""))
8961                  (const_int 0)))]
8962   "TARGET_64BIT
8963    && ix86_match_ccmode (insn, CCNOmode)
8964    && INTVAL (operands[1]) > 0
8965    && INTVAL (operands[2]) >= 0
8966    /* Ensure that resulting mask is zero or sign extended operand.  */
8967    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8968        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8969            && INTVAL (operands[1]) > 32))
8970    && (GET_MODE (operands[0]) == SImode
8971        || GET_MODE (operands[0]) == DImode
8972        || GET_MODE (operands[0]) == HImode
8973        || GET_MODE (operands[0]) == QImode)"
8974   "#")
8976 (define_split
8977   [(set (match_operand 0 "flags_reg_operand" "")
8978         (match_operator 1 "compare_operator"
8979           [(zero_extract
8980              (match_operand 2 "nonimmediate_operand" "")
8981              (match_operand 3 "const_int_operand" "")
8982              (match_operand 4 "const_int_operand" ""))
8983            (const_int 0)]))]
8984   "ix86_match_ccmode (insn, CCNOmode)"
8985   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8987   rtx val = operands[2];
8988   HOST_WIDE_INT len = INTVAL (operands[3]);
8989   HOST_WIDE_INT pos = INTVAL (operands[4]);
8990   HOST_WIDE_INT mask;
8991   enum machine_mode mode, submode;
8993   mode = GET_MODE (val);
8994   if (MEM_P (val))
8995     {
8996       /* ??? Combine likes to put non-volatile mem extractions in QImode
8997          no matter the size of the test.  So find a mode that works.  */
8998       if (! MEM_VOLATILE_P (val))
8999         {
9000           mode = smallest_mode_for_size (pos + len, MODE_INT);
9001           val = adjust_address (val, mode, 0);
9002         }
9003     }
9004   else if (GET_CODE (val) == SUBREG
9005            && (submode = GET_MODE (SUBREG_REG (val)),
9006                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9007            && pos + len <= GET_MODE_BITSIZE (submode))
9008     {
9009       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
9010       mode = submode;
9011       val = SUBREG_REG (val);
9012     }
9013   else if (mode == HImode && pos + len <= 8)
9014     {
9015       /* Small HImode tests can be converted to QImode.  */
9016       mode = QImode;
9017       val = gen_lowpart (QImode, val);
9018     }
9020   if (len == HOST_BITS_PER_WIDE_INT)
9021     mask = -1;
9022   else
9023     mask = ((HOST_WIDE_INT)1 << len) - 1;
9024   mask <<= pos;
9026   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9029 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9030 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9031 ;; this is relatively important trick.
9032 ;; Do the conversion only post-reload to avoid limiting of the register class
9033 ;; to QI regs.
9034 (define_split
9035   [(set (match_operand 0 "flags_reg_operand" "")
9036         (match_operator 1 "compare_operator"
9037           [(and (match_operand 2 "register_operand" "")
9038                 (match_operand 3 "const_int_operand" ""))
9039            (const_int 0)]))]
9040    "reload_completed
9041     && QI_REG_P (operands[2])
9042     && GET_MODE (operands[2]) != QImode
9043     && ((ix86_match_ccmode (insn, CCZmode)
9044          && !(INTVAL (operands[3]) & ~(255 << 8)))
9045         || (ix86_match_ccmode (insn, CCNOmode)
9046             && !(INTVAL (operands[3]) & ~(127 << 8))))"
9047   [(set (match_dup 0)
9048         (match_op_dup 1
9049           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9050                    (match_dup 3))
9051            (const_int 0)]))]
9052   "operands[2] = gen_lowpart (SImode, operands[2]);
9053    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9055 (define_split
9056   [(set (match_operand 0 "flags_reg_operand" "")
9057         (match_operator 1 "compare_operator"
9058           [(and (match_operand 2 "nonimmediate_operand" "")
9059                 (match_operand 3 "const_int_operand" ""))
9060            (const_int 0)]))]
9061    "reload_completed
9062     && GET_MODE (operands[2]) != QImode
9063     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9064     && ((ix86_match_ccmode (insn, CCZmode)
9065          && !(INTVAL (operands[3]) & ~255))
9066         || (ix86_match_ccmode (insn, CCNOmode)
9067             && !(INTVAL (operands[3]) & ~127)))"
9068   [(set (match_dup 0)
9069         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9070                          (const_int 0)]))]
9071   "operands[2] = gen_lowpart (QImode, operands[2]);
9072    operands[3] = gen_lowpart (QImode, operands[3]);")
9075 ;; %%% This used to optimize known byte-wide and operations to memory,
9076 ;; and sometimes to QImode registers.  If this is considered useful,
9077 ;; it should be done with splitters.
9079 (define_expand "anddi3"
9080   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9081         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9082                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9083   "TARGET_64BIT"
9084   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9086 (define_insn "*anddi_1_rex64"
9087   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9088         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9089                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9090    (clobber (reg:CC FLAGS_REG))]
9091   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9093   switch (get_attr_type (insn))
9094     {
9095     case TYPE_IMOVX:
9096       {
9097         enum machine_mode mode;
9099         gcc_assert (CONST_INT_P (operands[2]));
9100         if (INTVAL (operands[2]) == 0xff)
9101           mode = QImode;
9102         else
9103           {
9104             gcc_assert (INTVAL (operands[2]) == 0xffff);
9105             mode = HImode;
9106           }
9108         operands[1] = gen_lowpart (mode, operands[1]);
9109         if (mode == QImode)
9110           return "movz{bq|x}\t{%1,%0|%0, %1}";
9111         else
9112           return "movz{wq|x}\t{%1,%0|%0, %1}";
9113       }
9115     default:
9116       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9117       if (get_attr_mode (insn) == MODE_SI)
9118         return "and{l}\t{%k2, %k0|%k0, %k2}";
9119       else
9120         return "and{q}\t{%2, %0|%0, %2}";
9121     }
9123   [(set_attr "type" "alu,alu,alu,imovx")
9124    (set_attr "length_immediate" "*,*,*,0")
9125    (set_attr "mode" "SI,DI,DI,DI")])
9127 (define_insn "*anddi_2"
9128   [(set (reg FLAGS_REG)
9129         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9130                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9131                  (const_int 0)))
9132    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9133         (and:DI (match_dup 1) (match_dup 2)))]
9134   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9135    && ix86_binary_operator_ok (AND, DImode, operands)"
9136   "@
9137    and{l}\t{%k2, %k0|%k0, %k2}
9138    and{q}\t{%2, %0|%0, %2}
9139    and{q}\t{%2, %0|%0, %2}"
9140   [(set_attr "type" "alu")
9141    (set_attr "mode" "SI,DI,DI")])
9143 (define_expand "andsi3"
9144   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9145         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9146                 (match_operand:SI 2 "general_operand" "")))]
9147   ""
9148   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9150 (define_insn "*andsi_1"
9151   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9152         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9153                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9154    (clobber (reg:CC FLAGS_REG))]
9155   "ix86_binary_operator_ok (AND, SImode, operands)"
9157   switch (get_attr_type (insn))
9158     {
9159     case TYPE_IMOVX:
9160       {
9161         enum machine_mode mode;
9163         gcc_assert (CONST_INT_P (operands[2]));
9164         if (INTVAL (operands[2]) == 0xff)
9165           mode = QImode;
9166         else
9167           {
9168             gcc_assert (INTVAL (operands[2]) == 0xffff);
9169             mode = HImode;
9170           }
9172         operands[1] = gen_lowpart (mode, operands[1]);
9173         if (mode == QImode)
9174           return "movz{bl|x}\t{%1,%0|%0, %1}";
9175         else
9176           return "movz{wl|x}\t{%1,%0|%0, %1}";
9177       }
9179     default:
9180       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9181       return "and{l}\t{%2, %0|%0, %2}";
9182     }
9184   [(set_attr "type" "alu,alu,imovx")
9185    (set_attr "length_immediate" "*,*,0")
9186    (set_attr "mode" "SI")])
9188 (define_split
9189   [(set (match_operand 0 "register_operand" "")
9190         (and (match_dup 0)
9191              (const_int -65536)))
9192    (clobber (reg:CC FLAGS_REG))]
9193   "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9194   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9195   "operands[1] = gen_lowpart (HImode, operands[0]);")
9197 (define_split
9198   [(set (match_operand 0 "ext_register_operand" "")
9199         (and (match_dup 0)
9200              (const_int -256)))
9201    (clobber (reg:CC FLAGS_REG))]
9202   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9203   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9204   "operands[1] = gen_lowpart (QImode, operands[0]);")
9206 (define_split
9207   [(set (match_operand 0 "ext_register_operand" "")
9208         (and (match_dup 0)
9209              (const_int -65281)))
9210    (clobber (reg:CC FLAGS_REG))]
9211   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9212   [(parallel [(set (zero_extract:SI (match_dup 0)
9213                                     (const_int 8)
9214                                     (const_int 8))
9215                    (xor:SI
9216                      (zero_extract:SI (match_dup 0)
9217                                       (const_int 8)
9218                                       (const_int 8))
9219                      (zero_extract:SI (match_dup 0)
9220                                       (const_int 8)
9221                                       (const_int 8))))
9222               (clobber (reg:CC FLAGS_REG))])]
9223   "operands[0] = gen_lowpart (SImode, operands[0]);")
9225 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9226 (define_insn "*andsi_1_zext"
9227   [(set (match_operand:DI 0 "register_operand" "=r")
9228         (zero_extend:DI
9229           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9230                   (match_operand:SI 2 "general_operand" "g"))))
9231    (clobber (reg:CC FLAGS_REG))]
9232   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9233   "and{l}\t{%2, %k0|%k0, %2}"
9234   [(set_attr "type" "alu")
9235    (set_attr "mode" "SI")])
9237 (define_insn "*andsi_2"
9238   [(set (reg FLAGS_REG)
9239         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9240                          (match_operand:SI 2 "general_operand" "g,ri"))
9241                  (const_int 0)))
9242    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9243         (and:SI (match_dup 1) (match_dup 2)))]
9244   "ix86_match_ccmode (insn, CCNOmode)
9245    && ix86_binary_operator_ok (AND, SImode, operands)"
9246   "and{l}\t{%2, %0|%0, %2}"
9247   [(set_attr "type" "alu")
9248    (set_attr "mode" "SI")])
9250 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9251 (define_insn "*andsi_2_zext"
9252   [(set (reg FLAGS_REG)
9253         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9254                          (match_operand:SI 2 "general_operand" "g"))
9255                  (const_int 0)))
9256    (set (match_operand:DI 0 "register_operand" "=r")
9257         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9258   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9259    && ix86_binary_operator_ok (AND, SImode, operands)"
9260   "and{l}\t{%2, %k0|%k0, %2}"
9261   [(set_attr "type" "alu")
9262    (set_attr "mode" "SI")])
9264 (define_expand "andhi3"
9265   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9266         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9267                 (match_operand:HI 2 "general_operand" "")))]
9268   "TARGET_HIMODE_MATH"
9269   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9271 (define_insn "*andhi_1"
9272   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9273         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9274                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9275    (clobber (reg:CC FLAGS_REG))]
9276   "ix86_binary_operator_ok (AND, HImode, operands)"
9278   switch (get_attr_type (insn))
9279     {
9280     case TYPE_IMOVX:
9281       gcc_assert (CONST_INT_P (operands[2]));
9282       gcc_assert (INTVAL (operands[2]) == 0xff);
9283       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9285     default:
9286       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9288       return "and{w}\t{%2, %0|%0, %2}";
9289     }
9291   [(set_attr "type" "alu,alu,imovx")
9292    (set_attr "length_immediate" "*,*,0")
9293    (set_attr "mode" "HI,HI,SI")])
9295 (define_insn "*andhi_2"
9296   [(set (reg FLAGS_REG)
9297         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9298                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9299                  (const_int 0)))
9300    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9301         (and:HI (match_dup 1) (match_dup 2)))]
9302   "ix86_match_ccmode (insn, CCNOmode)
9303    && ix86_binary_operator_ok (AND, HImode, operands)"
9304   "and{w}\t{%2, %0|%0, %2}"
9305   [(set_attr "type" "alu")
9306    (set_attr "mode" "HI")])
9308 (define_expand "andqi3"
9309   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9310         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9311                 (match_operand:QI 2 "general_operand" "")))]
9312   "TARGET_QIMODE_MATH"
9313   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9315 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9316 (define_insn "*andqi_1"
9317   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9318         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9319                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9320    (clobber (reg:CC FLAGS_REG))]
9321   "ix86_binary_operator_ok (AND, QImode, operands)"
9322   "@
9323    and{b}\t{%2, %0|%0, %2}
9324    and{b}\t{%2, %0|%0, %2}
9325    and{l}\t{%k2, %k0|%k0, %k2}"
9326   [(set_attr "type" "alu")
9327    (set_attr "mode" "QI,QI,SI")])
9329 (define_insn "*andqi_1_slp"
9330   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9331         (and:QI (match_dup 0)
9332                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9333    (clobber (reg:CC FLAGS_REG))]
9334   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9335    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9336   "and{b}\t{%1, %0|%0, %1}"
9337   [(set_attr "type" "alu1")
9338    (set_attr "mode" "QI")])
9340 (define_insn "*andqi_2_maybe_si"
9341   [(set (reg FLAGS_REG)
9342         (compare (and:QI
9343                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9344                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9345                  (const_int 0)))
9346    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9347         (and:QI (match_dup 1) (match_dup 2)))]
9348   "ix86_binary_operator_ok (AND, QImode, operands)
9349    && ix86_match_ccmode (insn,
9350                          CONST_INT_P (operands[2])
9351                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9353   if (which_alternative == 2)
9354     {
9355       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9356         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9357       return "and{l}\t{%2, %k0|%k0, %2}";
9358     }
9359   return "and{b}\t{%2, %0|%0, %2}";
9361   [(set_attr "type" "alu")
9362    (set_attr "mode" "QI,QI,SI")])
9364 (define_insn "*andqi_2"
9365   [(set (reg FLAGS_REG)
9366         (compare (and:QI
9367                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9368                    (match_operand:QI 2 "general_operand" "qmn,qn"))
9369                  (const_int 0)))
9370    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9371         (and:QI (match_dup 1) (match_dup 2)))]
9372   "ix86_match_ccmode (insn, CCNOmode)
9373    && ix86_binary_operator_ok (AND, QImode, operands)"
9374   "and{b}\t{%2, %0|%0, %2}"
9375   [(set_attr "type" "alu")
9376    (set_attr "mode" "QI")])
9378 (define_insn "*andqi_2_slp"
9379   [(set (reg FLAGS_REG)
9380         (compare (and:QI
9381                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9382                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9383                  (const_int 0)))
9384    (set (strict_low_part (match_dup 0))
9385         (and:QI (match_dup 0) (match_dup 1)))]
9386   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9387    && ix86_match_ccmode (insn, CCNOmode)
9388    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9389   "and{b}\t{%1, %0|%0, %1}"
9390   [(set_attr "type" "alu1")
9391    (set_attr "mode" "QI")])
9393 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9394 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9395 ;; for a QImode operand, which of course failed.
9397 (define_insn "andqi_ext_0"
9398   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9399                          (const_int 8)
9400                          (const_int 8))
9401         (and:SI
9402           (zero_extract:SI
9403             (match_operand 1 "ext_register_operand" "0")
9404             (const_int 8)
9405             (const_int 8))
9406           (match_operand 2 "const_int_operand" "n")))
9407    (clobber (reg:CC FLAGS_REG))]
9408   ""
9409   "and{b}\t{%2, %h0|%h0, %2}"
9410   [(set_attr "type" "alu")
9411    (set_attr "length_immediate" "1")
9412    (set_attr "mode" "QI")])
9414 ;; Generated by peephole translating test to and.  This shows up
9415 ;; often in fp comparisons.
9417 (define_insn "*andqi_ext_0_cc"
9418   [(set (reg FLAGS_REG)
9419         (compare
9420           (and:SI
9421             (zero_extract:SI
9422               (match_operand 1 "ext_register_operand" "0")
9423               (const_int 8)
9424               (const_int 8))
9425             (match_operand 2 "const_int_operand" "n"))
9426           (const_int 0)))
9427    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9428                          (const_int 8)
9429                          (const_int 8))
9430         (and:SI
9431           (zero_extract:SI
9432             (match_dup 1)
9433             (const_int 8)
9434             (const_int 8))
9435           (match_dup 2)))]
9436   "ix86_match_ccmode (insn, CCNOmode)"
9437   "and{b}\t{%2, %h0|%h0, %2}"
9438   [(set_attr "type" "alu")
9439    (set_attr "length_immediate" "1")
9440    (set_attr "mode" "QI")])
9442 (define_insn "*andqi_ext_1"
9443   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9444                          (const_int 8)
9445                          (const_int 8))
9446         (and:SI
9447           (zero_extract:SI
9448             (match_operand 1 "ext_register_operand" "0")
9449             (const_int 8)
9450             (const_int 8))
9451           (zero_extend:SI
9452             (match_operand:QI 2 "general_operand" "Qm"))))
9453    (clobber (reg:CC FLAGS_REG))]
9454   "!TARGET_64BIT"
9455   "and{b}\t{%2, %h0|%h0, %2}"
9456   [(set_attr "type" "alu")
9457    (set_attr "length_immediate" "0")
9458    (set_attr "mode" "QI")])
9460 (define_insn "*andqi_ext_1_rex64"
9461   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9462                          (const_int 8)
9463                          (const_int 8))
9464         (and:SI
9465           (zero_extract:SI
9466             (match_operand 1 "ext_register_operand" "0")
9467             (const_int 8)
9468             (const_int 8))
9469           (zero_extend:SI
9470             (match_operand 2 "ext_register_operand" "Q"))))
9471    (clobber (reg:CC FLAGS_REG))]
9472   "TARGET_64BIT"
9473   "and{b}\t{%2, %h0|%h0, %2}"
9474   [(set_attr "type" "alu")
9475    (set_attr "length_immediate" "0")
9476    (set_attr "mode" "QI")])
9478 (define_insn "*andqi_ext_2"
9479   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9480                          (const_int 8)
9481                          (const_int 8))
9482         (and:SI
9483           (zero_extract:SI
9484             (match_operand 1 "ext_register_operand" "%0")
9485             (const_int 8)
9486             (const_int 8))
9487           (zero_extract:SI
9488             (match_operand 2 "ext_register_operand" "Q")
9489             (const_int 8)
9490             (const_int 8))))
9491    (clobber (reg:CC FLAGS_REG))]
9492   ""
9493   "and{b}\t{%h2, %h0|%h0, %h2}"
9494   [(set_attr "type" "alu")
9495    (set_attr "length_immediate" "0")
9496    (set_attr "mode" "QI")])
9498 ;; Convert wide AND instructions with immediate operand to shorter QImode
9499 ;; equivalents when possible.
9500 ;; Don't do the splitting with memory operands, since it introduces risk
9501 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9502 ;; for size, but that can (should?) be handled by generic code instead.
9503 (define_split
9504   [(set (match_operand 0 "register_operand" "")
9505         (and (match_operand 1 "register_operand" "")
9506              (match_operand 2 "const_int_operand" "")))
9507    (clobber (reg:CC FLAGS_REG))]
9508    "reload_completed
9509     && QI_REG_P (operands[0])
9510     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9511     && !(~INTVAL (operands[2]) & ~(255 << 8))
9512     && GET_MODE (operands[0]) != QImode"
9513   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9514                    (and:SI (zero_extract:SI (match_dup 1)
9515                                             (const_int 8) (const_int 8))
9516                            (match_dup 2)))
9517               (clobber (reg:CC FLAGS_REG))])]
9518   "operands[0] = gen_lowpart (SImode, operands[0]);
9519    operands[1] = gen_lowpart (SImode, operands[1]);
9520    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9522 ;; Since AND can be encoded with sign extended immediate, this is only
9523 ;; profitable when 7th bit is not set.
9524 (define_split
9525   [(set (match_operand 0 "register_operand" "")
9526         (and (match_operand 1 "general_operand" "")
9527              (match_operand 2 "const_int_operand" "")))
9528    (clobber (reg:CC FLAGS_REG))]
9529    "reload_completed
9530     && ANY_QI_REG_P (operands[0])
9531     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9532     && !(~INTVAL (operands[2]) & ~255)
9533     && !(INTVAL (operands[2]) & 128)
9534     && GET_MODE (operands[0]) != QImode"
9535   [(parallel [(set (strict_low_part (match_dup 0))
9536                    (and:QI (match_dup 1)
9537                            (match_dup 2)))
9538               (clobber (reg:CC FLAGS_REG))])]
9539   "operands[0] = gen_lowpart (QImode, operands[0]);
9540    operands[1] = gen_lowpart (QImode, operands[1]);
9541    operands[2] = gen_lowpart (QImode, operands[2]);")
9543 ;; Logical inclusive OR instructions
9545 ;; %%% This used to optimize known byte-wide and operations to memory.
9546 ;; If this is considered useful, it should be done with splitters.
9548 (define_expand "iordi3"
9549   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9550         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9551                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9552   "TARGET_64BIT"
9553   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9555 (define_insn "*iordi_1_rex64"
9556   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9557         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9558                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9559    (clobber (reg:CC FLAGS_REG))]
9560   "TARGET_64BIT
9561    && ix86_binary_operator_ok (IOR, DImode, operands)"
9562   "or{q}\t{%2, %0|%0, %2}"
9563   [(set_attr "type" "alu")
9564    (set_attr "mode" "DI")])
9566 (define_insn "*iordi_2_rex64"
9567   [(set (reg FLAGS_REG)
9568         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9569                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9570                  (const_int 0)))
9571    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9572         (ior:DI (match_dup 1) (match_dup 2)))]
9573   "TARGET_64BIT
9574    && ix86_match_ccmode (insn, CCNOmode)
9575    && ix86_binary_operator_ok (IOR, DImode, operands)"
9576   "or{q}\t{%2, %0|%0, %2}"
9577   [(set_attr "type" "alu")
9578    (set_attr "mode" "DI")])
9580 (define_insn "*iordi_3_rex64"
9581   [(set (reg FLAGS_REG)
9582         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9583                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9584                  (const_int 0)))
9585    (clobber (match_scratch:DI 0 "=r"))]
9586   "TARGET_64BIT
9587    && ix86_match_ccmode (insn, CCNOmode)
9588    && ix86_binary_operator_ok (IOR, DImode, operands)"
9589   "or{q}\t{%2, %0|%0, %2}"
9590   [(set_attr "type" "alu")
9591    (set_attr "mode" "DI")])
9594 (define_expand "iorsi3"
9595   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9596         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9597                 (match_operand:SI 2 "general_operand" "")))]
9598   ""
9599   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9601 (define_insn "*iorsi_1"
9602   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9603         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9604                 (match_operand:SI 2 "general_operand" "ri,g")))
9605    (clobber (reg:CC FLAGS_REG))]
9606   "ix86_binary_operator_ok (IOR, SImode, operands)"
9607   "or{l}\t{%2, %0|%0, %2}"
9608   [(set_attr "type" "alu")
9609    (set_attr "mode" "SI")])
9611 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9612 (define_insn "*iorsi_1_zext"
9613   [(set (match_operand:DI 0 "register_operand" "=r")
9614         (zero_extend:DI
9615           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9616                   (match_operand:SI 2 "general_operand" "g"))))
9617    (clobber (reg:CC FLAGS_REG))]
9618   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9619   "or{l}\t{%2, %k0|%k0, %2}"
9620   [(set_attr "type" "alu")
9621    (set_attr "mode" "SI")])
9623 (define_insn "*iorsi_1_zext_imm"
9624   [(set (match_operand:DI 0 "register_operand" "=r")
9625         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9626                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9627    (clobber (reg:CC FLAGS_REG))]
9628   "TARGET_64BIT"
9629   "or{l}\t{%2, %k0|%k0, %2}"
9630   [(set_attr "type" "alu")
9631    (set_attr "mode" "SI")])
9633 (define_insn "*iorsi_2"
9634   [(set (reg FLAGS_REG)
9635         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9636                          (match_operand:SI 2 "general_operand" "g,ri"))
9637                  (const_int 0)))
9638    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9639         (ior:SI (match_dup 1) (match_dup 2)))]
9640   "ix86_match_ccmode (insn, CCNOmode)
9641    && ix86_binary_operator_ok (IOR, SImode, operands)"
9642   "or{l}\t{%2, %0|%0, %2}"
9643   [(set_attr "type" "alu")
9644    (set_attr "mode" "SI")])
9646 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9647 ;; ??? Special case for immediate operand is missing - it is tricky.
9648 (define_insn "*iorsi_2_zext"
9649   [(set (reg FLAGS_REG)
9650         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9651                          (match_operand:SI 2 "general_operand" "g"))
9652                  (const_int 0)))
9653    (set (match_operand:DI 0 "register_operand" "=r")
9654         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9655   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9656    && ix86_binary_operator_ok (IOR, SImode, operands)"
9657   "or{l}\t{%2, %k0|%k0, %2}"
9658   [(set_attr "type" "alu")
9659    (set_attr "mode" "SI")])
9661 (define_insn "*iorsi_2_zext_imm"
9662   [(set (reg FLAGS_REG)
9663         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9664                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9665                  (const_int 0)))
9666    (set (match_operand:DI 0 "register_operand" "=r")
9667         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9668   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9669    && ix86_binary_operator_ok (IOR, SImode, operands)"
9670   "or{l}\t{%2, %k0|%k0, %2}"
9671   [(set_attr "type" "alu")
9672    (set_attr "mode" "SI")])
9674 (define_insn "*iorsi_3"
9675   [(set (reg FLAGS_REG)
9676         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9677                          (match_operand:SI 2 "general_operand" "g"))
9678                  (const_int 0)))
9679    (clobber (match_scratch:SI 0 "=r"))]
9680   "ix86_match_ccmode (insn, CCNOmode)
9681    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9682   "or{l}\t{%2, %0|%0, %2}"
9683   [(set_attr "type" "alu")
9684    (set_attr "mode" "SI")])
9686 (define_expand "iorhi3"
9687   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9688         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9689                 (match_operand:HI 2 "general_operand" "")))]
9690   "TARGET_HIMODE_MATH"
9691   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9693 (define_insn "*iorhi_1"
9694   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9695         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9696                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9697    (clobber (reg:CC FLAGS_REG))]
9698   "ix86_binary_operator_ok (IOR, HImode, operands)"
9699   "or{w}\t{%2, %0|%0, %2}"
9700   [(set_attr "type" "alu")
9701    (set_attr "mode" "HI")])
9703 (define_insn "*iorhi_2"
9704   [(set (reg FLAGS_REG)
9705         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9706                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9707                  (const_int 0)))
9708    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9709         (ior:HI (match_dup 1) (match_dup 2)))]
9710   "ix86_match_ccmode (insn, CCNOmode)
9711    && ix86_binary_operator_ok (IOR, HImode, operands)"
9712   "or{w}\t{%2, %0|%0, %2}"
9713   [(set_attr "type" "alu")
9714    (set_attr "mode" "HI")])
9716 (define_insn "*iorhi_3"
9717   [(set (reg FLAGS_REG)
9718         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9719                          (match_operand:HI 2 "general_operand" "rmn"))
9720                  (const_int 0)))
9721    (clobber (match_scratch:HI 0 "=r"))]
9722   "ix86_match_ccmode (insn, CCNOmode)
9723    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9724   "or{w}\t{%2, %0|%0, %2}"
9725   [(set_attr "type" "alu")
9726    (set_attr "mode" "HI")])
9728 (define_expand "iorqi3"
9729   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9730         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9731                 (match_operand:QI 2 "general_operand" "")))]
9732   "TARGET_QIMODE_MATH"
9733   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9735 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9736 (define_insn "*iorqi_1"
9737   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9738         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9739                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9740    (clobber (reg:CC FLAGS_REG))]
9741   "ix86_binary_operator_ok (IOR, QImode, operands)"
9742   "@
9743    or{b}\t{%2, %0|%0, %2}
9744    or{b}\t{%2, %0|%0, %2}
9745    or{l}\t{%k2, %k0|%k0, %k2}"
9746   [(set_attr "type" "alu")
9747    (set_attr "mode" "QI,QI,SI")])
9749 (define_insn "*iorqi_1_slp"
9750   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9751         (ior:QI (match_dup 0)
9752                 (match_operand:QI 1 "general_operand" "qmn,qn")))
9753    (clobber (reg:CC FLAGS_REG))]
9754   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9755    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9756   "or{b}\t{%1, %0|%0, %1}"
9757   [(set_attr "type" "alu1")
9758    (set_attr "mode" "QI")])
9760 (define_insn "*iorqi_2"
9761   [(set (reg FLAGS_REG)
9762         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9763                          (match_operand:QI 2 "general_operand" "qmn,qn"))
9764                  (const_int 0)))
9765    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9766         (ior:QI (match_dup 1) (match_dup 2)))]
9767   "ix86_match_ccmode (insn, CCNOmode)
9768    && ix86_binary_operator_ok (IOR, QImode, operands)"
9769   "or{b}\t{%2, %0|%0, %2}"
9770   [(set_attr "type" "alu")
9771    (set_attr "mode" "QI")])
9773 (define_insn "*iorqi_2_slp"
9774   [(set (reg FLAGS_REG)
9775         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9776                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9777                  (const_int 0)))
9778    (set (strict_low_part (match_dup 0))
9779         (ior:QI (match_dup 0) (match_dup 1)))]
9780   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9781    && ix86_match_ccmode (insn, CCNOmode)
9782    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9783   "or{b}\t{%1, %0|%0, %1}"
9784   [(set_attr "type" "alu1")
9785    (set_attr "mode" "QI")])
9787 (define_insn "*iorqi_3"
9788   [(set (reg FLAGS_REG)
9789         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9790                          (match_operand:QI 2 "general_operand" "qmn"))
9791                  (const_int 0)))
9792    (clobber (match_scratch:QI 0 "=q"))]
9793   "ix86_match_ccmode (insn, CCNOmode)
9794    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9795   "or{b}\t{%2, %0|%0, %2}"
9796   [(set_attr "type" "alu")
9797    (set_attr "mode" "QI")])
9799 (define_insn "*iorqi_ext_0"
9800   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9801                          (const_int 8)
9802                          (const_int 8))
9803         (ior:SI
9804           (zero_extract:SI
9805             (match_operand 1 "ext_register_operand" "0")
9806             (const_int 8)
9807             (const_int 8))
9808           (match_operand 2 "const_int_operand" "n")))
9809    (clobber (reg:CC FLAGS_REG))]
9810   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9811   "or{b}\t{%2, %h0|%h0, %2}"
9812   [(set_attr "type" "alu")
9813    (set_attr "length_immediate" "1")
9814    (set_attr "mode" "QI")])
9816 (define_insn "*iorqi_ext_1"
9817   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9818                          (const_int 8)
9819                          (const_int 8))
9820         (ior:SI
9821           (zero_extract:SI
9822             (match_operand 1 "ext_register_operand" "0")
9823             (const_int 8)
9824             (const_int 8))
9825           (zero_extend:SI
9826             (match_operand:QI 2 "general_operand" "Qm"))))
9827    (clobber (reg:CC FLAGS_REG))]
9828   "!TARGET_64BIT
9829    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9830   "or{b}\t{%2, %h0|%h0, %2}"
9831   [(set_attr "type" "alu")
9832    (set_attr "length_immediate" "0")
9833    (set_attr "mode" "QI")])
9835 (define_insn "*iorqi_ext_1_rex64"
9836   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9837                          (const_int 8)
9838                          (const_int 8))
9839         (ior:SI
9840           (zero_extract:SI
9841             (match_operand 1 "ext_register_operand" "0")
9842             (const_int 8)
9843             (const_int 8))
9844           (zero_extend:SI
9845             (match_operand 2 "ext_register_operand" "Q"))))
9846    (clobber (reg:CC FLAGS_REG))]
9847   "TARGET_64BIT
9848    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9849   "or{b}\t{%2, %h0|%h0, %2}"
9850   [(set_attr "type" "alu")
9851    (set_attr "length_immediate" "0")
9852    (set_attr "mode" "QI")])
9854 (define_insn "*iorqi_ext_2"
9855   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9856                          (const_int 8)
9857                          (const_int 8))
9858         (ior:SI
9859           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9860                            (const_int 8)
9861                            (const_int 8))
9862           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9863                            (const_int 8)
9864                            (const_int 8))))
9865    (clobber (reg:CC FLAGS_REG))]
9866   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9867   "ior{b}\t{%h2, %h0|%h0, %h2}"
9868   [(set_attr "type" "alu")
9869    (set_attr "length_immediate" "0")
9870    (set_attr "mode" "QI")])
9872 (define_split
9873   [(set (match_operand 0 "register_operand" "")
9874         (ior (match_operand 1 "register_operand" "")
9875              (match_operand 2 "const_int_operand" "")))
9876    (clobber (reg:CC FLAGS_REG))]
9877    "reload_completed
9878     && QI_REG_P (operands[0])
9879     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9880     && !(INTVAL (operands[2]) & ~(255 << 8))
9881     && GET_MODE (operands[0]) != QImode"
9882   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9883                    (ior:SI (zero_extract:SI (match_dup 1)
9884                                             (const_int 8) (const_int 8))
9885                            (match_dup 2)))
9886               (clobber (reg:CC FLAGS_REG))])]
9887   "operands[0] = gen_lowpart (SImode, operands[0]);
9888    operands[1] = gen_lowpart (SImode, operands[1]);
9889    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9891 ;; Since OR can be encoded with sign extended immediate, this is only
9892 ;; profitable when 7th bit is set.
9893 (define_split
9894   [(set (match_operand 0 "register_operand" "")
9895         (ior (match_operand 1 "general_operand" "")
9896              (match_operand 2 "const_int_operand" "")))
9897    (clobber (reg:CC FLAGS_REG))]
9898    "reload_completed
9899     && ANY_QI_REG_P (operands[0])
9900     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9901     && !(INTVAL (operands[2]) & ~255)
9902     && (INTVAL (operands[2]) & 128)
9903     && GET_MODE (operands[0]) != QImode"
9904   [(parallel [(set (strict_low_part (match_dup 0))
9905                    (ior:QI (match_dup 1)
9906                            (match_dup 2)))
9907               (clobber (reg:CC FLAGS_REG))])]
9908   "operands[0] = gen_lowpart (QImode, operands[0]);
9909    operands[1] = gen_lowpart (QImode, operands[1]);
9910    operands[2] = gen_lowpart (QImode, operands[2]);")
9912 ;; Logical XOR instructions
9914 ;; %%% This used to optimize known byte-wide and operations to memory.
9915 ;; If this is considered useful, it should be done with splitters.
9917 (define_expand "xordi3"
9918   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9919         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9920                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9921   "TARGET_64BIT"
9922   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9924 (define_insn "*xordi_1_rex64"
9925   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9926         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9927                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9928    (clobber (reg:CC FLAGS_REG))]
9929   "TARGET_64BIT
9930    && ix86_binary_operator_ok (XOR, DImode, operands)"
9931   "xor{q}\t{%2, %0|%0, %2}"
9932   [(set_attr "type" "alu")
9933    (set_attr "mode" "DI")])
9935 (define_insn "*xordi_2_rex64"
9936   [(set (reg FLAGS_REG)
9937         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9938                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9939                  (const_int 0)))
9940    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9941         (xor:DI (match_dup 1) (match_dup 2)))]
9942   "TARGET_64BIT
9943    && ix86_match_ccmode (insn, CCNOmode)
9944    && ix86_binary_operator_ok (XOR, DImode, operands)"
9945   "xor{q}\t{%2, %0|%0, %2}"
9946   [(set_attr "type" "alu")
9947    (set_attr "mode" "DI")])
9949 (define_insn "*xordi_3_rex64"
9950   [(set (reg FLAGS_REG)
9951         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9952                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9953                  (const_int 0)))
9954    (clobber (match_scratch:DI 0 "=r"))]
9955   "TARGET_64BIT
9956    && ix86_match_ccmode (insn, CCNOmode)
9957    && ix86_binary_operator_ok (XOR, DImode, operands)"
9958   "xor{q}\t{%2, %0|%0, %2}"
9959   [(set_attr "type" "alu")
9960    (set_attr "mode" "DI")])
9962 (define_expand "xorsi3"
9963   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9964         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9965                 (match_operand:SI 2 "general_operand" "")))]
9966   ""
9967   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9969 (define_insn "*xorsi_1"
9970   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9971         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9972                 (match_operand:SI 2 "general_operand" "ri,rm")))
9973    (clobber (reg:CC FLAGS_REG))]
9974   "ix86_binary_operator_ok (XOR, SImode, operands)"
9975   "xor{l}\t{%2, %0|%0, %2}"
9976   [(set_attr "type" "alu")
9977    (set_attr "mode" "SI")])
9979 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9980 ;; Add speccase for immediates
9981 (define_insn "*xorsi_1_zext"
9982   [(set (match_operand:DI 0 "register_operand" "=r")
9983         (zero_extend:DI
9984           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9985                   (match_operand:SI 2 "general_operand" "g"))))
9986    (clobber (reg:CC FLAGS_REG))]
9987   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9988   "xor{l}\t{%2, %k0|%k0, %2}"
9989   [(set_attr "type" "alu")
9990    (set_attr "mode" "SI")])
9992 (define_insn "*xorsi_1_zext_imm"
9993   [(set (match_operand:DI 0 "register_operand" "=r")
9994         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9995                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9996    (clobber (reg:CC FLAGS_REG))]
9997   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9998   "xor{l}\t{%2, %k0|%k0, %2}"
9999   [(set_attr "type" "alu")
10000    (set_attr "mode" "SI")])
10002 (define_insn "*xorsi_2"
10003   [(set (reg FLAGS_REG)
10004         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10005                          (match_operand:SI 2 "general_operand" "g,ri"))
10006                  (const_int 0)))
10007    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10008         (xor:SI (match_dup 1) (match_dup 2)))]
10009   "ix86_match_ccmode (insn, CCNOmode)
10010    && ix86_binary_operator_ok (XOR, SImode, operands)"
10011   "xor{l}\t{%2, %0|%0, %2}"
10012   [(set_attr "type" "alu")
10013    (set_attr "mode" "SI")])
10015 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10016 ;; ??? Special case for immediate operand is missing - it is tricky.
10017 (define_insn "*xorsi_2_zext"
10018   [(set (reg FLAGS_REG)
10019         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10020                          (match_operand:SI 2 "general_operand" "g"))
10021                  (const_int 0)))
10022    (set (match_operand:DI 0 "register_operand" "=r")
10023         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10024   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10025    && ix86_binary_operator_ok (XOR, SImode, operands)"
10026   "xor{l}\t{%2, %k0|%k0, %2}"
10027   [(set_attr "type" "alu")
10028    (set_attr "mode" "SI")])
10030 (define_insn "*xorsi_2_zext_imm"
10031   [(set (reg FLAGS_REG)
10032         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10033                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10034                  (const_int 0)))
10035    (set (match_operand:DI 0 "register_operand" "=r")
10036         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10037   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10038    && ix86_binary_operator_ok (XOR, SImode, operands)"
10039   "xor{l}\t{%2, %k0|%k0, %2}"
10040   [(set_attr "type" "alu")
10041    (set_attr "mode" "SI")])
10043 (define_insn "*xorsi_3"
10044   [(set (reg FLAGS_REG)
10045         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10046                          (match_operand:SI 2 "general_operand" "g"))
10047                  (const_int 0)))
10048    (clobber (match_scratch:SI 0 "=r"))]
10049   "ix86_match_ccmode (insn, CCNOmode)
10050    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10051   "xor{l}\t{%2, %0|%0, %2}"
10052   [(set_attr "type" "alu")
10053    (set_attr "mode" "SI")])
10055 (define_expand "xorhi3"
10056   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10057         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10058                 (match_operand:HI 2 "general_operand" "")))]
10059   "TARGET_HIMODE_MATH"
10060   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10062 (define_insn "*xorhi_1"
10063   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10064         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10065                 (match_operand:HI 2 "general_operand" "rmn,rn")))
10066    (clobber (reg:CC FLAGS_REG))]
10067   "ix86_binary_operator_ok (XOR, HImode, operands)"
10068   "xor{w}\t{%2, %0|%0, %2}"
10069   [(set_attr "type" "alu")
10070    (set_attr "mode" "HI")])
10072 (define_insn "*xorhi_2"
10073   [(set (reg FLAGS_REG)
10074         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10075                          (match_operand:HI 2 "general_operand" "rmn,rn"))
10076                  (const_int 0)))
10077    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10078         (xor:HI (match_dup 1) (match_dup 2)))]
10079   "ix86_match_ccmode (insn, CCNOmode)
10080    && ix86_binary_operator_ok (XOR, HImode, operands)"
10081   "xor{w}\t{%2, %0|%0, %2}"
10082   [(set_attr "type" "alu")
10083    (set_attr "mode" "HI")])
10085 (define_insn "*xorhi_3"
10086   [(set (reg FLAGS_REG)
10087         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10088                          (match_operand:HI 2 "general_operand" "rmn"))
10089                  (const_int 0)))
10090    (clobber (match_scratch:HI 0 "=r"))]
10091   "ix86_match_ccmode (insn, CCNOmode)
10092    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10093   "xor{w}\t{%2, %0|%0, %2}"
10094   [(set_attr "type" "alu")
10095    (set_attr "mode" "HI")])
10097 (define_expand "xorqi3"
10098   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10099         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10100                 (match_operand:QI 2 "general_operand" "")))]
10101   "TARGET_QIMODE_MATH"
10102   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10104 ;; %%% Potential partial reg stall on alternative 2.  What to do?
10105 (define_insn "*xorqi_1"
10106   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10107         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10108                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10109    (clobber (reg:CC FLAGS_REG))]
10110   "ix86_binary_operator_ok (XOR, QImode, operands)"
10111   "@
10112    xor{b}\t{%2, %0|%0, %2}
10113    xor{b}\t{%2, %0|%0, %2}
10114    xor{l}\t{%k2, %k0|%k0, %k2}"
10115   [(set_attr "type" "alu")
10116    (set_attr "mode" "QI,QI,SI")])
10118 (define_insn "*xorqi_1_slp"
10119   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10120         (xor:QI (match_dup 0)
10121                 (match_operand:QI 1 "general_operand" "qn,qmn")))
10122    (clobber (reg:CC FLAGS_REG))]
10123   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10124    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10125   "xor{b}\t{%1, %0|%0, %1}"
10126   [(set_attr "type" "alu1")
10127    (set_attr "mode" "QI")])
10129 (define_insn "*xorqi_ext_0"
10130   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10131                          (const_int 8)
10132                          (const_int 8))
10133         (xor:SI
10134           (zero_extract:SI
10135             (match_operand 1 "ext_register_operand" "0")
10136             (const_int 8)
10137             (const_int 8))
10138           (match_operand 2 "const_int_operand" "n")))
10139    (clobber (reg:CC FLAGS_REG))]
10140   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10141   "xor{b}\t{%2, %h0|%h0, %2}"
10142   [(set_attr "type" "alu")
10143    (set_attr "length_immediate" "1")
10144    (set_attr "mode" "QI")])
10146 (define_insn "*xorqi_ext_1"
10147   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10148                          (const_int 8)
10149                          (const_int 8))
10150         (xor:SI
10151           (zero_extract:SI
10152             (match_operand 1 "ext_register_operand" "0")
10153             (const_int 8)
10154             (const_int 8))
10155           (zero_extend:SI
10156             (match_operand:QI 2 "general_operand" "Qm"))))
10157    (clobber (reg:CC FLAGS_REG))]
10158   "!TARGET_64BIT
10159    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10160   "xor{b}\t{%2, %h0|%h0, %2}"
10161   [(set_attr "type" "alu")
10162    (set_attr "length_immediate" "0")
10163    (set_attr "mode" "QI")])
10165 (define_insn "*xorqi_ext_1_rex64"
10166   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10167                          (const_int 8)
10168                          (const_int 8))
10169         (xor:SI
10170           (zero_extract:SI
10171             (match_operand 1 "ext_register_operand" "0")
10172             (const_int 8)
10173             (const_int 8))
10174           (zero_extend:SI
10175             (match_operand 2 "ext_register_operand" "Q"))))
10176    (clobber (reg:CC FLAGS_REG))]
10177   "TARGET_64BIT
10178    && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10179   "xor{b}\t{%2, %h0|%h0, %2}"
10180   [(set_attr "type" "alu")
10181    (set_attr "length_immediate" "0")
10182    (set_attr "mode" "QI")])
10184 (define_insn "*xorqi_ext_2"
10185   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10186                          (const_int 8)
10187                          (const_int 8))
10188         (xor:SI
10189           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10190                            (const_int 8)
10191                            (const_int 8))
10192           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10193                            (const_int 8)
10194                            (const_int 8))))
10195    (clobber (reg:CC FLAGS_REG))]
10196   "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10197   "xor{b}\t{%h2, %h0|%h0, %h2}"
10198   [(set_attr "type" "alu")
10199    (set_attr "length_immediate" "0")
10200    (set_attr "mode" "QI")])
10202 (define_insn "*xorqi_cc_1"
10203   [(set (reg FLAGS_REG)
10204         (compare
10205           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10206                   (match_operand:QI 2 "general_operand" "qmn,qn"))
10207           (const_int 0)))
10208    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10209         (xor:QI (match_dup 1) (match_dup 2)))]
10210   "ix86_match_ccmode (insn, CCNOmode)
10211    && ix86_binary_operator_ok (XOR, QImode, operands)"
10212   "xor{b}\t{%2, %0|%0, %2}"
10213   [(set_attr "type" "alu")
10214    (set_attr "mode" "QI")])
10216 (define_insn "*xorqi_2_slp"
10217   [(set (reg FLAGS_REG)
10218         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10219                          (match_operand:QI 1 "general_operand" "qmn,qn"))
10220                  (const_int 0)))
10221    (set (strict_low_part (match_dup 0))
10222         (xor:QI (match_dup 0) (match_dup 1)))]
10223   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10224    && ix86_match_ccmode (insn, CCNOmode)
10225    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10226   "xor{b}\t{%1, %0|%0, %1}"
10227   [(set_attr "type" "alu1")
10228    (set_attr "mode" "QI")])
10230 (define_insn "*xorqi_cc_2"
10231   [(set (reg FLAGS_REG)
10232         (compare
10233           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10234                   (match_operand:QI 2 "general_operand" "qmn"))
10235           (const_int 0)))
10236    (clobber (match_scratch:QI 0 "=q"))]
10237   "ix86_match_ccmode (insn, CCNOmode)
10238    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10239   "xor{b}\t{%2, %0|%0, %2}"
10240   [(set_attr "type" "alu")
10241    (set_attr "mode" "QI")])
10243 (define_insn "*xorqi_cc_ext_1"
10244   [(set (reg FLAGS_REG)
10245         (compare
10246           (xor:SI
10247             (zero_extract:SI
10248               (match_operand 1 "ext_register_operand" "0")
10249               (const_int 8)
10250               (const_int 8))
10251             (match_operand:QI 2 "general_operand" "qmn"))
10252           (const_int 0)))
10253    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10254                          (const_int 8)
10255                          (const_int 8))
10256         (xor:SI
10257           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10258           (match_dup 2)))]
10259   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10260   "xor{b}\t{%2, %h0|%h0, %2}"
10261   [(set_attr "type" "alu")
10262    (set_attr "mode" "QI")])
10264 (define_insn "*xorqi_cc_ext_1_rex64"
10265   [(set (reg FLAGS_REG)
10266         (compare
10267           (xor:SI
10268             (zero_extract:SI
10269               (match_operand 1 "ext_register_operand" "0")
10270               (const_int 8)
10271               (const_int 8))
10272             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10273           (const_int 0)))
10274    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10275                          (const_int 8)
10276                          (const_int 8))
10277         (xor:SI
10278           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10279           (match_dup 2)))]
10280   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10281   "xor{b}\t{%2, %h0|%h0, %2}"
10282   [(set_attr "type" "alu")
10283    (set_attr "mode" "QI")])
10285 (define_expand "xorqi_cc_ext_1"
10286   [(parallel [
10287      (set (reg:CCNO FLAGS_REG)
10288           (compare:CCNO
10289             (xor:SI
10290               (zero_extract:SI
10291                 (match_operand 1 "ext_register_operand" "")
10292                 (const_int 8)
10293                 (const_int 8))
10294               (match_operand:QI 2 "general_operand" ""))
10295             (const_int 0)))
10296      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10297                            (const_int 8)
10298                            (const_int 8))
10299           (xor:SI
10300             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10301             (match_dup 2)))])]
10302   ""
10303   "")
10305 (define_split
10306   [(set (match_operand 0 "register_operand" "")
10307         (xor (match_operand 1 "register_operand" "")
10308              (match_operand 2 "const_int_operand" "")))
10309    (clobber (reg:CC FLAGS_REG))]
10310    "reload_completed
10311     && QI_REG_P (operands[0])
10312     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10313     && !(INTVAL (operands[2]) & ~(255 << 8))
10314     && GET_MODE (operands[0]) != QImode"
10315   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10316                    (xor:SI (zero_extract:SI (match_dup 1)
10317                                             (const_int 8) (const_int 8))
10318                            (match_dup 2)))
10319               (clobber (reg:CC FLAGS_REG))])]
10320   "operands[0] = gen_lowpart (SImode, operands[0]);
10321    operands[1] = gen_lowpart (SImode, operands[1]);
10322    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10324 ;; Since XOR can be encoded with sign extended immediate, this is only
10325 ;; profitable when 7th bit is set.
10326 (define_split
10327   [(set (match_operand 0 "register_operand" "")
10328         (xor (match_operand 1 "general_operand" "")
10329              (match_operand 2 "const_int_operand" "")))
10330    (clobber (reg:CC FLAGS_REG))]
10331    "reload_completed
10332     && ANY_QI_REG_P (operands[0])
10333     && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10334     && !(INTVAL (operands[2]) & ~255)
10335     && (INTVAL (operands[2]) & 128)
10336     && GET_MODE (operands[0]) != QImode"
10337   [(parallel [(set (strict_low_part (match_dup 0))
10338                    (xor:QI (match_dup 1)
10339                            (match_dup 2)))
10340               (clobber (reg:CC FLAGS_REG))])]
10341   "operands[0] = gen_lowpart (QImode, operands[0]);
10342    operands[1] = gen_lowpart (QImode, operands[1]);
10343    operands[2] = gen_lowpart (QImode, operands[2]);")
10345 ;; Negation instructions
10347 (define_expand "negti2"
10348   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10349         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10350   "TARGET_64BIT"
10351   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10353 (define_insn "*negti2_1"
10354   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10355         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10356    (clobber (reg:CC FLAGS_REG))]
10357   "TARGET_64BIT
10358    && ix86_unary_operator_ok (NEG, TImode, operands)"
10359   "#")
10361 (define_split
10362   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10363         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10364    (clobber (reg:CC FLAGS_REG))]
10365   "TARGET_64BIT && reload_completed"
10366   [(parallel
10367     [(set (reg:CCZ FLAGS_REG)
10368           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10369      (set (match_dup 0) (neg:DI (match_dup 1)))])
10370    (parallel
10371     [(set (match_dup 2)
10372           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10373                             (match_dup 3))
10374                    (const_int 0)))
10375      (clobber (reg:CC FLAGS_REG))])
10376    (parallel
10377     [(set (match_dup 2)
10378           (neg:DI (match_dup 2)))
10379      (clobber (reg:CC FLAGS_REG))])]
10380   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10382 (define_expand "negdi2"
10383   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10384         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10385   ""
10386   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10388 (define_insn "*negdi2_1"
10389   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10390         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10391    (clobber (reg:CC FLAGS_REG))]
10392   "!TARGET_64BIT
10393    && ix86_unary_operator_ok (NEG, DImode, operands)"
10394   "#")
10396 (define_split
10397   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10398         (neg:DI (match_operand:DI 1 "general_operand" "")))
10399    (clobber (reg:CC FLAGS_REG))]
10400   "!TARGET_64BIT && reload_completed"
10401   [(parallel
10402     [(set (reg:CCZ FLAGS_REG)
10403           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10404      (set (match_dup 0) (neg:SI (match_dup 1)))])
10405    (parallel
10406     [(set (match_dup 2)
10407           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10408                             (match_dup 3))
10409                    (const_int 0)))
10410      (clobber (reg:CC FLAGS_REG))])
10411    (parallel
10412     [(set (match_dup 2)
10413           (neg:SI (match_dup 2)))
10414      (clobber (reg:CC FLAGS_REG))])]
10415   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10417 (define_insn "*negdi2_1_rex64"
10418   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10419         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10420    (clobber (reg:CC FLAGS_REG))]
10421   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10422   "neg{q}\t%0"
10423   [(set_attr "type" "negnot")
10424    (set_attr "mode" "DI")])
10426 ;; The problem with neg is that it does not perform (compare x 0),
10427 ;; it really performs (compare 0 x), which leaves us with the zero
10428 ;; flag being the only useful item.
10430 (define_insn "*negdi2_cmpz_rex64"
10431   [(set (reg:CCZ FLAGS_REG)
10432         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10433                      (const_int 0)))
10434    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10435         (neg:DI (match_dup 1)))]
10436   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10437   "neg{q}\t%0"
10438   [(set_attr "type" "negnot")
10439    (set_attr "mode" "DI")])
10442 (define_expand "negsi2"
10443   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10444         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10445   ""
10446   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10448 (define_insn "*negsi2_1"
10449   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10450         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10451    (clobber (reg:CC FLAGS_REG))]
10452   "ix86_unary_operator_ok (NEG, SImode, operands)"
10453   "neg{l}\t%0"
10454   [(set_attr "type" "negnot")
10455    (set_attr "mode" "SI")])
10457 ;; Combine is quite creative about this pattern.
10458 (define_insn "*negsi2_1_zext"
10459   [(set (match_operand:DI 0 "register_operand" "=r")
10460         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10461                                         (const_int 32)))
10462                      (const_int 32)))
10463    (clobber (reg:CC FLAGS_REG))]
10464   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10465   "neg{l}\t%k0"
10466   [(set_attr "type" "negnot")
10467    (set_attr "mode" "SI")])
10469 ;; The problem with neg is that it does not perform (compare x 0),
10470 ;; it really performs (compare 0 x), which leaves us with the zero
10471 ;; flag being the only useful item.
10473 (define_insn "*negsi2_cmpz"
10474   [(set (reg:CCZ FLAGS_REG)
10475         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10476                      (const_int 0)))
10477    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10478         (neg:SI (match_dup 1)))]
10479   "ix86_unary_operator_ok (NEG, SImode, operands)"
10480   "neg{l}\t%0"
10481   [(set_attr "type" "negnot")
10482    (set_attr "mode" "SI")])
10484 (define_insn "*negsi2_cmpz_zext"
10485   [(set (reg:CCZ FLAGS_REG)
10486         (compare:CCZ (lshiftrt:DI
10487                        (neg:DI (ashift:DI
10488                                  (match_operand:DI 1 "register_operand" "0")
10489                                  (const_int 32)))
10490                        (const_int 32))
10491                      (const_int 0)))
10492    (set (match_operand:DI 0 "register_operand" "=r")
10493         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10494                                         (const_int 32)))
10495                      (const_int 32)))]
10496   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10497   "neg{l}\t%k0"
10498   [(set_attr "type" "negnot")
10499    (set_attr "mode" "SI")])
10501 (define_expand "neghi2"
10502   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10503         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10504   "TARGET_HIMODE_MATH"
10505   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10507 (define_insn "*neghi2_1"
10508   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10509         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10510    (clobber (reg:CC FLAGS_REG))]
10511   "ix86_unary_operator_ok (NEG, HImode, operands)"
10512   "neg{w}\t%0"
10513   [(set_attr "type" "negnot")
10514    (set_attr "mode" "HI")])
10516 (define_insn "*neghi2_cmpz"
10517   [(set (reg:CCZ FLAGS_REG)
10518         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10519                      (const_int 0)))
10520    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10521         (neg:HI (match_dup 1)))]
10522   "ix86_unary_operator_ok (NEG, HImode, operands)"
10523   "neg{w}\t%0"
10524   [(set_attr "type" "negnot")
10525    (set_attr "mode" "HI")])
10527 (define_expand "negqi2"
10528   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10529         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10530   "TARGET_QIMODE_MATH"
10531   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10533 (define_insn "*negqi2_1"
10534   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10535         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10536    (clobber (reg:CC FLAGS_REG))]
10537   "ix86_unary_operator_ok (NEG, QImode, operands)"
10538   "neg{b}\t%0"
10539   [(set_attr "type" "negnot")
10540    (set_attr "mode" "QI")])
10542 (define_insn "*negqi2_cmpz"
10543   [(set (reg:CCZ FLAGS_REG)
10544         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10545                      (const_int 0)))
10546    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10547         (neg:QI (match_dup 1)))]
10548   "ix86_unary_operator_ok (NEG, QImode, operands)"
10549   "neg{b}\t%0"
10550   [(set_attr "type" "negnot")
10551    (set_attr "mode" "QI")])
10553 ;; Changing of sign for FP values is doable using integer unit too.
10555 (define_expand "<code><mode>2"
10556   [(set (match_operand:X87MODEF 0 "register_operand" "")
10557         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10558   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10559   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10561 (define_insn "*absneg<mode>2_mixed"
10562   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10563         (match_operator:MODEF 3 "absneg_operator"
10564           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10565    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10566    (clobber (reg:CC FLAGS_REG))]
10567   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10568   "#")
10570 (define_insn "*absneg<mode>2_sse"
10571   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10572         (match_operator:MODEF 3 "absneg_operator"
10573           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10574    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10575    (clobber (reg:CC FLAGS_REG))]
10576   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10577   "#")
10579 (define_insn "*absneg<mode>2_i387"
10580   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10581         (match_operator:X87MODEF 3 "absneg_operator"
10582           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10583    (use (match_operand 2 "" ""))
10584    (clobber (reg:CC FLAGS_REG))]
10585   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10586   "#")
10588 (define_expand "<code>tf2"
10589   [(set (match_operand:TF 0 "register_operand" "")
10590         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10591   "TARGET_SSE2"
10592   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10594 (define_insn "*absnegtf2_sse"
10595   [(set (match_operand:TF 0 "register_operand" "=x,x")
10596         (match_operator:TF 3 "absneg_operator"
10597           [(match_operand:TF 1 "register_operand" "0,x")]))
10598    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10599    (clobber (reg:CC FLAGS_REG))]
10600   "TARGET_SSE2"
10601   "#")
10603 ;; Splitters for fp abs and neg.
10605 (define_split
10606   [(set (match_operand 0 "fp_register_operand" "")
10607         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10608    (use (match_operand 2 "" ""))
10609    (clobber (reg:CC FLAGS_REG))]
10610   "reload_completed"
10611   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10613 (define_split
10614   [(set (match_operand 0 "register_operand" "")
10615         (match_operator 3 "absneg_operator"
10616           [(match_operand 1 "register_operand" "")]))
10617    (use (match_operand 2 "nonimmediate_operand" ""))
10618    (clobber (reg:CC FLAGS_REG))]
10619   "reload_completed && SSE_REG_P (operands[0])"
10620   [(set (match_dup 0) (match_dup 3))]
10622   enum machine_mode mode = GET_MODE (operands[0]);
10623   enum machine_mode vmode = GET_MODE (operands[2]);
10624   rtx tmp;
10626   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10627   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10628   if (operands_match_p (operands[0], operands[2]))
10629     {
10630       tmp = operands[1];
10631       operands[1] = operands[2];
10632       operands[2] = tmp;
10633     }
10634   if (GET_CODE (operands[3]) == ABS)
10635     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10636   else
10637     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10638   operands[3] = tmp;
10641 (define_split
10642   [(set (match_operand:SF 0 "register_operand" "")
10643         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10644    (use (match_operand:V4SF 2 "" ""))
10645    (clobber (reg:CC FLAGS_REG))]
10646   "reload_completed"
10647   [(parallel [(set (match_dup 0) (match_dup 1))
10648               (clobber (reg:CC FLAGS_REG))])]
10650   rtx tmp;
10651   operands[0] = gen_lowpart (SImode, operands[0]);
10652   if (GET_CODE (operands[1]) == ABS)
10653     {
10654       tmp = gen_int_mode (0x7fffffff, SImode);
10655       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10656     }
10657   else
10658     {
10659       tmp = gen_int_mode (0x80000000, SImode);
10660       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10661     }
10662   operands[1] = tmp;
10665 (define_split
10666   [(set (match_operand:DF 0 "register_operand" "")
10667         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10668    (use (match_operand 2 "" ""))
10669    (clobber (reg:CC FLAGS_REG))]
10670   "reload_completed"
10671   [(parallel [(set (match_dup 0) (match_dup 1))
10672               (clobber (reg:CC FLAGS_REG))])]
10674   rtx tmp;
10675   if (TARGET_64BIT)
10676     {
10677       tmp = gen_lowpart (DImode, operands[0]);
10678       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10679       operands[0] = tmp;
10681       if (GET_CODE (operands[1]) == ABS)
10682         tmp = const0_rtx;
10683       else
10684         tmp = gen_rtx_NOT (DImode, tmp);
10685     }
10686   else
10687     {
10688       operands[0] = gen_highpart (SImode, operands[0]);
10689       if (GET_CODE (operands[1]) == ABS)
10690         {
10691           tmp = gen_int_mode (0x7fffffff, SImode);
10692           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10693         }
10694       else
10695         {
10696           tmp = gen_int_mode (0x80000000, SImode);
10697           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10698         }
10699     }
10700   operands[1] = tmp;
10703 (define_split
10704   [(set (match_operand:XF 0 "register_operand" "")
10705         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10706    (use (match_operand 2 "" ""))
10707    (clobber (reg:CC FLAGS_REG))]
10708   "reload_completed"
10709   [(parallel [(set (match_dup 0) (match_dup 1))
10710               (clobber (reg:CC FLAGS_REG))])]
10712   rtx tmp;
10713   operands[0] = gen_rtx_REG (SImode,
10714                              true_regnum (operands[0])
10715                              + (TARGET_64BIT ? 1 : 2));
10716   if (GET_CODE (operands[1]) == ABS)
10717     {
10718       tmp = GEN_INT (0x7fff);
10719       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10720     }
10721   else
10722     {
10723       tmp = GEN_INT (0x8000);
10724       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10725     }
10726   operands[1] = tmp;
10729 ;; Conditionalize these after reload. If they match before reload, we
10730 ;; lose the clobber and ability to use integer instructions.
10732 (define_insn "*<code><mode>2_1"
10733   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10734         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10735   "TARGET_80387
10736    && (reload_completed
10737        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10738   "f<absnegprefix>"
10739   [(set_attr "type" "fsgn")
10740    (set_attr "mode" "<MODE>")])
10742 (define_insn "*<code>extendsfdf2"
10743   [(set (match_operand:DF 0 "register_operand" "=f")
10744         (absneg:DF (float_extend:DF
10745                      (match_operand:SF 1 "register_operand" "0"))))]
10746   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10747   "f<absnegprefix>"
10748   [(set_attr "type" "fsgn")
10749    (set_attr "mode" "DF")])
10751 (define_insn "*<code>extendsfxf2"
10752   [(set (match_operand:XF 0 "register_operand" "=f")
10753         (absneg:XF (float_extend:XF
10754                      (match_operand:SF 1 "register_operand" "0"))))]
10755   "TARGET_80387"
10756   "f<absnegprefix>"
10757   [(set_attr "type" "fsgn")
10758    (set_attr "mode" "XF")])
10760 (define_insn "*<code>extenddfxf2"
10761   [(set (match_operand:XF 0 "register_operand" "=f")
10762         (absneg:XF (float_extend:XF
10763                       (match_operand:DF 1 "register_operand" "0"))))]
10764   "TARGET_80387"
10765   "f<absnegprefix>"
10766   [(set_attr "type" "fsgn")
10767    (set_attr "mode" "XF")])
10769 ;; Copysign instructions
10771 (define_mode_iterator CSGNMODE [SF DF TF])
10772 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10774 (define_expand "copysign<mode>3"
10775   [(match_operand:CSGNMODE 0 "register_operand" "")
10776    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10777    (match_operand:CSGNMODE 2 "register_operand" "")]
10778   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10779    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10781   ix86_expand_copysign (operands);
10782   DONE;
10785 (define_insn_and_split "copysign<mode>3_const"
10786   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10787         (unspec:CSGNMODE
10788           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10789            (match_operand:CSGNMODE 2 "register_operand" "0")
10790            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10791           UNSPEC_COPYSIGN))]
10792   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10793    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10794   "#"
10795   "&& reload_completed"
10796   [(const_int 0)]
10798   ix86_split_copysign_const (operands);
10799   DONE;
10802 (define_insn "copysign<mode>3_var"
10803   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10804         (unspec:CSGNMODE
10805           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10806            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10807            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10808            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10809           UNSPEC_COPYSIGN))
10810    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10811   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10812    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10813   "#")
10815 (define_split
10816   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10817         (unspec:CSGNMODE
10818           [(match_operand:CSGNMODE 2 "register_operand" "")
10819            (match_operand:CSGNMODE 3 "register_operand" "")
10820            (match_operand:<CSGNVMODE> 4 "" "")
10821            (match_operand:<CSGNVMODE> 5 "" "")]
10822           UNSPEC_COPYSIGN))
10823    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10824   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10825     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10826    && reload_completed"
10827   [(const_int 0)]
10829   ix86_split_copysign_var (operands);
10830   DONE;
10833 ;; One complement instructions
10835 (define_expand "one_cmpldi2"
10836   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10837         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10838   "TARGET_64BIT"
10839   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10841 (define_insn "*one_cmpldi2_1_rex64"
10842   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10843         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10844   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10845   "not{q}\t%0"
10846   [(set_attr "type" "negnot")
10847    (set_attr "mode" "DI")])
10849 (define_insn "*one_cmpldi2_2_rex64"
10850   [(set (reg FLAGS_REG)
10851         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10852                  (const_int 0)))
10853    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10854         (not:DI (match_dup 1)))]
10855   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10856    && ix86_unary_operator_ok (NOT, DImode, operands)"
10857   "#"
10858   [(set_attr "type" "alu1")
10859    (set_attr "mode" "DI")])
10861 (define_split
10862   [(set (match_operand 0 "flags_reg_operand" "")
10863         (match_operator 2 "compare_operator"
10864           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10865            (const_int 0)]))
10866    (set (match_operand:DI 1 "nonimmediate_operand" "")
10867         (not:DI (match_dup 3)))]
10868   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10869   [(parallel [(set (match_dup 0)
10870                    (match_op_dup 2
10871                      [(xor:DI (match_dup 3) (const_int -1))
10872                       (const_int 0)]))
10873               (set (match_dup 1)
10874                    (xor:DI (match_dup 3) (const_int -1)))])]
10875   "")
10877 (define_expand "one_cmplsi2"
10878   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10879         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10880   ""
10881   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10883 (define_insn "*one_cmplsi2_1"
10884   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10885         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10886   "ix86_unary_operator_ok (NOT, SImode, operands)"
10887   "not{l}\t%0"
10888   [(set_attr "type" "negnot")
10889    (set_attr "mode" "SI")])
10891 ;; ??? Currently never generated - xor is used instead.
10892 (define_insn "*one_cmplsi2_1_zext"
10893   [(set (match_operand:DI 0 "register_operand" "=r")
10894         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10895   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10896   "not{l}\t%k0"
10897   [(set_attr "type" "negnot")
10898    (set_attr "mode" "SI")])
10900 (define_insn "*one_cmplsi2_2"
10901   [(set (reg FLAGS_REG)
10902         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10903                  (const_int 0)))
10904    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10905         (not:SI (match_dup 1)))]
10906   "ix86_match_ccmode (insn, CCNOmode)
10907    && ix86_unary_operator_ok (NOT, SImode, operands)"
10908   "#"
10909   [(set_attr "type" "alu1")
10910    (set_attr "mode" "SI")])
10912 (define_split
10913   [(set (match_operand 0 "flags_reg_operand" "")
10914         (match_operator 2 "compare_operator"
10915           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10916            (const_int 0)]))
10917    (set (match_operand:SI 1 "nonimmediate_operand" "")
10918         (not:SI (match_dup 3)))]
10919   "ix86_match_ccmode (insn, CCNOmode)"
10920   [(parallel [(set (match_dup 0)
10921                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10922                                     (const_int 0)]))
10923               (set (match_dup 1)
10924                    (xor:SI (match_dup 3) (const_int -1)))])]
10925   "")
10927 ;; ??? Currently never generated - xor is used instead.
10928 (define_insn "*one_cmplsi2_2_zext"
10929   [(set (reg FLAGS_REG)
10930         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10931                  (const_int 0)))
10932    (set (match_operand:DI 0 "register_operand" "=r")
10933         (zero_extend:DI (not:SI (match_dup 1))))]
10934   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10935    && ix86_unary_operator_ok (NOT, SImode, operands)"
10936   "#"
10937   [(set_attr "type" "alu1")
10938    (set_attr "mode" "SI")])
10940 (define_split
10941   [(set (match_operand 0 "flags_reg_operand" "")
10942         (match_operator 2 "compare_operator"
10943           [(not:SI (match_operand:SI 3 "register_operand" ""))
10944            (const_int 0)]))
10945    (set (match_operand:DI 1 "register_operand" "")
10946         (zero_extend:DI (not:SI (match_dup 3))))]
10947   "ix86_match_ccmode (insn, CCNOmode)"
10948   [(parallel [(set (match_dup 0)
10949                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10950                                     (const_int 0)]))
10951               (set (match_dup 1)
10952                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10953   "")
10955 (define_expand "one_cmplhi2"
10956   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10957         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10958   "TARGET_HIMODE_MATH"
10959   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10961 (define_insn "*one_cmplhi2_1"
10962   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10963         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10964   "ix86_unary_operator_ok (NOT, HImode, operands)"
10965   "not{w}\t%0"
10966   [(set_attr "type" "negnot")
10967    (set_attr "mode" "HI")])
10969 (define_insn "*one_cmplhi2_2"
10970   [(set (reg FLAGS_REG)
10971         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10972                  (const_int 0)))
10973    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10974         (not:HI (match_dup 1)))]
10975   "ix86_match_ccmode (insn, CCNOmode)
10976    && ix86_unary_operator_ok (NEG, HImode, operands)"
10977   "#"
10978   [(set_attr "type" "alu1")
10979    (set_attr "mode" "HI")])
10981 (define_split
10982   [(set (match_operand 0 "flags_reg_operand" "")
10983         (match_operator 2 "compare_operator"
10984           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10985            (const_int 0)]))
10986    (set (match_operand:HI 1 "nonimmediate_operand" "")
10987         (not:HI (match_dup 3)))]
10988   "ix86_match_ccmode (insn, CCNOmode)"
10989   [(parallel [(set (match_dup 0)
10990                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10991                                     (const_int 0)]))
10992               (set (match_dup 1)
10993                    (xor:HI (match_dup 3) (const_int -1)))])]
10994   "")
10996 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10997 (define_expand "one_cmplqi2"
10998   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10999         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11000   "TARGET_QIMODE_MATH"
11001   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11003 (define_insn "*one_cmplqi2_1"
11004   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11005         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11006   "ix86_unary_operator_ok (NOT, QImode, operands)"
11007   "@
11008    not{b}\t%0
11009    not{l}\t%k0"
11010   [(set_attr "type" "negnot")
11011    (set_attr "mode" "QI,SI")])
11013 (define_insn "*one_cmplqi2_2"
11014   [(set (reg FLAGS_REG)
11015         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11016                  (const_int 0)))
11017    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11018         (not:QI (match_dup 1)))]
11019   "ix86_match_ccmode (insn, CCNOmode)
11020    && ix86_unary_operator_ok (NOT, QImode, operands)"
11021   "#"
11022   [(set_attr "type" "alu1")
11023    (set_attr "mode" "QI")])
11025 (define_split
11026   [(set (match_operand 0 "flags_reg_operand" "")
11027         (match_operator 2 "compare_operator"
11028           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11029            (const_int 0)]))
11030    (set (match_operand:QI 1 "nonimmediate_operand" "")
11031         (not:QI (match_dup 3)))]
11032   "ix86_match_ccmode (insn, CCNOmode)"
11033   [(parallel [(set (match_dup 0)
11034                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11035                                     (const_int 0)]))
11036               (set (match_dup 1)
11037                    (xor:QI (match_dup 3) (const_int -1)))])]
11038   "")
11040 ;; Arithmetic shift instructions
11042 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11043 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
11044 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11045 ;; from the assembler input.
11047 ;; This instruction shifts the target reg/mem as usual, but instead of
11048 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
11049 ;; is a left shift double, bits are taken from the high order bits of
11050 ;; reg, else if the insn is a shift right double, bits are taken from the
11051 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
11052 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11054 ;; Since sh[lr]d does not change the `reg' operand, that is done
11055 ;; separately, making all shifts emit pairs of shift double and normal
11056 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
11057 ;; support a 63 bit shift, each shift where the count is in a reg expands
11058 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11060 ;; If the shift count is a constant, we need never emit more than one
11061 ;; shift pair, instead using moves and sign extension for counts greater
11062 ;; than 31.
11064 (define_expand "ashlti3"
11065   [(set (match_operand:TI 0 "register_operand" "")
11066         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11067                    (match_operand:QI 2 "nonmemory_operand" "")))]
11068   "TARGET_64BIT"
11069   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11071 ;; This pattern must be defined before *ashlti3_1 to prevent
11072 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11074 (define_insn "*avx_ashlti3"
11075   [(set (match_operand:TI 0 "register_operand" "=x")
11076         (ashift:TI (match_operand:TI 1 "register_operand" "x")
11077                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11078   "TARGET_AVX"
11080   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11081   return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11083   [(set_attr "type" "sseishft")
11084    (set_attr "prefix" "vex")
11085    (set_attr "mode" "TI")])
11087 (define_insn "sse2_ashlti3"
11088   [(set (match_operand:TI 0 "register_operand" "=x")
11089         (ashift:TI (match_operand:TI 1 "register_operand" "0")
11090                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11091   "TARGET_SSE2"
11093   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11094   return "pslldq\t{%2, %0|%0, %2}";
11096   [(set_attr "type" "sseishft")
11097    (set_attr "prefix_data16" "1")
11098    (set_attr "mode" "TI")])
11100 (define_insn "*ashlti3_1"
11101   [(set (match_operand:TI 0 "register_operand" "=&r,r")
11102         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11103                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11104    (clobber (reg:CC FLAGS_REG))]
11105   "TARGET_64BIT"
11106   "#"
11107   [(set_attr "type" "multi")])
11109 (define_peephole2
11110   [(match_scratch:DI 3 "r")
11111    (parallel [(set (match_operand:TI 0 "register_operand" "")
11112                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11113                               (match_operand:QI 2 "nonmemory_operand" "")))
11114               (clobber (reg:CC FLAGS_REG))])
11115    (match_dup 3)]
11116   "TARGET_64BIT"
11117   [(const_int 0)]
11118   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11120 (define_split
11121   [(set (match_operand:TI 0 "register_operand" "")
11122         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11123                    (match_operand:QI 2 "nonmemory_operand" "")))
11124    (clobber (reg:CC FLAGS_REG))]
11125   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11126                     ? epilogue_completed : reload_completed)"
11127   [(const_int 0)]
11128   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11130 (define_insn "x86_64_shld"
11131   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11132         (ior:DI (ashift:DI (match_dup 0)
11133                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11134                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11135                   (minus:QI (const_int 64) (match_dup 2)))))
11136    (clobber (reg:CC FLAGS_REG))]
11137   "TARGET_64BIT"
11138   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11139   [(set_attr "type" "ishift")
11140    (set_attr "prefix_0f" "1")
11141    (set_attr "mode" "DI")
11142    (set_attr "athlon_decode" "vector")
11143    (set_attr "amdfam10_decode" "vector")])
11145 (define_expand "x86_64_shift_adj_1"
11146   [(set (reg:CCZ FLAGS_REG)
11147         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11148                              (const_int 64))
11149                      (const_int 0)))
11150    (set (match_operand:DI 0 "register_operand" "")
11151         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11152                          (match_operand:DI 1 "register_operand" "")
11153                          (match_dup 0)))
11154    (set (match_dup 1)
11155         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11156                          (match_operand:DI 3 "register_operand" "r")
11157                          (match_dup 1)))]
11158   "TARGET_64BIT"
11159   "")
11161 (define_expand "x86_64_shift_adj_2"
11162   [(use (match_operand:DI 0 "register_operand" ""))
11163    (use (match_operand:DI 1 "register_operand" ""))
11164    (use (match_operand:QI 2 "register_operand" ""))]
11165   "TARGET_64BIT"
11167   rtx label = gen_label_rtx ();
11168   rtx tmp;
11170   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11172   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11173   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11174   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11175                               gen_rtx_LABEL_REF (VOIDmode, label),
11176                               pc_rtx);
11177   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11178   JUMP_LABEL (tmp) = label;
11180   emit_move_insn (operands[0], operands[1]);
11181   ix86_expand_clear (operands[1]);
11183   emit_label (label);
11184   LABEL_NUSES (label) = 1;
11186   DONE;
11189 (define_expand "ashldi3"
11190   [(set (match_operand:DI 0 "shiftdi_operand" "")
11191         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11192                    (match_operand:QI 2 "nonmemory_operand" "")))]
11193   ""
11194   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11196 (define_insn "*ashldi3_1_rex64"
11197   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11198         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11199                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11200    (clobber (reg:CC FLAGS_REG))]
11201   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11203   switch (get_attr_type (insn))
11204     {
11205     case TYPE_ALU:
11206       gcc_assert (operands[2] == const1_rtx);
11207       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11208       return "add{q}\t%0, %0";
11210     case TYPE_LEA:
11211       gcc_assert (CONST_INT_P (operands[2]));
11212       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11213       operands[1] = gen_rtx_MULT (DImode, operands[1],
11214                                   GEN_INT (1 << INTVAL (operands[2])));
11215       return "lea{q}\t{%a1, %0|%0, %a1}";
11217     default:
11218       if (REG_P (operands[2]))
11219         return "sal{q}\t{%b2, %0|%0, %b2}";
11220       else if (operands[2] == const1_rtx
11221                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11222         return "sal{q}\t%0";
11223       else
11224         return "sal{q}\t{%2, %0|%0, %2}";
11225     }
11227   [(set (attr "type")
11228      (cond [(eq_attr "alternative" "1")
11229               (const_string "lea")
11230             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11231                           (const_int 0))
11232                       (match_operand 0 "register_operand" ""))
11233                  (match_operand 2 "const1_operand" ""))
11234               (const_string "alu")
11235            ]
11236            (const_string "ishift")))
11237    (set_attr "mode" "DI")])
11239 ;; Convert lea to the lea pattern to avoid flags dependency.
11240 (define_split
11241   [(set (match_operand:DI 0 "register_operand" "")
11242         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11243                    (match_operand:QI 2 "immediate_operand" "")))
11244    (clobber (reg:CC FLAGS_REG))]
11245   "TARGET_64BIT && reload_completed
11246    && true_regnum (operands[0]) != true_regnum (operands[1])"
11247   [(set (match_dup 0)
11248         (mult:DI (match_dup 1)
11249                  (match_dup 2)))]
11250   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11252 ;; This pattern can't accept a variable shift count, since shifts by
11253 ;; zero don't affect the flags.  We assume that shifts by constant
11254 ;; zero are optimized away.
11255 (define_insn "*ashldi3_cmp_rex64"
11256   [(set (reg FLAGS_REG)
11257         (compare
11258           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11259                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11260           (const_int 0)))
11261    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11262         (ashift:DI (match_dup 1) (match_dup 2)))]
11263   "TARGET_64BIT
11264    && (optimize_function_for_size_p (cfun)
11265        || !TARGET_PARTIAL_FLAG_REG_STALL
11266        || (operands[2] == const1_rtx
11267            && (TARGET_SHIFT1
11268                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11269    && ix86_match_ccmode (insn, CCGOCmode)
11270    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11272   switch (get_attr_type (insn))
11273     {
11274     case TYPE_ALU:
11275       gcc_assert (operands[2] == const1_rtx);
11276       return "add{q}\t%0, %0";
11278     default:
11279       if (REG_P (operands[2]))
11280         return "sal{q}\t{%b2, %0|%0, %b2}";
11281       else if (operands[2] == const1_rtx
11282                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11283         return "sal{q}\t%0";
11284       else
11285         return "sal{q}\t{%2, %0|%0, %2}";
11286     }
11288   [(set (attr "type")
11289      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11290                           (const_int 0))
11291                       (match_operand 0 "register_operand" ""))
11292                  (match_operand 2 "const1_operand" ""))
11293               (const_string "alu")
11294            ]
11295            (const_string "ishift")))
11296    (set_attr "mode" "DI")])
11298 (define_insn "*ashldi3_cconly_rex64"
11299   [(set (reg FLAGS_REG)
11300         (compare
11301           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11302                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11303           (const_int 0)))
11304    (clobber (match_scratch:DI 0 "=r"))]
11305   "TARGET_64BIT
11306    && (optimize_function_for_size_p (cfun)
11307        || !TARGET_PARTIAL_FLAG_REG_STALL
11308        || (operands[2] == const1_rtx
11309            && (TARGET_SHIFT1
11310                || TARGET_DOUBLE_WITH_ADD)))
11311    && ix86_match_ccmode (insn, CCGOCmode)
11312    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11314   switch (get_attr_type (insn))
11315     {
11316     case TYPE_ALU:
11317       gcc_assert (operands[2] == const1_rtx);
11318       return "add{q}\t%0, %0";
11320     default:
11321       if (REG_P (operands[2]))
11322         return "sal{q}\t{%b2, %0|%0, %b2}";
11323       else if (operands[2] == const1_rtx
11324                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11325         return "sal{q}\t%0";
11326       else
11327         return "sal{q}\t{%2, %0|%0, %2}";
11328     }
11330   [(set (attr "type")
11331      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11332                           (const_int 0))
11333                       (match_operand 0 "register_operand" ""))
11334                  (match_operand 2 "const1_operand" ""))
11335               (const_string "alu")
11336            ]
11337            (const_string "ishift")))
11338    (set_attr "mode" "DI")])
11340 (define_insn "*ashldi3_1"
11341   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11342         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11343                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11344    (clobber (reg:CC FLAGS_REG))]
11345   "!TARGET_64BIT"
11346   "#"
11347   [(set_attr "type" "multi")])
11349 ;; By default we don't ask for a scratch register, because when DImode
11350 ;; values are manipulated, registers are already at a premium.  But if
11351 ;; we have one handy, we won't turn it away.
11352 (define_peephole2
11353   [(match_scratch:SI 3 "r")
11354    (parallel [(set (match_operand:DI 0 "register_operand" "")
11355                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11356                               (match_operand:QI 2 "nonmemory_operand" "")))
11357               (clobber (reg:CC FLAGS_REG))])
11358    (match_dup 3)]
11359   "!TARGET_64BIT && TARGET_CMOVE"
11360   [(const_int 0)]
11361   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11363 (define_split
11364   [(set (match_operand:DI 0 "register_operand" "")
11365         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11366                    (match_operand:QI 2 "nonmemory_operand" "")))
11367    (clobber (reg:CC FLAGS_REG))]
11368   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11369                      ? epilogue_completed : reload_completed)"
11370   [(const_int 0)]
11371   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11373 (define_insn "x86_shld"
11374   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11375         (ior:SI (ashift:SI (match_dup 0)
11376                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11377                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11378                   (minus:QI (const_int 32) (match_dup 2)))))
11379    (clobber (reg:CC FLAGS_REG))]
11380   ""
11381   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11382   [(set_attr "type" "ishift")
11383    (set_attr "prefix_0f" "1")
11384    (set_attr "mode" "SI")
11385    (set_attr "pent_pair" "np")
11386    (set_attr "athlon_decode" "vector")
11387    (set_attr "amdfam10_decode" "vector")])
11389 (define_expand "x86_shift_adj_1"
11390   [(set (reg:CCZ FLAGS_REG)
11391         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11392                              (const_int 32))
11393                      (const_int 0)))
11394    (set (match_operand:SI 0 "register_operand" "")
11395         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11396                          (match_operand:SI 1 "register_operand" "")
11397                          (match_dup 0)))
11398    (set (match_dup 1)
11399         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11400                          (match_operand:SI 3 "register_operand" "r")
11401                          (match_dup 1)))]
11402   "TARGET_CMOVE"
11403   "")
11405 (define_expand "x86_shift_adj_2"
11406   [(use (match_operand:SI 0 "register_operand" ""))
11407    (use (match_operand:SI 1 "register_operand" ""))
11408    (use (match_operand:QI 2 "register_operand" ""))]
11409   ""
11411   rtx label = gen_label_rtx ();
11412   rtx tmp;
11414   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11416   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11417   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11418   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11419                               gen_rtx_LABEL_REF (VOIDmode, label),
11420                               pc_rtx);
11421   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11422   JUMP_LABEL (tmp) = label;
11424   emit_move_insn (operands[0], operands[1]);
11425   ix86_expand_clear (operands[1]);
11427   emit_label (label);
11428   LABEL_NUSES (label) = 1;
11430   DONE;
11433 (define_expand "ashlsi3"
11434   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11435         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11436                    (match_operand:QI 2 "nonmemory_operand" "")))]
11437   ""
11438   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11440 (define_insn "*ashlsi3_1"
11441   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11442         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11443                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11444    (clobber (reg:CC FLAGS_REG))]
11445   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11447   switch (get_attr_type (insn))
11448     {
11449     case TYPE_ALU:
11450       gcc_assert (operands[2] == const1_rtx);
11451       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11452       return "add{l}\t%0, %0";
11454     case TYPE_LEA:
11455       return "#";
11457     default:
11458       if (REG_P (operands[2]))
11459         return "sal{l}\t{%b2, %0|%0, %b2}";
11460       else if (operands[2] == const1_rtx
11461                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11462         return "sal{l}\t%0";
11463       else
11464         return "sal{l}\t{%2, %0|%0, %2}";
11465     }
11467   [(set (attr "type")
11468      (cond [(eq_attr "alternative" "1")
11469               (const_string "lea")
11470             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11471                           (const_int 0))
11472                       (match_operand 0 "register_operand" ""))
11473                  (match_operand 2 "const1_operand" ""))
11474               (const_string "alu")
11475            ]
11476            (const_string "ishift")))
11477    (set_attr "mode" "SI")])
11479 ;; Convert lea to the lea pattern to avoid flags dependency.
11480 (define_split
11481   [(set (match_operand 0 "register_operand" "")
11482         (ashift (match_operand 1 "index_register_operand" "")
11483                 (match_operand:QI 2 "const_int_operand" "")))
11484    (clobber (reg:CC FLAGS_REG))]
11485   "reload_completed
11486    && true_regnum (operands[0]) != true_regnum (operands[1])
11487    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11488   [(const_int 0)]
11490   rtx pat;
11491   enum machine_mode mode = GET_MODE (operands[0]);
11493   if (GET_MODE_SIZE (mode) < 4)
11494     operands[0] = gen_lowpart (SImode, operands[0]);
11495   if (mode != Pmode)
11496     operands[1] = gen_lowpart (Pmode, operands[1]);
11497   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11499   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11500   if (Pmode != SImode)
11501     pat = gen_rtx_SUBREG (SImode, pat, 0);
11502   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11503   DONE;
11506 ;; Rare case of shifting RSP is handled by generating move and shift
11507 (define_split
11508   [(set (match_operand 0 "register_operand" "")
11509         (ashift (match_operand 1 "register_operand" "")
11510                 (match_operand:QI 2 "const_int_operand" "")))
11511    (clobber (reg:CC FLAGS_REG))]
11512   "reload_completed
11513    && true_regnum (operands[0]) != true_regnum (operands[1])"
11514   [(const_int 0)]
11516   rtx pat, clob;
11517   emit_move_insn (operands[0], operands[1]);
11518   pat = gen_rtx_SET (VOIDmode, operands[0],
11519                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11520                                      operands[0], operands[2]));
11521   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11522   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11523   DONE;
11526 (define_insn "*ashlsi3_1_zext"
11527   [(set (match_operand:DI 0 "register_operand" "=r,r")
11528         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11529                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11530    (clobber (reg:CC FLAGS_REG))]
11531   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11533   switch (get_attr_type (insn))
11534     {
11535     case TYPE_ALU:
11536       gcc_assert (operands[2] == const1_rtx);
11537       return "add{l}\t%k0, %k0";
11539     case TYPE_LEA:
11540       return "#";
11542     default:
11543       if (REG_P (operands[2]))
11544         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11545       else if (operands[2] == const1_rtx
11546                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11547         return "sal{l}\t%k0";
11548       else
11549         return "sal{l}\t{%2, %k0|%k0, %2}";
11550     }
11552   [(set (attr "type")
11553      (cond [(eq_attr "alternative" "1")
11554               (const_string "lea")
11555             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11556                      (const_int 0))
11557                  (match_operand 2 "const1_operand" ""))
11558               (const_string "alu")
11559            ]
11560            (const_string "ishift")))
11561    (set_attr "mode" "SI")])
11563 ;; Convert lea to the lea pattern to avoid flags dependency.
11564 (define_split
11565   [(set (match_operand:DI 0 "register_operand" "")
11566         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11567                                 (match_operand:QI 2 "const_int_operand" ""))))
11568    (clobber (reg:CC FLAGS_REG))]
11569   "TARGET_64BIT && reload_completed
11570    && true_regnum (operands[0]) != true_regnum (operands[1])"
11571   [(set (match_dup 0) (zero_extend:DI
11572                         (subreg:SI (mult:SI (match_dup 1)
11573                                             (match_dup 2)) 0)))]
11575   operands[1] = gen_lowpart (Pmode, operands[1]);
11576   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11579 ;; This pattern can't accept a variable shift count, since shifts by
11580 ;; zero don't affect the flags.  We assume that shifts by constant
11581 ;; zero are optimized away.
11582 (define_insn "*ashlsi3_cmp"
11583   [(set (reg FLAGS_REG)
11584         (compare
11585           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11586                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11587           (const_int 0)))
11588    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11589         (ashift:SI (match_dup 1) (match_dup 2)))]
11590    "(optimize_function_for_size_p (cfun)
11591      || !TARGET_PARTIAL_FLAG_REG_STALL
11592      || (operands[2] == const1_rtx
11593          && (TARGET_SHIFT1
11594              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11595    && ix86_match_ccmode (insn, CCGOCmode)
11596    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11598   switch (get_attr_type (insn))
11599     {
11600     case TYPE_ALU:
11601       gcc_assert (operands[2] == const1_rtx);
11602       return "add{l}\t%0, %0";
11604     default:
11605       if (REG_P (operands[2]))
11606         return "sal{l}\t{%b2, %0|%0, %b2}";
11607       else if (operands[2] == const1_rtx
11608                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11609         return "sal{l}\t%0";
11610       else
11611         return "sal{l}\t{%2, %0|%0, %2}";
11612     }
11614   [(set (attr "type")
11615      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11616                           (const_int 0))
11617                       (match_operand 0 "register_operand" ""))
11618                  (match_operand 2 "const1_operand" ""))
11619               (const_string "alu")
11620            ]
11621            (const_string "ishift")))
11622    (set_attr "mode" "SI")])
11624 (define_insn "*ashlsi3_cconly"
11625   [(set (reg FLAGS_REG)
11626         (compare
11627           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11628                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11629           (const_int 0)))
11630    (clobber (match_scratch:SI 0 "=r"))]
11631   "(optimize_function_for_size_p (cfun)
11632     || !TARGET_PARTIAL_FLAG_REG_STALL
11633     || (operands[2] == const1_rtx
11634         && (TARGET_SHIFT1
11635             || TARGET_DOUBLE_WITH_ADD)))
11636    && ix86_match_ccmode (insn, CCGOCmode)
11637    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11639   switch (get_attr_type (insn))
11640     {
11641     case TYPE_ALU:
11642       gcc_assert (operands[2] == const1_rtx);
11643       return "add{l}\t%0, %0";
11645     default:
11646       if (REG_P (operands[2]))
11647         return "sal{l}\t{%b2, %0|%0, %b2}";
11648       else if (operands[2] == const1_rtx
11649                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11650         return "sal{l}\t%0";
11651       else
11652         return "sal{l}\t{%2, %0|%0, %2}";
11653     }
11655   [(set (attr "type")
11656      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11657                           (const_int 0))
11658                       (match_operand 0 "register_operand" ""))
11659                  (match_operand 2 "const1_operand" ""))
11660               (const_string "alu")
11661            ]
11662            (const_string "ishift")))
11663    (set_attr "mode" "SI")])
11665 (define_insn "*ashlsi3_cmp_zext"
11666   [(set (reg FLAGS_REG)
11667         (compare
11668           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11669                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11670           (const_int 0)))
11671    (set (match_operand:DI 0 "register_operand" "=r")
11672         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11673   "TARGET_64BIT
11674    && (optimize_function_for_size_p (cfun)
11675        || !TARGET_PARTIAL_FLAG_REG_STALL
11676        || (operands[2] == const1_rtx
11677            && (TARGET_SHIFT1
11678                || TARGET_DOUBLE_WITH_ADD)))
11679    && ix86_match_ccmode (insn, CCGOCmode)
11680    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11682   switch (get_attr_type (insn))
11683     {
11684     case TYPE_ALU:
11685       gcc_assert (operands[2] == const1_rtx);
11686       return "add{l}\t%k0, %k0";
11688     default:
11689       if (REG_P (operands[2]))
11690         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11691       else if (operands[2] == const1_rtx
11692                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11693         return "sal{l}\t%k0";
11694       else
11695         return "sal{l}\t{%2, %k0|%k0, %2}";
11696     }
11698   [(set (attr "type")
11699      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11700                      (const_int 0))
11701                  (match_operand 2 "const1_operand" ""))
11702               (const_string "alu")
11703            ]
11704            (const_string "ishift")))
11705    (set_attr "mode" "SI")])
11707 (define_expand "ashlhi3"
11708   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11709         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11710                    (match_operand:QI 2 "nonmemory_operand" "")))]
11711   "TARGET_HIMODE_MATH"
11712   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11714 (define_insn "*ashlhi3_1_lea"
11715   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11716         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11717                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11718    (clobber (reg:CC FLAGS_REG))]
11719   "!TARGET_PARTIAL_REG_STALL
11720    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11722   switch (get_attr_type (insn))
11723     {
11724     case TYPE_LEA:
11725       return "#";
11726     case TYPE_ALU:
11727       gcc_assert (operands[2] == const1_rtx);
11728       return "add{w}\t%0, %0";
11730     default:
11731       if (REG_P (operands[2]))
11732         return "sal{w}\t{%b2, %0|%0, %b2}";
11733       else if (operands[2] == const1_rtx
11734                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11735         return "sal{w}\t%0";
11736       else
11737         return "sal{w}\t{%2, %0|%0, %2}";
11738     }
11740   [(set (attr "type")
11741      (cond [(eq_attr "alternative" "1")
11742               (const_string "lea")
11743             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11744                           (const_int 0))
11745                       (match_operand 0 "register_operand" ""))
11746                  (match_operand 2 "const1_operand" ""))
11747               (const_string "alu")
11748            ]
11749            (const_string "ishift")))
11750    (set_attr "mode" "HI,SI")])
11752 (define_insn "*ashlhi3_1"
11753   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11754         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11755                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11756    (clobber (reg:CC FLAGS_REG))]
11757   "TARGET_PARTIAL_REG_STALL
11758    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11760   switch (get_attr_type (insn))
11761     {
11762     case TYPE_ALU:
11763       gcc_assert (operands[2] == const1_rtx);
11764       return "add{w}\t%0, %0";
11766     default:
11767       if (REG_P (operands[2]))
11768         return "sal{w}\t{%b2, %0|%0, %b2}";
11769       else if (operands[2] == const1_rtx
11770                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11771         return "sal{w}\t%0";
11772       else
11773         return "sal{w}\t{%2, %0|%0, %2}";
11774     }
11776   [(set (attr "type")
11777      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11778                           (const_int 0))
11779                       (match_operand 0 "register_operand" ""))
11780                  (match_operand 2 "const1_operand" ""))
11781               (const_string "alu")
11782            ]
11783            (const_string "ishift")))
11784    (set_attr "mode" "HI")])
11786 ;; This pattern can't accept a variable shift count, since shifts by
11787 ;; zero don't affect the flags.  We assume that shifts by constant
11788 ;; zero are optimized away.
11789 (define_insn "*ashlhi3_cmp"
11790   [(set (reg FLAGS_REG)
11791         (compare
11792           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11793                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11794           (const_int 0)))
11795    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11796         (ashift:HI (match_dup 1) (match_dup 2)))]
11797   "(optimize_function_for_size_p (cfun)
11798     || !TARGET_PARTIAL_FLAG_REG_STALL
11799     || (operands[2] == const1_rtx
11800         && (TARGET_SHIFT1
11801             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11802    && ix86_match_ccmode (insn, CCGOCmode)
11803    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11805   switch (get_attr_type (insn))
11806     {
11807     case TYPE_ALU:
11808       gcc_assert (operands[2] == const1_rtx);
11809       return "add{w}\t%0, %0";
11811     default:
11812       if (REG_P (operands[2]))
11813         return "sal{w}\t{%b2, %0|%0, %b2}";
11814       else if (operands[2] == const1_rtx
11815                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11816         return "sal{w}\t%0";
11817       else
11818         return "sal{w}\t{%2, %0|%0, %2}";
11819     }
11821   [(set (attr "type")
11822      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11823                           (const_int 0))
11824                       (match_operand 0 "register_operand" ""))
11825                  (match_operand 2 "const1_operand" ""))
11826               (const_string "alu")
11827            ]
11828            (const_string "ishift")))
11829    (set_attr "mode" "HI")])
11831 (define_insn "*ashlhi3_cconly"
11832   [(set (reg FLAGS_REG)
11833         (compare
11834           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11835                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11836           (const_int 0)))
11837    (clobber (match_scratch:HI 0 "=r"))]
11838   "(optimize_function_for_size_p (cfun)
11839     || !TARGET_PARTIAL_FLAG_REG_STALL
11840     || (operands[2] == const1_rtx
11841         && (TARGET_SHIFT1
11842             || TARGET_DOUBLE_WITH_ADD)))
11843    && ix86_match_ccmode (insn, CCGOCmode)
11844    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11846   switch (get_attr_type (insn))
11847     {
11848     case TYPE_ALU:
11849       gcc_assert (operands[2] == const1_rtx);
11850       return "add{w}\t%0, %0";
11852     default:
11853       if (REG_P (operands[2]))
11854         return "sal{w}\t{%b2, %0|%0, %b2}";
11855       else if (operands[2] == const1_rtx
11856                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11857         return "sal{w}\t%0";
11858       else
11859         return "sal{w}\t{%2, %0|%0, %2}";
11860     }
11862   [(set (attr "type")
11863      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11864                           (const_int 0))
11865                       (match_operand 0 "register_operand" ""))
11866                  (match_operand 2 "const1_operand" ""))
11867               (const_string "alu")
11868            ]
11869            (const_string "ishift")))
11870    (set_attr "mode" "HI")])
11872 (define_expand "ashlqi3"
11873   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11874         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11875                    (match_operand:QI 2 "nonmemory_operand" "")))]
11876   "TARGET_QIMODE_MATH"
11877   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11879 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11881 (define_insn "*ashlqi3_1_lea"
11882   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11883         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11884                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11885    (clobber (reg:CC FLAGS_REG))]
11886   "!TARGET_PARTIAL_REG_STALL
11887    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11889   switch (get_attr_type (insn))
11890     {
11891     case TYPE_LEA:
11892       return "#";
11893     case TYPE_ALU:
11894       gcc_assert (operands[2] == const1_rtx);
11895       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11896         return "add{l}\t%k0, %k0";
11897       else
11898         return "add{b}\t%0, %0";
11900     default:
11901       if (REG_P (operands[2]))
11902         {
11903           if (get_attr_mode (insn) == MODE_SI)
11904             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11905           else
11906             return "sal{b}\t{%b2, %0|%0, %b2}";
11907         }
11908       else if (operands[2] == const1_rtx
11909                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11910         {
11911           if (get_attr_mode (insn) == MODE_SI)
11912             return "sal{l}\t%0";
11913           else
11914             return "sal{b}\t%0";
11915         }
11916       else
11917         {
11918           if (get_attr_mode (insn) == MODE_SI)
11919             return "sal{l}\t{%2, %k0|%k0, %2}";
11920           else
11921             return "sal{b}\t{%2, %0|%0, %2}";
11922         }
11923     }
11925   [(set (attr "type")
11926      (cond [(eq_attr "alternative" "2")
11927               (const_string "lea")
11928             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11929                           (const_int 0))
11930                       (match_operand 0 "register_operand" ""))
11931                  (match_operand 2 "const1_operand" ""))
11932               (const_string "alu")
11933            ]
11934            (const_string "ishift")))
11935    (set_attr "mode" "QI,SI,SI")])
11937 (define_insn "*ashlqi3_1"
11938   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11939         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11940                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11941    (clobber (reg:CC FLAGS_REG))]
11942   "TARGET_PARTIAL_REG_STALL
11943    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11945   switch (get_attr_type (insn))
11946     {
11947     case TYPE_ALU:
11948       gcc_assert (operands[2] == const1_rtx);
11949       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11950         return "add{l}\t%k0, %k0";
11951       else
11952         return "add{b}\t%0, %0";
11954     default:
11955       if (REG_P (operands[2]))
11956         {
11957           if (get_attr_mode (insn) == MODE_SI)
11958             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11959           else
11960             return "sal{b}\t{%b2, %0|%0, %b2}";
11961         }
11962       else if (operands[2] == const1_rtx
11963                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11964         {
11965           if (get_attr_mode (insn) == MODE_SI)
11966             return "sal{l}\t%0";
11967           else
11968             return "sal{b}\t%0";
11969         }
11970       else
11971         {
11972           if (get_attr_mode (insn) == MODE_SI)
11973             return "sal{l}\t{%2, %k0|%k0, %2}";
11974           else
11975             return "sal{b}\t{%2, %0|%0, %2}";
11976         }
11977     }
11979   [(set (attr "type")
11980      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11981                           (const_int 0))
11982                       (match_operand 0 "register_operand" ""))
11983                  (match_operand 2 "const1_operand" ""))
11984               (const_string "alu")
11985            ]
11986            (const_string "ishift")))
11987    (set_attr "mode" "QI,SI")])
11989 ;; This pattern can't accept a variable shift count, since shifts by
11990 ;; zero don't affect the flags.  We assume that shifts by constant
11991 ;; zero are optimized away.
11992 (define_insn "*ashlqi3_cmp"
11993   [(set (reg FLAGS_REG)
11994         (compare
11995           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11996                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11997           (const_int 0)))
11998    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11999         (ashift:QI (match_dup 1) (match_dup 2)))]
12000   "(optimize_function_for_size_p (cfun)
12001     || !TARGET_PARTIAL_FLAG_REG_STALL
12002     || (operands[2] == const1_rtx
12003         && (TARGET_SHIFT1
12004             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12005    && ix86_match_ccmode (insn, CCGOCmode)
12006    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12008   switch (get_attr_type (insn))
12009     {
12010     case TYPE_ALU:
12011       gcc_assert (operands[2] == const1_rtx);
12012       return "add{b}\t%0, %0";
12014     default:
12015       if (REG_P (operands[2]))
12016         return "sal{b}\t{%b2, %0|%0, %b2}";
12017       else if (operands[2] == const1_rtx
12018                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12019         return "sal{b}\t%0";
12020       else
12021         return "sal{b}\t{%2, %0|%0, %2}";
12022     }
12024   [(set (attr "type")
12025      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12026                           (const_int 0))
12027                       (match_operand 0 "register_operand" ""))
12028                  (match_operand 2 "const1_operand" ""))
12029               (const_string "alu")
12030            ]
12031            (const_string "ishift")))
12032    (set_attr "mode" "QI")])
12034 (define_insn "*ashlqi3_cconly"
12035   [(set (reg FLAGS_REG)
12036         (compare
12037           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12038                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12039           (const_int 0)))
12040    (clobber (match_scratch:QI 0 "=q"))]
12041   "(optimize_function_for_size_p (cfun)
12042     || !TARGET_PARTIAL_FLAG_REG_STALL
12043     || (operands[2] == const1_rtx
12044         && (TARGET_SHIFT1
12045             || TARGET_DOUBLE_WITH_ADD)))
12046    && ix86_match_ccmode (insn, CCGOCmode)
12047    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12049   switch (get_attr_type (insn))
12050     {
12051     case TYPE_ALU:
12052       gcc_assert (operands[2] == const1_rtx);
12053       return "add{b}\t%0, %0";
12055     default:
12056       if (REG_P (operands[2]))
12057         return "sal{b}\t{%b2, %0|%0, %b2}";
12058       else if (operands[2] == const1_rtx
12059                && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12060         return "sal{b}\t%0";
12061       else
12062         return "sal{b}\t{%2, %0|%0, %2}";
12063     }
12065   [(set (attr "type")
12066      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12067                           (const_int 0))
12068                       (match_operand 0 "register_operand" ""))
12069                  (match_operand 2 "const1_operand" ""))
12070               (const_string "alu")
12071            ]
12072            (const_string "ishift")))
12073    (set_attr "mode" "QI")])
12075 ;; See comment above `ashldi3' about how this works.
12077 (define_expand "ashrti3"
12078   [(set (match_operand:TI 0 "register_operand" "")
12079         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12080                      (match_operand:QI 2 "nonmemory_operand" "")))]
12081   "TARGET_64BIT"
12082   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12084 (define_insn "*ashrti3_1"
12085   [(set (match_operand:TI 0 "register_operand" "=r")
12086         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12087                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12088    (clobber (reg:CC FLAGS_REG))]
12089   "TARGET_64BIT"
12090   "#"
12091   [(set_attr "type" "multi")])
12093 (define_peephole2
12094   [(match_scratch:DI 3 "r")
12095    (parallel [(set (match_operand:TI 0 "register_operand" "")
12096                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12097                                 (match_operand:QI 2 "nonmemory_operand" "")))
12098               (clobber (reg:CC FLAGS_REG))])
12099    (match_dup 3)]
12100   "TARGET_64BIT"
12101   [(const_int 0)]
12102   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12104 (define_split
12105   [(set (match_operand:TI 0 "register_operand" "")
12106         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12107                      (match_operand:QI 2 "nonmemory_operand" "")))
12108    (clobber (reg:CC FLAGS_REG))]
12109   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12110                     ? epilogue_completed : reload_completed)"
12111   [(const_int 0)]
12112   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12114 (define_insn "x86_64_shrd"
12115   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12116         (ior:DI (ashiftrt:DI (match_dup 0)
12117                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
12118                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12119                   (minus:QI (const_int 64) (match_dup 2)))))
12120    (clobber (reg:CC FLAGS_REG))]
12121   "TARGET_64BIT"
12122   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12123   [(set_attr "type" "ishift")
12124    (set_attr "prefix_0f" "1")
12125    (set_attr "mode" "DI")
12126    (set_attr "athlon_decode" "vector")
12127    (set_attr "amdfam10_decode" "vector")])
12129 (define_expand "ashrdi3"
12130   [(set (match_operand:DI 0 "shiftdi_operand" "")
12131         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12132                      (match_operand:QI 2 "nonmemory_operand" "")))]
12133   ""
12134   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12136 (define_expand "x86_64_shift_adj_3"
12137   [(use (match_operand:DI 0 "register_operand" ""))
12138    (use (match_operand:DI 1 "register_operand" ""))
12139    (use (match_operand:QI 2 "register_operand" ""))]
12140   ""
12142   rtx label = gen_label_rtx ();
12143   rtx tmp;
12145   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12147   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12148   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12149   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12150                               gen_rtx_LABEL_REF (VOIDmode, label),
12151                               pc_rtx);
12152   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12153   JUMP_LABEL (tmp) = label;
12155   emit_move_insn (operands[0], operands[1]);
12156   emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12158   emit_label (label);
12159   LABEL_NUSES (label) = 1;
12161   DONE;
12164 (define_insn "ashrdi3_63_rex64"
12165   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12166         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12167                      (match_operand:DI 2 "const_int_operand" "i,i")))
12168    (clobber (reg:CC FLAGS_REG))]
12169   "TARGET_64BIT && INTVAL (operands[2]) == 63
12170    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12171    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12172   "@
12173    {cqto|cqo}
12174    sar{q}\t{%2, %0|%0, %2}"
12175   [(set_attr "type" "imovx,ishift")
12176    (set_attr "prefix_0f" "0,*")
12177    (set_attr "length_immediate" "0,*")
12178    (set_attr "modrm" "0,1")
12179    (set_attr "mode" "DI")])
12181 (define_insn "*ashrdi3_1_one_bit_rex64"
12182   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12183         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12184                      (match_operand:QI 2 "const1_operand" "")))
12185    (clobber (reg:CC FLAGS_REG))]
12186   "TARGET_64BIT
12187    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12188    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12189   "sar{q}\t%0"
12190   [(set_attr "type" "ishift")
12191    (set (attr "length")
12192      (if_then_else (match_operand:DI 0 "register_operand" "")
12193         (const_string "2")
12194         (const_string "*")))])
12196 (define_insn "*ashrdi3_1_rex64"
12197   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12198         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12199                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12200    (clobber (reg:CC FLAGS_REG))]
12201   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12202   "@
12203    sar{q}\t{%2, %0|%0, %2}
12204    sar{q}\t{%b2, %0|%0, %b2}"
12205   [(set_attr "type" "ishift")
12206    (set_attr "mode" "DI")])
12208 ;; This pattern can't accept a variable shift count, since shifts by
12209 ;; zero don't affect the flags.  We assume that shifts by constant
12210 ;; zero are optimized away.
12211 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12212   [(set (reg FLAGS_REG)
12213         (compare
12214           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12215                        (match_operand:QI 2 "const1_operand" ""))
12216           (const_int 0)))
12217    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12218         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12219   "TARGET_64BIT
12220    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12221    && ix86_match_ccmode (insn, CCGOCmode)
12222    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12223   "sar{q}\t%0"
12224   [(set_attr "type" "ishift")
12225    (set (attr "length")
12226      (if_then_else (match_operand:DI 0 "register_operand" "")
12227         (const_string "2")
12228         (const_string "*")))])
12230 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12231   [(set (reg FLAGS_REG)
12232         (compare
12233           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12234                        (match_operand:QI 2 "const1_operand" ""))
12235           (const_int 0)))
12236    (clobber (match_scratch:DI 0 "=r"))]
12237   "TARGET_64BIT
12238    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12239    && ix86_match_ccmode (insn, CCGOCmode)
12240    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12241   "sar{q}\t%0"
12242   [(set_attr "type" "ishift")
12243    (set_attr "length" "2")])
12245 ;; This pattern can't accept a variable shift count, since shifts by
12246 ;; zero don't affect the flags.  We assume that shifts by constant
12247 ;; zero are optimized away.
12248 (define_insn "*ashrdi3_cmp_rex64"
12249   [(set (reg FLAGS_REG)
12250         (compare
12251           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12252                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12253           (const_int 0)))
12254    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12255         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12256   "TARGET_64BIT
12257    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12258    && ix86_match_ccmode (insn, CCGOCmode)
12259    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12260   "sar{q}\t{%2, %0|%0, %2}"
12261   [(set_attr "type" "ishift")
12262    (set_attr "mode" "DI")])
12264 (define_insn "*ashrdi3_cconly_rex64"
12265   [(set (reg FLAGS_REG)
12266         (compare
12267           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12268                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12269           (const_int 0)))
12270    (clobber (match_scratch:DI 0 "=r"))]
12271   "TARGET_64BIT
12272    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12273    && ix86_match_ccmode (insn, CCGOCmode)
12274    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12275   "sar{q}\t{%2, %0|%0, %2}"
12276   [(set_attr "type" "ishift")
12277    (set_attr "mode" "DI")])
12279 (define_insn "*ashrdi3_1"
12280   [(set (match_operand:DI 0 "register_operand" "=r")
12281         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12282                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12283    (clobber (reg:CC FLAGS_REG))]
12284   "!TARGET_64BIT"
12285   "#"
12286   [(set_attr "type" "multi")])
12288 ;; By default we don't ask for a scratch register, because when DImode
12289 ;; values are manipulated, registers are already at a premium.  But if
12290 ;; we have one handy, we won't turn it away.
12291 (define_peephole2
12292   [(match_scratch:SI 3 "r")
12293    (parallel [(set (match_operand:DI 0 "register_operand" "")
12294                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12295                                 (match_operand:QI 2 "nonmemory_operand" "")))
12296               (clobber (reg:CC FLAGS_REG))])
12297    (match_dup 3)]
12298   "!TARGET_64BIT && TARGET_CMOVE"
12299   [(const_int 0)]
12300   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12302 (define_split
12303   [(set (match_operand:DI 0 "register_operand" "")
12304         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12305                      (match_operand:QI 2 "nonmemory_operand" "")))
12306    (clobber (reg:CC FLAGS_REG))]
12307   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12308                      ? epilogue_completed : reload_completed)"
12309   [(const_int 0)]
12310   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12312 (define_insn "x86_shrd"
12313   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12314         (ior:SI (ashiftrt:SI (match_dup 0)
12315                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
12316                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12317                   (minus:QI (const_int 32) (match_dup 2)))))
12318    (clobber (reg:CC FLAGS_REG))]
12319   ""
12320   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12321   [(set_attr "type" "ishift")
12322    (set_attr "prefix_0f" "1")
12323    (set_attr "pent_pair" "np")
12324    (set_attr "mode" "SI")])
12326 (define_expand "x86_shift_adj_3"
12327   [(use (match_operand:SI 0 "register_operand" ""))
12328    (use (match_operand:SI 1 "register_operand" ""))
12329    (use (match_operand:QI 2 "register_operand" ""))]
12330   ""
12332   rtx label = gen_label_rtx ();
12333   rtx tmp;
12335   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12337   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12338   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12339   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12340                               gen_rtx_LABEL_REF (VOIDmode, label),
12341                               pc_rtx);
12342   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12343   JUMP_LABEL (tmp) = label;
12345   emit_move_insn (operands[0], operands[1]);
12346   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12348   emit_label (label);
12349   LABEL_NUSES (label) = 1;
12351   DONE;
12354 (define_expand "ashrsi3_31"
12355   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12356                    (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12357                                 (match_operand:SI 2 "const_int_operand" "i,i")))
12358               (clobber (reg:CC FLAGS_REG))])]
12359   "")
12361 (define_insn "*ashrsi3_31"
12362   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12363         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12364                      (match_operand:SI 2 "const_int_operand" "i,i")))
12365    (clobber (reg:CC FLAGS_REG))]
12366   "INTVAL (operands[2]) == 31
12367    && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12368    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12369   "@
12370    {cltd|cdq}
12371    sar{l}\t{%2, %0|%0, %2}"
12372   [(set_attr "type" "imovx,ishift")
12373    (set_attr "prefix_0f" "0,*")
12374    (set_attr "length_immediate" "0,*")
12375    (set_attr "modrm" "0,1")
12376    (set_attr "mode" "SI")])
12378 (define_insn "*ashrsi3_31_zext"
12379   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12380         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12381                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12382    (clobber (reg:CC FLAGS_REG))]
12383   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12384    && INTVAL (operands[2]) == 31
12385    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12386   "@
12387    {cltd|cdq}
12388    sar{l}\t{%2, %k0|%k0, %2}"
12389   [(set_attr "type" "imovx,ishift")
12390    (set_attr "prefix_0f" "0,*")
12391    (set_attr "length_immediate" "0,*")
12392    (set_attr "modrm" "0,1")
12393    (set_attr "mode" "SI")])
12395 (define_expand "ashrsi3"
12396   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12397         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12398                      (match_operand:QI 2 "nonmemory_operand" "")))]
12399   ""
12400   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12402 (define_insn "*ashrsi3_1_one_bit"
12403   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12404         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12405                      (match_operand:QI 2 "const1_operand" "")))
12406    (clobber (reg:CC FLAGS_REG))]
12407   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12408    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12409   "sar{l}\t%0"
12410   [(set_attr "type" "ishift")
12411    (set (attr "length")
12412      (if_then_else (match_operand:SI 0 "register_operand" "")
12413         (const_string "2")
12414         (const_string "*")))])
12416 (define_insn "*ashrsi3_1_one_bit_zext"
12417   [(set (match_operand:DI 0 "register_operand" "=r")
12418         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12419                                      (match_operand:QI 2 "const1_operand" ""))))
12420    (clobber (reg:CC FLAGS_REG))]
12421   "TARGET_64BIT
12422    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12423    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12424   "sar{l}\t%k0"
12425   [(set_attr "type" "ishift")
12426    (set_attr "length" "2")])
12428 (define_insn "*ashrsi3_1"
12429   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12430         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12431                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12432    (clobber (reg:CC FLAGS_REG))]
12433   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12434   "@
12435    sar{l}\t{%2, %0|%0, %2}
12436    sar{l}\t{%b2, %0|%0, %b2}"
12437   [(set_attr "type" "ishift")
12438    (set_attr "mode" "SI")])
12440 (define_insn "*ashrsi3_1_zext"
12441   [(set (match_operand:DI 0 "register_operand" "=r,r")
12442         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12443                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12444    (clobber (reg:CC FLAGS_REG))]
12445   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12446   "@
12447    sar{l}\t{%2, %k0|%k0, %2}
12448    sar{l}\t{%b2, %k0|%k0, %b2}"
12449   [(set_attr "type" "ishift")
12450    (set_attr "mode" "SI")])
12452 ;; This pattern can't accept a variable shift count, since shifts by
12453 ;; zero don't affect the flags.  We assume that shifts by constant
12454 ;; zero are optimized away.
12455 (define_insn "*ashrsi3_one_bit_cmp"
12456   [(set (reg FLAGS_REG)
12457         (compare
12458           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12459                        (match_operand:QI 2 "const1_operand" ""))
12460           (const_int 0)))
12461    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12462         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12463   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12464    && ix86_match_ccmode (insn, CCGOCmode)
12465    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12466   "sar{l}\t%0"
12467   [(set_attr "type" "ishift")
12468    (set (attr "length")
12469      (if_then_else (match_operand:SI 0 "register_operand" "")
12470         (const_string "2")
12471         (const_string "*")))])
12473 (define_insn "*ashrsi3_one_bit_cconly"
12474   [(set (reg FLAGS_REG)
12475         (compare
12476           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12477                        (match_operand:QI 2 "const1_operand" ""))
12478           (const_int 0)))
12479    (clobber (match_scratch:SI 0 "=r"))]
12480   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12481    && ix86_match_ccmode (insn, CCGOCmode)
12482    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12483   "sar{l}\t%0"
12484   [(set_attr "type" "ishift")
12485    (set_attr "length" "2")])
12487 (define_insn "*ashrsi3_one_bit_cmp_zext"
12488   [(set (reg FLAGS_REG)
12489         (compare
12490           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12491                        (match_operand:QI 2 "const1_operand" ""))
12492           (const_int 0)))
12493    (set (match_operand:DI 0 "register_operand" "=r")
12494         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12495   "TARGET_64BIT
12496    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12497    && ix86_match_ccmode (insn, CCmode)
12498    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12499   "sar{l}\t%k0"
12500   [(set_attr "type" "ishift")
12501    (set_attr "length" "2")])
12503 ;; This pattern can't accept a variable shift count, since shifts by
12504 ;; zero don't affect the flags.  We assume that shifts by constant
12505 ;; zero are optimized away.
12506 (define_insn "*ashrsi3_cmp"
12507   [(set (reg FLAGS_REG)
12508         (compare
12509           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12510                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12511           (const_int 0)))
12512    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12513         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12514   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12515    && ix86_match_ccmode (insn, CCGOCmode)
12516    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12517   "sar{l}\t{%2, %0|%0, %2}"
12518   [(set_attr "type" "ishift")
12519    (set_attr "mode" "SI")])
12521 (define_insn "*ashrsi3_cconly"
12522   [(set (reg FLAGS_REG)
12523         (compare
12524           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12525                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12526           (const_int 0)))
12527    (clobber (match_scratch:SI 0 "=r"))]
12528   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12529    && ix86_match_ccmode (insn, CCGOCmode)
12530    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12531   "sar{l}\t{%2, %0|%0, %2}"
12532   [(set_attr "type" "ishift")
12533    (set_attr "mode" "SI")])
12535 (define_insn "*ashrsi3_cmp_zext"
12536   [(set (reg FLAGS_REG)
12537         (compare
12538           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12539                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12540           (const_int 0)))
12541    (set (match_operand:DI 0 "register_operand" "=r")
12542         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12543   "TARGET_64BIT
12544    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12545    && ix86_match_ccmode (insn, CCGOCmode)
12546    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12547   "sar{l}\t{%2, %k0|%k0, %2}"
12548   [(set_attr "type" "ishift")
12549    (set_attr "mode" "SI")])
12551 (define_expand "ashrhi3"
12552   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12553         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12554                      (match_operand:QI 2 "nonmemory_operand" "")))]
12555   "TARGET_HIMODE_MATH"
12556   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12558 (define_insn "*ashrhi3_1_one_bit"
12559   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12560         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12561                      (match_operand:QI 2 "const1_operand" "")))
12562    (clobber (reg:CC FLAGS_REG))]
12563   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12564    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12565   "sar{w}\t%0"
12566   [(set_attr "type" "ishift")
12567    (set (attr "length")
12568      (if_then_else (match_operand 0 "register_operand" "")
12569         (const_string "2")
12570         (const_string "*")))])
12572 (define_insn "*ashrhi3_1"
12573   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12574         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12575                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12576    (clobber (reg:CC FLAGS_REG))]
12577   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12578   "@
12579    sar{w}\t{%2, %0|%0, %2}
12580    sar{w}\t{%b2, %0|%0, %b2}"
12581   [(set_attr "type" "ishift")
12582    (set_attr "mode" "HI")])
12584 ;; This pattern can't accept a variable shift count, since shifts by
12585 ;; zero don't affect the flags.  We assume that shifts by constant
12586 ;; zero are optimized away.
12587 (define_insn "*ashrhi3_one_bit_cmp"
12588   [(set (reg FLAGS_REG)
12589         (compare
12590           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12591                        (match_operand:QI 2 "const1_operand" ""))
12592           (const_int 0)))
12593    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12594         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12595   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12596    && ix86_match_ccmode (insn, CCGOCmode)
12597    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12598   "sar{w}\t%0"
12599   [(set_attr "type" "ishift")
12600    (set (attr "length")
12601      (if_then_else (match_operand 0 "register_operand" "")
12602         (const_string "2")
12603         (const_string "*")))])
12605 (define_insn "*ashrhi3_one_bit_cconly"
12606   [(set (reg FLAGS_REG)
12607         (compare
12608           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12609                        (match_operand:QI 2 "const1_operand" ""))
12610           (const_int 0)))
12611    (clobber (match_scratch:HI 0 "=r"))]
12612   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12613    && ix86_match_ccmode (insn, CCGOCmode)
12614    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12615   "sar{w}\t%0"
12616   [(set_attr "type" "ishift")
12617    (set_attr "length" "2")])
12619 ;; This pattern can't accept a variable shift count, since shifts by
12620 ;; zero don't affect the flags.  We assume that shifts by constant
12621 ;; zero are optimized away.
12622 (define_insn "*ashrhi3_cmp"
12623   [(set (reg FLAGS_REG)
12624         (compare
12625           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12626                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12627           (const_int 0)))
12628    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12629         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12630   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12631    && ix86_match_ccmode (insn, CCGOCmode)
12632    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12633   "sar{w}\t{%2, %0|%0, %2}"
12634   [(set_attr "type" "ishift")
12635    (set_attr "mode" "HI")])
12637 (define_insn "*ashrhi3_cconly"
12638   [(set (reg FLAGS_REG)
12639         (compare
12640           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12641                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12642           (const_int 0)))
12643    (clobber (match_scratch:HI 0 "=r"))]
12644   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12645    && ix86_match_ccmode (insn, CCGOCmode)
12646    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12647   "sar{w}\t{%2, %0|%0, %2}"
12648   [(set_attr "type" "ishift")
12649    (set_attr "mode" "HI")])
12651 (define_expand "ashrqi3"
12652   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12653         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12654                      (match_operand:QI 2 "nonmemory_operand" "")))]
12655   "TARGET_QIMODE_MATH"
12656   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12658 (define_insn "*ashrqi3_1_one_bit"
12659   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12660         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12661                      (match_operand:QI 2 "const1_operand" "")))
12662    (clobber (reg:CC FLAGS_REG))]
12663   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12664    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12665   "sar{b}\t%0"
12666   [(set_attr "type" "ishift")
12667    (set (attr "length")
12668      (if_then_else (match_operand 0 "register_operand" "")
12669         (const_string "2")
12670         (const_string "*")))])
12672 (define_insn "*ashrqi3_1_one_bit_slp"
12673   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12674         (ashiftrt:QI (match_dup 0)
12675                      (match_operand:QI 1 "const1_operand" "")))
12676    (clobber (reg:CC FLAGS_REG))]
12677   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12678    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12679    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12680   "sar{b}\t%0"
12681   [(set_attr "type" "ishift1")
12682    (set (attr "length")
12683      (if_then_else (match_operand 0 "register_operand" "")
12684         (const_string "2")
12685         (const_string "*")))])
12687 (define_insn "*ashrqi3_1"
12688   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12689         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12690                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12691    (clobber (reg:CC FLAGS_REG))]
12692   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12693   "@
12694    sar{b}\t{%2, %0|%0, %2}
12695    sar{b}\t{%b2, %0|%0, %b2}"
12696   [(set_attr "type" "ishift")
12697    (set_attr "mode" "QI")])
12699 (define_insn "*ashrqi3_1_slp"
12700   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12701         (ashiftrt:QI (match_dup 0)
12702                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12703    (clobber (reg:CC FLAGS_REG))]
12704   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12705    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12706   "@
12707    sar{b}\t{%1, %0|%0, %1}
12708    sar{b}\t{%b1, %0|%0, %b1}"
12709   [(set_attr "type" "ishift1")
12710    (set_attr "mode" "QI")])
12712 ;; This pattern can't accept a variable shift count, since shifts by
12713 ;; zero don't affect the flags.  We assume that shifts by constant
12714 ;; zero are optimized away.
12715 (define_insn "*ashrqi3_one_bit_cmp"
12716   [(set (reg FLAGS_REG)
12717         (compare
12718           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12719                        (match_operand:QI 2 "const1_operand" "I"))
12720           (const_int 0)))
12721    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12722         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12723   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12724    && ix86_match_ccmode (insn, CCGOCmode)
12725    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12726   "sar{b}\t%0"
12727   [(set_attr "type" "ishift")
12728    (set (attr "length")
12729      (if_then_else (match_operand 0 "register_operand" "")
12730         (const_string "2")
12731         (const_string "*")))])
12733 (define_insn "*ashrqi3_one_bit_cconly"
12734   [(set (reg FLAGS_REG)
12735         (compare
12736           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12737                        (match_operand:QI 2 "const1_operand" ""))
12738           (const_int 0)))
12739    (clobber (match_scratch:QI 0 "=q"))]
12740   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12741    && ix86_match_ccmode (insn, CCGOCmode)
12742    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12743   "sar{b}\t%0"
12744   [(set_attr "type" "ishift")
12745    (set_attr "length" "2")])
12747 ;; This pattern can't accept a variable shift count, since shifts by
12748 ;; zero don't affect the flags.  We assume that shifts by constant
12749 ;; zero are optimized away.
12750 (define_insn "*ashrqi3_cmp"
12751   [(set (reg FLAGS_REG)
12752         (compare
12753           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12754                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12755           (const_int 0)))
12756    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12757         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12758   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12759    && ix86_match_ccmode (insn, CCGOCmode)
12760    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12761   "sar{b}\t{%2, %0|%0, %2}"
12762   [(set_attr "type" "ishift")
12763    (set_attr "mode" "QI")])
12765 (define_insn "*ashrqi3_cconly"
12766   [(set (reg FLAGS_REG)
12767         (compare
12768           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12769                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12770           (const_int 0)))
12771    (clobber (match_scratch:QI 0 "=q"))]
12772   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12773    && ix86_match_ccmode (insn, CCGOCmode)
12774    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12775   "sar{b}\t{%2, %0|%0, %2}"
12776   [(set_attr "type" "ishift")
12777    (set_attr "mode" "QI")])
12780 ;; Logical shift instructions
12782 ;; See comment above `ashldi3' about how this works.
12784 (define_expand "lshrti3"
12785   [(set (match_operand:TI 0 "register_operand" "")
12786         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12787                      (match_operand:QI 2 "nonmemory_operand" "")))]
12788   "TARGET_64BIT"
12789   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12791 ;; This pattern must be defined before *lshrti3_1 to prevent
12792 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12794 (define_insn "*avx_lshrti3"
12795   [(set (match_operand:TI 0 "register_operand" "=x")
12796         (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12797                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12798   "TARGET_AVX"
12800   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12801   return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12803   [(set_attr "type" "sseishft")
12804    (set_attr "prefix" "vex")
12805    (set_attr "mode" "TI")])
12807 (define_insn "sse2_lshrti3"
12808   [(set (match_operand:TI 0 "register_operand" "=x")
12809         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12810                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12811   "TARGET_SSE2"
12813   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12814   return "psrldq\t{%2, %0|%0, %2}";
12816   [(set_attr "type" "sseishft")
12817    (set_attr "prefix_data16" "1")
12818    (set_attr "mode" "TI")])
12820 (define_insn "*lshrti3_1"
12821   [(set (match_operand:TI 0 "register_operand" "=r")
12822         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12823                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12824    (clobber (reg:CC FLAGS_REG))]
12825   "TARGET_64BIT"
12826   "#"
12827   [(set_attr "type" "multi")])
12829 (define_peephole2
12830   [(match_scratch:DI 3 "r")
12831    (parallel [(set (match_operand:TI 0 "register_operand" "")
12832                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12833                                 (match_operand:QI 2 "nonmemory_operand" "")))
12834               (clobber (reg:CC FLAGS_REG))])
12835    (match_dup 3)]
12836   "TARGET_64BIT"
12837   [(const_int 0)]
12838   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12840 (define_split
12841   [(set (match_operand:TI 0 "register_operand" "")
12842         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12843                      (match_operand:QI 2 "nonmemory_operand" "")))
12844    (clobber (reg:CC FLAGS_REG))]
12845   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12846                     ? epilogue_completed : reload_completed)"
12847   [(const_int 0)]
12848   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12850 (define_expand "lshrdi3"
12851   [(set (match_operand:DI 0 "shiftdi_operand" "")
12852         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12853                      (match_operand:QI 2 "nonmemory_operand" "")))]
12854   ""
12855   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12857 (define_insn "*lshrdi3_1_one_bit_rex64"
12858   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12859         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12860                      (match_operand:QI 2 "const1_operand" "")))
12861    (clobber (reg:CC FLAGS_REG))]
12862   "TARGET_64BIT
12863    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12864    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12865   "shr{q}\t%0"
12866   [(set_attr "type" "ishift")
12867    (set (attr "length")
12868      (if_then_else (match_operand:DI 0 "register_operand" "")
12869         (const_string "2")
12870         (const_string "*")))])
12872 (define_insn "*lshrdi3_1_rex64"
12873   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12874         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12875                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12876    (clobber (reg:CC FLAGS_REG))]
12877   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12878   "@
12879    shr{q}\t{%2, %0|%0, %2}
12880    shr{q}\t{%b2, %0|%0, %b2}"
12881   [(set_attr "type" "ishift")
12882    (set_attr "mode" "DI")])
12884 ;; This pattern can't accept a variable shift count, since shifts by
12885 ;; zero don't affect the flags.  We assume that shifts by constant
12886 ;; zero are optimized away.
12887 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12888   [(set (reg FLAGS_REG)
12889         (compare
12890           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12891                        (match_operand:QI 2 "const1_operand" ""))
12892           (const_int 0)))
12893    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12894         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12895   "TARGET_64BIT
12896    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12897    && ix86_match_ccmode (insn, CCGOCmode)
12898    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12899   "shr{q}\t%0"
12900   [(set_attr "type" "ishift")
12901    (set (attr "length")
12902      (if_then_else (match_operand:DI 0 "register_operand" "")
12903         (const_string "2")
12904         (const_string "*")))])
12906 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12907   [(set (reg FLAGS_REG)
12908         (compare
12909           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12910                        (match_operand:QI 2 "const1_operand" ""))
12911           (const_int 0)))
12912    (clobber (match_scratch:DI 0 "=r"))]
12913   "TARGET_64BIT
12914    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12915    && ix86_match_ccmode (insn, CCGOCmode)
12916    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12917   "shr{q}\t%0"
12918   [(set_attr "type" "ishift")
12919    (set_attr "length" "2")])
12921 ;; This pattern can't accept a variable shift count, since shifts by
12922 ;; zero don't affect the flags.  We assume that shifts by constant
12923 ;; zero are optimized away.
12924 (define_insn "*lshrdi3_cmp_rex64"
12925   [(set (reg FLAGS_REG)
12926         (compare
12927           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12928                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12929           (const_int 0)))
12930    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12931         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12932   "TARGET_64BIT
12933    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12934    && ix86_match_ccmode (insn, CCGOCmode)
12935    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12936   "shr{q}\t{%2, %0|%0, %2}"
12937   [(set_attr "type" "ishift")
12938    (set_attr "mode" "DI")])
12940 (define_insn "*lshrdi3_cconly_rex64"
12941   [(set (reg FLAGS_REG)
12942         (compare
12943           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12944                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12945           (const_int 0)))
12946    (clobber (match_scratch:DI 0 "=r"))]
12947   "TARGET_64BIT
12948    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12949    && ix86_match_ccmode (insn, CCGOCmode)
12950    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12951   "shr{q}\t{%2, %0|%0, %2}"
12952   [(set_attr "type" "ishift")
12953    (set_attr "mode" "DI")])
12955 (define_insn "*lshrdi3_1"
12956   [(set (match_operand:DI 0 "register_operand" "=r")
12957         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12958                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12959    (clobber (reg:CC FLAGS_REG))]
12960   "!TARGET_64BIT"
12961   "#"
12962   [(set_attr "type" "multi")])
12964 ;; By default we don't ask for a scratch register, because when DImode
12965 ;; values are manipulated, registers are already at a premium.  But if
12966 ;; we have one handy, we won't turn it away.
12967 (define_peephole2
12968   [(match_scratch:SI 3 "r")
12969    (parallel [(set (match_operand:DI 0 "register_operand" "")
12970                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12971                                 (match_operand:QI 2 "nonmemory_operand" "")))
12972               (clobber (reg:CC FLAGS_REG))])
12973    (match_dup 3)]
12974   "!TARGET_64BIT && TARGET_CMOVE"
12975   [(const_int 0)]
12976   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12978 (define_split
12979   [(set (match_operand:DI 0 "register_operand" "")
12980         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12981                      (match_operand:QI 2 "nonmemory_operand" "")))
12982    (clobber (reg:CC FLAGS_REG))]
12983   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12984                      ? epilogue_completed : reload_completed)"
12985   [(const_int 0)]
12986   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12988 (define_expand "lshrsi3"
12989   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12990         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12991                      (match_operand:QI 2 "nonmemory_operand" "")))]
12992   ""
12993   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12995 (define_insn "*lshrsi3_1_one_bit"
12996   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12997         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12998                      (match_operand:QI 2 "const1_operand" "")))
12999    (clobber (reg:CC FLAGS_REG))]
13000   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13001    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13002   "shr{l}\t%0"
13003   [(set_attr "type" "ishift")
13004    (set (attr "length")
13005      (if_then_else (match_operand:SI 0 "register_operand" "")
13006         (const_string "2")
13007         (const_string "*")))])
13009 (define_insn "*lshrsi3_1_one_bit_zext"
13010   [(set (match_operand:DI 0 "register_operand" "=r")
13011         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13012                      (match_operand:QI 2 "const1_operand" "")))
13013    (clobber (reg:CC FLAGS_REG))]
13014   "TARGET_64BIT
13015    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13016    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13017   "shr{l}\t%k0"
13018   [(set_attr "type" "ishift")
13019    (set_attr "length" "2")])
13021 (define_insn "*lshrsi3_1"
13022   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13023         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13024                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13025    (clobber (reg:CC FLAGS_REG))]
13026   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13027   "@
13028    shr{l}\t{%2, %0|%0, %2}
13029    shr{l}\t{%b2, %0|%0, %b2}"
13030   [(set_attr "type" "ishift")
13031    (set_attr "mode" "SI")])
13033 (define_insn "*lshrsi3_1_zext"
13034   [(set (match_operand:DI 0 "register_operand" "=r,r")
13035         (zero_extend:DI
13036           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13037                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13038    (clobber (reg:CC FLAGS_REG))]
13039   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13040   "@
13041    shr{l}\t{%2, %k0|%k0, %2}
13042    shr{l}\t{%b2, %k0|%k0, %b2}"
13043   [(set_attr "type" "ishift")
13044    (set_attr "mode" "SI")])
13046 ;; This pattern can't accept a variable shift count, since shifts by
13047 ;; zero don't affect the flags.  We assume that shifts by constant
13048 ;; zero are optimized away.
13049 (define_insn "*lshrsi3_one_bit_cmp"
13050   [(set (reg FLAGS_REG)
13051         (compare
13052           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13053                        (match_operand:QI 2 "const1_operand" ""))
13054           (const_int 0)))
13055    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13056         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13057   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13058    && ix86_match_ccmode (insn, CCGOCmode)
13059    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13060   "shr{l}\t%0"
13061   [(set_attr "type" "ishift")
13062    (set (attr "length")
13063      (if_then_else (match_operand:SI 0 "register_operand" "")
13064         (const_string "2")
13065         (const_string "*")))])
13067 (define_insn "*lshrsi3_one_bit_cconly"
13068   [(set (reg FLAGS_REG)
13069         (compare
13070           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13071                        (match_operand:QI 2 "const1_operand" ""))
13072           (const_int 0)))
13073    (clobber (match_scratch:SI 0 "=r"))]
13074   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13075    && ix86_match_ccmode (insn, CCGOCmode)
13076    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13077   "shr{l}\t%0"
13078   [(set_attr "type" "ishift")
13079    (set_attr "length" "2")])
13081 (define_insn "*lshrsi3_cmp_one_bit_zext"
13082   [(set (reg FLAGS_REG)
13083         (compare
13084           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13085                        (match_operand:QI 2 "const1_operand" ""))
13086           (const_int 0)))
13087    (set (match_operand:DI 0 "register_operand" "=r")
13088         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13089   "TARGET_64BIT
13090    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13091    && ix86_match_ccmode (insn, CCGOCmode)
13092    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13093   "shr{l}\t%k0"
13094   [(set_attr "type" "ishift")
13095    (set_attr "length" "2")])
13097 ;; This pattern can't accept a variable shift count, since shifts by
13098 ;; zero don't affect the flags.  We assume that shifts by constant
13099 ;; zero are optimized away.
13100 (define_insn "*lshrsi3_cmp"
13101   [(set (reg FLAGS_REG)
13102         (compare
13103           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13104                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13105           (const_int 0)))
13106    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13107         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13108   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13109    && ix86_match_ccmode (insn, CCGOCmode)
13110    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13111   "shr{l}\t{%2, %0|%0, %2}"
13112   [(set_attr "type" "ishift")
13113    (set_attr "mode" "SI")])
13115 (define_insn "*lshrsi3_cconly"
13116   [(set (reg FLAGS_REG)
13117       (compare
13118         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13119                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
13120         (const_int 0)))
13121    (clobber (match_scratch:SI 0 "=r"))]
13122   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13123    && ix86_match_ccmode (insn, CCGOCmode)
13124    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13125   "shr{l}\t{%2, %0|%0, %2}"
13126   [(set_attr "type" "ishift")
13127    (set_attr "mode" "SI")])
13129 (define_insn "*lshrsi3_cmp_zext"
13130   [(set (reg FLAGS_REG)
13131         (compare
13132           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13133                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13134           (const_int 0)))
13135    (set (match_operand:DI 0 "register_operand" "=r")
13136         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13137   "TARGET_64BIT
13138    && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13139    && ix86_match_ccmode (insn, CCGOCmode)
13140    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13141   "shr{l}\t{%2, %k0|%k0, %2}"
13142   [(set_attr "type" "ishift")
13143    (set_attr "mode" "SI")])
13145 (define_expand "lshrhi3"
13146   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13147         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13148                      (match_operand:QI 2 "nonmemory_operand" "")))]
13149   "TARGET_HIMODE_MATH"
13150   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13152 (define_insn "*lshrhi3_1_one_bit"
13153   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13154         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13155                      (match_operand:QI 2 "const1_operand" "")))
13156    (clobber (reg:CC FLAGS_REG))]
13157   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13158    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13159   "shr{w}\t%0"
13160   [(set_attr "type" "ishift")
13161    (set (attr "length")
13162      (if_then_else (match_operand 0 "register_operand" "")
13163         (const_string "2")
13164         (const_string "*")))])
13166 (define_insn "*lshrhi3_1"
13167   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13168         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13169                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13170    (clobber (reg:CC FLAGS_REG))]
13171   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13172   "@
13173    shr{w}\t{%2, %0|%0, %2}
13174    shr{w}\t{%b2, %0|%0, %b2}"
13175   [(set_attr "type" "ishift")
13176    (set_attr "mode" "HI")])
13178 ;; This pattern can't accept a variable shift count, since shifts by
13179 ;; zero don't affect the flags.  We assume that shifts by constant
13180 ;; zero are optimized away.
13181 (define_insn "*lshrhi3_one_bit_cmp"
13182   [(set (reg FLAGS_REG)
13183         (compare
13184           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13185                        (match_operand:QI 2 "const1_operand" ""))
13186           (const_int 0)))
13187    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13188         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13189   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13190    && ix86_match_ccmode (insn, CCGOCmode)
13191    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13192   "shr{w}\t%0"
13193   [(set_attr "type" "ishift")
13194    (set (attr "length")
13195      (if_then_else (match_operand:SI 0 "register_operand" "")
13196         (const_string "2")
13197         (const_string "*")))])
13199 (define_insn "*lshrhi3_one_bit_cconly"
13200   [(set (reg FLAGS_REG)
13201         (compare
13202           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13203                        (match_operand:QI 2 "const1_operand" ""))
13204           (const_int 0)))
13205    (clobber (match_scratch:HI 0 "=r"))]
13206   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13207    && ix86_match_ccmode (insn, CCGOCmode)
13208    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13209   "shr{w}\t%0"
13210   [(set_attr "type" "ishift")
13211    (set_attr "length" "2")])
13213 ;; This pattern can't accept a variable shift count, since shifts by
13214 ;; zero don't affect the flags.  We assume that shifts by constant
13215 ;; zero are optimized away.
13216 (define_insn "*lshrhi3_cmp"
13217   [(set (reg FLAGS_REG)
13218         (compare
13219           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13220                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13221           (const_int 0)))
13222    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13223         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13224   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13225    && ix86_match_ccmode (insn, CCGOCmode)
13226    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13227   "shr{w}\t{%2, %0|%0, %2}"
13228   [(set_attr "type" "ishift")
13229    (set_attr "mode" "HI")])
13231 (define_insn "*lshrhi3_cconly"
13232   [(set (reg FLAGS_REG)
13233         (compare
13234           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13235                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13236           (const_int 0)))
13237    (clobber (match_scratch:HI 0 "=r"))]
13238   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13239    && ix86_match_ccmode (insn, CCGOCmode)
13240    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13241   "shr{w}\t{%2, %0|%0, %2}"
13242   [(set_attr "type" "ishift")
13243    (set_attr "mode" "HI")])
13245 (define_expand "lshrqi3"
13246   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13247         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13248                      (match_operand:QI 2 "nonmemory_operand" "")))]
13249   "TARGET_QIMODE_MATH"
13250   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13252 (define_insn "*lshrqi3_1_one_bit"
13253   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13254         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13255                      (match_operand:QI 2 "const1_operand" "")))
13256    (clobber (reg:CC FLAGS_REG))]
13257   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13258    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13259   "shr{b}\t%0"
13260   [(set_attr "type" "ishift")
13261    (set (attr "length")
13262      (if_then_else (match_operand 0 "register_operand" "")
13263         (const_string "2")
13264         (const_string "*")))])
13266 (define_insn "*lshrqi3_1_one_bit_slp"
13267   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13268         (lshiftrt:QI (match_dup 0)
13269                      (match_operand:QI 1 "const1_operand" "")))
13270    (clobber (reg:CC FLAGS_REG))]
13271   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13272    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13273   "shr{b}\t%0"
13274   [(set_attr "type" "ishift1")
13275    (set (attr "length")
13276      (if_then_else (match_operand 0 "register_operand" "")
13277         (const_string "2")
13278         (const_string "*")))])
13280 (define_insn "*lshrqi3_1"
13281   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13282         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13283                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13284    (clobber (reg:CC FLAGS_REG))]
13285   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13286   "@
13287    shr{b}\t{%2, %0|%0, %2}
13288    shr{b}\t{%b2, %0|%0, %b2}"
13289   [(set_attr "type" "ishift")
13290    (set_attr "mode" "QI")])
13292 (define_insn "*lshrqi3_1_slp"
13293   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13294         (lshiftrt:QI (match_dup 0)
13295                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13296    (clobber (reg:CC FLAGS_REG))]
13297   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13298    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13299   "@
13300    shr{b}\t{%1, %0|%0, %1}
13301    shr{b}\t{%b1, %0|%0, %b1}"
13302   [(set_attr "type" "ishift1")
13303    (set_attr "mode" "QI")])
13305 ;; This pattern can't accept a variable shift count, since shifts by
13306 ;; zero don't affect the flags.  We assume that shifts by constant
13307 ;; zero are optimized away.
13308 (define_insn "*lshrqi2_one_bit_cmp"
13309   [(set (reg FLAGS_REG)
13310         (compare
13311           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13312                        (match_operand:QI 2 "const1_operand" ""))
13313           (const_int 0)))
13314    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13315         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13316   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13317    && ix86_match_ccmode (insn, CCGOCmode)
13318    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13319   "shr{b}\t%0"
13320   [(set_attr "type" "ishift")
13321    (set (attr "length")
13322      (if_then_else (match_operand:SI 0 "register_operand" "")
13323         (const_string "2")
13324         (const_string "*")))])
13326 (define_insn "*lshrqi2_one_bit_cconly"
13327   [(set (reg FLAGS_REG)
13328         (compare
13329           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13330                        (match_operand:QI 2 "const1_operand" ""))
13331           (const_int 0)))
13332    (clobber (match_scratch:QI 0 "=q"))]
13333   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13334    && ix86_match_ccmode (insn, CCGOCmode)
13335    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13336   "shr{b}\t%0"
13337   [(set_attr "type" "ishift")
13338    (set_attr "length" "2")])
13340 ;; This pattern can't accept a variable shift count, since shifts by
13341 ;; zero don't affect the flags.  We assume that shifts by constant
13342 ;; zero are optimized away.
13343 (define_insn "*lshrqi2_cmp"
13344   [(set (reg FLAGS_REG)
13345         (compare
13346           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13347                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13348           (const_int 0)))
13349    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13350         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13351   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13352    && ix86_match_ccmode (insn, CCGOCmode)
13353    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13354   "shr{b}\t{%2, %0|%0, %2}"
13355   [(set_attr "type" "ishift")
13356    (set_attr "mode" "QI")])
13358 (define_insn "*lshrqi2_cconly"
13359   [(set (reg FLAGS_REG)
13360         (compare
13361           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13362                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13363           (const_int 0)))
13364    (clobber (match_scratch:QI 0 "=q"))]
13365   "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13366    && ix86_match_ccmode (insn, CCGOCmode)
13367    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13368   "shr{b}\t{%2, %0|%0, %2}"
13369   [(set_attr "type" "ishift")
13370    (set_attr "mode" "QI")])
13372 ;; Rotate instructions
13374 (define_expand "rotldi3"
13375   [(set (match_operand:DI 0 "shiftdi_operand" "")
13376         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13377                    (match_operand:QI 2 "nonmemory_operand" "")))]
13378  ""
13380   if (TARGET_64BIT)
13381     {
13382       ix86_expand_binary_operator (ROTATE, DImode, operands);
13383       DONE;
13384     }
13385   if (!const_1_to_31_operand (operands[2], VOIDmode))
13386     FAIL;
13387   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13388   DONE;
13391 ;; Implement rotation using two double-precision shift instructions
13392 ;; and a scratch register.
13393 (define_insn_and_split "ix86_rotldi3"
13394  [(set (match_operand:DI 0 "register_operand" "=r")
13395        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13396                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13397   (clobber (reg:CC FLAGS_REG))
13398   (clobber (match_scratch:SI 3 "=&r"))]
13399  "!TARGET_64BIT"
13400  ""
13401  "&& reload_completed"
13402  [(set (match_dup 3) (match_dup 4))
13403   (parallel
13404    [(set (match_dup 4)
13405          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13406                  (lshiftrt:SI (match_dup 5)
13407                               (minus:QI (const_int 32) (match_dup 2)))))
13408     (clobber (reg:CC FLAGS_REG))])
13409   (parallel
13410    [(set (match_dup 5)
13411          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13412                  (lshiftrt:SI (match_dup 3)
13413                               (minus:QI (const_int 32) (match_dup 2)))))
13414     (clobber (reg:CC FLAGS_REG))])]
13415  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13417 (define_insn "*rotlsi3_1_one_bit_rex64"
13418   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13419         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13420                    (match_operand:QI 2 "const1_operand" "")))
13421    (clobber (reg:CC FLAGS_REG))]
13422   "TARGET_64BIT
13423    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13424    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13425   "rol{q}\t%0"
13426   [(set_attr "type" "rotate")
13427    (set (attr "length")
13428      (if_then_else (match_operand:DI 0 "register_operand" "")
13429         (const_string "2")
13430         (const_string "*")))])
13432 (define_insn "*rotldi3_1_rex64"
13433   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13434         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13435                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13436    (clobber (reg:CC FLAGS_REG))]
13437   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13438   "@
13439    rol{q}\t{%2, %0|%0, %2}
13440    rol{q}\t{%b2, %0|%0, %b2}"
13441   [(set_attr "type" "rotate")
13442    (set_attr "mode" "DI")])
13444 (define_expand "rotlsi3"
13445   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13446         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13447                    (match_operand:QI 2 "nonmemory_operand" "")))]
13448   ""
13449   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13451 (define_insn "*rotlsi3_1_one_bit"
13452   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13453         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13454                    (match_operand:QI 2 "const1_operand" "")))
13455    (clobber (reg:CC FLAGS_REG))]
13456   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13457    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13458   "rol{l}\t%0"
13459   [(set_attr "type" "rotate")
13460    (set (attr "length")
13461      (if_then_else (match_operand:SI 0 "register_operand" "")
13462         (const_string "2")
13463         (const_string "*")))])
13465 (define_insn "*rotlsi3_1_one_bit_zext"
13466   [(set (match_operand:DI 0 "register_operand" "=r")
13467         (zero_extend:DI
13468           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13469                      (match_operand:QI 2 "const1_operand" ""))))
13470    (clobber (reg:CC FLAGS_REG))]
13471   "TARGET_64BIT
13472    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13473    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13474   "rol{l}\t%k0"
13475   [(set_attr "type" "rotate")
13476    (set_attr "length" "2")])
13478 (define_insn "*rotlsi3_1"
13479   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13480         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13481                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13482    (clobber (reg:CC FLAGS_REG))]
13483   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13484   "@
13485    rol{l}\t{%2, %0|%0, %2}
13486    rol{l}\t{%b2, %0|%0, %b2}"
13487   [(set_attr "type" "rotate")
13488    (set_attr "mode" "SI")])
13490 (define_insn "*rotlsi3_1_zext"
13491   [(set (match_operand:DI 0 "register_operand" "=r,r")
13492         (zero_extend:DI
13493           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13494                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13495    (clobber (reg:CC FLAGS_REG))]
13496   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13497   "@
13498    rol{l}\t{%2, %k0|%k0, %2}
13499    rol{l}\t{%b2, %k0|%k0, %b2}"
13500   [(set_attr "type" "rotate")
13501    (set_attr "mode" "SI")])
13503 (define_expand "rotlhi3"
13504   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13505         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13506                    (match_operand:QI 2 "nonmemory_operand" "")))]
13507   "TARGET_HIMODE_MATH"
13508   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13510 (define_insn "*rotlhi3_1_one_bit"
13511   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13512         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13513                    (match_operand:QI 2 "const1_operand" "")))
13514    (clobber (reg:CC FLAGS_REG))]
13515   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13516    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13517   "rol{w}\t%0"
13518   [(set_attr "type" "rotate")
13519    (set (attr "length")
13520      (if_then_else (match_operand 0 "register_operand" "")
13521         (const_string "2")
13522         (const_string "*")))])
13524 (define_insn "*rotlhi3_1"
13525   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13526         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13527                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13528    (clobber (reg:CC FLAGS_REG))]
13529   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13530   "@
13531    rol{w}\t{%2, %0|%0, %2}
13532    rol{w}\t{%b2, %0|%0, %b2}"
13533   [(set_attr "type" "rotate")
13534    (set_attr "mode" "HI")])
13536 (define_split
13537  [(set (match_operand:HI 0 "register_operand" "")
13538        (rotate:HI (match_dup 0) (const_int 8)))
13539   (clobber (reg:CC FLAGS_REG))]
13540  "reload_completed"
13541  [(parallel [(set (strict_low_part (match_dup 0))
13542                   (bswap:HI (match_dup 0)))
13543              (clobber (reg:CC FLAGS_REG))])]
13544  "")
13546 (define_expand "rotlqi3"
13547   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13548         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13549                    (match_operand:QI 2 "nonmemory_operand" "")))]
13550   "TARGET_QIMODE_MATH"
13551   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13553 (define_insn "*rotlqi3_1_one_bit_slp"
13554   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13555         (rotate:QI (match_dup 0)
13556                    (match_operand:QI 1 "const1_operand" "")))
13557    (clobber (reg:CC FLAGS_REG))]
13558   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13559    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13560   "rol{b}\t%0"
13561   [(set_attr "type" "rotate1")
13562    (set (attr "length")
13563      (if_then_else (match_operand 0 "register_operand" "")
13564         (const_string "2")
13565         (const_string "*")))])
13567 (define_insn "*rotlqi3_1_one_bit"
13568   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13569         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13570                    (match_operand:QI 2 "const1_operand" "")))
13571    (clobber (reg:CC FLAGS_REG))]
13572   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13573    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13574   "rol{b}\t%0"
13575   [(set_attr "type" "rotate")
13576    (set (attr "length")
13577      (if_then_else (match_operand 0 "register_operand" "")
13578         (const_string "2")
13579         (const_string "*")))])
13581 (define_insn "*rotlqi3_1_slp"
13582   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13583         (rotate:QI (match_dup 0)
13584                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13585    (clobber (reg:CC FLAGS_REG))]
13586   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13587    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13588   "@
13589    rol{b}\t{%1, %0|%0, %1}
13590    rol{b}\t{%b1, %0|%0, %b1}"
13591   [(set_attr "type" "rotate1")
13592    (set_attr "mode" "QI")])
13594 (define_insn "*rotlqi3_1"
13595   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13596         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13597                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13598    (clobber (reg:CC FLAGS_REG))]
13599   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13600   "@
13601    rol{b}\t{%2, %0|%0, %2}
13602    rol{b}\t{%b2, %0|%0, %b2}"
13603   [(set_attr "type" "rotate")
13604    (set_attr "mode" "QI")])
13606 (define_expand "rotrdi3"
13607   [(set (match_operand:DI 0 "shiftdi_operand" "")
13608         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13609                    (match_operand:QI 2 "nonmemory_operand" "")))]
13610  ""
13612   if (TARGET_64BIT)
13613     {
13614       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13615       DONE;
13616     }
13617   if (!const_1_to_31_operand (operands[2], VOIDmode))
13618     FAIL;
13619   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13620   DONE;
13623 ;; Implement rotation using two double-precision shift instructions
13624 ;; and a scratch register.
13625 (define_insn_and_split "ix86_rotrdi3"
13626  [(set (match_operand:DI 0 "register_operand" "=r")
13627        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13628                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13629   (clobber (reg:CC FLAGS_REG))
13630   (clobber (match_scratch:SI 3 "=&r"))]
13631  "!TARGET_64BIT"
13632  ""
13633  "&& reload_completed"
13634  [(set (match_dup 3) (match_dup 4))
13635   (parallel
13636    [(set (match_dup 4)
13637          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13638                  (ashift:SI (match_dup 5)
13639                             (minus:QI (const_int 32) (match_dup 2)))))
13640     (clobber (reg:CC FLAGS_REG))])
13641   (parallel
13642    [(set (match_dup 5)
13643          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13644                  (ashift:SI (match_dup 3)
13645                             (minus:QI (const_int 32) (match_dup 2)))))
13646     (clobber (reg:CC FLAGS_REG))])]
13647  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13649 (define_insn "*rotrdi3_1_one_bit_rex64"
13650   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13651         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13652                      (match_operand:QI 2 "const1_operand" "")))
13653    (clobber (reg:CC FLAGS_REG))]
13654   "TARGET_64BIT
13655    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13656    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13657   "ror{q}\t%0"
13658   [(set_attr "type" "rotate")
13659    (set (attr "length")
13660      (if_then_else (match_operand:DI 0 "register_operand" "")
13661         (const_string "2")
13662         (const_string "*")))])
13664 (define_insn "*rotrdi3_1_rex64"
13665   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13666         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13667                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13668    (clobber (reg:CC FLAGS_REG))]
13669   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13670   "@
13671    ror{q}\t{%2, %0|%0, %2}
13672    ror{q}\t{%b2, %0|%0, %b2}"
13673   [(set_attr "type" "rotate")
13674    (set_attr "mode" "DI")])
13676 (define_expand "rotrsi3"
13677   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13678         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13679                      (match_operand:QI 2 "nonmemory_operand" "")))]
13680   ""
13681   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13683 (define_insn "*rotrsi3_1_one_bit"
13684   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13685         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13686                      (match_operand:QI 2 "const1_operand" "")))
13687    (clobber (reg:CC FLAGS_REG))]
13688   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13689    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13690   "ror{l}\t%0"
13691   [(set_attr "type" "rotate")
13692    (set (attr "length")
13693      (if_then_else (match_operand:SI 0 "register_operand" "")
13694         (const_string "2")
13695         (const_string "*")))])
13697 (define_insn "*rotrsi3_1_one_bit_zext"
13698   [(set (match_operand:DI 0 "register_operand" "=r")
13699         (zero_extend:DI
13700           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13701                        (match_operand:QI 2 "const1_operand" ""))))
13702    (clobber (reg:CC FLAGS_REG))]
13703   "TARGET_64BIT
13704    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13705    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13706   "ror{l}\t%k0"
13707   [(set_attr "type" "rotate")
13708    (set (attr "length")
13709      (if_then_else (match_operand:SI 0 "register_operand" "")
13710         (const_string "2")
13711         (const_string "*")))])
13713 (define_insn "*rotrsi3_1"
13714   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13715         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13716                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13717    (clobber (reg:CC FLAGS_REG))]
13718   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13719   "@
13720    ror{l}\t{%2, %0|%0, %2}
13721    ror{l}\t{%b2, %0|%0, %b2}"
13722   [(set_attr "type" "rotate")
13723    (set_attr "mode" "SI")])
13725 (define_insn "*rotrsi3_1_zext"
13726   [(set (match_operand:DI 0 "register_operand" "=r,r")
13727         (zero_extend:DI
13728           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13729                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13730    (clobber (reg:CC FLAGS_REG))]
13731   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13732   "@
13733    ror{l}\t{%2, %k0|%k0, %2}
13734    ror{l}\t{%b2, %k0|%k0, %b2}"
13735   [(set_attr "type" "rotate")
13736    (set_attr "mode" "SI")])
13738 (define_expand "rotrhi3"
13739   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13740         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13741                      (match_operand:QI 2 "nonmemory_operand" "")))]
13742   "TARGET_HIMODE_MATH"
13743   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13745 (define_insn "*rotrhi3_one_bit"
13746   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13747         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13748                      (match_operand:QI 2 "const1_operand" "")))
13749    (clobber (reg:CC FLAGS_REG))]
13750   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13751    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13752   "ror{w}\t%0"
13753   [(set_attr "type" "rotate")
13754    (set (attr "length")
13755      (if_then_else (match_operand 0 "register_operand" "")
13756         (const_string "2")
13757         (const_string "*")))])
13759 (define_insn "*rotrhi3_1"
13760   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13761         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13762                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13763    (clobber (reg:CC FLAGS_REG))]
13764   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13765   "@
13766    ror{w}\t{%2, %0|%0, %2}
13767    ror{w}\t{%b2, %0|%0, %b2}"
13768   [(set_attr "type" "rotate")
13769    (set_attr "mode" "HI")])
13771 (define_split
13772  [(set (match_operand:HI 0 "register_operand" "")
13773        (rotatert:HI (match_dup 0) (const_int 8)))
13774   (clobber (reg:CC FLAGS_REG))]
13775  "reload_completed"
13776  [(parallel [(set (strict_low_part (match_dup 0))
13777                   (bswap:HI (match_dup 0)))
13778              (clobber (reg:CC FLAGS_REG))])]
13779  "")
13781 (define_expand "rotrqi3"
13782   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13783         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13784                      (match_operand:QI 2 "nonmemory_operand" "")))]
13785   "TARGET_QIMODE_MATH"
13786   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13788 (define_insn "*rotrqi3_1_one_bit"
13789   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13790         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13791                      (match_operand:QI 2 "const1_operand" "")))
13792    (clobber (reg:CC FLAGS_REG))]
13793   "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13794    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13795   "ror{b}\t%0"
13796   [(set_attr "type" "rotate")
13797    (set (attr "length")
13798      (if_then_else (match_operand 0 "register_operand" "")
13799         (const_string "2")
13800         (const_string "*")))])
13802 (define_insn "*rotrqi3_1_one_bit_slp"
13803   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13804         (rotatert:QI (match_dup 0)
13805                      (match_operand:QI 1 "const1_operand" "")))
13806    (clobber (reg:CC FLAGS_REG))]
13807   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13808    && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13809   "ror{b}\t%0"
13810   [(set_attr "type" "rotate1")
13811    (set (attr "length")
13812      (if_then_else (match_operand 0 "register_operand" "")
13813         (const_string "2")
13814         (const_string "*")))])
13816 (define_insn "*rotrqi3_1"
13817   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13818         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13819                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13820    (clobber (reg:CC FLAGS_REG))]
13821   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13822   "@
13823    ror{b}\t{%2, %0|%0, %2}
13824    ror{b}\t{%b2, %0|%0, %b2}"
13825   [(set_attr "type" "rotate")
13826    (set_attr "mode" "QI")])
13828 (define_insn "*rotrqi3_1_slp"
13829   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13830         (rotatert:QI (match_dup 0)
13831                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13832    (clobber (reg:CC FLAGS_REG))]
13833   "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13834    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13835   "@
13836    ror{b}\t{%1, %0|%0, %1}
13837    ror{b}\t{%b1, %0|%0, %b1}"
13838   [(set_attr "type" "rotate1")
13839    (set_attr "mode" "QI")])
13841 ;; Bit set / bit test instructions
13843 (define_expand "extv"
13844   [(set (match_operand:SI 0 "register_operand" "")
13845         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13846                          (match_operand:SI 2 "const8_operand" "")
13847                          (match_operand:SI 3 "const8_operand" "")))]
13848   ""
13850   /* Handle extractions from %ah et al.  */
13851   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13852     FAIL;
13854   /* From mips.md: extract_bit_field doesn't verify that our source
13855      matches the predicate, so check it again here.  */
13856   if (! ext_register_operand (operands[1], VOIDmode))
13857     FAIL;
13860 (define_expand "extzv"
13861   [(set (match_operand:SI 0 "register_operand" "")
13862         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13863                          (match_operand:SI 2 "const8_operand" "")
13864                          (match_operand:SI 3 "const8_operand" "")))]
13865   ""
13867   /* Handle extractions from %ah et al.  */
13868   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13869     FAIL;
13871   /* From mips.md: extract_bit_field doesn't verify that our source
13872      matches the predicate, so check it again here.  */
13873   if (! ext_register_operand (operands[1], VOIDmode))
13874     FAIL;
13877 (define_expand "insv"
13878   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13879                       (match_operand 1 "const8_operand" "")
13880                       (match_operand 2 "const8_operand" ""))
13881         (match_operand 3 "register_operand" ""))]
13882   ""
13884   /* Handle insertions to %ah et al.  */
13885   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13886     FAIL;
13888   /* From mips.md: insert_bit_field doesn't verify that our source
13889      matches the predicate, so check it again here.  */
13890   if (! ext_register_operand (operands[0], VOIDmode))
13891     FAIL;
13893   if (TARGET_64BIT)
13894     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13895   else
13896     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13898   DONE;
13901 ;; %%% bts, btr, btc, bt.
13902 ;; In general these instructions are *slow* when applied to memory,
13903 ;; since they enforce atomic operation.  When applied to registers,
13904 ;; it depends on the cpu implementation.  They're never faster than
13905 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13906 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13907 ;; within the instruction itself, so operating on bits in the high
13908 ;; 32-bits of a register becomes easier.
13910 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13911 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13912 ;; negdf respectively, so they can never be disabled entirely.
13914 (define_insn "*btsq"
13915   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13916                          (const_int 1)
13917                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13918         (const_int 1))
13919    (clobber (reg:CC FLAGS_REG))]
13920   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13921   "bts{q}\t{%1, %0|%0, %1}"
13922   [(set_attr "type" "alu1")])
13924 (define_insn "*btrq"
13925   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13926                          (const_int 1)
13927                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13928         (const_int 0))
13929    (clobber (reg:CC FLAGS_REG))]
13930   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13931   "btr{q}\t{%1, %0|%0, %1}"
13932   [(set_attr "type" "alu1")])
13934 (define_insn "*btcq"
13935   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13936                          (const_int 1)
13937                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13938         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13939    (clobber (reg:CC FLAGS_REG))]
13940   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13941   "btc{q}\t{%1, %0|%0, %1}"
13942   [(set_attr "type" "alu1")])
13944 ;; Allow Nocona to avoid these instructions if a register is available.
13946 (define_peephole2
13947   [(match_scratch:DI 2 "r")
13948    (parallel [(set (zero_extract:DI
13949                      (match_operand:DI 0 "register_operand" "")
13950                      (const_int 1)
13951                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13952                    (const_int 1))
13953               (clobber (reg:CC FLAGS_REG))])]
13954   "TARGET_64BIT && !TARGET_USE_BT"
13955   [(const_int 0)]
13957   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13958   rtx op1;
13960   if (HOST_BITS_PER_WIDE_INT >= 64)
13961     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13962   else if (i < HOST_BITS_PER_WIDE_INT)
13963     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13964   else
13965     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13967   op1 = immed_double_const (lo, hi, DImode);
13968   if (i >= 31)
13969     {
13970       emit_move_insn (operands[2], op1);
13971       op1 = operands[2];
13972     }
13974   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13975   DONE;
13978 (define_peephole2
13979   [(match_scratch:DI 2 "r")
13980    (parallel [(set (zero_extract:DI
13981                      (match_operand:DI 0 "register_operand" "")
13982                      (const_int 1)
13983                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13984                    (const_int 0))
13985               (clobber (reg:CC FLAGS_REG))])]
13986   "TARGET_64BIT && !TARGET_USE_BT"
13987   [(const_int 0)]
13989   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13990   rtx op1;
13992   if (HOST_BITS_PER_WIDE_INT >= 64)
13993     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13994   else if (i < HOST_BITS_PER_WIDE_INT)
13995     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13996   else
13997     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13999   op1 = immed_double_const (~lo, ~hi, DImode);
14000   if (i >= 32)
14001     {
14002       emit_move_insn (operands[2], op1);
14003       op1 = operands[2];
14004     }
14006   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14007   DONE;
14010 (define_peephole2
14011   [(match_scratch:DI 2 "r")
14012    (parallel [(set (zero_extract:DI
14013                      (match_operand:DI 0 "register_operand" "")
14014                      (const_int 1)
14015                      (match_operand:DI 1 "const_0_to_63_operand" ""))
14016               (not:DI (zero_extract:DI
14017                         (match_dup 0) (const_int 1) (match_dup 1))))
14018               (clobber (reg:CC FLAGS_REG))])]
14019   "TARGET_64BIT && !TARGET_USE_BT"
14020   [(const_int 0)]
14022   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14023   rtx op1;
14025   if (HOST_BITS_PER_WIDE_INT >= 64)
14026     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14027   else if (i < HOST_BITS_PER_WIDE_INT)
14028     lo = (HOST_WIDE_INT)1 << i, hi = 0;
14029   else
14030     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14032   op1 = immed_double_const (lo, hi, DImode);
14033   if (i >= 31)
14034     {
14035       emit_move_insn (operands[2], op1);
14036       op1 = operands[2];
14037     }
14039   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14040   DONE;
14043 (define_insn "*btdi_rex64"
14044   [(set (reg:CCC FLAGS_REG)
14045         (compare:CCC
14046           (zero_extract:DI
14047             (match_operand:DI 0 "register_operand" "r")
14048             (const_int 1)
14049             (match_operand:DI 1 "nonmemory_operand" "rN"))
14050           (const_int 0)))]
14051   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14052   "bt{q}\t{%1, %0|%0, %1}"
14053   [(set_attr "type" "alu1")])
14055 (define_insn "*btsi"
14056   [(set (reg:CCC FLAGS_REG)
14057         (compare:CCC
14058           (zero_extract:SI
14059             (match_operand:SI 0 "register_operand" "r")
14060             (const_int 1)
14061             (match_operand:SI 1 "nonmemory_operand" "rN"))
14062           (const_int 0)))]
14063   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14064   "bt{l}\t{%1, %0|%0, %1}"
14065   [(set_attr "type" "alu1")])
14067 ;; Store-flag instructions.
14069 ;; For all sCOND expanders, also expand the compare or test insn that
14070 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
14072 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
14073 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
14074 ;; way, which can later delete the movzx if only QImode is needed.
14076 (define_expand "s<code>"
14077   [(set (match_operand:QI 0 "register_operand" "")
14078         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14079   ""
14080   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14082 (define_expand "s<code>"
14083   [(set (match_operand:QI 0 "register_operand" "")
14084         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
14085   "TARGET_80387 || TARGET_SSE"
14086   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
14088 (define_insn "*setcc_1"
14089   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14090         (match_operator:QI 1 "ix86_comparison_operator"
14091           [(reg FLAGS_REG) (const_int 0)]))]
14092   ""
14093   "set%C1\t%0"
14094   [(set_attr "type" "setcc")
14095    (set_attr "mode" "QI")])
14097 (define_insn "*setcc_2"
14098   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14099         (match_operator:QI 1 "ix86_comparison_operator"
14100           [(reg FLAGS_REG) (const_int 0)]))]
14101   ""
14102   "set%C1\t%0"
14103   [(set_attr "type" "setcc")
14104    (set_attr "mode" "QI")])
14106 ;; In general it is not safe to assume too much about CCmode registers,
14107 ;; so simplify-rtx stops when it sees a second one.  Under certain
14108 ;; conditions this is safe on x86, so help combine not create
14110 ;;      seta    %al
14111 ;;      testb   %al, %al
14112 ;;      sete    %al
14114 (define_split
14115   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14116         (ne:QI (match_operator 1 "ix86_comparison_operator"
14117                  [(reg FLAGS_REG) (const_int 0)])
14118             (const_int 0)))]
14119   ""
14120   [(set (match_dup 0) (match_dup 1))]
14122   PUT_MODE (operands[1], QImode);
14125 (define_split
14126   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14127         (ne:QI (match_operator 1 "ix86_comparison_operator"
14128                  [(reg FLAGS_REG) (const_int 0)])
14129             (const_int 0)))]
14130   ""
14131   [(set (match_dup 0) (match_dup 1))]
14133   PUT_MODE (operands[1], QImode);
14136 (define_split
14137   [(set (match_operand:QI 0 "nonimmediate_operand" "")
14138         (eq:QI (match_operator 1 "ix86_comparison_operator"
14139                  [(reg FLAGS_REG) (const_int 0)])
14140             (const_int 0)))]
14141   ""
14142   [(set (match_dup 0) (match_dup 1))]
14144   rtx new_op1 = copy_rtx (operands[1]);
14145   operands[1] = new_op1;
14146   PUT_MODE (new_op1, QImode);
14147   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14148                                              GET_MODE (XEXP (new_op1, 0))));
14150   /* Make sure that (a) the CCmode we have for the flags is strong
14151      enough for the reversed compare or (b) we have a valid FP compare.  */
14152   if (! ix86_comparison_operator (new_op1, VOIDmode))
14153     FAIL;
14156 (define_split
14157   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14158         (eq:QI (match_operator 1 "ix86_comparison_operator"
14159                  [(reg FLAGS_REG) (const_int 0)])
14160             (const_int 0)))]
14161   ""
14162   [(set (match_dup 0) (match_dup 1))]
14164   rtx new_op1 = copy_rtx (operands[1]);
14165   operands[1] = new_op1;
14166   PUT_MODE (new_op1, QImode);
14167   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14168                                              GET_MODE (XEXP (new_op1, 0))));
14170   /* Make sure that (a) the CCmode we have for the flags is strong
14171      enough for the reversed compare or (b) we have a valid FP compare.  */
14172   if (! ix86_comparison_operator (new_op1, VOIDmode))
14173     FAIL;
14176 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14177 ;; subsequent logical operations are used to imitate conditional moves.
14178 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14179 ;; it directly.
14181 (define_insn "*avx_setcc<mode>"
14182   [(set (match_operand:MODEF 0 "register_operand" "=x")
14183         (match_operator:MODEF 1 "avx_comparison_float_operator"
14184           [(match_operand:MODEF 2 "register_operand" "x")
14185            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14186   "TARGET_AVX"
14187   "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14188   [(set_attr "type" "ssecmp")
14189    (set_attr "prefix" "vex")
14190    (set_attr "mode" "<MODE>")])
14192 (define_insn "*sse_setcc<mode>"
14193   [(set (match_operand:MODEF 0 "register_operand" "=x")
14194         (match_operator:MODEF 1 "sse_comparison_operator"
14195           [(match_operand:MODEF 2 "register_operand" "0")
14196            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14197   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14198   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14199   [(set_attr "type" "ssecmp")
14200    (set_attr "mode" "<MODE>")])
14202 (define_insn "*sse5_setcc<mode>"
14203   [(set (match_operand:MODEF 0 "register_operand" "=x")
14204         (match_operator:MODEF 1 "sse5_comparison_float_operator"
14205           [(match_operand:MODEF 2 "register_operand" "x")
14206            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14207   "TARGET_SSE5"
14208   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14209   [(set_attr "type" "sse4arg")
14210    (set_attr "mode" "<MODE>")])
14213 ;; Basic conditional jump instructions.
14214 ;; We ignore the overflow flag for signed branch instructions.
14216 ;; For all bCOND expanders, also expand the compare or test insn that
14217 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
14219 (define_expand "b<code>"
14220   [(set (pc)
14221         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
14222                                    (const_int 0))
14223                       (label_ref (match_operand 0 ""))
14224                       (pc)))]
14225   ""
14226   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14228 (define_expand "b<code>"
14229   [(set (pc)
14230         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14231                                   (const_int 0))
14232                       (label_ref (match_operand 0 ""))
14233                       (pc)))]
14234   "TARGET_80387 || TARGET_SSE_MATH"
14235   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14237 (define_insn "*jcc_1"
14238   [(set (pc)
14239         (if_then_else (match_operator 1 "ix86_comparison_operator"
14240                                       [(reg FLAGS_REG) (const_int 0)])
14241                       (label_ref (match_operand 0 "" ""))
14242                       (pc)))]
14243   ""
14244   "%+j%C1\t%l0"
14245   [(set_attr "type" "ibr")
14246    (set_attr "modrm" "0")
14247    (set (attr "length")
14248            (if_then_else (and (ge (minus (match_dup 0) (pc))
14249                                   (const_int -126))
14250                               (lt (minus (match_dup 0) (pc))
14251                                   (const_int 128)))
14252              (const_int 2)
14253              (const_int 6)))])
14255 (define_insn "*jcc_2"
14256   [(set (pc)
14257         (if_then_else (match_operator 1 "ix86_comparison_operator"
14258                                       [(reg FLAGS_REG) (const_int 0)])
14259                       (pc)
14260                       (label_ref (match_operand 0 "" ""))))]
14261   ""
14262   "%+j%c1\t%l0"
14263   [(set_attr "type" "ibr")
14264    (set_attr "modrm" "0")
14265    (set (attr "length")
14266            (if_then_else (and (ge (minus (match_dup 0) (pc))
14267                                   (const_int -126))
14268                               (lt (minus (match_dup 0) (pc))
14269                                   (const_int 128)))
14270              (const_int 2)
14271              (const_int 6)))])
14273 ;; In general it is not safe to assume too much about CCmode registers,
14274 ;; so simplify-rtx stops when it sees a second one.  Under certain
14275 ;; conditions this is safe on x86, so help combine not create
14277 ;;      seta    %al
14278 ;;      testb   %al, %al
14279 ;;      je      Lfoo
14281 (define_split
14282   [(set (pc)
14283         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14284                                       [(reg FLAGS_REG) (const_int 0)])
14285                           (const_int 0))
14286                       (label_ref (match_operand 1 "" ""))
14287                       (pc)))]
14288   ""
14289   [(set (pc)
14290         (if_then_else (match_dup 0)
14291                       (label_ref (match_dup 1))
14292                       (pc)))]
14294   PUT_MODE (operands[0], VOIDmode);
14297 (define_split
14298   [(set (pc)
14299         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14300                                       [(reg FLAGS_REG) (const_int 0)])
14301                           (const_int 0))
14302                       (label_ref (match_operand 1 "" ""))
14303                       (pc)))]
14304   ""
14305   [(set (pc)
14306         (if_then_else (match_dup 0)
14307                       (label_ref (match_dup 1))
14308                       (pc)))]
14310   rtx new_op0 = copy_rtx (operands[0]);
14311   operands[0] = new_op0;
14312   PUT_MODE (new_op0, VOIDmode);
14313   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14314                                              GET_MODE (XEXP (new_op0, 0))));
14316   /* Make sure that (a) the CCmode we have for the flags is strong
14317      enough for the reversed compare or (b) we have a valid FP compare.  */
14318   if (! ix86_comparison_operator (new_op0, VOIDmode))
14319     FAIL;
14322 ;; zero_extend in SImode is correct, since this is what combine pass
14323 ;; generates from shift insn with QImode operand.  Actually, the mode of
14324 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14325 ;; appropriate modulo of the bit offset value.
14327 (define_insn_and_split "*jcc_btdi_rex64"
14328   [(set (pc)
14329         (if_then_else (match_operator 0 "bt_comparison_operator"
14330                         [(zero_extract:DI
14331                            (match_operand:DI 1 "register_operand" "r")
14332                            (const_int 1)
14333                            (zero_extend:SI
14334                              (match_operand:QI 2 "register_operand" "r")))
14335                          (const_int 0)])
14336                       (label_ref (match_operand 3 "" ""))
14337                       (pc)))
14338    (clobber (reg:CC FLAGS_REG))]
14339   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14340   "#"
14341   "&& 1"
14342   [(set (reg:CCC FLAGS_REG)
14343         (compare:CCC
14344           (zero_extract:DI
14345             (match_dup 1)
14346             (const_int 1)
14347             (match_dup 2))
14348           (const_int 0)))
14349    (set (pc)
14350         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14351                       (label_ref (match_dup 3))
14352                       (pc)))]
14354   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14356   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14359 ;; avoid useless masking of bit offset operand
14360 (define_insn_and_split "*jcc_btdi_mask_rex64"
14361   [(set (pc)
14362         (if_then_else (match_operator 0 "bt_comparison_operator"
14363                         [(zero_extract:DI
14364                            (match_operand:DI 1 "register_operand" "r")
14365                            (const_int 1)
14366                            (and:SI
14367                              (match_operand:SI 2 "register_operand" "r")
14368                              (match_operand:SI 3 "const_int_operand" "n")))])
14369                       (label_ref (match_operand 4 "" ""))
14370                       (pc)))
14371    (clobber (reg:CC FLAGS_REG))]
14372   "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14373    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14374   "#"
14375   "&& 1"
14376   [(set (reg:CCC FLAGS_REG)
14377         (compare:CCC
14378           (zero_extract:DI
14379             (match_dup 1)
14380             (const_int 1)
14381             (match_dup 2))
14382           (const_int 0)))
14383    (set (pc)
14384         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14385                       (label_ref (match_dup 4))
14386                       (pc)))]
14388   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14390   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14393 (define_insn_and_split "*jcc_btsi"
14394   [(set (pc)
14395         (if_then_else (match_operator 0 "bt_comparison_operator"
14396                         [(zero_extract:SI
14397                            (match_operand:SI 1 "register_operand" "r")
14398                            (const_int 1)
14399                            (zero_extend:SI
14400                              (match_operand:QI 2 "register_operand" "r")))
14401                          (const_int 0)])
14402                       (label_ref (match_operand 3 "" ""))
14403                       (pc)))
14404    (clobber (reg:CC FLAGS_REG))]
14405   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14406   "#"
14407   "&& 1"
14408   [(set (reg:CCC FLAGS_REG)
14409         (compare:CCC
14410           (zero_extract:SI
14411             (match_dup 1)
14412             (const_int 1)
14413             (match_dup 2))
14414           (const_int 0)))
14415    (set (pc)
14416         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14417                       (label_ref (match_dup 3))
14418                       (pc)))]
14420   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14422   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14425 ;; avoid useless masking of bit offset operand
14426 (define_insn_and_split "*jcc_btsi_mask"
14427   [(set (pc)
14428         (if_then_else (match_operator 0 "bt_comparison_operator"
14429                         [(zero_extract:SI
14430                            (match_operand:SI 1 "register_operand" "r")
14431                            (const_int 1)
14432                            (and:SI
14433                              (match_operand:SI 2 "register_operand" "r")
14434                              (match_operand:SI 3 "const_int_operand" "n")))])
14435                       (label_ref (match_operand 4 "" ""))
14436                       (pc)))
14437    (clobber (reg:CC FLAGS_REG))]
14438   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14439    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14440   "#"
14441   "&& 1"
14442   [(set (reg:CCC FLAGS_REG)
14443         (compare:CCC
14444           (zero_extract:SI
14445             (match_dup 1)
14446             (const_int 1)
14447             (match_dup 2))
14448           (const_int 0)))
14449    (set (pc)
14450         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14451                       (label_ref (match_dup 4))
14452                       (pc)))]
14453   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14455 (define_insn_and_split "*jcc_btsi_1"
14456   [(set (pc)
14457         (if_then_else (match_operator 0 "bt_comparison_operator"
14458                         [(and:SI
14459                            (lshiftrt:SI
14460                              (match_operand:SI 1 "register_operand" "r")
14461                              (match_operand:QI 2 "register_operand" "r"))
14462                            (const_int 1))
14463                          (const_int 0)])
14464                       (label_ref (match_operand 3 "" ""))
14465                       (pc)))
14466    (clobber (reg:CC FLAGS_REG))]
14467   "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14468   "#"
14469   "&& 1"
14470   [(set (reg:CCC FLAGS_REG)
14471         (compare:CCC
14472           (zero_extract:SI
14473             (match_dup 1)
14474             (const_int 1)
14475             (match_dup 2))
14476           (const_int 0)))
14477    (set (pc)
14478         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14479                       (label_ref (match_dup 3))
14480                       (pc)))]
14482   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14484   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14487 ;; avoid useless masking of bit offset operand
14488 (define_insn_and_split "*jcc_btsi_mask_1"
14489   [(set (pc)
14490         (if_then_else
14491           (match_operator 0 "bt_comparison_operator"
14492             [(and:SI
14493                (lshiftrt:SI
14494                  (match_operand:SI 1 "register_operand" "r")
14495                  (subreg:QI
14496                    (and:SI
14497                      (match_operand:SI 2 "register_operand" "r")
14498                      (match_operand:SI 3 "const_int_operand" "n")) 0))
14499                (const_int 1))
14500              (const_int 0)])
14501           (label_ref (match_operand 4 "" ""))
14502           (pc)))
14503    (clobber (reg:CC FLAGS_REG))]
14504   "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
14505    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14506   "#"
14507   "&& 1"
14508   [(set (reg:CCC FLAGS_REG)
14509         (compare:CCC
14510           (zero_extract:SI
14511             (match_dup 1)
14512             (const_int 1)
14513             (match_dup 2))
14514           (const_int 0)))
14515    (set (pc)
14516         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14517                       (label_ref (match_dup 4))
14518                       (pc)))]
14519   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14521 ;; Define combination compare-and-branch fp compare instructions to use
14522 ;; during early optimization.  Splitting the operation apart early makes
14523 ;; for bad code when we want to reverse the operation.
14525 (define_insn "*fp_jcc_1_mixed"
14526   [(set (pc)
14527         (if_then_else (match_operator 0 "comparison_operator"
14528                         [(match_operand 1 "register_operand" "f,x")
14529                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14530           (label_ref (match_operand 3 "" ""))
14531           (pc)))
14532    (clobber (reg:CCFP FPSR_REG))
14533    (clobber (reg:CCFP FLAGS_REG))]
14534   "TARGET_MIX_SSE_I387
14535    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14536    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14537    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14538   "#")
14540 (define_insn "*fp_jcc_1_sse"
14541   [(set (pc)
14542         (if_then_else (match_operator 0 "comparison_operator"
14543                         [(match_operand 1 "register_operand" "x")
14544                          (match_operand 2 "nonimmediate_operand" "xm")])
14545           (label_ref (match_operand 3 "" ""))
14546           (pc)))
14547    (clobber (reg:CCFP FPSR_REG))
14548    (clobber (reg:CCFP FLAGS_REG))]
14549   "TARGET_SSE_MATH
14550    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14551    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14552    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14553   "#")
14555 (define_insn "*fp_jcc_1_387"
14556   [(set (pc)
14557         (if_then_else (match_operator 0 "comparison_operator"
14558                         [(match_operand 1 "register_operand" "f")
14559                          (match_operand 2 "register_operand" "f")])
14560           (label_ref (match_operand 3 "" ""))
14561           (pc)))
14562    (clobber (reg:CCFP FPSR_REG))
14563    (clobber (reg:CCFP FLAGS_REG))]
14564   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14565    && TARGET_CMOVE
14566    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14567    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14568   "#")
14570 (define_insn "*fp_jcc_2_mixed"
14571   [(set (pc)
14572         (if_then_else (match_operator 0 "comparison_operator"
14573                         [(match_operand 1 "register_operand" "f,x")
14574                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14575           (pc)
14576           (label_ref (match_operand 3 "" ""))))
14577    (clobber (reg:CCFP FPSR_REG))
14578    (clobber (reg:CCFP FLAGS_REG))]
14579   "TARGET_MIX_SSE_I387
14580    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14581    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14582    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14583   "#")
14585 (define_insn "*fp_jcc_2_sse"
14586   [(set (pc)
14587         (if_then_else (match_operator 0 "comparison_operator"
14588                         [(match_operand 1 "register_operand" "x")
14589                          (match_operand 2 "nonimmediate_operand" "xm")])
14590           (pc)
14591           (label_ref (match_operand 3 "" ""))))
14592    (clobber (reg:CCFP FPSR_REG))
14593    (clobber (reg:CCFP FLAGS_REG))]
14594   "TARGET_SSE_MATH
14595    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14596    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14597    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14598   "#")
14600 (define_insn "*fp_jcc_2_387"
14601   [(set (pc)
14602         (if_then_else (match_operator 0 "comparison_operator"
14603                         [(match_operand 1 "register_operand" "f")
14604                          (match_operand 2 "register_operand" "f")])
14605           (pc)
14606           (label_ref (match_operand 3 "" ""))))
14607    (clobber (reg:CCFP FPSR_REG))
14608    (clobber (reg:CCFP FLAGS_REG))]
14609   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14610    && TARGET_CMOVE
14611    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14612    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14613   "#")
14615 (define_insn "*fp_jcc_3_387"
14616   [(set (pc)
14617         (if_then_else (match_operator 0 "comparison_operator"
14618                         [(match_operand 1 "register_operand" "f")
14619                          (match_operand 2 "nonimmediate_operand" "fm")])
14620           (label_ref (match_operand 3 "" ""))
14621           (pc)))
14622    (clobber (reg:CCFP FPSR_REG))
14623    (clobber (reg:CCFP FLAGS_REG))
14624    (clobber (match_scratch:HI 4 "=a"))]
14625   "TARGET_80387
14626    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14627    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14628    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14629    && SELECT_CC_MODE (GET_CODE (operands[0]),
14630                       operands[1], operands[2]) == CCFPmode
14631    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14632   "#")
14634 (define_insn "*fp_jcc_4_387"
14635   [(set (pc)
14636         (if_then_else (match_operator 0 "comparison_operator"
14637                         [(match_operand 1 "register_operand" "f")
14638                          (match_operand 2 "nonimmediate_operand" "fm")])
14639           (pc)
14640           (label_ref (match_operand 3 "" ""))))
14641    (clobber (reg:CCFP FPSR_REG))
14642    (clobber (reg:CCFP FLAGS_REG))
14643    (clobber (match_scratch:HI 4 "=a"))]
14644   "TARGET_80387
14645    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14646    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14647    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14648    && SELECT_CC_MODE (GET_CODE (operands[0]),
14649                       operands[1], operands[2]) == CCFPmode
14650    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14651   "#")
14653 (define_insn "*fp_jcc_5_387"
14654   [(set (pc)
14655         (if_then_else (match_operator 0 "comparison_operator"
14656                         [(match_operand 1 "register_operand" "f")
14657                          (match_operand 2 "register_operand" "f")])
14658           (label_ref (match_operand 3 "" ""))
14659           (pc)))
14660    (clobber (reg:CCFP FPSR_REG))
14661    (clobber (reg:CCFP FLAGS_REG))
14662    (clobber (match_scratch:HI 4 "=a"))]
14663   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14664    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14665    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14666   "#")
14668 (define_insn "*fp_jcc_6_387"
14669   [(set (pc)
14670         (if_then_else (match_operator 0 "comparison_operator"
14671                         [(match_operand 1 "register_operand" "f")
14672                          (match_operand 2 "register_operand" "f")])
14673           (pc)
14674           (label_ref (match_operand 3 "" ""))))
14675    (clobber (reg:CCFP FPSR_REG))
14676    (clobber (reg:CCFP FLAGS_REG))
14677    (clobber (match_scratch:HI 4 "=a"))]
14678   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14679    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14680    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14681   "#")
14683 (define_insn "*fp_jcc_7_387"
14684   [(set (pc)
14685         (if_then_else (match_operator 0 "comparison_operator"
14686                         [(match_operand 1 "register_operand" "f")
14687                          (match_operand 2 "const0_operand" "")])
14688           (label_ref (match_operand 3 "" ""))
14689           (pc)))
14690    (clobber (reg:CCFP FPSR_REG))
14691    (clobber (reg:CCFP FLAGS_REG))
14692    (clobber (match_scratch:HI 4 "=a"))]
14693   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14694    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14695    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14696    && SELECT_CC_MODE (GET_CODE (operands[0]),
14697                       operands[1], operands[2]) == CCFPmode
14698    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14699   "#")
14701 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14702 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14703 ;; with a precedence over other operators and is always put in the first
14704 ;; place. Swap condition and operands to match ficom instruction.
14706 (define_insn "*fp_jcc_8<mode>_387"
14707   [(set (pc)
14708         (if_then_else (match_operator 0 "comparison_operator"
14709                         [(match_operator 1 "float_operator"
14710                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14711                            (match_operand 3 "register_operand" "f,f")])
14712           (label_ref (match_operand 4 "" ""))
14713           (pc)))
14714    (clobber (reg:CCFP FPSR_REG))
14715    (clobber (reg:CCFP FLAGS_REG))
14716    (clobber (match_scratch:HI 5 "=a,a"))]
14717   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14718    && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14719    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14720    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14721    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14722    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14723   "#")
14725 (define_split
14726   [(set (pc)
14727         (if_then_else (match_operator 0 "comparison_operator"
14728                         [(match_operand 1 "register_operand" "")
14729                          (match_operand 2 "nonimmediate_operand" "")])
14730           (match_operand 3 "" "")
14731           (match_operand 4 "" "")))
14732    (clobber (reg:CCFP FPSR_REG))
14733    (clobber (reg:CCFP FLAGS_REG))]
14734   "reload_completed"
14735   [(const_int 0)]
14737   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14738                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14739   DONE;
14742 (define_split
14743   [(set (pc)
14744         (if_then_else (match_operator 0 "comparison_operator"
14745                         [(match_operand 1 "register_operand" "")
14746                          (match_operand 2 "general_operand" "")])
14747           (match_operand 3 "" "")
14748           (match_operand 4 "" "")))
14749    (clobber (reg:CCFP FPSR_REG))
14750    (clobber (reg:CCFP FLAGS_REG))
14751    (clobber (match_scratch:HI 5 "=a"))]
14752   "reload_completed"
14753   [(const_int 0)]
14755   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14756                         operands[3], operands[4], operands[5], NULL_RTX);
14757   DONE;
14760 (define_split
14761   [(set (pc)
14762         (if_then_else (match_operator 0 "comparison_operator"
14763                         [(match_operator 1 "float_operator"
14764                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14765                            (match_operand 3 "register_operand" "")])
14766           (match_operand 4 "" "")
14767           (match_operand 5 "" "")))
14768    (clobber (reg:CCFP FPSR_REG))
14769    (clobber (reg:CCFP FLAGS_REG))
14770    (clobber (match_scratch:HI 6 "=a"))]
14771   "reload_completed"
14772   [(const_int 0)]
14774   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14775   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14776                         operands[3], operands[7],
14777                         operands[4], operands[5], operands[6], NULL_RTX);
14778   DONE;
14781 ;; %%% Kill this when reload knows how to do it.
14782 (define_split
14783   [(set (pc)
14784         (if_then_else (match_operator 0 "comparison_operator"
14785                         [(match_operator 1 "float_operator"
14786                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14787                            (match_operand 3 "register_operand" "")])
14788           (match_operand 4 "" "")
14789           (match_operand 5 "" "")))
14790    (clobber (reg:CCFP FPSR_REG))
14791    (clobber (reg:CCFP FLAGS_REG))
14792    (clobber (match_scratch:HI 6 "=a"))]
14793   "reload_completed"
14794   [(const_int 0)]
14796   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14797   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14798   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14799                         operands[3], operands[7],
14800                         operands[4], operands[5], operands[6], operands[2]);
14801   DONE;
14804 ;; Unconditional and other jump instructions
14806 (define_insn "jump"
14807   [(set (pc)
14808         (label_ref (match_operand 0 "" "")))]
14809   ""
14810   "jmp\t%l0"
14811   [(set_attr "type" "ibr")
14812    (set (attr "length")
14813            (if_then_else (and (ge (minus (match_dup 0) (pc))
14814                                   (const_int -126))
14815                               (lt (minus (match_dup 0) (pc))
14816                                   (const_int 128)))
14817              (const_int 2)
14818              (const_int 5)))
14819    (set_attr "modrm" "0")])
14821 (define_expand "indirect_jump"
14822   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14823   ""
14824   "")
14826 (define_insn "*indirect_jump"
14827   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14828   ""
14829   "jmp\t%A0"
14830   [(set_attr "type" "ibr")
14831    (set_attr "length_immediate" "0")])
14833 (define_expand "tablejump"
14834   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14835               (use (label_ref (match_operand 1 "" "")))])]
14836   ""
14838   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14839      relative.  Convert the relative address to an absolute address.  */
14840   if (flag_pic)
14841     {
14842       rtx op0, op1;
14843       enum rtx_code code;
14845       /* We can't use @GOTOFF for text labels on VxWorks;
14846          see gotoff_operand.  */
14847       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14848         {
14849           code = PLUS;
14850           op0 = operands[0];
14851           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14852         }
14853       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14854         {
14855           code = PLUS;
14856           op0 = operands[0];
14857           op1 = pic_offset_table_rtx;
14858         }
14859       else
14860         {
14861           code = MINUS;
14862           op0 = pic_offset_table_rtx;
14863           op1 = operands[0];
14864         }
14866       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14867                                          OPTAB_DIRECT);
14868     }
14871 (define_insn "*tablejump_1"
14872   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14873    (use (label_ref (match_operand 1 "" "")))]
14874   ""
14875   "jmp\t%A0"
14876   [(set_attr "type" "ibr")
14877    (set_attr "length_immediate" "0")])
14879 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14881 (define_peephole2
14882   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14883    (set (match_operand:QI 1 "register_operand" "")
14884         (match_operator:QI 2 "ix86_comparison_operator"
14885           [(reg FLAGS_REG) (const_int 0)]))
14886    (set (match_operand 3 "q_regs_operand" "")
14887         (zero_extend (match_dup 1)))]
14888   "(peep2_reg_dead_p (3, operands[1])
14889     || operands_match_p (operands[1], operands[3]))
14890    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14891   [(set (match_dup 4) (match_dup 0))
14892    (set (strict_low_part (match_dup 5))
14893         (match_dup 2))]
14895   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14896   operands[5] = gen_lowpart (QImode, operands[3]);
14897   ix86_expand_clear (operands[3]);
14900 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14902 (define_peephole2
14903   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14904    (set (match_operand:QI 1 "register_operand" "")
14905         (match_operator:QI 2 "ix86_comparison_operator"
14906           [(reg FLAGS_REG) (const_int 0)]))
14907    (parallel [(set (match_operand 3 "q_regs_operand" "")
14908                    (zero_extend (match_dup 1)))
14909               (clobber (reg:CC FLAGS_REG))])]
14910   "(peep2_reg_dead_p (3, operands[1])
14911     || operands_match_p (operands[1], operands[3]))
14912    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14913   [(set (match_dup 4) (match_dup 0))
14914    (set (strict_low_part (match_dup 5))
14915         (match_dup 2))]
14917   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14918   operands[5] = gen_lowpart (QImode, operands[3]);
14919   ix86_expand_clear (operands[3]);
14922 ;; Call instructions.
14924 ;; The predicates normally associated with named expanders are not properly
14925 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14926 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14928 ;; Call subroutine returning no value.
14930 (define_expand "call_pop"
14931   [(parallel [(call (match_operand:QI 0 "" "")
14932                     (match_operand:SI 1 "" ""))
14933               (set (reg:SI SP_REG)
14934                    (plus:SI (reg:SI SP_REG)
14935                             (match_operand:SI 3 "" "")))])]
14936   "!TARGET_64BIT"
14938   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14939   DONE;
14942 (define_insn "*call_pop_0"
14943   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14944          (match_operand:SI 1 "" ""))
14945    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14946                             (match_operand:SI 2 "immediate_operand" "")))]
14947   "!TARGET_64BIT"
14949   if (SIBLING_CALL_P (insn))
14950     return "jmp\t%P0";
14951   else
14952     return "call\t%P0";
14954   [(set_attr "type" "call")])
14956 (define_insn "*call_pop_1"
14957   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14958          (match_operand:SI 1 "" ""))
14959    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14960                             (match_operand:SI 2 "immediate_operand" "i")))]
14961   "!TARGET_64BIT"
14963   if (constant_call_address_operand (operands[0], Pmode))
14964     {
14965       if (SIBLING_CALL_P (insn))
14966         return "jmp\t%P0";
14967       else
14968         return "call\t%P0";
14969     }
14970   if (SIBLING_CALL_P (insn))
14971     return "jmp\t%A0";
14972   else
14973     return "call\t%A0";
14975   [(set_attr "type" "call")])
14977 (define_expand "call"
14978   [(call (match_operand:QI 0 "" "")
14979          (match_operand 1 "" ""))
14980    (use (match_operand 2 "" ""))]
14981   ""
14983   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14984   DONE;
14987 (define_expand "sibcall"
14988   [(call (match_operand:QI 0 "" "")
14989          (match_operand 1 "" ""))
14990    (use (match_operand 2 "" ""))]
14991   ""
14993   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14994   DONE;
14997 (define_insn "*call_0"
14998   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14999          (match_operand 1 "" ""))]
15000   ""
15002   if (SIBLING_CALL_P (insn))
15003     return "jmp\t%P0";
15004   else
15005     return "call\t%P0";
15007   [(set_attr "type" "call")])
15009 (define_insn "*call_1"
15010   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15011          (match_operand 1 "" ""))]
15012   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15014   if (constant_call_address_operand (operands[0], Pmode))
15015     return "call\t%P0";
15016   return "call\t%A0";
15018   [(set_attr "type" "call")])
15020 (define_insn "*sibcall_1"
15021   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15022          (match_operand 1 "" ""))]
15023   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15025   if (constant_call_address_operand (operands[0], Pmode))
15026     return "jmp\t%P0";
15027   return "jmp\t%A0";
15029   [(set_attr "type" "call")])
15031 (define_insn "*call_1_rex64"
15032   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15033          (match_operand 1 "" ""))]
15034   "!SIBLING_CALL_P (insn) && TARGET_64BIT
15035    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15037   if (constant_call_address_operand (operands[0], Pmode))
15038     return "call\t%P0";
15039   return "call\t%A0";
15041   [(set_attr "type" "call")])
15043 (define_insn "*call_1_rex64_large"
15044   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15045          (match_operand 1 "" ""))]
15046   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15047   "call\t%A0"
15048   [(set_attr "type" "call")])
15050 (define_insn "*sibcall_1_rex64"
15051   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15052          (match_operand 1 "" ""))]
15053   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15054   "jmp\t%P0"
15055   [(set_attr "type" "call")])
15057 (define_insn "*sibcall_1_rex64_v"
15058   [(call (mem:QI (reg:DI R11_REG))
15059          (match_operand 0 "" ""))]
15060   "SIBLING_CALL_P (insn) && TARGET_64BIT"
15061   "jmp\t{*%%}r11"
15062   [(set_attr "type" "call")])
15065 ;; Call subroutine, returning value in operand 0
15067 (define_expand "call_value_pop"
15068   [(parallel [(set (match_operand 0 "" "")
15069                    (call (match_operand:QI 1 "" "")
15070                          (match_operand:SI 2 "" "")))
15071               (set (reg:SI SP_REG)
15072                    (plus:SI (reg:SI SP_REG)
15073                             (match_operand:SI 4 "" "")))])]
15074   "!TARGET_64BIT"
15076   ix86_expand_call (operands[0], operands[1], operands[2],
15077                     operands[3], operands[4], 0);
15078   DONE;
15081 (define_expand "call_value"
15082   [(set (match_operand 0 "" "")
15083         (call (match_operand:QI 1 "" "")
15084               (match_operand:SI 2 "" "")))
15085    (use (match_operand:SI 3 "" ""))]
15086   ;; Operand 2 not used on the i386.
15087   ""
15089   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15090   DONE;
15093 (define_expand "sibcall_value"
15094   [(set (match_operand 0 "" "")
15095         (call (match_operand:QI 1 "" "")
15096               (match_operand:SI 2 "" "")))
15097    (use (match_operand:SI 3 "" ""))]
15098   ;; Operand 2 not used on the i386.
15099   ""
15101   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15102   DONE;
15105 ;; Call subroutine returning any type.
15107 (define_expand "untyped_call"
15108   [(parallel [(call (match_operand 0 "" "")
15109                     (const_int 0))
15110               (match_operand 1 "" "")
15111               (match_operand 2 "" "")])]
15112   ""
15114   int i;
15116   /* In order to give reg-stack an easier job in validating two
15117      coprocessor registers as containing a possible return value,
15118      simply pretend the untyped call returns a complex long double
15119      value.  */
15121   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15122                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15123                     operands[0], const0_rtx,
15124                     GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
15125                                                       : X64_SSE_REGPARM_MAX)
15126                              - 1),
15127                     NULL, 0);
15129   for (i = 0; i < XVECLEN (operands[2], 0); i++)
15130     {
15131       rtx set = XVECEXP (operands[2], 0, i);
15132       emit_move_insn (SET_DEST (set), SET_SRC (set));
15133     }
15135   /* The optimizer does not know that the call sets the function value
15136      registers we stored in the result block.  We avoid problems by
15137      claiming that all hard registers are used and clobbered at this
15138      point.  */
15139   emit_insn (gen_blockage ());
15141   DONE;
15144 ;; Prologue and epilogue instructions
15146 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15147 ;; all of memory.  This blocks insns from being moved across this point.
15149 (define_insn "blockage"
15150   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15151   ""
15152   ""
15153   [(set_attr "length" "0")])
15155 ;; As USE insns aren't meaningful after reload, this is used instead
15156 ;; to prevent deleting instructions setting registers for PIC code
15157 (define_insn "prologue_use"
15158   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15159   ""
15160   ""
15161   [(set_attr "length" "0")])
15163 ;; Insn emitted into the body of a function to return from a function.
15164 ;; This is only done if the function's epilogue is known to be simple.
15165 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15167 (define_expand "return"
15168   [(return)]
15169   "ix86_can_use_return_insn_p ()"
15171   if (crtl->args.pops_args)
15172     {
15173       rtx popc = GEN_INT (crtl->args.pops_args);
15174       emit_jump_insn (gen_return_pop_internal (popc));
15175       DONE;
15176     }
15179 (define_insn "return_internal"
15180   [(return)]
15181   "reload_completed"
15182   "ret"
15183   [(set_attr "length" "1")
15184    (set_attr "length_immediate" "0")
15185    (set_attr "modrm" "0")])
15187 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15188 ;; instruction Athlon and K8 have.
15190 (define_insn "return_internal_long"
15191   [(return)
15192    (unspec [(const_int 0)] UNSPEC_REP)]
15193   "reload_completed"
15194   "rep\;ret"
15195   [(set_attr "length" "1")
15196    (set_attr "length_immediate" "0")
15197    (set_attr "prefix_rep" "1")
15198    (set_attr "modrm" "0")])
15200 (define_insn "return_pop_internal"
15201   [(return)
15202    (use (match_operand:SI 0 "const_int_operand" ""))]
15203   "reload_completed"
15204   "ret\t%0"
15205   [(set_attr "length" "3")
15206    (set_attr "length_immediate" "2")
15207    (set_attr "modrm" "0")])
15209 (define_insn "return_indirect_internal"
15210   [(return)
15211    (use (match_operand:SI 0 "register_operand" "r"))]
15212   "reload_completed"
15213   "jmp\t%A0"
15214   [(set_attr "type" "ibr")
15215    (set_attr "length_immediate" "0")])
15217 (define_insn "nop"
15218   [(const_int 0)]
15219   ""
15220   "nop"
15221   [(set_attr "length" "1")
15222    (set_attr "length_immediate" "0")
15223    (set_attr "modrm" "0")])
15225 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
15226 ;; branch prediction penalty for the third jump in a 16-byte
15227 ;; block on K8.
15229 (define_insn "align"
15230   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15231   ""
15233 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
15234   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
15235 #else
15236   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15237      The align insn is used to avoid 3 jump instructions in the row to improve
15238      branch prediction and the benefits hardly outweigh the cost of extra 8
15239      nops on the average inserted by full alignment pseudo operation.  */
15240 #endif
15241   return "";
15243   [(set_attr "length" "16")])
15245 (define_expand "prologue"
15246   [(const_int 0)]
15247   ""
15248   "ix86_expand_prologue (); DONE;")
15250 (define_insn "set_got"
15251   [(set (match_operand:SI 0 "register_operand" "=r")
15252         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15253    (clobber (reg:CC FLAGS_REG))]
15254   "!TARGET_64BIT"
15255   { return output_set_got (operands[0], NULL_RTX); }
15256   [(set_attr "type" "multi")
15257    (set_attr "length" "12")])
15259 (define_insn "set_got_labelled"
15260   [(set (match_operand:SI 0 "register_operand" "=r")
15261         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15262          UNSPEC_SET_GOT))
15263    (clobber (reg:CC FLAGS_REG))]
15264   "!TARGET_64BIT"
15265   { return output_set_got (operands[0], operands[1]); }
15266   [(set_attr "type" "multi")
15267    (set_attr "length" "12")])
15269 (define_insn "set_got_rex64"
15270   [(set (match_operand:DI 0 "register_operand" "=r")
15271         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15272   "TARGET_64BIT"
15273   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15274   [(set_attr "type" "lea")
15275    (set_attr "length" "6")])
15277 (define_insn "set_rip_rex64"
15278   [(set (match_operand:DI 0 "register_operand" "=r")
15279         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15280   "TARGET_64BIT"
15281   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15282   [(set_attr "type" "lea")
15283    (set_attr "length" "6")])
15285 (define_insn "set_got_offset_rex64"
15286   [(set (match_operand:DI 0 "register_operand" "=r")
15287         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15288   "TARGET_64BIT"
15289   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15290   [(set_attr "type" "imov")
15291    (set_attr "length" "11")])
15293 (define_expand "epilogue"
15294   [(const_int 0)]
15295   ""
15296   "ix86_expand_epilogue (1); DONE;")
15298 (define_expand "sibcall_epilogue"
15299   [(const_int 0)]
15300   ""
15301   "ix86_expand_epilogue (0); DONE;")
15303 (define_expand "eh_return"
15304   [(use (match_operand 0 "register_operand" ""))]
15305   ""
15307   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15309   /* Tricky bit: we write the address of the handler to which we will
15310      be returning into someone else's stack frame, one word below the
15311      stack address we wish to restore.  */
15312   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15313   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15314   tmp = gen_rtx_MEM (Pmode, tmp);
15315   emit_move_insn (tmp, ra);
15317   if (Pmode == SImode)
15318     emit_jump_insn (gen_eh_return_si (sa));
15319   else
15320     emit_jump_insn (gen_eh_return_di (sa));
15321   emit_barrier ();
15322   DONE;
15325 (define_insn_and_split "eh_return_<mode>"
15326   [(set (pc)
15327         (unspec [(match_operand:P 0 "register_operand" "c")]
15328                  UNSPEC_EH_RETURN))]
15329   ""
15330   "#"
15331   "reload_completed"
15332   [(const_int 0)]
15333   "ix86_expand_epilogue (2); DONE;")
15335 (define_insn "leave"
15336   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15337    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15338    (clobber (mem:BLK (scratch)))]
15339   "!TARGET_64BIT"
15340   "leave"
15341   [(set_attr "type" "leave")])
15343 (define_insn "leave_rex64"
15344   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15345    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15346    (clobber (mem:BLK (scratch)))]
15347   "TARGET_64BIT"
15348   "leave"
15349   [(set_attr "type" "leave")])
15351 (define_expand "ffssi2"
15352   [(parallel
15353      [(set (match_operand:SI 0 "register_operand" "")
15354            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15355       (clobber (match_scratch:SI 2 ""))
15356       (clobber (reg:CC FLAGS_REG))])]
15357   ""
15359   if (TARGET_CMOVE)
15360     {
15361       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15362       DONE;
15363     }
15366 (define_expand "ffs_cmove"
15367   [(set (match_dup 2) (const_int -1))
15368    (parallel [(set (reg:CCZ FLAGS_REG)
15369                    (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
15370                                 (const_int 0)))
15371               (set (match_operand:SI 0 "register_operand" "")
15372                    (ctz:SI (match_dup 1)))])
15373    (set (match_dup 0) (if_then_else:SI
15374                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15375                         (match_dup 2)
15376                         (match_dup 0)))
15377    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15378               (clobber (reg:CC FLAGS_REG))])]
15379   "TARGET_CMOVE"
15380   "operands[2] = gen_reg_rtx (SImode);")
15382 (define_insn_and_split "*ffs_no_cmove"
15383   [(set (match_operand:SI 0 "register_operand" "=r")
15384         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15385    (clobber (match_scratch:SI 2 "=&q"))
15386    (clobber (reg:CC FLAGS_REG))]
15387   "!TARGET_CMOVE"
15388   "#"
15389   "&& reload_completed"
15390   [(parallel [(set (reg:CCZ FLAGS_REG)
15391                    (compare:CCZ (match_dup 1) (const_int 0)))
15392               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15393    (set (strict_low_part (match_dup 3))
15394         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15395    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15396               (clobber (reg:CC FLAGS_REG))])
15397    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15398               (clobber (reg:CC FLAGS_REG))])
15399    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15400               (clobber (reg:CC FLAGS_REG))])]
15402   operands[3] = gen_lowpart (QImode, operands[2]);
15403   ix86_expand_clear (operands[2]);
15406 (define_insn "*ffssi_1"
15407   [(set (reg:CCZ FLAGS_REG)
15408         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15409                      (const_int 0)))
15410    (set (match_operand:SI 0 "register_operand" "=r")
15411         (ctz:SI (match_dup 1)))]
15412   ""
15413   "bsf{l}\t{%1, %0|%0, %1}"
15414   [(set_attr "prefix_0f" "1")])
15416 (define_expand "ffsdi2"
15417   [(set (match_dup 2) (const_int -1))
15418    (parallel [(set (reg:CCZ FLAGS_REG)
15419                    (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
15420                                 (const_int 0)))
15421               (set (match_operand:DI 0 "register_operand" "")
15422                    (ctz:DI (match_dup 1)))])
15423    (set (match_dup 0) (if_then_else:DI
15424                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15425                         (match_dup 2)
15426                         (match_dup 0)))
15427    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15428               (clobber (reg:CC FLAGS_REG))])]
15429   "TARGET_64BIT"
15430   "operands[2] = gen_reg_rtx (DImode);")
15432 (define_insn "*ffsdi_1"
15433   [(set (reg:CCZ FLAGS_REG)
15434         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15435                      (const_int 0)))
15436    (set (match_operand:DI 0 "register_operand" "=r")
15437         (ctz:DI (match_dup 1)))]
15438   "TARGET_64BIT"
15439   "bsf{q}\t{%1, %0|%0, %1}"
15440   [(set_attr "prefix_0f" "1")])
15442 (define_insn "ctzsi2"
15443   [(set (match_operand:SI 0 "register_operand" "=r")
15444         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15445    (clobber (reg:CC FLAGS_REG))]
15446   ""
15447   "bsf{l}\t{%1, %0|%0, %1}"
15448   [(set_attr "prefix_0f" "1")])
15450 (define_insn "ctzdi2"
15451   [(set (match_operand:DI 0 "register_operand" "=r")
15452         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15453    (clobber (reg:CC FLAGS_REG))]
15454   "TARGET_64BIT"
15455   "bsf{q}\t{%1, %0|%0, %1}"
15456   [(set_attr "prefix_0f" "1")])
15458 (define_expand "clzsi2"
15459   [(parallel
15460      [(set (match_operand:SI 0 "register_operand" "")
15461            (minus:SI (const_int 31)
15462                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15463       (clobber (reg:CC FLAGS_REG))])
15464    (parallel
15465      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15466       (clobber (reg:CC FLAGS_REG))])]
15467   ""
15469   if (TARGET_ABM)
15470     {
15471       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15472       DONE;
15473     }
15476 (define_insn "clzsi2_abm"
15477   [(set (match_operand:SI 0 "register_operand" "=r")
15478         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15479    (clobber (reg:CC FLAGS_REG))]
15480   "TARGET_ABM"
15481   "lzcnt{l}\t{%1, %0|%0, %1}"
15482   [(set_attr "prefix_rep" "1")
15483    (set_attr "type" "bitmanip")
15484    (set_attr "mode" "SI")])
15486 (define_insn "*bsr"
15487   [(set (match_operand:SI 0 "register_operand" "=r")
15488         (minus:SI (const_int 31)
15489                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15490    (clobber (reg:CC FLAGS_REG))]
15491   ""
15492   "bsr{l}\t{%1, %0|%0, %1}"
15493   [(set_attr "prefix_0f" "1")
15494    (set_attr "mode" "SI")])
15496 (define_insn "popcountsi2"
15497   [(set (match_operand:SI 0 "register_operand" "=r")
15498         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15499    (clobber (reg:CC FLAGS_REG))]
15500   "TARGET_POPCNT"
15501   "popcnt{l}\t{%1, %0|%0, %1}"
15502   [(set_attr "prefix_rep" "1")
15503    (set_attr "type" "bitmanip")
15504    (set_attr "mode" "SI")])
15506 (define_insn "*popcountsi2_cmp"
15507   [(set (reg FLAGS_REG)
15508         (compare
15509           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15510           (const_int 0)))
15511    (set (match_operand:SI 0 "register_operand" "=r")
15512         (popcount:SI (match_dup 1)))]
15513   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15514   "popcnt{l}\t{%1, %0|%0, %1}"
15515   [(set_attr "prefix_rep" "1")
15516    (set_attr "type" "bitmanip")
15517    (set_attr "mode" "SI")])
15519 (define_insn "*popcountsi2_cmp_zext"
15520   [(set (reg FLAGS_REG)
15521         (compare
15522           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15523           (const_int 0)))
15524    (set (match_operand:DI 0 "register_operand" "=r")
15525         (zero_extend:DI(popcount:SI (match_dup 1))))]
15526   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15527   "popcnt{l}\t{%1, %0|%0, %1}"
15528   [(set_attr "prefix_rep" "1")
15529    (set_attr "type" "bitmanip")
15530    (set_attr "mode" "SI")])
15532 (define_expand "bswapsi2"
15533   [(set (match_operand:SI 0 "register_operand" "")
15534         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15535   ""
15537   if (!TARGET_BSWAP)
15538     {
15539       rtx x = operands[0];
15541       emit_move_insn (x, operands[1]);
15542       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15543       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15544       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15545       DONE;
15546     }
15549 (define_insn "*bswapsi_1"
15550   [(set (match_operand:SI 0 "register_operand" "=r")
15551         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15552   "TARGET_BSWAP"
15553   "bswap\t%0"
15554   [(set_attr "prefix_0f" "1")
15555    (set_attr "length" "2")])
15557 (define_insn "*bswaphi_lowpart_1"
15558   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15559         (bswap:HI (match_dup 0)))
15560    (clobber (reg:CC FLAGS_REG))]
15561   "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15562   "@
15563     xchg{b}\t{%h0, %b0|%b0, %h0}
15564     rol{w}\t{$8, %0|%0, 8}"
15565   [(set_attr "length" "2,4")
15566    (set_attr "mode" "QI,HI")])
15568 (define_insn "bswaphi_lowpart"
15569   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15570         (bswap:HI (match_dup 0)))
15571    (clobber (reg:CC FLAGS_REG))]
15572   ""
15573   "rol{w}\t{$8, %0|%0, 8}"
15574   [(set_attr "length" "4")
15575    (set_attr "mode" "HI")])
15577 (define_insn "bswapdi2"
15578   [(set (match_operand:DI 0 "register_operand" "=r")
15579         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15580   "TARGET_64BIT"
15581   "bswap\t%0"
15582   [(set_attr "prefix_0f" "1")
15583    (set_attr "length" "3")])
15585 (define_expand "clzdi2"
15586   [(parallel
15587      [(set (match_operand:DI 0 "register_operand" "")
15588            (minus:DI (const_int 63)
15589                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15590       (clobber (reg:CC FLAGS_REG))])
15591    (parallel
15592      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15593       (clobber (reg:CC FLAGS_REG))])]
15594   "TARGET_64BIT"
15596   if (TARGET_ABM)
15597     {
15598       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15599       DONE;
15600     }
15603 (define_insn "clzdi2_abm"
15604   [(set (match_operand:DI 0 "register_operand" "=r")
15605         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15606    (clobber (reg:CC FLAGS_REG))]
15607   "TARGET_64BIT && TARGET_ABM"
15608   "lzcnt{q}\t{%1, %0|%0, %1}"
15609   [(set_attr "prefix_rep" "1")
15610    (set_attr "type" "bitmanip")
15611    (set_attr "mode" "DI")])
15613 (define_insn "*bsr_rex64"
15614   [(set (match_operand:DI 0 "register_operand" "=r")
15615         (minus:DI (const_int 63)
15616                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15617    (clobber (reg:CC FLAGS_REG))]
15618   "TARGET_64BIT"
15619   "bsr{q}\t{%1, %0|%0, %1}"
15620   [(set_attr "prefix_0f" "1")
15621    (set_attr "mode" "DI")])
15623 (define_insn "popcountdi2"
15624   [(set (match_operand:DI 0 "register_operand" "=r")
15625         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15626    (clobber (reg:CC FLAGS_REG))]
15627   "TARGET_64BIT && TARGET_POPCNT"
15628   "popcnt{q}\t{%1, %0|%0, %1}"
15629   [(set_attr "prefix_rep" "1")
15630    (set_attr "type" "bitmanip")
15631    (set_attr "mode" "DI")])
15633 (define_insn "*popcountdi2_cmp"
15634   [(set (reg FLAGS_REG)
15635         (compare
15636           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15637           (const_int 0)))
15638    (set (match_operand:DI 0 "register_operand" "=r")
15639         (popcount:DI (match_dup 1)))]
15640   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15641   "popcnt{q}\t{%1, %0|%0, %1}"
15642   [(set_attr "prefix_rep" "1")
15643    (set_attr "type" "bitmanip")
15644    (set_attr "mode" "DI")])
15646 (define_expand "clzhi2"
15647   [(parallel
15648      [(set (match_operand:HI 0 "register_operand" "")
15649            (minus:HI (const_int 15)
15650                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15651       (clobber (reg:CC FLAGS_REG))])
15652    (parallel
15653      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15654       (clobber (reg:CC FLAGS_REG))])]
15655   ""
15657   if (TARGET_ABM)
15658     {
15659       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15660       DONE;
15661     }
15664 (define_insn "clzhi2_abm"
15665   [(set (match_operand:HI 0 "register_operand" "=r")
15666         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15667    (clobber (reg:CC FLAGS_REG))]
15668   "TARGET_ABM"
15669   "lzcnt{w}\t{%1, %0|%0, %1}"
15670   [(set_attr "prefix_rep" "1")
15671    (set_attr "type" "bitmanip")
15672    (set_attr "mode" "HI")])
15674 (define_insn "*bsrhi"
15675   [(set (match_operand:HI 0 "register_operand" "=r")
15676         (minus:HI (const_int 15)
15677                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15678    (clobber (reg:CC FLAGS_REG))]
15679   ""
15680   "bsr{w}\t{%1, %0|%0, %1}"
15681   [(set_attr "prefix_0f" "1")
15682    (set_attr "mode" "HI")])
15684 (define_insn "popcounthi2"
15685   [(set (match_operand:HI 0 "register_operand" "=r")
15686         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15687    (clobber (reg:CC FLAGS_REG))]
15688   "TARGET_POPCNT"
15689   "popcnt{w}\t{%1, %0|%0, %1}"
15690   [(set_attr "prefix_rep" "1")
15691    (set_attr "type" "bitmanip")
15692    (set_attr "mode" "HI")])
15694 (define_insn "*popcounthi2_cmp"
15695   [(set (reg FLAGS_REG)
15696         (compare
15697           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15698           (const_int 0)))
15699    (set (match_operand:HI 0 "register_operand" "=r")
15700         (popcount:HI (match_dup 1)))]
15701   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15702   "popcnt{w}\t{%1, %0|%0, %1}"
15703   [(set_attr "prefix_rep" "1")
15704    (set_attr "type" "bitmanip")
15705    (set_attr "mode" "HI")])
15707 (define_expand "paritydi2"
15708   [(set (match_operand:DI 0 "register_operand" "")
15709         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15710   "! TARGET_POPCNT"
15712   rtx scratch = gen_reg_rtx (QImode);
15713   rtx cond;
15715   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15716                                 NULL_RTX, operands[1]));
15718   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15719                          gen_rtx_REG (CCmode, FLAGS_REG),
15720                          const0_rtx);
15721   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15723   if (TARGET_64BIT)
15724     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15725   else
15726     {
15727       rtx tmp = gen_reg_rtx (SImode);
15729       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15730       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15731     }
15732   DONE;
15735 (define_insn_and_split "paritydi2_cmp"
15736   [(set (reg:CC FLAGS_REG)
15737         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15738    (clobber (match_scratch:DI 0 "=r"))
15739    (clobber (match_scratch:SI 1 "=&r"))
15740    (clobber (match_scratch:HI 2 "=Q"))]
15741   "! TARGET_POPCNT"
15742   "#"
15743   "&& reload_completed"
15744   [(parallel
15745      [(set (match_dup 1)
15746            (xor:SI (match_dup 1) (match_dup 4)))
15747       (clobber (reg:CC FLAGS_REG))])
15748    (parallel
15749      [(set (reg:CC FLAGS_REG)
15750            (parity:CC (match_dup 1)))
15751       (clobber (match_dup 1))
15752       (clobber (match_dup 2))])]
15754   operands[4] = gen_lowpart (SImode, operands[3]);
15756   if (TARGET_64BIT)
15757     {
15758       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15759       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15760     }
15761   else
15762     operands[1] = gen_highpart (SImode, operands[3]);
15765 (define_expand "paritysi2"
15766   [(set (match_operand:SI 0 "register_operand" "")
15767         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15768   "! TARGET_POPCNT"
15770   rtx scratch = gen_reg_rtx (QImode);
15771   rtx cond;
15773   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15775   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15776                          gen_rtx_REG (CCmode, FLAGS_REG),
15777                          const0_rtx);
15778   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15780   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15781   DONE;
15784 (define_insn_and_split "paritysi2_cmp"
15785   [(set (reg:CC FLAGS_REG)
15786         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15787    (clobber (match_scratch:SI 0 "=r"))
15788    (clobber (match_scratch:HI 1 "=&Q"))]
15789   "! TARGET_POPCNT"
15790   "#"
15791   "&& reload_completed"
15792   [(parallel
15793      [(set (match_dup 1)
15794            (xor:HI (match_dup 1) (match_dup 3)))
15795       (clobber (reg:CC FLAGS_REG))])
15796    (parallel
15797      [(set (reg:CC FLAGS_REG)
15798            (parity:CC (match_dup 1)))
15799       (clobber (match_dup 1))])]
15801   operands[3] = gen_lowpart (HImode, operands[2]);
15803   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15804   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15807 (define_insn "*parityhi2_cmp"
15808   [(set (reg:CC FLAGS_REG)
15809         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15810    (clobber (match_scratch:HI 0 "=Q"))]
15811   "! TARGET_POPCNT"
15812   "xor{b}\t{%h0, %b0|%b0, %h0}"
15813   [(set_attr "length" "2")
15814    (set_attr "mode" "HI")])
15816 (define_insn "*parityqi2_cmp"
15817   [(set (reg:CC FLAGS_REG)
15818         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15819   "! TARGET_POPCNT"
15820   "test{b}\t%0, %0"
15821   [(set_attr "length" "2")
15822    (set_attr "mode" "QI")])
15824 ;; Thread-local storage patterns for ELF.
15826 ;; Note that these code sequences must appear exactly as shown
15827 ;; in order to allow linker relaxation.
15829 (define_insn "*tls_global_dynamic_32_gnu"
15830   [(set (match_operand:SI 0 "register_operand" "=a")
15831         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15832                     (match_operand:SI 2 "tls_symbolic_operand" "")
15833                     (match_operand:SI 3 "call_insn_operand" "")]
15834                     UNSPEC_TLS_GD))
15835    (clobber (match_scratch:SI 4 "=d"))
15836    (clobber (match_scratch:SI 5 "=c"))
15837    (clobber (reg:CC FLAGS_REG))]
15838   "!TARGET_64BIT && TARGET_GNU_TLS"
15839   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15840   [(set_attr "type" "multi")
15841    (set_attr "length" "12")])
15843 (define_insn "*tls_global_dynamic_32_sun"
15844   [(set (match_operand:SI 0 "register_operand" "=a")
15845         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15846                     (match_operand:SI 2 "tls_symbolic_operand" "")
15847                     (match_operand:SI 3 "call_insn_operand" "")]
15848                     UNSPEC_TLS_GD))
15849    (clobber (match_scratch:SI 4 "=d"))
15850    (clobber (match_scratch:SI 5 "=c"))
15851    (clobber (reg:CC FLAGS_REG))]
15852   "!TARGET_64BIT && TARGET_SUN_TLS"
15853   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15854         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15855   [(set_attr "type" "multi")
15856    (set_attr "length" "14")])
15858 (define_expand "tls_global_dynamic_32"
15859   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15860                    (unspec:SI
15861                     [(match_dup 2)
15862                      (match_operand:SI 1 "tls_symbolic_operand" "")
15863                      (match_dup 3)]
15864                     UNSPEC_TLS_GD))
15865               (clobber (match_scratch:SI 4 ""))
15866               (clobber (match_scratch:SI 5 ""))
15867               (clobber (reg:CC FLAGS_REG))])]
15868   ""
15870   if (flag_pic)
15871     operands[2] = pic_offset_table_rtx;
15872   else
15873     {
15874       operands[2] = gen_reg_rtx (Pmode);
15875       emit_insn (gen_set_got (operands[2]));
15876     }
15877   if (TARGET_GNU2_TLS)
15878     {
15879        emit_insn (gen_tls_dynamic_gnu2_32
15880                   (operands[0], operands[1], operands[2]));
15881        DONE;
15882     }
15883   operands[3] = ix86_tls_get_addr ();
15886 (define_insn "*tls_global_dynamic_64"
15887   [(set (match_operand:DI 0 "register_operand" "=a")
15888         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15889                  (match_operand:DI 3 "" "")))
15890    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15891               UNSPEC_TLS_GD)]
15892   "TARGET_64BIT"
15893   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15894   [(set_attr "type" "multi")
15895    (set_attr "length" "16")])
15897 (define_expand "tls_global_dynamic_64"
15898   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15899                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15900               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15901                          UNSPEC_TLS_GD)])]
15902   ""
15904   if (TARGET_GNU2_TLS)
15905     {
15906        emit_insn (gen_tls_dynamic_gnu2_64
15907                   (operands[0], operands[1]));
15908        DONE;
15909     }
15910   operands[2] = ix86_tls_get_addr ();
15913 (define_insn "*tls_local_dynamic_base_32_gnu"
15914   [(set (match_operand:SI 0 "register_operand" "=a")
15915         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15916                     (match_operand:SI 2 "call_insn_operand" "")]
15917                    UNSPEC_TLS_LD_BASE))
15918    (clobber (match_scratch:SI 3 "=d"))
15919    (clobber (match_scratch:SI 4 "=c"))
15920    (clobber (reg:CC FLAGS_REG))]
15921   "!TARGET_64BIT && TARGET_GNU_TLS"
15922   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15923   [(set_attr "type" "multi")
15924    (set_attr "length" "11")])
15926 (define_insn "*tls_local_dynamic_base_32_sun"
15927   [(set (match_operand:SI 0 "register_operand" "=a")
15928         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15929                     (match_operand:SI 2 "call_insn_operand" "")]
15930                    UNSPEC_TLS_LD_BASE))
15931    (clobber (match_scratch:SI 3 "=d"))
15932    (clobber (match_scratch:SI 4 "=c"))
15933    (clobber (reg:CC FLAGS_REG))]
15934   "!TARGET_64BIT && TARGET_SUN_TLS"
15935   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15936         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15937   [(set_attr "type" "multi")
15938    (set_attr "length" "13")])
15940 (define_expand "tls_local_dynamic_base_32"
15941   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15942                    (unspec:SI [(match_dup 1) (match_dup 2)]
15943                               UNSPEC_TLS_LD_BASE))
15944               (clobber (match_scratch:SI 3 ""))
15945               (clobber (match_scratch:SI 4 ""))
15946               (clobber (reg:CC FLAGS_REG))])]
15947   ""
15949   if (flag_pic)
15950     operands[1] = pic_offset_table_rtx;
15951   else
15952     {
15953       operands[1] = gen_reg_rtx (Pmode);
15954       emit_insn (gen_set_got (operands[1]));
15955     }
15956   if (TARGET_GNU2_TLS)
15957     {
15958        emit_insn (gen_tls_dynamic_gnu2_32
15959                   (operands[0], ix86_tls_module_base (), operands[1]));
15960        DONE;
15961     }
15962   operands[2] = ix86_tls_get_addr ();
15965 (define_insn "*tls_local_dynamic_base_64"
15966   [(set (match_operand:DI 0 "register_operand" "=a")
15967         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15968                  (match_operand:DI 2 "" "")))
15969    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15970   "TARGET_64BIT"
15971   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15972   [(set_attr "type" "multi")
15973    (set_attr "length" "12")])
15975 (define_expand "tls_local_dynamic_base_64"
15976   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15977                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15978               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15979   ""
15981   if (TARGET_GNU2_TLS)
15982     {
15983        emit_insn (gen_tls_dynamic_gnu2_64
15984                   (operands[0], ix86_tls_module_base ()));
15985        DONE;
15986     }
15987   operands[1] = ix86_tls_get_addr ();
15990 ;; Local dynamic of a single variable is a lose.  Show combine how
15991 ;; to convert that back to global dynamic.
15993 (define_insn_and_split "*tls_local_dynamic_32_once"
15994   [(set (match_operand:SI 0 "register_operand" "=a")
15995         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15996                              (match_operand:SI 2 "call_insn_operand" "")]
15997                             UNSPEC_TLS_LD_BASE)
15998                  (const:SI (unspec:SI
15999                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
16000                             UNSPEC_DTPOFF))))
16001    (clobber (match_scratch:SI 4 "=d"))
16002    (clobber (match_scratch:SI 5 "=c"))
16003    (clobber (reg:CC FLAGS_REG))]
16004   ""
16005   "#"
16006   ""
16007   [(parallel [(set (match_dup 0)
16008                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16009                               UNSPEC_TLS_GD))
16010               (clobber (match_dup 4))
16011               (clobber (match_dup 5))
16012               (clobber (reg:CC FLAGS_REG))])]
16013   "")
16015 ;; Load and add the thread base pointer from %gs:0.
16017 (define_insn "*load_tp_si"
16018   [(set (match_operand:SI 0 "register_operand" "=r")
16019         (unspec:SI [(const_int 0)] UNSPEC_TP))]
16020   "!TARGET_64BIT"
16021   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16022   [(set_attr "type" "imov")
16023    (set_attr "modrm" "0")
16024    (set_attr "length" "7")
16025    (set_attr "memory" "load")
16026    (set_attr "imm_disp" "false")])
16028 (define_insn "*add_tp_si"
16029   [(set (match_operand:SI 0 "register_operand" "=r")
16030         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16031                  (match_operand:SI 1 "register_operand" "0")))
16032    (clobber (reg:CC FLAGS_REG))]
16033   "!TARGET_64BIT"
16034   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16035   [(set_attr "type" "alu")
16036    (set_attr "modrm" "0")
16037    (set_attr "length" "7")
16038    (set_attr "memory" "load")
16039    (set_attr "imm_disp" "false")])
16041 (define_insn "*load_tp_di"
16042   [(set (match_operand:DI 0 "register_operand" "=r")
16043         (unspec:DI [(const_int 0)] UNSPEC_TP))]
16044   "TARGET_64BIT"
16045   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16046   [(set_attr "type" "imov")
16047    (set_attr "modrm" "0")
16048    (set_attr "length" "7")
16049    (set_attr "memory" "load")
16050    (set_attr "imm_disp" "false")])
16052 (define_insn "*add_tp_di"
16053   [(set (match_operand:DI 0 "register_operand" "=r")
16054         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16055                  (match_operand:DI 1 "register_operand" "0")))
16056    (clobber (reg:CC FLAGS_REG))]
16057   "TARGET_64BIT"
16058   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16059   [(set_attr "type" "alu")
16060    (set_attr "modrm" "0")
16061    (set_attr "length" "7")
16062    (set_attr "memory" "load")
16063    (set_attr "imm_disp" "false")])
16065 ;; GNU2 TLS patterns can be split.
16067 (define_expand "tls_dynamic_gnu2_32"
16068   [(set (match_dup 3)
16069         (plus:SI (match_operand:SI 2 "register_operand" "")
16070                  (const:SI
16071                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16072                              UNSPEC_TLSDESC))))
16073    (parallel
16074     [(set (match_operand:SI 0 "register_operand" "")
16075           (unspec:SI [(match_dup 1) (match_dup 3)
16076                       (match_dup 2) (reg:SI SP_REG)]
16077                       UNSPEC_TLSDESC))
16078      (clobber (reg:CC FLAGS_REG))])]
16079   "!TARGET_64BIT && TARGET_GNU2_TLS"
16081   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16082   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16085 (define_insn "*tls_dynamic_lea_32"
16086   [(set (match_operand:SI 0 "register_operand" "=r")
16087         (plus:SI (match_operand:SI 1 "register_operand" "b")
16088                  (const:SI
16089                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16090                               UNSPEC_TLSDESC))))]
16091   "!TARGET_64BIT && TARGET_GNU2_TLS"
16092   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16093   [(set_attr "type" "lea")
16094    (set_attr "mode" "SI")
16095    (set_attr "length" "6")
16096    (set_attr "length_address" "4")])
16098 (define_insn "*tls_dynamic_call_32"
16099   [(set (match_operand:SI 0 "register_operand" "=a")
16100         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16101                     (match_operand:SI 2 "register_operand" "0")
16102                     ;; we have to make sure %ebx still points to the GOT
16103                     (match_operand:SI 3 "register_operand" "b")
16104                     (reg:SI SP_REG)]
16105                    UNSPEC_TLSDESC))
16106    (clobber (reg:CC FLAGS_REG))]
16107   "!TARGET_64BIT && TARGET_GNU2_TLS"
16108   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16109   [(set_attr "type" "call")
16110    (set_attr "length" "2")
16111    (set_attr "length_address" "0")])
16113 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16114   [(set (match_operand:SI 0 "register_operand" "=&a")
16115         (plus:SI
16116          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16117                      (match_operand:SI 4 "" "")
16118                      (match_operand:SI 2 "register_operand" "b")
16119                      (reg:SI SP_REG)]
16120                     UNSPEC_TLSDESC)
16121          (const:SI (unspec:SI
16122                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
16123                     UNSPEC_DTPOFF))))
16124    (clobber (reg:CC FLAGS_REG))]
16125   "!TARGET_64BIT && TARGET_GNU2_TLS"
16126   "#"
16127   ""
16128   [(set (match_dup 0) (match_dup 5))]
16130   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16131   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16134 (define_expand "tls_dynamic_gnu2_64"
16135   [(set (match_dup 2)
16136         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16137                    UNSPEC_TLSDESC))
16138    (parallel
16139     [(set (match_operand:DI 0 "register_operand" "")
16140           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16141                      UNSPEC_TLSDESC))
16142      (clobber (reg:CC FLAGS_REG))])]
16143   "TARGET_64BIT && TARGET_GNU2_TLS"
16145   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16146   ix86_tls_descriptor_calls_expanded_in_cfun = true;
16149 (define_insn "*tls_dynamic_lea_64"
16150   [(set (match_operand:DI 0 "register_operand" "=r")
16151         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16152                    UNSPEC_TLSDESC))]
16153   "TARGET_64BIT && TARGET_GNU2_TLS"
16154   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16155   [(set_attr "type" "lea")
16156    (set_attr "mode" "DI")
16157    (set_attr "length" "7")
16158    (set_attr "length_address" "4")])
16160 (define_insn "*tls_dynamic_call_64"
16161   [(set (match_operand:DI 0 "register_operand" "=a")
16162         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16163                     (match_operand:DI 2 "register_operand" "0")
16164                     (reg:DI SP_REG)]
16165                    UNSPEC_TLSDESC))
16166    (clobber (reg:CC FLAGS_REG))]
16167   "TARGET_64BIT && TARGET_GNU2_TLS"
16168   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16169   [(set_attr "type" "call")
16170    (set_attr "length" "2")
16171    (set_attr "length_address" "0")])
16173 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16174   [(set (match_operand:DI 0 "register_operand" "=&a")
16175         (plus:DI
16176          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16177                      (match_operand:DI 3 "" "")
16178                      (reg:DI SP_REG)]
16179                     UNSPEC_TLSDESC)
16180          (const:DI (unspec:DI
16181                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
16182                     UNSPEC_DTPOFF))))
16183    (clobber (reg:CC FLAGS_REG))]
16184   "TARGET_64BIT && TARGET_GNU2_TLS"
16185   "#"
16186   ""
16187   [(set (match_dup 0) (match_dup 4))]
16189   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16190   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16195 ;; These patterns match the binary 387 instructions for addM3, subM3,
16196 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
16197 ;; SFmode.  The first is the normal insn, the second the same insn but
16198 ;; with one operand a conversion, and the third the same insn but with
16199 ;; the other operand a conversion.  The conversion may be SFmode or
16200 ;; SImode if the target mode DFmode, but only SImode if the target mode
16201 ;; is SFmode.
16203 ;; Gcc is slightly more smart about handling normal two address instructions
16204 ;; so use special patterns for add and mull.
16206 (define_insn "*fop_<mode>_comm_mixed_avx"
16207   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16208         (match_operator:MODEF 3 "binary_fp_operator"
16209           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16210            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16211   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16212    && COMMUTATIVE_ARITH_P (operands[3])
16213    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16214   "* return output_387_binary_op (insn, operands);"
16215   [(set (attr "type")
16216         (if_then_else (eq_attr "alternative" "1")
16217            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16218               (const_string "ssemul")
16219               (const_string "sseadd"))
16220            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16221               (const_string "fmul")
16222               (const_string "fop"))))
16223    (set_attr "prefix" "orig,maybe_vex")
16224    (set_attr "mode" "<MODE>")])
16226 (define_insn "*fop_<mode>_comm_mixed"
16227   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16228         (match_operator:MODEF 3 "binary_fp_operator"
16229           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16230            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16231   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16232    && COMMUTATIVE_ARITH_P (operands[3])
16233    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16234   "* return output_387_binary_op (insn, operands);"
16235   [(set (attr "type")
16236         (if_then_else (eq_attr "alternative" "1")
16237            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16238               (const_string "ssemul")
16239               (const_string "sseadd"))
16240            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16241               (const_string "fmul")
16242               (const_string "fop"))))
16243    (set_attr "mode" "<MODE>")])
16245 (define_insn "*fop_<mode>_comm_avx"
16246   [(set (match_operand:MODEF 0 "register_operand" "=x")
16247         (match_operator:MODEF 3 "binary_fp_operator"
16248           [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16249            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16250   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16251    && COMMUTATIVE_ARITH_P (operands[3])
16252    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16253   "* return output_387_binary_op (insn, operands);"
16254   [(set (attr "type")
16255         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16256            (const_string "ssemul")
16257            (const_string "sseadd")))
16258    (set_attr "prefix" "vex")
16259    (set_attr "mode" "<MODE>")])
16261 (define_insn "*fop_<mode>_comm_sse"
16262   [(set (match_operand:MODEF 0 "register_operand" "=x")
16263         (match_operator:MODEF 3 "binary_fp_operator"
16264           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16265            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16266   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16267    && COMMUTATIVE_ARITH_P (operands[3])
16268    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16269   "* return output_387_binary_op (insn, operands);"
16270   [(set (attr "type")
16271         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16272            (const_string "ssemul")
16273            (const_string "sseadd")))
16274    (set_attr "mode" "<MODE>")])
16276 (define_insn "*fop_<mode>_comm_i387"
16277   [(set (match_operand:MODEF 0 "register_operand" "=f")
16278         (match_operator:MODEF 3 "binary_fp_operator"
16279           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16280            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16281   "TARGET_80387
16282    && COMMUTATIVE_ARITH_P (operands[3])
16283    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16284   "* return output_387_binary_op (insn, operands);"
16285   [(set (attr "type")
16286         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16287            (const_string "fmul")
16288            (const_string "fop")))
16289    (set_attr "mode" "<MODE>")])
16291 (define_insn "*fop_<mode>_1_mixed_avx"
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,x")
16295            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16296   "AVX_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 "prefix" "orig,orig,maybe_vex")
16316    (set_attr "mode" "<MODE>")])
16318 (define_insn "*fop_<mode>_1_mixed"
16319   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16320         (match_operator:MODEF 3 "binary_fp_operator"
16321           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16322            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16323   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16324    && !COMMUTATIVE_ARITH_P (operands[3])
16325    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16326   "* return output_387_binary_op (insn, operands);"
16327   [(set (attr "type")
16328         (cond [(and (eq_attr "alternative" "2")
16329                     (match_operand:MODEF 3 "mult_operator" ""))
16330                  (const_string "ssemul")
16331                (and (eq_attr "alternative" "2")
16332                     (match_operand:MODEF 3 "div_operator" ""))
16333                  (const_string "ssediv")
16334                (eq_attr "alternative" "2")
16335                  (const_string "sseadd")
16336                (match_operand:MODEF 3 "mult_operator" "")
16337                  (const_string "fmul")
16338                (match_operand:MODEF 3 "div_operator" "")
16339                  (const_string "fdiv")
16340               ]
16341               (const_string "fop")))
16342    (set_attr "mode" "<MODE>")])
16344 (define_insn "*rcpsf2_sse"
16345   [(set (match_operand:SF 0 "register_operand" "=x")
16346         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16347                    UNSPEC_RCP))]
16348   "TARGET_SSE_MATH"
16349   "%vrcpss\t{%1, %d0|%d0, %1}"
16350   [(set_attr "type" "sse")
16351    (set_attr "prefix" "maybe_vex")
16352    (set_attr "mode" "SF")])
16354 (define_insn "*fop_<mode>_1_avx"
16355   [(set (match_operand:MODEF 0 "register_operand" "=x")
16356         (match_operator:MODEF 3 "binary_fp_operator"
16357           [(match_operand:MODEF 1 "register_operand" "x")
16358            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16359   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16360    && !COMMUTATIVE_ARITH_P (operands[3])"
16361   "* return output_387_binary_op (insn, operands);"
16362   [(set (attr "type")
16363         (cond [(match_operand:MODEF 3 "mult_operator" "")
16364                  (const_string "ssemul")
16365                (match_operand:MODEF 3 "div_operator" "")
16366                  (const_string "ssediv")
16367               ]
16368               (const_string "sseadd")))
16369    (set_attr "prefix" "vex")
16370    (set_attr "mode" "<MODE>")])
16372 (define_insn "*fop_<mode>_1_sse"
16373   [(set (match_operand:MODEF 0 "register_operand" "=x")
16374         (match_operator:MODEF 3 "binary_fp_operator"
16375           [(match_operand:MODEF 1 "register_operand" "0")
16376            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16377   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16378    && !COMMUTATIVE_ARITH_P (operands[3])"
16379   "* return output_387_binary_op (insn, operands);"
16380   [(set (attr "type")
16381         (cond [(match_operand:MODEF 3 "mult_operator" "")
16382                  (const_string "ssemul")
16383                (match_operand:MODEF 3 "div_operator" "")
16384                  (const_string "ssediv")
16385               ]
16386               (const_string "sseadd")))
16387    (set_attr "mode" "<MODE>")])
16389 ;; This pattern is not fully shadowed by the pattern above.
16390 (define_insn "*fop_<mode>_1_i387"
16391   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16392         (match_operator:MODEF 3 "binary_fp_operator"
16393           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16394            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16395   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16396    && !COMMUTATIVE_ARITH_P (operands[3])
16397    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16398   "* return output_387_binary_op (insn, operands);"
16399   [(set (attr "type")
16400         (cond [(match_operand:MODEF 3 "mult_operator" "")
16401                  (const_string "fmul")
16402                (match_operand:MODEF 3 "div_operator" "")
16403                  (const_string "fdiv")
16404               ]
16405               (const_string "fop")))
16406    (set_attr "mode" "<MODE>")])
16408 ;; ??? Add SSE splitters for these!
16409 (define_insn "*fop_<MODEF:mode>_2_i387"
16410   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16411         (match_operator:MODEF 3 "binary_fp_operator"
16412           [(float:MODEF
16413              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16414            (match_operand:MODEF 2 "register_operand" "0,0")]))]
16415   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16416    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16417   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16418   [(set (attr "type")
16419         (cond [(match_operand:MODEF 3 "mult_operator" "")
16420                  (const_string "fmul")
16421                (match_operand:MODEF 3 "div_operator" "")
16422                  (const_string "fdiv")
16423               ]
16424               (const_string "fop")))
16425    (set_attr "fp_int_src" "true")
16426    (set_attr "mode" "<X87MODEI12:MODE>")])
16428 (define_insn "*fop_<MODEF:mode>_3_i387"
16429   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16430         (match_operator:MODEF 3 "binary_fp_operator"
16431           [(match_operand:MODEF 1 "register_operand" "0,0")
16432            (float:MODEF
16433              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16434   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16435    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16436   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16437   [(set (attr "type")
16438         (cond [(match_operand:MODEF 3 "mult_operator" "")
16439                  (const_string "fmul")
16440                (match_operand:MODEF 3 "div_operator" "")
16441                  (const_string "fdiv")
16442               ]
16443               (const_string "fop")))
16444    (set_attr "fp_int_src" "true")
16445    (set_attr "mode" "<MODE>")])
16447 (define_insn "*fop_df_4_i387"
16448   [(set (match_operand:DF 0 "register_operand" "=f,f")
16449         (match_operator:DF 3 "binary_fp_operator"
16450            [(float_extend:DF
16451              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16452             (match_operand:DF 2 "register_operand" "0,f")]))]
16453   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16454    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16455   "* return output_387_binary_op (insn, operands);"
16456   [(set (attr "type")
16457         (cond [(match_operand:DF 3 "mult_operator" "")
16458                  (const_string "fmul")
16459                (match_operand:DF 3 "div_operator" "")
16460                  (const_string "fdiv")
16461               ]
16462               (const_string "fop")))
16463    (set_attr "mode" "SF")])
16465 (define_insn "*fop_df_5_i387"
16466   [(set (match_operand:DF 0 "register_operand" "=f,f")
16467         (match_operator:DF 3 "binary_fp_operator"
16468           [(match_operand:DF 1 "register_operand" "0,f")
16469            (float_extend:DF
16470             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16471   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16472   "* return output_387_binary_op (insn, operands);"
16473   [(set (attr "type")
16474         (cond [(match_operand:DF 3 "mult_operator" "")
16475                  (const_string "fmul")
16476                (match_operand:DF 3 "div_operator" "")
16477                  (const_string "fdiv")
16478               ]
16479               (const_string "fop")))
16480    (set_attr "mode" "SF")])
16482 (define_insn "*fop_df_6_i387"
16483   [(set (match_operand:DF 0 "register_operand" "=f,f")
16484         (match_operator:DF 3 "binary_fp_operator"
16485           [(float_extend:DF
16486             (match_operand:SF 1 "register_operand" "0,f"))
16487            (float_extend:DF
16488             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16489   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16490   "* return output_387_binary_op (insn, operands);"
16491   [(set (attr "type")
16492         (cond [(match_operand:DF 3 "mult_operator" "")
16493                  (const_string "fmul")
16494                (match_operand:DF 3 "div_operator" "")
16495                  (const_string "fdiv")
16496               ]
16497               (const_string "fop")))
16498    (set_attr "mode" "SF")])
16500 (define_insn "*fop_xf_comm_i387"
16501   [(set (match_operand:XF 0 "register_operand" "=f")
16502         (match_operator:XF 3 "binary_fp_operator"
16503                         [(match_operand:XF 1 "register_operand" "%0")
16504                          (match_operand:XF 2 "register_operand" "f")]))]
16505   "TARGET_80387
16506    && COMMUTATIVE_ARITH_P (operands[3])"
16507   "* return output_387_binary_op (insn, operands);"
16508   [(set (attr "type")
16509         (if_then_else (match_operand:XF 3 "mult_operator" "")
16510            (const_string "fmul")
16511            (const_string "fop")))
16512    (set_attr "mode" "XF")])
16514 (define_insn "*fop_xf_1_i387"
16515   [(set (match_operand:XF 0 "register_operand" "=f,f")
16516         (match_operator:XF 3 "binary_fp_operator"
16517                         [(match_operand:XF 1 "register_operand" "0,f")
16518                          (match_operand:XF 2 "register_operand" "f,0")]))]
16519   "TARGET_80387
16520    && !COMMUTATIVE_ARITH_P (operands[3])"
16521   "* return output_387_binary_op (insn, operands);"
16522   [(set (attr "type")
16523         (cond [(match_operand:XF 3 "mult_operator" "")
16524                  (const_string "fmul")
16525                (match_operand:XF 3 "div_operator" "")
16526                  (const_string "fdiv")
16527               ]
16528               (const_string "fop")))
16529    (set_attr "mode" "XF")])
16531 (define_insn "*fop_xf_2_i387"
16532   [(set (match_operand:XF 0 "register_operand" "=f,f")
16533         (match_operator:XF 3 "binary_fp_operator"
16534           [(float:XF
16535              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16536            (match_operand:XF 2 "register_operand" "0,0")]))]
16537   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16538   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16539   [(set (attr "type")
16540         (cond [(match_operand:XF 3 "mult_operator" "")
16541                  (const_string "fmul")
16542                (match_operand:XF 3 "div_operator" "")
16543                  (const_string "fdiv")
16544               ]
16545               (const_string "fop")))
16546    (set_attr "fp_int_src" "true")
16547    (set_attr "mode" "<MODE>")])
16549 (define_insn "*fop_xf_3_i387"
16550   [(set (match_operand:XF 0 "register_operand" "=f,f")
16551         (match_operator:XF 3 "binary_fp_operator"
16552           [(match_operand:XF 1 "register_operand" "0,0")
16553            (float:XF
16554              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16555   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16556   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16557   [(set (attr "type")
16558         (cond [(match_operand:XF 3 "mult_operator" "")
16559                  (const_string "fmul")
16560                (match_operand:XF 3 "div_operator" "")
16561                  (const_string "fdiv")
16562               ]
16563               (const_string "fop")))
16564    (set_attr "fp_int_src" "true")
16565    (set_attr "mode" "<MODE>")])
16567 (define_insn "*fop_xf_4_i387"
16568   [(set (match_operand:XF 0 "register_operand" "=f,f")
16569         (match_operator:XF 3 "binary_fp_operator"
16570            [(float_extend:XF
16571               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16572             (match_operand:XF 2 "register_operand" "0,f")]))]
16573   "TARGET_80387"
16574   "* return output_387_binary_op (insn, operands);"
16575   [(set (attr "type")
16576         (cond [(match_operand:XF 3 "mult_operator" "")
16577                  (const_string "fmul")
16578                (match_operand:XF 3 "div_operator" "")
16579                  (const_string "fdiv")
16580               ]
16581               (const_string "fop")))
16582    (set_attr "mode" "<MODE>")])
16584 (define_insn "*fop_xf_5_i387"
16585   [(set (match_operand:XF 0 "register_operand" "=f,f")
16586         (match_operator:XF 3 "binary_fp_operator"
16587           [(match_operand:XF 1 "register_operand" "0,f")
16588            (float_extend:XF
16589              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16590   "TARGET_80387"
16591   "* return output_387_binary_op (insn, operands);"
16592   [(set (attr "type")
16593         (cond [(match_operand:XF 3 "mult_operator" "")
16594                  (const_string "fmul")
16595                (match_operand:XF 3 "div_operator" "")
16596                  (const_string "fdiv")
16597               ]
16598               (const_string "fop")))
16599    (set_attr "mode" "<MODE>")])
16601 (define_insn "*fop_xf_6_i387"
16602   [(set (match_operand:XF 0 "register_operand" "=f,f")
16603         (match_operator:XF 3 "binary_fp_operator"
16604           [(float_extend:XF
16605              (match_operand:MODEF 1 "register_operand" "0,f"))
16606            (float_extend:XF
16607              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16608   "TARGET_80387"
16609   "* return output_387_binary_op (insn, operands);"
16610   [(set (attr "type")
16611         (cond [(match_operand:XF 3 "mult_operator" "")
16612                  (const_string "fmul")
16613                (match_operand:XF 3 "div_operator" "")
16614                  (const_string "fdiv")
16615               ]
16616               (const_string "fop")))
16617    (set_attr "mode" "<MODE>")])
16619 (define_split
16620   [(set (match_operand 0 "register_operand" "")
16621         (match_operator 3 "binary_fp_operator"
16622            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16623             (match_operand 2 "register_operand" "")]))]
16624   "reload_completed
16625    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16626   [(const_int 0)]
16628   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16629   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16630   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16631                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16632                                           GET_MODE (operands[3]),
16633                                           operands[4],
16634                                           operands[2])));
16635   ix86_free_from_memory (GET_MODE (operands[1]));
16636   DONE;
16639 (define_split
16640   [(set (match_operand 0 "register_operand" "")
16641         (match_operator 3 "binary_fp_operator"
16642            [(match_operand 1 "register_operand" "")
16643             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16644   "reload_completed
16645    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16646   [(const_int 0)]
16648   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16649   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16650   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16651                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16652                                           GET_MODE (operands[3]),
16653                                           operands[1],
16654                                           operands[4])));
16655   ix86_free_from_memory (GET_MODE (operands[2]));
16656   DONE;
16659 ;; FPU special functions.
16661 ;; This pattern implements a no-op XFmode truncation for
16662 ;; all fancy i386 XFmode math functions.
16664 (define_insn "truncxf<mode>2_i387_noop_unspec"
16665   [(set (match_operand:MODEF 0 "register_operand" "=f")
16666         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16667         UNSPEC_TRUNC_NOOP))]
16668   "TARGET_USE_FANCY_MATH_387"
16669   "* return output_387_reg_move (insn, operands);"
16670   [(set_attr "type" "fmov")
16671    (set_attr "mode" "<MODE>")])
16673 (define_insn "sqrtxf2"
16674   [(set (match_operand:XF 0 "register_operand" "=f")
16675         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16676   "TARGET_USE_FANCY_MATH_387"
16677   "fsqrt"
16678   [(set_attr "type" "fpspc")
16679    (set_attr "mode" "XF")
16680    (set_attr "athlon_decode" "direct")
16681    (set_attr "amdfam10_decode" "direct")])
16683 (define_insn "sqrt_extend<mode>xf2_i387"
16684   [(set (match_operand:XF 0 "register_operand" "=f")
16685         (sqrt:XF
16686           (float_extend:XF
16687             (match_operand:MODEF 1 "register_operand" "0"))))]
16688   "TARGET_USE_FANCY_MATH_387"
16689   "fsqrt"
16690   [(set_attr "type" "fpspc")
16691    (set_attr "mode" "XF")
16692    (set_attr "athlon_decode" "direct")
16693    (set_attr "amdfam10_decode" "direct")])
16695 (define_insn "*rsqrtsf2_sse"
16696   [(set (match_operand:SF 0 "register_operand" "=x")
16697         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16698                    UNSPEC_RSQRT))]
16699   "TARGET_SSE_MATH"
16700   "%vrsqrtss\t{%1, %d0|%d0, %1}"
16701   [(set_attr "type" "sse")
16702    (set_attr "prefix" "maybe_vex")
16703    (set_attr "mode" "SF")])
16705 (define_expand "rsqrtsf2"
16706   [(set (match_operand:SF 0 "register_operand" "")
16707         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16708                    UNSPEC_RSQRT))]
16709   "TARGET_SSE_MATH"
16711   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16712   DONE;
16715 (define_insn "*sqrt<mode>2_sse"
16716   [(set (match_operand:MODEF 0 "register_operand" "=x")
16717         (sqrt:MODEF
16718           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16719   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16720   "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16721   [(set_attr "type" "sse")
16722    (set_attr "prefix" "maybe_vex")
16723    (set_attr "mode" "<MODE>")
16724    (set_attr "athlon_decode" "*")
16725    (set_attr "amdfam10_decode" "*")])
16727 (define_expand "sqrt<mode>2"
16728   [(set (match_operand:MODEF 0 "register_operand" "")
16729         (sqrt:MODEF
16730           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16731   "TARGET_USE_FANCY_MATH_387
16732    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16734   if (<MODE>mode == SFmode
16735       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16736       && flag_finite_math_only && !flag_trapping_math
16737       && flag_unsafe_math_optimizations)
16738     {
16739       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16740       DONE;
16741     }
16743   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16744     {
16745       rtx op0 = gen_reg_rtx (XFmode);
16746       rtx op1 = force_reg (<MODE>mode, operands[1]);
16748       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16749       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16750       DONE;
16751    }
16754 (define_insn "fpremxf4_i387"
16755   [(set (match_operand:XF 0 "register_operand" "=f")
16756         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16757                     (match_operand:XF 3 "register_operand" "1")]
16758                    UNSPEC_FPREM_F))
16759    (set (match_operand:XF 1 "register_operand" "=u")
16760         (unspec:XF [(match_dup 2) (match_dup 3)]
16761                    UNSPEC_FPREM_U))
16762    (set (reg:CCFP FPSR_REG)
16763         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16764                      UNSPEC_C2_FLAG))]
16765   "TARGET_USE_FANCY_MATH_387"
16766   "fprem"
16767   [(set_attr "type" "fpspc")
16768    (set_attr "mode" "XF")])
16770 (define_expand "fmodxf3"
16771   [(use (match_operand:XF 0 "register_operand" ""))
16772    (use (match_operand:XF 1 "general_operand" ""))
16773    (use (match_operand:XF 2 "general_operand" ""))]
16774   "TARGET_USE_FANCY_MATH_387"
16776   rtx label = gen_label_rtx ();
16778   rtx op1 = gen_reg_rtx (XFmode);
16779   rtx op2 = gen_reg_rtx (XFmode);
16781   emit_move_insn (op2, operands[2]);
16782   emit_move_insn (op1, operands[1]);
16784   emit_label (label);
16785   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16786   ix86_emit_fp_unordered_jump (label);
16787   LABEL_NUSES (label) = 1;
16789   emit_move_insn (operands[0], op1);
16790   DONE;
16793 (define_expand "fmod<mode>3"
16794   [(use (match_operand:MODEF 0 "register_operand" ""))
16795    (use (match_operand:MODEF 1 "general_operand" ""))
16796    (use (match_operand:MODEF 2 "general_operand" ""))]
16797   "TARGET_USE_FANCY_MATH_387"
16799   rtx label = gen_label_rtx ();
16801   rtx op1 = gen_reg_rtx (XFmode);
16802   rtx op2 = gen_reg_rtx (XFmode);
16804   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16805   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16807   emit_label (label);
16808   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16809   ix86_emit_fp_unordered_jump (label);
16810   LABEL_NUSES (label) = 1;
16812   /* Truncate the result properly for strict SSE math.  */
16813   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16814       && !TARGET_MIX_SSE_I387)
16815     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16816   else
16817     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16819   DONE;
16822 (define_insn "fprem1xf4_i387"
16823   [(set (match_operand:XF 0 "register_operand" "=f")
16824         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16825                     (match_operand:XF 3 "register_operand" "1")]
16826                    UNSPEC_FPREM1_F))
16827    (set (match_operand:XF 1 "register_operand" "=u")
16828         (unspec:XF [(match_dup 2) (match_dup 3)]
16829                    UNSPEC_FPREM1_U))
16830    (set (reg:CCFP FPSR_REG)
16831         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16832                      UNSPEC_C2_FLAG))]
16833   "TARGET_USE_FANCY_MATH_387"
16834   "fprem1"
16835   [(set_attr "type" "fpspc")
16836    (set_attr "mode" "XF")])
16838 (define_expand "remainderxf3"
16839   [(use (match_operand:XF 0 "register_operand" ""))
16840    (use (match_operand:XF 1 "general_operand" ""))
16841    (use (match_operand:XF 2 "general_operand" ""))]
16842   "TARGET_USE_FANCY_MATH_387"
16844   rtx label = gen_label_rtx ();
16846   rtx op1 = gen_reg_rtx (XFmode);
16847   rtx op2 = gen_reg_rtx (XFmode);
16849   emit_move_insn (op2, operands[2]);
16850   emit_move_insn (op1, operands[1]);
16852   emit_label (label);
16853   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16854   ix86_emit_fp_unordered_jump (label);
16855   LABEL_NUSES (label) = 1;
16857   emit_move_insn (operands[0], op1);
16858   DONE;
16861 (define_expand "remainder<mode>3"
16862   [(use (match_operand:MODEF 0 "register_operand" ""))
16863    (use (match_operand:MODEF 1 "general_operand" ""))
16864    (use (match_operand:MODEF 2 "general_operand" ""))]
16865   "TARGET_USE_FANCY_MATH_387"
16867   rtx label = gen_label_rtx ();
16869   rtx op1 = gen_reg_rtx (XFmode);
16870   rtx op2 = gen_reg_rtx (XFmode);
16872   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16873   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16875   emit_label (label);
16877   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16878   ix86_emit_fp_unordered_jump (label);
16879   LABEL_NUSES (label) = 1;
16881   /* Truncate the result properly for strict SSE math.  */
16882   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16883       && !TARGET_MIX_SSE_I387)
16884     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16885   else
16886     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16888   DONE;
16891 (define_insn "*sinxf2_i387"
16892   [(set (match_operand:XF 0 "register_operand" "=f")
16893         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16894   "TARGET_USE_FANCY_MATH_387
16895    && flag_unsafe_math_optimizations"
16896   "fsin"
16897   [(set_attr "type" "fpspc")
16898    (set_attr "mode" "XF")])
16900 (define_insn "*sin_extend<mode>xf2_i387"
16901   [(set (match_operand:XF 0 "register_operand" "=f")
16902         (unspec:XF [(float_extend:XF
16903                       (match_operand:MODEF 1 "register_operand" "0"))]
16904                    UNSPEC_SIN))]
16905   "TARGET_USE_FANCY_MATH_387
16906    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16907        || TARGET_MIX_SSE_I387)
16908    && flag_unsafe_math_optimizations"
16909   "fsin"
16910   [(set_attr "type" "fpspc")
16911    (set_attr "mode" "XF")])
16913 (define_insn "*cosxf2_i387"
16914   [(set (match_operand:XF 0 "register_operand" "=f")
16915         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16916   "TARGET_USE_FANCY_MATH_387
16917    && flag_unsafe_math_optimizations"
16918   "fcos"
16919   [(set_attr "type" "fpspc")
16920    (set_attr "mode" "XF")])
16922 (define_insn "*cos_extend<mode>xf2_i387"
16923   [(set (match_operand:XF 0 "register_operand" "=f")
16924         (unspec:XF [(float_extend:XF
16925                       (match_operand:MODEF 1 "register_operand" "0"))]
16926                    UNSPEC_COS))]
16927   "TARGET_USE_FANCY_MATH_387
16928    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16929        || TARGET_MIX_SSE_I387)
16930    && flag_unsafe_math_optimizations"
16931   "fcos"
16932   [(set_attr "type" "fpspc")
16933    (set_attr "mode" "XF")])
16935 ;; When sincos pattern is defined, sin and cos builtin functions will be
16936 ;; expanded to sincos pattern with one of its outputs left unused.
16937 ;; CSE pass will figure out if two sincos patterns can be combined,
16938 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16939 ;; depending on the unused output.
16941 (define_insn "sincosxf3"
16942   [(set (match_operand:XF 0 "register_operand" "=f")
16943         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16944                    UNSPEC_SINCOS_COS))
16945    (set (match_operand:XF 1 "register_operand" "=u")
16946         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16947   "TARGET_USE_FANCY_MATH_387
16948    && flag_unsafe_math_optimizations"
16949   "fsincos"
16950   [(set_attr "type" "fpspc")
16951    (set_attr "mode" "XF")])
16953 (define_split
16954   [(set (match_operand:XF 0 "register_operand" "")
16955         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16956                    UNSPEC_SINCOS_COS))
16957    (set (match_operand:XF 1 "register_operand" "")
16958         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16959   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16960    && !(reload_completed || reload_in_progress)"
16961   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16962   "")
16964 (define_split
16965   [(set (match_operand:XF 0 "register_operand" "")
16966         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16967                    UNSPEC_SINCOS_COS))
16968    (set (match_operand:XF 1 "register_operand" "")
16969         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16970   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16971    && !(reload_completed || reload_in_progress)"
16972   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16973   "")
16975 (define_insn "sincos_extend<mode>xf3_i387"
16976   [(set (match_operand:XF 0 "register_operand" "=f")
16977         (unspec:XF [(float_extend:XF
16978                       (match_operand:MODEF 2 "register_operand" "0"))]
16979                    UNSPEC_SINCOS_COS))
16980    (set (match_operand:XF 1 "register_operand" "=u")
16981         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16982   "TARGET_USE_FANCY_MATH_387
16983    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16984        || TARGET_MIX_SSE_I387)
16985    && flag_unsafe_math_optimizations"
16986   "fsincos"
16987   [(set_attr "type" "fpspc")
16988    (set_attr "mode" "XF")])
16990 (define_split
16991   [(set (match_operand:XF 0 "register_operand" "")
16992         (unspec:XF [(float_extend:XF
16993                       (match_operand:MODEF 2 "register_operand" ""))]
16994                    UNSPEC_SINCOS_COS))
16995    (set (match_operand:XF 1 "register_operand" "")
16996         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16997   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16998    && !(reload_completed || reload_in_progress)"
16999   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17000   "")
17002 (define_split
17003   [(set (match_operand:XF 0 "register_operand" "")
17004         (unspec:XF [(float_extend:XF
17005                       (match_operand:MODEF 2 "register_operand" ""))]
17006                    UNSPEC_SINCOS_COS))
17007    (set (match_operand:XF 1 "register_operand" "")
17008         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17009   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17010    && !(reload_completed || reload_in_progress)"
17011   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17012   "")
17014 (define_expand "sincos<mode>3"
17015   [(use (match_operand:MODEF 0 "register_operand" ""))
17016    (use (match_operand:MODEF 1 "register_operand" ""))
17017    (use (match_operand:MODEF 2 "register_operand" ""))]
17018   "TARGET_USE_FANCY_MATH_387
17019    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17020        || TARGET_MIX_SSE_I387)
17021    && flag_unsafe_math_optimizations"
17023   rtx op0 = gen_reg_rtx (XFmode);
17024   rtx op1 = gen_reg_rtx (XFmode);
17026   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17027   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17028   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17029   DONE;
17032 (define_insn "fptanxf4_i387"
17033   [(set (match_operand:XF 0 "register_operand" "=f")
17034         (match_operand:XF 3 "const_double_operand" "F"))
17035    (set (match_operand:XF 1 "register_operand" "=u")
17036         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17037                    UNSPEC_TAN))]
17038   "TARGET_USE_FANCY_MATH_387
17039    && flag_unsafe_math_optimizations
17040    && standard_80387_constant_p (operands[3]) == 2"
17041   "fptan"
17042   [(set_attr "type" "fpspc")
17043    (set_attr "mode" "XF")])
17045 (define_insn "fptan_extend<mode>xf4_i387"
17046   [(set (match_operand:MODEF 0 "register_operand" "=f")
17047         (match_operand:MODEF 3 "const_double_operand" "F"))
17048    (set (match_operand:XF 1 "register_operand" "=u")
17049         (unspec:XF [(float_extend:XF
17050                       (match_operand:MODEF 2 "register_operand" "0"))]
17051                    UNSPEC_TAN))]
17052   "TARGET_USE_FANCY_MATH_387
17053    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17054        || TARGET_MIX_SSE_I387)
17055    && flag_unsafe_math_optimizations
17056    && standard_80387_constant_p (operands[3]) == 2"
17057   "fptan"
17058   [(set_attr "type" "fpspc")
17059    (set_attr "mode" "XF")])
17061 (define_expand "tanxf2"
17062   [(use (match_operand:XF 0 "register_operand" ""))
17063    (use (match_operand:XF 1 "register_operand" ""))]
17064   "TARGET_USE_FANCY_MATH_387
17065    && flag_unsafe_math_optimizations"
17067   rtx one = gen_reg_rtx (XFmode);
17068   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17070   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17071   DONE;
17074 (define_expand "tan<mode>2"
17075   [(use (match_operand:MODEF 0 "register_operand" ""))
17076    (use (match_operand:MODEF 1 "register_operand" ""))]
17077   "TARGET_USE_FANCY_MATH_387
17078    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17079        || TARGET_MIX_SSE_I387)
17080    && flag_unsafe_math_optimizations"
17082   rtx op0 = gen_reg_rtx (XFmode);
17084   rtx one = gen_reg_rtx (<MODE>mode);
17085   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17087   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17088                                              operands[1], op2));
17089   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17090   DONE;
17093 (define_insn "*fpatanxf3_i387"
17094   [(set (match_operand:XF 0 "register_operand" "=f")
17095         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17096                     (match_operand:XF 2 "register_operand" "u")]
17097                    UNSPEC_FPATAN))
17098    (clobber (match_scratch:XF 3 "=2"))]
17099   "TARGET_USE_FANCY_MATH_387
17100    && flag_unsafe_math_optimizations"
17101   "fpatan"
17102   [(set_attr "type" "fpspc")
17103    (set_attr "mode" "XF")])
17105 (define_insn "fpatan_extend<mode>xf3_i387"
17106   [(set (match_operand:XF 0 "register_operand" "=f")
17107         (unspec:XF [(float_extend:XF
17108                       (match_operand:MODEF 1 "register_operand" "0"))
17109                     (float_extend:XF
17110                       (match_operand:MODEF 2 "register_operand" "u"))]
17111                    UNSPEC_FPATAN))
17112    (clobber (match_scratch:XF 3 "=2"))]
17113   "TARGET_USE_FANCY_MATH_387
17114    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17115        || TARGET_MIX_SSE_I387)
17116    && flag_unsafe_math_optimizations"
17117   "fpatan"
17118   [(set_attr "type" "fpspc")
17119    (set_attr "mode" "XF")])
17121 (define_expand "atan2xf3"
17122   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17123                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
17124                                (match_operand:XF 1 "register_operand" "")]
17125                               UNSPEC_FPATAN))
17126               (clobber (match_scratch:XF 3 ""))])]
17127   "TARGET_USE_FANCY_MATH_387
17128    && flag_unsafe_math_optimizations"
17129   "")
17131 (define_expand "atan2<mode>3"
17132   [(use (match_operand:MODEF 0 "register_operand" ""))
17133    (use (match_operand:MODEF 1 "register_operand" ""))
17134    (use (match_operand:MODEF 2 "register_operand" ""))]
17135   "TARGET_USE_FANCY_MATH_387
17136    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17137        || TARGET_MIX_SSE_I387)
17138    && flag_unsafe_math_optimizations"
17140   rtx op0 = gen_reg_rtx (XFmode);
17142   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17143   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17144   DONE;
17147 (define_expand "atanxf2"
17148   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17149                    (unspec:XF [(match_dup 2)
17150                                (match_operand:XF 1 "register_operand" "")]
17151                               UNSPEC_FPATAN))
17152               (clobber (match_scratch:XF 3 ""))])]
17153   "TARGET_USE_FANCY_MATH_387
17154    && flag_unsafe_math_optimizations"
17156   operands[2] = gen_reg_rtx (XFmode);
17157   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
17160 (define_expand "atan<mode>2"
17161   [(use (match_operand:MODEF 0 "register_operand" ""))
17162    (use (match_operand:MODEF 1 "register_operand" ""))]
17163   "TARGET_USE_FANCY_MATH_387
17164    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17165        || TARGET_MIX_SSE_I387)
17166    && flag_unsafe_math_optimizations"
17168   rtx op0 = gen_reg_rtx (XFmode);
17170   rtx op2 = gen_reg_rtx (<MODE>mode);
17171   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
17173   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17174   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17175   DONE;
17178 (define_expand "asinxf2"
17179   [(set (match_dup 2)
17180         (mult:XF (match_operand:XF 1 "register_operand" "")
17181                  (match_dup 1)))
17182    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17183    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17184    (parallel [(set (match_operand:XF 0 "register_operand" "")
17185                    (unspec:XF [(match_dup 5) (match_dup 1)]
17186                               UNSPEC_FPATAN))
17187               (clobber (match_scratch:XF 6 ""))])]
17188   "TARGET_USE_FANCY_MATH_387
17189    && flag_unsafe_math_optimizations"
17191   int i;
17193   if (optimize_insn_for_size_p ())
17194     FAIL;
17196   for (i = 2; i < 6; i++)
17197     operands[i] = gen_reg_rtx (XFmode);
17199   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17202 (define_expand "asin<mode>2"
17203   [(use (match_operand:MODEF 0 "register_operand" ""))
17204    (use (match_operand:MODEF 1 "general_operand" ""))]
17205  "TARGET_USE_FANCY_MATH_387
17206    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17207        || TARGET_MIX_SSE_I387)
17208    && flag_unsafe_math_optimizations"
17210   rtx op0 = gen_reg_rtx (XFmode);
17211   rtx op1 = gen_reg_rtx (XFmode);
17213   if (optimize_insn_for_size_p ())
17214     FAIL;
17216   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17217   emit_insn (gen_asinxf2 (op0, op1));
17218   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17219   DONE;
17222 (define_expand "acosxf2"
17223   [(set (match_dup 2)
17224         (mult:XF (match_operand:XF 1 "register_operand" "")
17225                  (match_dup 1)))
17226    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17227    (set (match_dup 5) (sqrt:XF (match_dup 4)))
17228    (parallel [(set (match_operand:XF 0 "register_operand" "")
17229                    (unspec:XF [(match_dup 1) (match_dup 5)]
17230                               UNSPEC_FPATAN))
17231               (clobber (match_scratch:XF 6 ""))])]
17232   "TARGET_USE_FANCY_MATH_387
17233    && flag_unsafe_math_optimizations"
17235   int i;
17237   if (optimize_insn_for_size_p ())
17238     FAIL;
17240   for (i = 2; i < 6; i++)
17241     operands[i] = gen_reg_rtx (XFmode);
17243   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
17246 (define_expand "acos<mode>2"
17247   [(use (match_operand:MODEF 0 "register_operand" ""))
17248    (use (match_operand:MODEF 1 "general_operand" ""))]
17249  "TARGET_USE_FANCY_MATH_387
17250    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17251        || TARGET_MIX_SSE_I387)
17252    && flag_unsafe_math_optimizations"
17254   rtx op0 = gen_reg_rtx (XFmode);
17255   rtx op1 = gen_reg_rtx (XFmode);
17257   if (optimize_insn_for_size_p ())
17258     FAIL;
17260   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17261   emit_insn (gen_acosxf2 (op0, op1));
17262   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17263   DONE;
17266 (define_insn "fyl2xxf3_i387"
17267   [(set (match_operand:XF 0 "register_operand" "=f")
17268         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17269                     (match_operand:XF 2 "register_operand" "u")]
17270                    UNSPEC_FYL2X))
17271    (clobber (match_scratch:XF 3 "=2"))]
17272   "TARGET_USE_FANCY_MATH_387
17273    && flag_unsafe_math_optimizations"
17274   "fyl2x"
17275   [(set_attr "type" "fpspc")
17276    (set_attr "mode" "XF")])
17278 (define_insn "fyl2x_extend<mode>xf3_i387"
17279   [(set (match_operand:XF 0 "register_operand" "=f")
17280         (unspec:XF [(float_extend:XF
17281                       (match_operand:MODEF 1 "register_operand" "0"))
17282                     (match_operand:XF 2 "register_operand" "u")]
17283                    UNSPEC_FYL2X))
17284    (clobber (match_scratch:XF 3 "=2"))]
17285   "TARGET_USE_FANCY_MATH_387
17286    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17287        || TARGET_MIX_SSE_I387)
17288    && flag_unsafe_math_optimizations"
17289   "fyl2x"
17290   [(set_attr "type" "fpspc")
17291    (set_attr "mode" "XF")])
17293 (define_expand "logxf2"
17294   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17295                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17296                                (match_dup 2)] UNSPEC_FYL2X))
17297               (clobber (match_scratch:XF 3 ""))])]
17298   "TARGET_USE_FANCY_MATH_387
17299    && flag_unsafe_math_optimizations"
17301   operands[2] = gen_reg_rtx (XFmode);
17302   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
17305 (define_expand "log<mode>2"
17306   [(use (match_operand:MODEF 0 "register_operand" ""))
17307    (use (match_operand:MODEF 1 "register_operand" ""))]
17308   "TARGET_USE_FANCY_MATH_387
17309    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17310        || TARGET_MIX_SSE_I387)
17311    && flag_unsafe_math_optimizations"
17313   rtx op0 = gen_reg_rtx (XFmode);
17315   rtx op2 = gen_reg_rtx (XFmode);
17316   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
17318   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17319   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17320   DONE;
17323 (define_expand "log10xf2"
17324   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17325                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17326                                (match_dup 2)] UNSPEC_FYL2X))
17327               (clobber (match_scratch:XF 3 ""))])]
17328   "TARGET_USE_FANCY_MATH_387
17329    && flag_unsafe_math_optimizations"
17331   operands[2] = gen_reg_rtx (XFmode);
17332   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
17335 (define_expand "log10<mode>2"
17336   [(use (match_operand:MODEF 0 "register_operand" ""))
17337    (use (match_operand:MODEF 1 "register_operand" ""))]
17338   "TARGET_USE_FANCY_MATH_387
17339    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17340        || TARGET_MIX_SSE_I387)
17341    && flag_unsafe_math_optimizations"
17343   rtx op0 = gen_reg_rtx (XFmode);
17345   rtx op2 = gen_reg_rtx (XFmode);
17346   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17348   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17349   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17350   DONE;
17353 (define_expand "log2xf2"
17354   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17355                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17356                                (match_dup 2)] UNSPEC_FYL2X))
17357               (clobber (match_scratch:XF 3 ""))])]
17358   "TARGET_USE_FANCY_MATH_387
17359    && flag_unsafe_math_optimizations"
17361   operands[2] = gen_reg_rtx (XFmode);
17362   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17365 (define_expand "log2<mode>2"
17366   [(use (match_operand:MODEF 0 "register_operand" ""))
17367    (use (match_operand:MODEF 1 "register_operand" ""))]
17368   "TARGET_USE_FANCY_MATH_387
17369    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17370        || TARGET_MIX_SSE_I387)
17371    && flag_unsafe_math_optimizations"
17373   rtx op0 = gen_reg_rtx (XFmode);
17375   rtx op2 = gen_reg_rtx (XFmode);
17376   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17378   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17379   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17380   DONE;
17383 (define_insn "fyl2xp1xf3_i387"
17384   [(set (match_operand:XF 0 "register_operand" "=f")
17385         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17386                     (match_operand:XF 2 "register_operand" "u")]
17387                    UNSPEC_FYL2XP1))
17388    (clobber (match_scratch:XF 3 "=2"))]
17389   "TARGET_USE_FANCY_MATH_387
17390    && flag_unsafe_math_optimizations"
17391   "fyl2xp1"
17392   [(set_attr "type" "fpspc")
17393    (set_attr "mode" "XF")])
17395 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17396   [(set (match_operand:XF 0 "register_operand" "=f")
17397         (unspec:XF [(float_extend:XF
17398                       (match_operand:MODEF 1 "register_operand" "0"))
17399                     (match_operand:XF 2 "register_operand" "u")]
17400                    UNSPEC_FYL2XP1))
17401    (clobber (match_scratch:XF 3 "=2"))]
17402   "TARGET_USE_FANCY_MATH_387
17403    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17404        || TARGET_MIX_SSE_I387)
17405    && flag_unsafe_math_optimizations"
17406   "fyl2xp1"
17407   [(set_attr "type" "fpspc")
17408    (set_attr "mode" "XF")])
17410 (define_expand "log1pxf2"
17411   [(use (match_operand:XF 0 "register_operand" ""))
17412    (use (match_operand:XF 1 "register_operand" ""))]
17413   "TARGET_USE_FANCY_MATH_387
17414    && flag_unsafe_math_optimizations"
17416   if (optimize_insn_for_size_p ())
17417     FAIL;
17419   ix86_emit_i387_log1p (operands[0], operands[1]);
17420   DONE;
17423 (define_expand "log1p<mode>2"
17424   [(use (match_operand:MODEF 0 "register_operand" ""))
17425    (use (match_operand:MODEF 1 "register_operand" ""))]
17426   "TARGET_USE_FANCY_MATH_387
17427    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17428        || TARGET_MIX_SSE_I387)
17429    && flag_unsafe_math_optimizations"
17431   rtx op0;
17433   if (optimize_insn_for_size_p ())
17434     FAIL;
17436   op0 = gen_reg_rtx (XFmode);
17438   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17440   ix86_emit_i387_log1p (op0, operands[1]);
17441   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17442   DONE;
17445 (define_insn "fxtractxf3_i387"
17446   [(set (match_operand:XF 0 "register_operand" "=f")
17447         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17448                    UNSPEC_XTRACT_FRACT))
17449    (set (match_operand:XF 1 "register_operand" "=u")
17450         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17451   "TARGET_USE_FANCY_MATH_387
17452    && flag_unsafe_math_optimizations"
17453   "fxtract"
17454   [(set_attr "type" "fpspc")
17455    (set_attr "mode" "XF")])
17457 (define_insn "fxtract_extend<mode>xf3_i387"
17458   [(set (match_operand:XF 0 "register_operand" "=f")
17459         (unspec:XF [(float_extend:XF
17460                       (match_operand:MODEF 2 "register_operand" "0"))]
17461                    UNSPEC_XTRACT_FRACT))
17462    (set (match_operand:XF 1 "register_operand" "=u")
17463         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17464   "TARGET_USE_FANCY_MATH_387
17465    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17466        || TARGET_MIX_SSE_I387)
17467    && flag_unsafe_math_optimizations"
17468   "fxtract"
17469   [(set_attr "type" "fpspc")
17470    (set_attr "mode" "XF")])
17472 (define_expand "logbxf2"
17473   [(parallel [(set (match_dup 2)
17474                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17475                               UNSPEC_XTRACT_FRACT))
17476               (set (match_operand:XF 0 "register_operand" "")
17477                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17478   "TARGET_USE_FANCY_MATH_387
17479    && flag_unsafe_math_optimizations"
17481   operands[2] = gen_reg_rtx (XFmode);
17484 (define_expand "logb<mode>2"
17485   [(use (match_operand:MODEF 0 "register_operand" ""))
17486    (use (match_operand:MODEF 1 "register_operand" ""))]
17487   "TARGET_USE_FANCY_MATH_387
17488    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17489        || TARGET_MIX_SSE_I387)
17490    && flag_unsafe_math_optimizations"
17492   rtx op0 = gen_reg_rtx (XFmode);
17493   rtx op1 = gen_reg_rtx (XFmode);
17495   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17496   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17497   DONE;
17500 (define_expand "ilogbxf2"
17501   [(use (match_operand:SI 0 "register_operand" ""))
17502    (use (match_operand:XF 1 "register_operand" ""))]
17503   "TARGET_USE_FANCY_MATH_387
17504    && flag_unsafe_math_optimizations"
17506   rtx op0, op1;
17508   if (optimize_insn_for_size_p ())
17509     FAIL;
17511   op0 = gen_reg_rtx (XFmode);
17512   op1 = gen_reg_rtx (XFmode);
17514   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17515   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17516   DONE;
17519 (define_expand "ilogb<mode>2"
17520   [(use (match_operand:SI 0 "register_operand" ""))
17521    (use (match_operand:MODEF 1 "register_operand" ""))]
17522   "TARGET_USE_FANCY_MATH_387
17523    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17524        || TARGET_MIX_SSE_I387)
17525    && flag_unsafe_math_optimizations"
17527   rtx op0, op1;
17529   if (optimize_insn_for_size_p ())
17530     FAIL;
17532   op0 = gen_reg_rtx (XFmode);
17533   op1 = gen_reg_rtx (XFmode);
17535   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17536   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17537   DONE;
17540 (define_insn "*f2xm1xf2_i387"
17541   [(set (match_operand:XF 0 "register_operand" "=f")
17542         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17543                    UNSPEC_F2XM1))]
17544   "TARGET_USE_FANCY_MATH_387
17545    && flag_unsafe_math_optimizations"
17546   "f2xm1"
17547   [(set_attr "type" "fpspc")
17548    (set_attr "mode" "XF")])
17550 (define_insn "*fscalexf4_i387"
17551   [(set (match_operand:XF 0 "register_operand" "=f")
17552         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17553                     (match_operand:XF 3 "register_operand" "1")]
17554                    UNSPEC_FSCALE_FRACT))
17555    (set (match_operand:XF 1 "register_operand" "=u")
17556         (unspec:XF [(match_dup 2) (match_dup 3)]
17557                    UNSPEC_FSCALE_EXP))]
17558   "TARGET_USE_FANCY_MATH_387
17559    && flag_unsafe_math_optimizations"
17560   "fscale"
17561   [(set_attr "type" "fpspc")
17562    (set_attr "mode" "XF")])
17564 (define_expand "expNcorexf3"
17565   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17566                                (match_operand:XF 2 "register_operand" "")))
17567    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17568    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17569    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17570    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17571    (parallel [(set (match_operand:XF 0 "register_operand" "")
17572                    (unspec:XF [(match_dup 8) (match_dup 4)]
17573                               UNSPEC_FSCALE_FRACT))
17574               (set (match_dup 9)
17575                    (unspec:XF [(match_dup 8) (match_dup 4)]
17576                               UNSPEC_FSCALE_EXP))])]
17577   "TARGET_USE_FANCY_MATH_387
17578    && flag_unsafe_math_optimizations"
17580   int i;
17582   if (optimize_insn_for_size_p ())
17583     FAIL;
17585   for (i = 3; i < 10; i++)
17586     operands[i] = gen_reg_rtx (XFmode);
17588   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17591 (define_expand "expxf2"
17592   [(use (match_operand:XF 0 "register_operand" ""))
17593    (use (match_operand:XF 1 "register_operand" ""))]
17594   "TARGET_USE_FANCY_MATH_387
17595    && flag_unsafe_math_optimizations"
17597   rtx op2;
17599   if (optimize_insn_for_size_p ())
17600     FAIL;
17602   op2 = gen_reg_rtx (XFmode);
17603   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17605   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17606   DONE;
17609 (define_expand "exp<mode>2"
17610   [(use (match_operand:MODEF 0 "register_operand" ""))
17611    (use (match_operand:MODEF 1 "general_operand" ""))]
17612  "TARGET_USE_FANCY_MATH_387
17613    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17614        || TARGET_MIX_SSE_I387)
17615    && flag_unsafe_math_optimizations"
17617   rtx op0, op1;
17619   if (optimize_insn_for_size_p ())
17620     FAIL;
17622   op0 = gen_reg_rtx (XFmode);
17623   op1 = gen_reg_rtx (XFmode);
17625   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17626   emit_insn (gen_expxf2 (op0, op1));
17627   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17628   DONE;
17631 (define_expand "exp10xf2"
17632   [(use (match_operand:XF 0 "register_operand" ""))
17633    (use (match_operand:XF 1 "register_operand" ""))]
17634   "TARGET_USE_FANCY_MATH_387
17635    && flag_unsafe_math_optimizations"
17637   rtx op2;
17639   if (optimize_insn_for_size_p ())
17640     FAIL;
17642   op2 = gen_reg_rtx (XFmode);
17643   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17645   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17646   DONE;
17649 (define_expand "exp10<mode>2"
17650   [(use (match_operand:MODEF 0 "register_operand" ""))
17651    (use (match_operand:MODEF 1 "general_operand" ""))]
17652  "TARGET_USE_FANCY_MATH_387
17653    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17654        || TARGET_MIX_SSE_I387)
17655    && flag_unsafe_math_optimizations"
17657   rtx op0, op1;
17659   if (optimize_insn_for_size_p ())
17660     FAIL;
17662   op0 = gen_reg_rtx (XFmode);
17663   op1 = gen_reg_rtx (XFmode);
17665   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17666   emit_insn (gen_exp10xf2 (op0, op1));
17667   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17668   DONE;
17671 (define_expand "exp2xf2"
17672   [(use (match_operand:XF 0 "register_operand" ""))
17673    (use (match_operand:XF 1 "register_operand" ""))]
17674   "TARGET_USE_FANCY_MATH_387
17675    && flag_unsafe_math_optimizations"
17677   rtx op2;
17679   if (optimize_insn_for_size_p ())
17680     FAIL;
17682   op2 = gen_reg_rtx (XFmode);
17683   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17685   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17686   DONE;
17689 (define_expand "exp2<mode>2"
17690   [(use (match_operand:MODEF 0 "register_operand" ""))
17691    (use (match_operand:MODEF 1 "general_operand" ""))]
17692  "TARGET_USE_FANCY_MATH_387
17693    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17694        || TARGET_MIX_SSE_I387)
17695    && flag_unsafe_math_optimizations"
17697   rtx op0, op1;
17699   if (optimize_insn_for_size_p ())
17700     FAIL;
17702   op0 = gen_reg_rtx (XFmode);
17703   op1 = gen_reg_rtx (XFmode);
17705   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17706   emit_insn (gen_exp2xf2 (op0, op1));
17707   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17708   DONE;
17711 (define_expand "expm1xf2"
17712   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17713                                (match_dup 2)))
17714    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17715    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17716    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17717    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17718    (parallel [(set (match_dup 7)
17719                    (unspec:XF [(match_dup 6) (match_dup 4)]
17720                               UNSPEC_FSCALE_FRACT))
17721               (set (match_dup 8)
17722                    (unspec:XF [(match_dup 6) (match_dup 4)]
17723                               UNSPEC_FSCALE_EXP))])
17724    (parallel [(set (match_dup 10)
17725                    (unspec:XF [(match_dup 9) (match_dup 8)]
17726                               UNSPEC_FSCALE_FRACT))
17727               (set (match_dup 11)
17728                    (unspec:XF [(match_dup 9) (match_dup 8)]
17729                               UNSPEC_FSCALE_EXP))])
17730    (set (match_dup 12) (minus:XF (match_dup 10)
17731                                  (float_extend:XF (match_dup 13))))
17732    (set (match_operand:XF 0 "register_operand" "")
17733         (plus:XF (match_dup 12) (match_dup 7)))]
17734   "TARGET_USE_FANCY_MATH_387
17735    && flag_unsafe_math_optimizations"
17737   int i;
17739   if (optimize_insn_for_size_p ())
17740     FAIL;
17742   for (i = 2; i < 13; i++)
17743     operands[i] = gen_reg_rtx (XFmode);
17745   operands[13]
17746     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17748   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17751 (define_expand "expm1<mode>2"
17752   [(use (match_operand:MODEF 0 "register_operand" ""))
17753    (use (match_operand:MODEF 1 "general_operand" ""))]
17754  "TARGET_USE_FANCY_MATH_387
17755    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17756        || TARGET_MIX_SSE_I387)
17757    && flag_unsafe_math_optimizations"
17759   rtx op0, op1;
17761   if (optimize_insn_for_size_p ())
17762     FAIL;
17764   op0 = gen_reg_rtx (XFmode);
17765   op1 = gen_reg_rtx (XFmode);
17767   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17768   emit_insn (gen_expm1xf2 (op0, op1));
17769   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17770   DONE;
17773 (define_expand "ldexpxf3"
17774   [(set (match_dup 3)
17775         (float:XF (match_operand:SI 2 "register_operand" "")))
17776    (parallel [(set (match_operand:XF 0 " register_operand" "")
17777                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17778                                (match_dup 3)]
17779                               UNSPEC_FSCALE_FRACT))
17780               (set (match_dup 4)
17781                    (unspec:XF [(match_dup 1) (match_dup 3)]
17782                               UNSPEC_FSCALE_EXP))])]
17783   "TARGET_USE_FANCY_MATH_387
17784    && flag_unsafe_math_optimizations"
17786   if (optimize_insn_for_size_p ())
17787     FAIL;
17789   operands[3] = gen_reg_rtx (XFmode);
17790   operands[4] = gen_reg_rtx (XFmode);
17793 (define_expand "ldexp<mode>3"
17794   [(use (match_operand:MODEF 0 "register_operand" ""))
17795    (use (match_operand:MODEF 1 "general_operand" ""))
17796    (use (match_operand:SI 2 "register_operand" ""))]
17797  "TARGET_USE_FANCY_MATH_387
17798    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17799        || TARGET_MIX_SSE_I387)
17800    && flag_unsafe_math_optimizations"
17802   rtx op0, op1;
17804   if (optimize_insn_for_size_p ())
17805     FAIL;
17807   op0 = gen_reg_rtx (XFmode);
17808   op1 = gen_reg_rtx (XFmode);
17810   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17811   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17812   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17813   DONE;
17816 (define_expand "scalbxf3"
17817   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17818                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17819                                (match_operand:XF 2 "register_operand" "")]
17820                               UNSPEC_FSCALE_FRACT))
17821               (set (match_dup 3)
17822                    (unspec:XF [(match_dup 1) (match_dup 2)]
17823                               UNSPEC_FSCALE_EXP))])]
17824   "TARGET_USE_FANCY_MATH_387
17825    && flag_unsafe_math_optimizations"
17827   if (optimize_insn_for_size_p ())
17828     FAIL;
17830   operands[3] = gen_reg_rtx (XFmode);
17833 (define_expand "scalb<mode>3"
17834   [(use (match_operand:MODEF 0 "register_operand" ""))
17835    (use (match_operand:MODEF 1 "general_operand" ""))
17836    (use (match_operand:MODEF 2 "register_operand" ""))]
17837  "TARGET_USE_FANCY_MATH_387
17838    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17839        || TARGET_MIX_SSE_I387)
17840    && flag_unsafe_math_optimizations"
17842   rtx op0, op1, op2;
17844   if (optimize_insn_for_size_p ())
17845     FAIL;
17847   op0 = gen_reg_rtx (XFmode);
17848   op1 = gen_reg_rtx (XFmode);
17849   op2 = gen_reg_rtx (XFmode);
17851   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17852   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17853   emit_insn (gen_scalbxf3 (op0, op1, op2));
17854   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17855   DONE;
17859 (define_insn "sse4_1_round<mode>2"
17860   [(set (match_operand:MODEF 0 "register_operand" "=x")
17861         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17862                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17863                       UNSPEC_ROUND))]
17864   "TARGET_ROUND"
17865   "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17866   [(set_attr "type" "ssecvt")
17867    (set_attr "prefix_extra" "1")
17868    (set_attr "prefix" "maybe_vex")
17869    (set_attr "mode" "<MODE>")])
17871 (define_insn "rintxf2"
17872   [(set (match_operand:XF 0 "register_operand" "=f")
17873         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17874                    UNSPEC_FRNDINT))]
17875   "TARGET_USE_FANCY_MATH_387
17876    && flag_unsafe_math_optimizations"
17877   "frndint"
17878   [(set_attr "type" "fpspc")
17879    (set_attr "mode" "XF")])
17881 (define_expand "rint<mode>2"
17882   [(use (match_operand:MODEF 0 "register_operand" ""))
17883    (use (match_operand:MODEF 1 "register_operand" ""))]
17884   "(TARGET_USE_FANCY_MATH_387
17885     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17886         || TARGET_MIX_SSE_I387)
17887     && flag_unsafe_math_optimizations)
17888    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17889        && !flag_trapping_math)"
17891   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17892       && !flag_trapping_math)
17893     {
17894       if (!TARGET_ROUND && optimize_insn_for_size_p ())
17895         FAIL;
17896       if (TARGET_ROUND)
17897         emit_insn (gen_sse4_1_round<mode>2
17898                    (operands[0], operands[1], GEN_INT (0x04)));
17899       else
17900         ix86_expand_rint (operand0, operand1);
17901     }
17902   else
17903     {
17904       rtx op0 = gen_reg_rtx (XFmode);
17905       rtx op1 = gen_reg_rtx (XFmode);
17907       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17908       emit_insn (gen_rintxf2 (op0, op1));
17910       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17911     }
17912   DONE;
17915 (define_expand "round<mode>2"
17916   [(match_operand:MODEF 0 "register_operand" "")
17917    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17918   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17919    && !flag_trapping_math && !flag_rounding_math"
17921   if (optimize_insn_for_size_p ())
17922     FAIL;
17923   if (TARGET_64BIT || (<MODE>mode != DFmode))
17924     ix86_expand_round (operand0, operand1);
17925   else
17926     ix86_expand_rounddf_32 (operand0, operand1);
17927   DONE;
17930 (define_insn_and_split "*fistdi2_1"
17931   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17932         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17933                    UNSPEC_FIST))]
17934   "TARGET_USE_FANCY_MATH_387
17935    && !(reload_completed || reload_in_progress)"
17936   "#"
17937   "&& 1"
17938   [(const_int 0)]
17940   if (memory_operand (operands[0], VOIDmode))
17941     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17942   else
17943     {
17944       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17945       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17946                                          operands[2]));
17947     }
17948   DONE;
17950   [(set_attr "type" "fpspc")
17951    (set_attr "mode" "DI")])
17953 (define_insn "fistdi2"
17954   [(set (match_operand:DI 0 "memory_operand" "=m")
17955         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17956                    UNSPEC_FIST))
17957    (clobber (match_scratch:XF 2 "=&1f"))]
17958   "TARGET_USE_FANCY_MATH_387"
17959   "* return output_fix_trunc (insn, operands, 0);"
17960   [(set_attr "type" "fpspc")
17961    (set_attr "mode" "DI")])
17963 (define_insn "fistdi2_with_temp"
17964   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17965         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17966                    UNSPEC_FIST))
17967    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17968    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17969   "TARGET_USE_FANCY_MATH_387"
17970   "#"
17971   [(set_attr "type" "fpspc")
17972    (set_attr "mode" "DI")])
17974 (define_split
17975   [(set (match_operand:DI 0 "register_operand" "")
17976         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17977                    UNSPEC_FIST))
17978    (clobber (match_operand:DI 2 "memory_operand" ""))
17979    (clobber (match_scratch 3 ""))]
17980   "reload_completed"
17981   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17982               (clobber (match_dup 3))])
17983    (set (match_dup 0) (match_dup 2))]
17984   "")
17986 (define_split
17987   [(set (match_operand:DI 0 "memory_operand" "")
17988         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17989                    UNSPEC_FIST))
17990    (clobber (match_operand:DI 2 "memory_operand" ""))
17991    (clobber (match_scratch 3 ""))]
17992   "reload_completed"
17993   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17994               (clobber (match_dup 3))])]
17995   "")
17997 (define_insn_and_split "*fist<mode>2_1"
17998   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17999         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18000                            UNSPEC_FIST))]
18001   "TARGET_USE_FANCY_MATH_387
18002    && !(reload_completed || reload_in_progress)"
18003   "#"
18004   "&& 1"
18005   [(const_int 0)]
18007   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18008   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18009                                         operands[2]));
18010   DONE;
18012   [(set_attr "type" "fpspc")
18013    (set_attr "mode" "<MODE>")])
18015 (define_insn "fist<mode>2"
18016   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18017         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18018                            UNSPEC_FIST))]
18019   "TARGET_USE_FANCY_MATH_387"
18020   "* return output_fix_trunc (insn, operands, 0);"
18021   [(set_attr "type" "fpspc")
18022    (set_attr "mode" "<MODE>")])
18024 (define_insn "fist<mode>2_with_temp"
18025   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18026         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18027                            UNSPEC_FIST))
18028    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18029   "TARGET_USE_FANCY_MATH_387"
18030   "#"
18031   [(set_attr "type" "fpspc")
18032    (set_attr "mode" "<MODE>")])
18034 (define_split
18035   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18036         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18037                            UNSPEC_FIST))
18038    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18039   "reload_completed"
18040   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18041    (set (match_dup 0) (match_dup 2))]
18042   "")
18044 (define_split
18045   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18046         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18047                            UNSPEC_FIST))
18048    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18049   "reload_completed"
18050   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18051   "")
18053 (define_expand "lrintxf<mode>2"
18054   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18055      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18056                       UNSPEC_FIST))]
18057   "TARGET_USE_FANCY_MATH_387"
18058   "")
18060 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18061   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18062      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18063                         UNSPEC_FIX_NOTRUNC))]
18064   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18065    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18066   "")
18068 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18069   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18070    (match_operand:MODEF 1 "register_operand" "")]
18071   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18072    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18073    && !flag_trapping_math && !flag_rounding_math"
18075   if (optimize_insn_for_size_p ())
18076     FAIL;
18077   ix86_expand_lround (operand0, operand1);
18078   DONE;
18081 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18082 (define_insn_and_split "frndintxf2_floor"
18083   [(set (match_operand:XF 0 "register_operand" "")
18084         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18085          UNSPEC_FRNDINT_FLOOR))
18086    (clobber (reg:CC FLAGS_REG))]
18087   "TARGET_USE_FANCY_MATH_387
18088    && flag_unsafe_math_optimizations
18089    && !(reload_completed || reload_in_progress)"
18090   "#"
18091   "&& 1"
18092   [(const_int 0)]
18094   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18096   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18097   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18099   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18100                                         operands[2], operands[3]));
18101   DONE;
18103   [(set_attr "type" "frndint")
18104    (set_attr "i387_cw" "floor")
18105    (set_attr "mode" "XF")])
18107 (define_insn "frndintxf2_floor_i387"
18108   [(set (match_operand:XF 0 "register_operand" "=f")
18109         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18110          UNSPEC_FRNDINT_FLOOR))
18111    (use (match_operand:HI 2 "memory_operand" "m"))
18112    (use (match_operand:HI 3 "memory_operand" "m"))]
18113   "TARGET_USE_FANCY_MATH_387
18114    && flag_unsafe_math_optimizations"
18115   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18116   [(set_attr "type" "frndint")
18117    (set_attr "i387_cw" "floor")
18118    (set_attr "mode" "XF")])
18120 (define_expand "floorxf2"
18121   [(use (match_operand:XF 0 "register_operand" ""))
18122    (use (match_operand:XF 1 "register_operand" ""))]
18123   "TARGET_USE_FANCY_MATH_387
18124    && flag_unsafe_math_optimizations"
18126   if (optimize_insn_for_size_p ())
18127     FAIL;
18128   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18129   DONE;
18132 (define_expand "floor<mode>2"
18133   [(use (match_operand:MODEF 0 "register_operand" ""))
18134    (use (match_operand:MODEF 1 "register_operand" ""))]
18135   "(TARGET_USE_FANCY_MATH_387
18136     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18137         || TARGET_MIX_SSE_I387)
18138     && flag_unsafe_math_optimizations)
18139    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18140        && !flag_trapping_math)"
18142   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18143       && !flag_trapping_math
18144       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18145     {
18146       if (!TARGET_ROUND && optimize_insn_for_size_p ())
18147         FAIL;
18148       if (TARGET_ROUND)
18149         emit_insn (gen_sse4_1_round<mode>2
18150                    (operands[0], operands[1], GEN_INT (0x01)));
18151       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18152         ix86_expand_floorceil (operand0, operand1, true);
18153       else
18154         ix86_expand_floorceildf_32 (operand0, operand1, true);
18155     }
18156   else
18157     {
18158       rtx op0, op1;
18160       if (optimize_insn_for_size_p ())
18161         FAIL;
18163       op0 = gen_reg_rtx (XFmode);
18164       op1 = gen_reg_rtx (XFmode);
18165       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18166       emit_insn (gen_frndintxf2_floor (op0, op1));
18168       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18169     }
18170   DONE;
18173 (define_insn_and_split "*fist<mode>2_floor_1"
18174   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18175         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18176          UNSPEC_FIST_FLOOR))
18177    (clobber (reg:CC FLAGS_REG))]
18178   "TARGET_USE_FANCY_MATH_387
18179    && flag_unsafe_math_optimizations
18180    && !(reload_completed || reload_in_progress)"
18181   "#"
18182   "&& 1"
18183   [(const_int 0)]
18185   ix86_optimize_mode_switching[I387_FLOOR] = 1;
18187   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18188   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18189   if (memory_operand (operands[0], VOIDmode))
18190     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18191                                       operands[2], operands[3]));
18192   else
18193     {
18194       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18195       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18196                                                   operands[2], operands[3],
18197                                                   operands[4]));
18198     }
18199   DONE;
18201   [(set_attr "type" "fistp")
18202    (set_attr "i387_cw" "floor")
18203    (set_attr "mode" "<MODE>")])
18205 (define_insn "fistdi2_floor"
18206   [(set (match_operand:DI 0 "memory_operand" "=m")
18207         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18208          UNSPEC_FIST_FLOOR))
18209    (use (match_operand:HI 2 "memory_operand" "m"))
18210    (use (match_operand:HI 3 "memory_operand" "m"))
18211    (clobber (match_scratch:XF 4 "=&1f"))]
18212   "TARGET_USE_FANCY_MATH_387
18213    && flag_unsafe_math_optimizations"
18214   "* return output_fix_trunc (insn, operands, 0);"
18215   [(set_attr "type" "fistp")
18216    (set_attr "i387_cw" "floor")
18217    (set_attr "mode" "DI")])
18219 (define_insn "fistdi2_floor_with_temp"
18220   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18221         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18222          UNSPEC_FIST_FLOOR))
18223    (use (match_operand:HI 2 "memory_operand" "m,m"))
18224    (use (match_operand:HI 3 "memory_operand" "m,m"))
18225    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18226    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18227   "TARGET_USE_FANCY_MATH_387
18228    && flag_unsafe_math_optimizations"
18229   "#"
18230   [(set_attr "type" "fistp")
18231    (set_attr "i387_cw" "floor")
18232    (set_attr "mode" "DI")])
18234 (define_split
18235   [(set (match_operand:DI 0 "register_operand" "")
18236         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18237          UNSPEC_FIST_FLOOR))
18238    (use (match_operand:HI 2 "memory_operand" ""))
18239    (use (match_operand:HI 3 "memory_operand" ""))
18240    (clobber (match_operand:DI 4 "memory_operand" ""))
18241    (clobber (match_scratch 5 ""))]
18242   "reload_completed"
18243   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18244               (use (match_dup 2))
18245               (use (match_dup 3))
18246               (clobber (match_dup 5))])
18247    (set (match_dup 0) (match_dup 4))]
18248   "")
18250 (define_split
18251   [(set (match_operand:DI 0 "memory_operand" "")
18252         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18253          UNSPEC_FIST_FLOOR))
18254    (use (match_operand:HI 2 "memory_operand" ""))
18255    (use (match_operand:HI 3 "memory_operand" ""))
18256    (clobber (match_operand:DI 4 "memory_operand" ""))
18257    (clobber (match_scratch 5 ""))]
18258   "reload_completed"
18259   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18260               (use (match_dup 2))
18261               (use (match_dup 3))
18262               (clobber (match_dup 5))])]
18263   "")
18265 (define_insn "fist<mode>2_floor"
18266   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18267         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18268          UNSPEC_FIST_FLOOR))
18269    (use (match_operand:HI 2 "memory_operand" "m"))
18270    (use (match_operand:HI 3 "memory_operand" "m"))]
18271   "TARGET_USE_FANCY_MATH_387
18272    && flag_unsafe_math_optimizations"
18273   "* return output_fix_trunc (insn, operands, 0);"
18274   [(set_attr "type" "fistp")
18275    (set_attr "i387_cw" "floor")
18276    (set_attr "mode" "<MODE>")])
18278 (define_insn "fist<mode>2_floor_with_temp"
18279   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18280         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18281          UNSPEC_FIST_FLOOR))
18282    (use (match_operand:HI 2 "memory_operand" "m,m"))
18283    (use (match_operand:HI 3 "memory_operand" "m,m"))
18284    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18285   "TARGET_USE_FANCY_MATH_387
18286    && flag_unsafe_math_optimizations"
18287   "#"
18288   [(set_attr "type" "fistp")
18289    (set_attr "i387_cw" "floor")
18290    (set_attr "mode" "<MODE>")])
18292 (define_split
18293   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18294         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18295          UNSPEC_FIST_FLOOR))
18296    (use (match_operand:HI 2 "memory_operand" ""))
18297    (use (match_operand:HI 3 "memory_operand" ""))
18298    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18299   "reload_completed"
18300   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18301                                   UNSPEC_FIST_FLOOR))
18302               (use (match_dup 2))
18303               (use (match_dup 3))])
18304    (set (match_dup 0) (match_dup 4))]
18305   "")
18307 (define_split
18308   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18309         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18310          UNSPEC_FIST_FLOOR))
18311    (use (match_operand:HI 2 "memory_operand" ""))
18312    (use (match_operand:HI 3 "memory_operand" ""))
18313    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18314   "reload_completed"
18315   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18316                                   UNSPEC_FIST_FLOOR))
18317               (use (match_dup 2))
18318               (use (match_dup 3))])]
18319   "")
18321 (define_expand "lfloorxf<mode>2"
18322   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18323                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18324                     UNSPEC_FIST_FLOOR))
18325               (clobber (reg:CC FLAGS_REG))])]
18326   "TARGET_USE_FANCY_MATH_387
18327    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18328    && flag_unsafe_math_optimizations"
18329   "")
18331 (define_expand "lfloor<mode>di2"
18332   [(match_operand:DI 0 "nonimmediate_operand" "")
18333    (match_operand:MODEF 1 "register_operand" "")]
18334   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18335    && !flag_trapping_math"
18337   if (optimize_insn_for_size_p ())
18338     FAIL;
18339   ix86_expand_lfloorceil (operand0, operand1, true);
18340   DONE;
18343 (define_expand "lfloor<mode>si2"
18344   [(match_operand:SI 0 "nonimmediate_operand" "")
18345    (match_operand:MODEF 1 "register_operand" "")]
18346   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18347    && !flag_trapping_math"
18349   if (optimize_insn_for_size_p () && TARGET_64BIT)
18350     FAIL;
18351   ix86_expand_lfloorceil (operand0, operand1, true);
18352   DONE;
18355 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18356 (define_insn_and_split "frndintxf2_ceil"
18357   [(set (match_operand:XF 0 "register_operand" "")
18358         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18359          UNSPEC_FRNDINT_CEIL))
18360    (clobber (reg:CC FLAGS_REG))]
18361   "TARGET_USE_FANCY_MATH_387
18362    && flag_unsafe_math_optimizations
18363    && !(reload_completed || reload_in_progress)"
18364   "#"
18365   "&& 1"
18366   [(const_int 0)]
18368   ix86_optimize_mode_switching[I387_CEIL] = 1;
18370   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18371   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18373   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
18374                                        operands[2], operands[3]));
18375   DONE;
18377   [(set_attr "type" "frndint")
18378    (set_attr "i387_cw" "ceil")
18379    (set_attr "mode" "XF")])
18381 (define_insn "frndintxf2_ceil_i387"
18382   [(set (match_operand:XF 0 "register_operand" "=f")
18383         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18384          UNSPEC_FRNDINT_CEIL))
18385    (use (match_operand:HI 2 "memory_operand" "m"))
18386    (use (match_operand:HI 3 "memory_operand" "m"))]
18387   "TARGET_USE_FANCY_MATH_387
18388    && flag_unsafe_math_optimizations"
18389   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18390   [(set_attr "type" "frndint")
18391    (set_attr "i387_cw" "ceil")
18392    (set_attr "mode" "XF")])
18394 (define_expand "ceilxf2"
18395   [(use (match_operand:XF 0 "register_operand" ""))
18396    (use (match_operand:XF 1 "register_operand" ""))]
18397   "TARGET_USE_FANCY_MATH_387
18398    && flag_unsafe_math_optimizations"
18400   if (optimize_insn_for_size_p ())
18401     FAIL;
18402   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
18403   DONE;
18406 (define_expand "ceil<mode>2"
18407   [(use (match_operand:MODEF 0 "register_operand" ""))
18408    (use (match_operand:MODEF 1 "register_operand" ""))]
18409   "(TARGET_USE_FANCY_MATH_387
18410     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18411         || TARGET_MIX_SSE_I387)
18412     && flag_unsafe_math_optimizations)
18413    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18414        && !flag_trapping_math)"
18416   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18417       && !flag_trapping_math
18418       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18419     {
18420       if (TARGET_ROUND)
18421         emit_insn (gen_sse4_1_round<mode>2
18422                    (operands[0], operands[1], GEN_INT (0x02)));
18423       else if (optimize_insn_for_size_p ())
18424         FAIL;
18425       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18426         ix86_expand_floorceil (operand0, operand1, false);
18427       else
18428         ix86_expand_floorceildf_32 (operand0, operand1, false);
18429     }
18430   else
18431     {
18432       rtx op0, op1;
18434       if (optimize_insn_for_size_p ())
18435         FAIL;
18437       op0 = gen_reg_rtx (XFmode);
18438       op1 = gen_reg_rtx (XFmode);
18439       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18440       emit_insn (gen_frndintxf2_ceil (op0, op1));
18442       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18443     }
18444   DONE;
18447 (define_insn_and_split "*fist<mode>2_ceil_1"
18448   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18449         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18450          UNSPEC_FIST_CEIL))
18451    (clobber (reg:CC FLAGS_REG))]
18452   "TARGET_USE_FANCY_MATH_387
18453    && flag_unsafe_math_optimizations
18454    && !(reload_completed || reload_in_progress)"
18455   "#"
18456   "&& 1"
18457   [(const_int 0)]
18459   ix86_optimize_mode_switching[I387_CEIL] = 1;
18461   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18462   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18463   if (memory_operand (operands[0], VOIDmode))
18464     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18465                                      operands[2], operands[3]));
18466   else
18467     {
18468       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18469       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18470                                                  operands[2], operands[3],
18471                                                  operands[4]));
18472     }
18473   DONE;
18475   [(set_attr "type" "fistp")
18476    (set_attr "i387_cw" "ceil")
18477    (set_attr "mode" "<MODE>")])
18479 (define_insn "fistdi2_ceil"
18480   [(set (match_operand:DI 0 "memory_operand" "=m")
18481         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18482          UNSPEC_FIST_CEIL))
18483    (use (match_operand:HI 2 "memory_operand" "m"))
18484    (use (match_operand:HI 3 "memory_operand" "m"))
18485    (clobber (match_scratch:XF 4 "=&1f"))]
18486   "TARGET_USE_FANCY_MATH_387
18487    && flag_unsafe_math_optimizations"
18488   "* return output_fix_trunc (insn, operands, 0);"
18489   [(set_attr "type" "fistp")
18490    (set_attr "i387_cw" "ceil")
18491    (set_attr "mode" "DI")])
18493 (define_insn "fistdi2_ceil_with_temp"
18494   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18495         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18496          UNSPEC_FIST_CEIL))
18497    (use (match_operand:HI 2 "memory_operand" "m,m"))
18498    (use (match_operand:HI 3 "memory_operand" "m,m"))
18499    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18500    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18501   "TARGET_USE_FANCY_MATH_387
18502    && flag_unsafe_math_optimizations"
18503   "#"
18504   [(set_attr "type" "fistp")
18505    (set_attr "i387_cw" "ceil")
18506    (set_attr "mode" "DI")])
18508 (define_split
18509   [(set (match_operand:DI 0 "register_operand" "")
18510         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18511          UNSPEC_FIST_CEIL))
18512    (use (match_operand:HI 2 "memory_operand" ""))
18513    (use (match_operand:HI 3 "memory_operand" ""))
18514    (clobber (match_operand:DI 4 "memory_operand" ""))
18515    (clobber (match_scratch 5 ""))]
18516   "reload_completed"
18517   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18518               (use (match_dup 2))
18519               (use (match_dup 3))
18520               (clobber (match_dup 5))])
18521    (set (match_dup 0) (match_dup 4))]
18522   "")
18524 (define_split
18525   [(set (match_operand:DI 0 "memory_operand" "")
18526         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18527          UNSPEC_FIST_CEIL))
18528    (use (match_operand:HI 2 "memory_operand" ""))
18529    (use (match_operand:HI 3 "memory_operand" ""))
18530    (clobber (match_operand:DI 4 "memory_operand" ""))
18531    (clobber (match_scratch 5 ""))]
18532   "reload_completed"
18533   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18534               (use (match_dup 2))
18535               (use (match_dup 3))
18536               (clobber (match_dup 5))])]
18537   "")
18539 (define_insn "fist<mode>2_ceil"
18540   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18541         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18542          UNSPEC_FIST_CEIL))
18543    (use (match_operand:HI 2 "memory_operand" "m"))
18544    (use (match_operand:HI 3 "memory_operand" "m"))]
18545   "TARGET_USE_FANCY_MATH_387
18546    && flag_unsafe_math_optimizations"
18547   "* return output_fix_trunc (insn, operands, 0);"
18548   [(set_attr "type" "fistp")
18549    (set_attr "i387_cw" "ceil")
18550    (set_attr "mode" "<MODE>")])
18552 (define_insn "fist<mode>2_ceil_with_temp"
18553   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18554         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18555          UNSPEC_FIST_CEIL))
18556    (use (match_operand:HI 2 "memory_operand" "m,m"))
18557    (use (match_operand:HI 3 "memory_operand" "m,m"))
18558    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18559   "TARGET_USE_FANCY_MATH_387
18560    && flag_unsafe_math_optimizations"
18561   "#"
18562   [(set_attr "type" "fistp")
18563    (set_attr "i387_cw" "ceil")
18564    (set_attr "mode" "<MODE>")])
18566 (define_split
18567   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18568         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18569          UNSPEC_FIST_CEIL))
18570    (use (match_operand:HI 2 "memory_operand" ""))
18571    (use (match_operand:HI 3 "memory_operand" ""))
18572    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18573   "reload_completed"
18574   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18575                                   UNSPEC_FIST_CEIL))
18576               (use (match_dup 2))
18577               (use (match_dup 3))])
18578    (set (match_dup 0) (match_dup 4))]
18579   "")
18581 (define_split
18582   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18583         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18584          UNSPEC_FIST_CEIL))
18585    (use (match_operand:HI 2 "memory_operand" ""))
18586    (use (match_operand:HI 3 "memory_operand" ""))
18587    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18588   "reload_completed"
18589   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18590                                   UNSPEC_FIST_CEIL))
18591               (use (match_dup 2))
18592               (use (match_dup 3))])]
18593   "")
18595 (define_expand "lceilxf<mode>2"
18596   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18597                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18598                     UNSPEC_FIST_CEIL))
18599               (clobber (reg:CC FLAGS_REG))])]
18600   "TARGET_USE_FANCY_MATH_387
18601    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18602    && flag_unsafe_math_optimizations"
18603   "")
18605 (define_expand "lceil<mode>di2"
18606   [(match_operand:DI 0 "nonimmediate_operand" "")
18607    (match_operand:MODEF 1 "register_operand" "")]
18608   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18609    && !flag_trapping_math"
18611   ix86_expand_lfloorceil (operand0, operand1, false);
18612   DONE;
18615 (define_expand "lceil<mode>si2"
18616   [(match_operand:SI 0 "nonimmediate_operand" "")
18617    (match_operand:MODEF 1 "register_operand" "")]
18618   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18619    && !flag_trapping_math"
18621   ix86_expand_lfloorceil (operand0, operand1, false);
18622   DONE;
18625 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18626 (define_insn_and_split "frndintxf2_trunc"
18627   [(set (match_operand:XF 0 "register_operand" "")
18628         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18629          UNSPEC_FRNDINT_TRUNC))
18630    (clobber (reg:CC FLAGS_REG))]
18631   "TARGET_USE_FANCY_MATH_387
18632    && flag_unsafe_math_optimizations
18633    && !(reload_completed || reload_in_progress)"
18634   "#"
18635   "&& 1"
18636   [(const_int 0)]
18638   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18640   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18641   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18643   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18644                                         operands[2], operands[3]));
18645   DONE;
18647   [(set_attr "type" "frndint")
18648    (set_attr "i387_cw" "trunc")
18649    (set_attr "mode" "XF")])
18651 (define_insn "frndintxf2_trunc_i387"
18652   [(set (match_operand:XF 0 "register_operand" "=f")
18653         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18654          UNSPEC_FRNDINT_TRUNC))
18655    (use (match_operand:HI 2 "memory_operand" "m"))
18656    (use (match_operand:HI 3 "memory_operand" "m"))]
18657   "TARGET_USE_FANCY_MATH_387
18658    && flag_unsafe_math_optimizations"
18659   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18660   [(set_attr "type" "frndint")
18661    (set_attr "i387_cw" "trunc")
18662    (set_attr "mode" "XF")])
18664 (define_expand "btruncxf2"
18665   [(use (match_operand:XF 0 "register_operand" ""))
18666    (use (match_operand:XF 1 "register_operand" ""))]
18667   "TARGET_USE_FANCY_MATH_387
18668    && flag_unsafe_math_optimizations"
18670   if (optimize_insn_for_size_p ())
18671     FAIL;
18672   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18673   DONE;
18676 (define_expand "btrunc<mode>2"
18677   [(use (match_operand:MODEF 0 "register_operand" ""))
18678    (use (match_operand:MODEF 1 "register_operand" ""))]
18679   "(TARGET_USE_FANCY_MATH_387
18680     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18681         || TARGET_MIX_SSE_I387)
18682     && flag_unsafe_math_optimizations)
18683    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18684        && !flag_trapping_math)"
18686   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18687       && !flag_trapping_math
18688       && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18689     {
18690       if (TARGET_ROUND)
18691         emit_insn (gen_sse4_1_round<mode>2
18692                    (operands[0], operands[1], GEN_INT (0x03)));
18693       else if (optimize_insn_for_size_p ())
18694         FAIL;
18695       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18696         ix86_expand_trunc (operand0, operand1);
18697       else
18698         ix86_expand_truncdf_32 (operand0, operand1);
18699     }
18700   else
18701     {
18702       rtx op0, op1;
18704       if (optimize_insn_for_size_p ())
18705         FAIL;
18707       op0 = gen_reg_rtx (XFmode);
18708       op1 = gen_reg_rtx (XFmode);
18709       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18710       emit_insn (gen_frndintxf2_trunc (op0, op1));
18712       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18713     }
18714   DONE;
18717 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18718 (define_insn_and_split "frndintxf2_mask_pm"
18719   [(set (match_operand:XF 0 "register_operand" "")
18720         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18721          UNSPEC_FRNDINT_MASK_PM))
18722    (clobber (reg:CC FLAGS_REG))]
18723   "TARGET_USE_FANCY_MATH_387
18724    && flag_unsafe_math_optimizations
18725    && !(reload_completed || reload_in_progress)"
18726   "#"
18727   "&& 1"
18728   [(const_int 0)]
18730   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18732   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18733   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18735   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18736                                           operands[2], operands[3]));
18737   DONE;
18739   [(set_attr "type" "frndint")
18740    (set_attr "i387_cw" "mask_pm")
18741    (set_attr "mode" "XF")])
18743 (define_insn "frndintxf2_mask_pm_i387"
18744   [(set (match_operand:XF 0 "register_operand" "=f")
18745         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18746          UNSPEC_FRNDINT_MASK_PM))
18747    (use (match_operand:HI 2 "memory_operand" "m"))
18748    (use (match_operand:HI 3 "memory_operand" "m"))]
18749   "TARGET_USE_FANCY_MATH_387
18750    && flag_unsafe_math_optimizations"
18751   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18752   [(set_attr "type" "frndint")
18753    (set_attr "i387_cw" "mask_pm")
18754    (set_attr "mode" "XF")])
18756 (define_expand "nearbyintxf2"
18757   [(use (match_operand:XF 0 "register_operand" ""))
18758    (use (match_operand:XF 1 "register_operand" ""))]
18759   "TARGET_USE_FANCY_MATH_387
18760    && flag_unsafe_math_optimizations"
18762   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18764   DONE;
18767 (define_expand "nearbyint<mode>2"
18768   [(use (match_operand:MODEF 0 "register_operand" ""))
18769    (use (match_operand:MODEF 1 "register_operand" ""))]
18770   "TARGET_USE_FANCY_MATH_387
18771    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18772        || TARGET_MIX_SSE_I387)
18773    && flag_unsafe_math_optimizations"
18775   rtx op0 = gen_reg_rtx (XFmode);
18776   rtx op1 = gen_reg_rtx (XFmode);
18778   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18779   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18781   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18782   DONE;
18785 (define_insn "fxam<mode>2_i387"
18786   [(set (match_operand:HI 0 "register_operand" "=a")
18787         (unspec:HI
18788           [(match_operand:X87MODEF 1 "register_operand" "f")]
18789           UNSPEC_FXAM))]
18790   "TARGET_USE_FANCY_MATH_387"
18791   "fxam\n\tfnstsw\t%0"
18792   [(set_attr "type" "multi")
18793    (set_attr "unit" "i387")
18794    (set_attr "mode" "<MODE>")])
18796 (define_expand "isinf<mode>2"
18797   [(use (match_operand:SI 0 "register_operand" ""))
18798    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18799   "TARGET_USE_FANCY_MATH_387
18800    && TARGET_C99_FUNCTIONS
18801    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18803   rtx mask = GEN_INT (0x45);
18804   rtx val = GEN_INT (0x05);
18806   rtx cond;
18808   rtx scratch = gen_reg_rtx (HImode);
18809   rtx res = gen_reg_rtx (QImode);
18811   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18812   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18813   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18814   cond = gen_rtx_fmt_ee (EQ, QImode,
18815                          gen_rtx_REG (CCmode, FLAGS_REG),
18816                          const0_rtx);
18817   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18818   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18819   DONE;
18822 (define_expand "signbit<mode>2"
18823   [(use (match_operand:SI 0 "register_operand" ""))
18824    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18825   "TARGET_USE_FANCY_MATH_387
18826    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18828   rtx mask = GEN_INT (0x0200);
18830   rtx scratch = gen_reg_rtx (HImode);
18832   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18833   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18834   DONE;
18837 ;; Block operation instructions
18839 (define_insn "cld"
18840   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18841   ""
18842   "cld"
18843   [(set_attr "length" "1")
18844    (set_attr "length_immediate" "0")
18845    (set_attr "modrm" "0")])
18847 (define_expand "movmemsi"
18848   [(use (match_operand:BLK 0 "memory_operand" ""))
18849    (use (match_operand:BLK 1 "memory_operand" ""))
18850    (use (match_operand:SI 2 "nonmemory_operand" ""))
18851    (use (match_operand:SI 3 "const_int_operand" ""))
18852    (use (match_operand:SI 4 "const_int_operand" ""))
18853    (use (match_operand:SI 5 "const_int_operand" ""))]
18854   ""
18856  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18857                          operands[4], operands[5]))
18858    DONE;
18859  else
18860    FAIL;
18863 (define_expand "movmemdi"
18864   [(use (match_operand:BLK 0 "memory_operand" ""))
18865    (use (match_operand:BLK 1 "memory_operand" ""))
18866    (use (match_operand:DI 2 "nonmemory_operand" ""))
18867    (use (match_operand:DI 3 "const_int_operand" ""))
18868    (use (match_operand:SI 4 "const_int_operand" ""))
18869    (use (match_operand:SI 5 "const_int_operand" ""))]
18870   "TARGET_64BIT"
18872  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18873                          operands[4], operands[5]))
18874    DONE;
18875  else
18876    FAIL;
18879 ;; Most CPUs don't like single string operations
18880 ;; Handle this case here to simplify previous expander.
18882 (define_expand "strmov"
18883   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18884    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18885    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18886               (clobber (reg:CC FLAGS_REG))])
18887    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18888               (clobber (reg:CC FLAGS_REG))])]
18889   ""
18891   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18893   /* If .md ever supports :P for Pmode, these can be directly
18894      in the pattern above.  */
18895   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18896   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18898   /* Can't use this if the user has appropriated esi or edi.  */
18899   if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18900       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18901     {
18902       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18903                                       operands[2], operands[3],
18904                                       operands[5], operands[6]));
18905       DONE;
18906     }
18908   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18911 (define_expand "strmov_singleop"
18912   [(parallel [(set (match_operand 1 "memory_operand" "")
18913                    (match_operand 3 "memory_operand" ""))
18914               (set (match_operand 0 "register_operand" "")
18915                    (match_operand 4 "" ""))
18916               (set (match_operand 2 "register_operand" "")
18917                    (match_operand 5 "" ""))])]
18918   ""
18919   "ix86_current_function_needs_cld = 1;")
18921 (define_insn "*strmovdi_rex_1"
18922   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18923         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18924    (set (match_operand:DI 0 "register_operand" "=D")
18925         (plus:DI (match_dup 2)
18926                  (const_int 8)))
18927    (set (match_operand:DI 1 "register_operand" "=S")
18928         (plus:DI (match_dup 3)
18929                  (const_int 8)))]
18930   "TARGET_64BIT"
18931   "movsq"
18932   [(set_attr "type" "str")
18933    (set_attr "mode" "DI")
18934    (set_attr "memory" "both")])
18936 (define_insn "*strmovsi_1"
18937   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18938         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18939    (set (match_operand:SI 0 "register_operand" "=D")
18940         (plus:SI (match_dup 2)
18941                  (const_int 4)))
18942    (set (match_operand:SI 1 "register_operand" "=S")
18943         (plus:SI (match_dup 3)
18944                  (const_int 4)))]
18945   "!TARGET_64BIT"
18946   "movs{l|d}"
18947   [(set_attr "type" "str")
18948    (set_attr "mode" "SI")
18949    (set_attr "memory" "both")])
18951 (define_insn "*strmovsi_rex_1"
18952   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18953         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18954    (set (match_operand:DI 0 "register_operand" "=D")
18955         (plus:DI (match_dup 2)
18956                  (const_int 4)))
18957    (set (match_operand:DI 1 "register_operand" "=S")
18958         (plus:DI (match_dup 3)
18959                  (const_int 4)))]
18960   "TARGET_64BIT"
18961   "movs{l|d}"
18962   [(set_attr "type" "str")
18963    (set_attr "mode" "SI")
18964    (set_attr "memory" "both")])
18966 (define_insn "*strmovhi_1"
18967   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18968         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18969    (set (match_operand:SI 0 "register_operand" "=D")
18970         (plus:SI (match_dup 2)
18971                  (const_int 2)))
18972    (set (match_operand:SI 1 "register_operand" "=S")
18973         (plus:SI (match_dup 3)
18974                  (const_int 2)))]
18975   "!TARGET_64BIT"
18976   "movsw"
18977   [(set_attr "type" "str")
18978    (set_attr "memory" "both")
18979    (set_attr "mode" "HI")])
18981 (define_insn "*strmovhi_rex_1"
18982   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18983         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18984    (set (match_operand:DI 0 "register_operand" "=D")
18985         (plus:DI (match_dup 2)
18986                  (const_int 2)))
18987    (set (match_operand:DI 1 "register_operand" "=S")
18988         (plus:DI (match_dup 3)
18989                  (const_int 2)))]
18990   "TARGET_64BIT"
18991   "movsw"
18992   [(set_attr "type" "str")
18993    (set_attr "memory" "both")
18994    (set_attr "mode" "HI")])
18996 (define_insn "*strmovqi_1"
18997   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18998         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18999    (set (match_operand:SI 0 "register_operand" "=D")
19000         (plus:SI (match_dup 2)
19001                  (const_int 1)))
19002    (set (match_operand:SI 1 "register_operand" "=S")
19003         (plus:SI (match_dup 3)
19004                  (const_int 1)))]
19005   "!TARGET_64BIT"
19006   "movsb"
19007   [(set_attr "type" "str")
19008    (set_attr "memory" "both")
19009    (set_attr "mode" "QI")])
19011 (define_insn "*strmovqi_rex_1"
19012   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19013         (mem:QI (match_operand:DI 3 "register_operand" "1")))
19014    (set (match_operand:DI 0 "register_operand" "=D")
19015         (plus:DI (match_dup 2)
19016                  (const_int 1)))
19017    (set (match_operand:DI 1 "register_operand" "=S")
19018         (plus:DI (match_dup 3)
19019                  (const_int 1)))]
19020   "TARGET_64BIT"
19021   "movsb"
19022   [(set_attr "type" "str")
19023    (set_attr "memory" "both")
19024    (set_attr "mode" "QI")])
19026 (define_expand "rep_mov"
19027   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19028               (set (match_operand 0 "register_operand" "")
19029                    (match_operand 5 "" ""))
19030               (set (match_operand 2 "register_operand" "")
19031                    (match_operand 6 "" ""))
19032               (set (match_operand 1 "memory_operand" "")
19033                    (match_operand 3 "memory_operand" ""))
19034               (use (match_dup 4))])]
19035   ""
19036   "ix86_current_function_needs_cld = 1;")
19038 (define_insn "*rep_movdi_rex64"
19039   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19040    (set (match_operand:DI 0 "register_operand" "=D")
19041         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19042                             (const_int 3))
19043                  (match_operand:DI 3 "register_operand" "0")))
19044    (set (match_operand:DI 1 "register_operand" "=S")
19045         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19046                  (match_operand:DI 4 "register_operand" "1")))
19047    (set (mem:BLK (match_dup 3))
19048         (mem:BLK (match_dup 4)))
19049    (use (match_dup 5))]
19050   "TARGET_64BIT"
19051   "rep movsq"
19052   [(set_attr "type" "str")
19053    (set_attr "prefix_rep" "1")
19054    (set_attr "memory" "both")
19055    (set_attr "mode" "DI")])
19057 (define_insn "*rep_movsi"
19058   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19059    (set (match_operand:SI 0 "register_operand" "=D")
19060         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19061                             (const_int 2))
19062                  (match_operand:SI 3 "register_operand" "0")))
19063    (set (match_operand:SI 1 "register_operand" "=S")
19064         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19065                  (match_operand:SI 4 "register_operand" "1")))
19066    (set (mem:BLK (match_dup 3))
19067         (mem:BLK (match_dup 4)))
19068    (use (match_dup 5))]
19069   "!TARGET_64BIT"
19070   "rep movs{l|d}"
19071   [(set_attr "type" "str")
19072    (set_attr "prefix_rep" "1")
19073    (set_attr "memory" "both")
19074    (set_attr "mode" "SI")])
19076 (define_insn "*rep_movsi_rex64"
19077   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19078    (set (match_operand:DI 0 "register_operand" "=D")
19079         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19080                             (const_int 2))
19081                  (match_operand:DI 3 "register_operand" "0")))
19082    (set (match_operand:DI 1 "register_operand" "=S")
19083         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19084                  (match_operand:DI 4 "register_operand" "1")))
19085    (set (mem:BLK (match_dup 3))
19086         (mem:BLK (match_dup 4)))
19087    (use (match_dup 5))]
19088   "TARGET_64BIT"
19089   "rep movs{l|d}"
19090   [(set_attr "type" "str")
19091    (set_attr "prefix_rep" "1")
19092    (set_attr "memory" "both")
19093    (set_attr "mode" "SI")])
19095 (define_insn "*rep_movqi"
19096   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19097    (set (match_operand:SI 0 "register_operand" "=D")
19098         (plus:SI (match_operand:SI 3 "register_operand" "0")
19099                  (match_operand:SI 5 "register_operand" "2")))
19100    (set (match_operand:SI 1 "register_operand" "=S")
19101         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19102    (set (mem:BLK (match_dup 3))
19103         (mem:BLK (match_dup 4)))
19104    (use (match_dup 5))]
19105   "!TARGET_64BIT"
19106   "rep movsb"
19107   [(set_attr "type" "str")
19108    (set_attr "prefix_rep" "1")
19109    (set_attr "memory" "both")
19110    (set_attr "mode" "SI")])
19112 (define_insn "*rep_movqi_rex64"
19113   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19114    (set (match_operand:DI 0 "register_operand" "=D")
19115         (plus:DI (match_operand:DI 3 "register_operand" "0")
19116                  (match_operand:DI 5 "register_operand" "2")))
19117    (set (match_operand:DI 1 "register_operand" "=S")
19118         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19119    (set (mem:BLK (match_dup 3))
19120         (mem:BLK (match_dup 4)))
19121    (use (match_dup 5))]
19122   "TARGET_64BIT"
19123   "rep movsb"
19124   [(set_attr "type" "str")
19125    (set_attr "prefix_rep" "1")
19126    (set_attr "memory" "both")
19127    (set_attr "mode" "SI")])
19129 (define_expand "setmemsi"
19130    [(use (match_operand:BLK 0 "memory_operand" ""))
19131     (use (match_operand:SI 1 "nonmemory_operand" ""))
19132     (use (match_operand 2 "const_int_operand" ""))
19133     (use (match_operand 3 "const_int_operand" ""))
19134     (use (match_operand:SI 4 "const_int_operand" ""))
19135     (use (match_operand:SI 5 "const_int_operand" ""))]
19136   ""
19138  if (ix86_expand_setmem (operands[0], operands[1],
19139                          operands[2], operands[3],
19140                          operands[4], operands[5]))
19141    DONE;
19142  else
19143    FAIL;
19146 (define_expand "setmemdi"
19147    [(use (match_operand:BLK 0 "memory_operand" ""))
19148     (use (match_operand:DI 1 "nonmemory_operand" ""))
19149     (use (match_operand 2 "const_int_operand" ""))
19150     (use (match_operand 3 "const_int_operand" ""))
19151     (use (match_operand 4 "const_int_operand" ""))
19152     (use (match_operand 5 "const_int_operand" ""))]
19153   "TARGET_64BIT"
19155  if (ix86_expand_setmem (operands[0], operands[1],
19156                          operands[2], operands[3],
19157                          operands[4], operands[5]))
19158    DONE;
19159  else
19160    FAIL;
19163 ;; Most CPUs don't like single string operations
19164 ;; Handle this case here to simplify previous expander.
19166 (define_expand "strset"
19167   [(set (match_operand 1 "memory_operand" "")
19168         (match_operand 2 "register_operand" ""))
19169    (parallel [(set (match_operand 0 "register_operand" "")
19170                    (match_dup 3))
19171               (clobber (reg:CC FLAGS_REG))])]
19172   ""
19174   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19175     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19177   /* If .md ever supports :P for Pmode, this can be directly
19178      in the pattern above.  */
19179   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19180                               GEN_INT (GET_MODE_SIZE (GET_MODE
19181                                                       (operands[2]))));
19182   if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19183     {
19184       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19185                                       operands[3]));
19186       DONE;
19187     }
19190 (define_expand "strset_singleop"
19191   [(parallel [(set (match_operand 1 "memory_operand" "")
19192                    (match_operand 2 "register_operand" ""))
19193               (set (match_operand 0 "register_operand" "")
19194                    (match_operand 3 "" ""))])]
19195   ""
19196   "ix86_current_function_needs_cld = 1;")
19198 (define_insn "*strsetdi_rex_1"
19199   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19200         (match_operand:DI 2 "register_operand" "a"))
19201    (set (match_operand:DI 0 "register_operand" "=D")
19202         (plus:DI (match_dup 1)
19203                  (const_int 8)))]
19204   "TARGET_64BIT"
19205   "stosq"
19206   [(set_attr "type" "str")
19207    (set_attr "memory" "store")
19208    (set_attr "mode" "DI")])
19210 (define_insn "*strsetsi_1"
19211   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19212         (match_operand:SI 2 "register_operand" "a"))
19213    (set (match_operand:SI 0 "register_operand" "=D")
19214         (plus:SI (match_dup 1)
19215                  (const_int 4)))]
19216   "!TARGET_64BIT"
19217   "stos{l|d}"
19218   [(set_attr "type" "str")
19219    (set_attr "memory" "store")
19220    (set_attr "mode" "SI")])
19222 (define_insn "*strsetsi_rex_1"
19223   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19224         (match_operand:SI 2 "register_operand" "a"))
19225    (set (match_operand:DI 0 "register_operand" "=D")
19226         (plus:DI (match_dup 1)
19227                  (const_int 4)))]
19228   "TARGET_64BIT"
19229   "stos{l|d}"
19230   [(set_attr "type" "str")
19231    (set_attr "memory" "store")
19232    (set_attr "mode" "SI")])
19234 (define_insn "*strsethi_1"
19235   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19236         (match_operand:HI 2 "register_operand" "a"))
19237    (set (match_operand:SI 0 "register_operand" "=D")
19238         (plus:SI (match_dup 1)
19239                  (const_int 2)))]
19240   "!TARGET_64BIT"
19241   "stosw"
19242   [(set_attr "type" "str")
19243    (set_attr "memory" "store")
19244    (set_attr "mode" "HI")])
19246 (define_insn "*strsethi_rex_1"
19247   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
19248         (match_operand:HI 2 "register_operand" "a"))
19249    (set (match_operand:DI 0 "register_operand" "=D")
19250         (plus:DI (match_dup 1)
19251                  (const_int 2)))]
19252   "TARGET_64BIT"
19253   "stosw"
19254   [(set_attr "type" "str")
19255    (set_attr "memory" "store")
19256    (set_attr "mode" "HI")])
19258 (define_insn "*strsetqi_1"
19259   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
19260         (match_operand:QI 2 "register_operand" "a"))
19261    (set (match_operand:SI 0 "register_operand" "=D")
19262         (plus:SI (match_dup 1)
19263                  (const_int 1)))]
19264   "!TARGET_64BIT"
19265   "stosb"
19266   [(set_attr "type" "str")
19267    (set_attr "memory" "store")
19268    (set_attr "mode" "QI")])
19270 (define_insn "*strsetqi_rex_1"
19271   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
19272         (match_operand:QI 2 "register_operand" "a"))
19273    (set (match_operand:DI 0 "register_operand" "=D")
19274         (plus:DI (match_dup 1)
19275                  (const_int 1)))]
19276   "TARGET_64BIT"
19277   "stosb"
19278   [(set_attr "type" "str")
19279    (set_attr "memory" "store")
19280    (set_attr "mode" "QI")])
19282 (define_expand "rep_stos"
19283   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
19284               (set (match_operand 0 "register_operand" "")
19285                    (match_operand 4 "" ""))
19286               (set (match_operand 2 "memory_operand" "") (const_int 0))
19287               (use (match_operand 3 "register_operand" ""))
19288               (use (match_dup 1))])]
19289   ""
19290   "ix86_current_function_needs_cld = 1;")
19292 (define_insn "*rep_stosdi_rex64"
19293   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19294    (set (match_operand:DI 0 "register_operand" "=D")
19295         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19296                             (const_int 3))
19297                  (match_operand:DI 3 "register_operand" "0")))
19298    (set (mem:BLK (match_dup 3))
19299         (const_int 0))
19300    (use (match_operand:DI 2 "register_operand" "a"))
19301    (use (match_dup 4))]
19302   "TARGET_64BIT"
19303   "rep stosq"
19304   [(set_attr "type" "str")
19305    (set_attr "prefix_rep" "1")
19306    (set_attr "memory" "store")
19307    (set_attr "mode" "DI")])
19309 (define_insn "*rep_stossi"
19310   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19311    (set (match_operand:SI 0 "register_operand" "=D")
19312         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
19313                             (const_int 2))
19314                  (match_operand:SI 3 "register_operand" "0")))
19315    (set (mem:BLK (match_dup 3))
19316         (const_int 0))
19317    (use (match_operand:SI 2 "register_operand" "a"))
19318    (use (match_dup 4))]
19319   "!TARGET_64BIT"
19320   "rep stos{l|d}"
19321   [(set_attr "type" "str")
19322    (set_attr "prefix_rep" "1")
19323    (set_attr "memory" "store")
19324    (set_attr "mode" "SI")])
19326 (define_insn "*rep_stossi_rex64"
19327   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19328    (set (match_operand:DI 0 "register_operand" "=D")
19329         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
19330                             (const_int 2))
19331                  (match_operand:DI 3 "register_operand" "0")))
19332    (set (mem:BLK (match_dup 3))
19333         (const_int 0))
19334    (use (match_operand:SI 2 "register_operand" "a"))
19335    (use (match_dup 4))]
19336   "TARGET_64BIT"
19337   "rep stos{l|d}"
19338   [(set_attr "type" "str")
19339    (set_attr "prefix_rep" "1")
19340    (set_attr "memory" "store")
19341    (set_attr "mode" "SI")])
19343 (define_insn "*rep_stosqi"
19344   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
19345    (set (match_operand:SI 0 "register_operand" "=D")
19346         (plus:SI (match_operand:SI 3 "register_operand" "0")
19347                  (match_operand:SI 4 "register_operand" "1")))
19348    (set (mem:BLK (match_dup 3))
19349         (const_int 0))
19350    (use (match_operand:QI 2 "register_operand" "a"))
19351    (use (match_dup 4))]
19352   "!TARGET_64BIT"
19353   "rep stosb"
19354   [(set_attr "type" "str")
19355    (set_attr "prefix_rep" "1")
19356    (set_attr "memory" "store")
19357    (set_attr "mode" "QI")])
19359 (define_insn "*rep_stosqi_rex64"
19360   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
19361    (set (match_operand:DI 0 "register_operand" "=D")
19362         (plus:DI (match_operand:DI 3 "register_operand" "0")
19363                  (match_operand:DI 4 "register_operand" "1")))
19364    (set (mem:BLK (match_dup 3))
19365         (const_int 0))
19366    (use (match_operand:QI 2 "register_operand" "a"))
19367    (use (match_dup 4))]
19368   "TARGET_64BIT"
19369   "rep stosb"
19370   [(set_attr "type" "str")
19371    (set_attr "prefix_rep" "1")
19372    (set_attr "memory" "store")
19373    (set_attr "mode" "QI")])
19375 (define_expand "cmpstrnsi"
19376   [(set (match_operand:SI 0 "register_operand" "")
19377         (compare:SI (match_operand:BLK 1 "general_operand" "")
19378                     (match_operand:BLK 2 "general_operand" "")))
19379    (use (match_operand 3 "general_operand" ""))
19380    (use (match_operand 4 "immediate_operand" ""))]
19381   ""
19383   rtx addr1, addr2, out, outlow, count, countreg, align;
19385   if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
19386     FAIL;
19388   /* Can't use this if the user has appropriated esi or edi.  */
19389   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
19390     FAIL;
19392   out = operands[0];
19393   if (!REG_P (out))
19394     out = gen_reg_rtx (SImode);
19396   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
19397   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
19398   if (addr1 != XEXP (operands[1], 0))
19399     operands[1] = replace_equiv_address_nv (operands[1], addr1);
19400   if (addr2 != XEXP (operands[2], 0))
19401     operands[2] = replace_equiv_address_nv (operands[2], addr2);
19403   count = operands[3];
19404   countreg = ix86_zero_extend_to_Pmode (count);
19406   /* %%% Iff we are testing strict equality, we can use known alignment
19407      to good advantage.  This may be possible with combine, particularly
19408      once cc0 is dead.  */
19409   align = operands[4];
19411   if (CONST_INT_P (count))
19412     {
19413       if (INTVAL (count) == 0)
19414         {
19415           emit_move_insn (operands[0], const0_rtx);
19416           DONE;
19417         }
19418       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
19419                                      operands[1], operands[2]));
19420     }
19421   else
19422     {
19423       if (TARGET_64BIT)
19424         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
19425       else
19426         emit_insn (gen_cmpsi_1 (countreg, countreg));
19427       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
19428                                   operands[1], operands[2]));
19429     }
19431   outlow = gen_lowpart (QImode, out);
19432   emit_insn (gen_cmpintqi (outlow));
19433   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19435   if (operands[0] != out)
19436     emit_move_insn (operands[0], out);
19438   DONE;
19441 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19443 (define_expand "cmpintqi"
19444   [(set (match_dup 1)
19445         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19446    (set (match_dup 2)
19447         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19448    (parallel [(set (match_operand:QI 0 "register_operand" "")
19449                    (minus:QI (match_dup 1)
19450                              (match_dup 2)))
19451               (clobber (reg:CC FLAGS_REG))])]
19452   ""
19453   "operands[1] = gen_reg_rtx (QImode);
19454    operands[2] = gen_reg_rtx (QImode);")
19456 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19457 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19459 (define_expand "cmpstrnqi_nz_1"
19460   [(parallel [(set (reg:CC FLAGS_REG)
19461                    (compare:CC (match_operand 4 "memory_operand" "")
19462                                (match_operand 5 "memory_operand" "")))
19463               (use (match_operand 2 "register_operand" ""))
19464               (use (match_operand:SI 3 "immediate_operand" ""))
19465               (clobber (match_operand 0 "register_operand" ""))
19466               (clobber (match_operand 1 "register_operand" ""))
19467               (clobber (match_dup 2))])]
19468   ""
19469   "ix86_current_function_needs_cld = 1;")
19471 (define_insn "*cmpstrnqi_nz_1"
19472   [(set (reg:CC FLAGS_REG)
19473         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19474                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19475    (use (match_operand:SI 6 "register_operand" "2"))
19476    (use (match_operand:SI 3 "immediate_operand" "i"))
19477    (clobber (match_operand:SI 0 "register_operand" "=S"))
19478    (clobber (match_operand:SI 1 "register_operand" "=D"))
19479    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19480   "!TARGET_64BIT"
19481   "repz cmpsb"
19482   [(set_attr "type" "str")
19483    (set_attr "mode" "QI")
19484    (set_attr "prefix_rep" "1")])
19486 (define_insn "*cmpstrnqi_nz_rex_1"
19487   [(set (reg:CC FLAGS_REG)
19488         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19489                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19490    (use (match_operand:DI 6 "register_operand" "2"))
19491    (use (match_operand:SI 3 "immediate_operand" "i"))
19492    (clobber (match_operand:DI 0 "register_operand" "=S"))
19493    (clobber (match_operand:DI 1 "register_operand" "=D"))
19494    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19495   "TARGET_64BIT"
19496   "repz cmpsb"
19497   [(set_attr "type" "str")
19498    (set_attr "mode" "QI")
19499    (set_attr "prefix_rep" "1")])
19501 ;; The same, but the count is not known to not be zero.
19503 (define_expand "cmpstrnqi_1"
19504   [(parallel [(set (reg:CC FLAGS_REG)
19505                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19506                                      (const_int 0))
19507                   (compare:CC (match_operand 4 "memory_operand" "")
19508                               (match_operand 5 "memory_operand" ""))
19509                   (const_int 0)))
19510               (use (match_operand:SI 3 "immediate_operand" ""))
19511               (use (reg:CC FLAGS_REG))
19512               (clobber (match_operand 0 "register_operand" ""))
19513               (clobber (match_operand 1 "register_operand" ""))
19514               (clobber (match_dup 2))])]
19515   ""
19516   "ix86_current_function_needs_cld = 1;")
19518 (define_insn "*cmpstrnqi_1"
19519   [(set (reg:CC FLAGS_REG)
19520         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19521                              (const_int 0))
19522           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19523                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19524           (const_int 0)))
19525    (use (match_operand:SI 3 "immediate_operand" "i"))
19526    (use (reg:CC FLAGS_REG))
19527    (clobber (match_operand:SI 0 "register_operand" "=S"))
19528    (clobber (match_operand:SI 1 "register_operand" "=D"))
19529    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19530   "!TARGET_64BIT"
19531   "repz cmpsb"
19532   [(set_attr "type" "str")
19533    (set_attr "mode" "QI")
19534    (set_attr "prefix_rep" "1")])
19536 (define_insn "*cmpstrnqi_rex_1"
19537   [(set (reg:CC FLAGS_REG)
19538         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19539                              (const_int 0))
19540           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19541                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19542           (const_int 0)))
19543    (use (match_operand:SI 3 "immediate_operand" "i"))
19544    (use (reg:CC FLAGS_REG))
19545    (clobber (match_operand:DI 0 "register_operand" "=S"))
19546    (clobber (match_operand:DI 1 "register_operand" "=D"))
19547    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19548   "TARGET_64BIT"
19549   "repz cmpsb"
19550   [(set_attr "type" "str")
19551    (set_attr "mode" "QI")
19552    (set_attr "prefix_rep" "1")])
19554 (define_expand "strlensi"
19555   [(set (match_operand:SI 0 "register_operand" "")
19556         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19557                     (match_operand:QI 2 "immediate_operand" "")
19558                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19559   ""
19561  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19562    DONE;
19563  else
19564    FAIL;
19567 (define_expand "strlendi"
19568   [(set (match_operand:DI 0 "register_operand" "")
19569         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19570                     (match_operand:QI 2 "immediate_operand" "")
19571                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19572   ""
19574  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19575    DONE;
19576  else
19577    FAIL;
19580 (define_expand "strlenqi_1"
19581   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19582               (clobber (match_operand 1 "register_operand" ""))
19583               (clobber (reg:CC FLAGS_REG))])]
19584   ""
19585   "ix86_current_function_needs_cld = 1;")
19587 (define_insn "*strlenqi_1"
19588   [(set (match_operand:SI 0 "register_operand" "=&c")
19589         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19590                     (match_operand:QI 2 "register_operand" "a")
19591                     (match_operand:SI 3 "immediate_operand" "i")
19592                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19593    (clobber (match_operand:SI 1 "register_operand" "=D"))
19594    (clobber (reg:CC FLAGS_REG))]
19595   "!TARGET_64BIT"
19596   "repnz scasb"
19597   [(set_attr "type" "str")
19598    (set_attr "mode" "QI")
19599    (set_attr "prefix_rep" "1")])
19601 (define_insn "*strlenqi_rex_1"
19602   [(set (match_operand:DI 0 "register_operand" "=&c")
19603         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19604                     (match_operand:QI 2 "register_operand" "a")
19605                     (match_operand:DI 3 "immediate_operand" "i")
19606                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19607    (clobber (match_operand:DI 1 "register_operand" "=D"))
19608    (clobber (reg:CC FLAGS_REG))]
19609   "TARGET_64BIT"
19610   "repnz scasb"
19611   [(set_attr "type" "str")
19612    (set_attr "mode" "QI")
19613    (set_attr "prefix_rep" "1")])
19615 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19616 ;; handled in combine, but it is not currently up to the task.
19617 ;; When used for their truth value, the cmpstrn* expanders generate
19618 ;; code like this:
19620 ;;   repz cmpsb
19621 ;;   seta       %al
19622 ;;   setb       %dl
19623 ;;   cmpb       %al, %dl
19624 ;;   jcc        label
19626 ;; The intermediate three instructions are unnecessary.
19628 ;; This one handles cmpstrn*_nz_1...
19629 (define_peephole2
19630   [(parallel[
19631      (set (reg:CC FLAGS_REG)
19632           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19633                       (mem:BLK (match_operand 5 "register_operand" ""))))
19634      (use (match_operand 6 "register_operand" ""))
19635      (use (match_operand:SI 3 "immediate_operand" ""))
19636      (clobber (match_operand 0 "register_operand" ""))
19637      (clobber (match_operand 1 "register_operand" ""))
19638      (clobber (match_operand 2 "register_operand" ""))])
19639    (set (match_operand:QI 7 "register_operand" "")
19640         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19641    (set (match_operand:QI 8 "register_operand" "")
19642         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19643    (set (reg FLAGS_REG)
19644         (compare (match_dup 7) (match_dup 8)))
19645   ]
19646   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19647   [(parallel[
19648      (set (reg:CC FLAGS_REG)
19649           (compare:CC (mem:BLK (match_dup 4))
19650                       (mem:BLK (match_dup 5))))
19651      (use (match_dup 6))
19652      (use (match_dup 3))
19653      (clobber (match_dup 0))
19654      (clobber (match_dup 1))
19655      (clobber (match_dup 2))])]
19656   "")
19658 ;; ...and this one handles cmpstrn*_1.
19659 (define_peephole2
19660   [(parallel[
19661      (set (reg:CC FLAGS_REG)
19662           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19663                                (const_int 0))
19664             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19665                         (mem:BLK (match_operand 5 "register_operand" "")))
19666             (const_int 0)))
19667      (use (match_operand:SI 3 "immediate_operand" ""))
19668      (use (reg:CC FLAGS_REG))
19669      (clobber (match_operand 0 "register_operand" ""))
19670      (clobber (match_operand 1 "register_operand" ""))
19671      (clobber (match_operand 2 "register_operand" ""))])
19672    (set (match_operand:QI 7 "register_operand" "")
19673         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19674    (set (match_operand:QI 8 "register_operand" "")
19675         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19676    (set (reg FLAGS_REG)
19677         (compare (match_dup 7) (match_dup 8)))
19678   ]
19679   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19680   [(parallel[
19681      (set (reg:CC FLAGS_REG)
19682           (if_then_else:CC (ne (match_dup 6)
19683                                (const_int 0))
19684             (compare:CC (mem:BLK (match_dup 4))
19685                         (mem:BLK (match_dup 5)))
19686             (const_int 0)))
19687      (use (match_dup 3))
19688      (use (reg:CC FLAGS_REG))
19689      (clobber (match_dup 0))
19690      (clobber (match_dup 1))
19691      (clobber (match_dup 2))])]
19692   "")
19696 ;; Conditional move instructions.
19698 (define_expand "movdicc"
19699   [(set (match_operand:DI 0 "register_operand" "")
19700         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19701                          (match_operand:DI 2 "general_operand" "")
19702                          (match_operand:DI 3 "general_operand" "")))]
19703   "TARGET_64BIT"
19704   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19706 (define_insn "x86_movdicc_0_m1_rex64"
19707   [(set (match_operand:DI 0 "register_operand" "=r")
19708         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19709           (const_int -1)
19710           (const_int 0)))
19711    (clobber (reg:CC FLAGS_REG))]
19712   "TARGET_64BIT"
19713   "sbb{q}\t%0, %0"
19714   ; Since we don't have the proper number of operands for an alu insn,
19715   ; fill in all the blanks.
19716   [(set_attr "type" "alu")
19717    (set_attr "pent_pair" "pu")
19718    (set_attr "memory" "none")
19719    (set_attr "imm_disp" "false")
19720    (set_attr "mode" "DI")
19721    (set_attr "length_immediate" "0")])
19723 (define_insn "*x86_movdicc_0_m1_se"
19724   [(set (match_operand:DI 0 "register_operand" "=r")
19725         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19726                          (const_int 1)
19727                          (const_int 0)))
19728    (clobber (reg:CC FLAGS_REG))]
19729   ""
19730   "sbb{q}\t%0, %0"
19731   [(set_attr "type" "alu")
19732    (set_attr "pent_pair" "pu")
19733    (set_attr "memory" "none")
19734    (set_attr "imm_disp" "false")
19735    (set_attr "mode" "DI")
19736    (set_attr "length_immediate" "0")])
19738 (define_insn "*movdicc_c_rex64"
19739   [(set (match_operand:DI 0 "register_operand" "=r,r")
19740         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19741                                 [(reg FLAGS_REG) (const_int 0)])
19742                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19743                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19744   "TARGET_64BIT && TARGET_CMOVE
19745    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19746   "@
19747    cmov%O2%C1\t{%2, %0|%0, %2}
19748    cmov%O2%c1\t{%3, %0|%0, %3}"
19749   [(set_attr "type" "icmov")
19750    (set_attr "mode" "DI")])
19752 (define_expand "movsicc"
19753   [(set (match_operand:SI 0 "register_operand" "")
19754         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19755                          (match_operand:SI 2 "general_operand" "")
19756                          (match_operand:SI 3 "general_operand" "")))]
19757   ""
19758   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19760 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19761 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19762 ;; So just document what we're doing explicitly.
19764 (define_insn "x86_movsicc_0_m1"
19765   [(set (match_operand:SI 0 "register_operand" "=r")
19766         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19767           (const_int -1)
19768           (const_int 0)))
19769    (clobber (reg:CC FLAGS_REG))]
19770   ""
19771   "sbb{l}\t%0, %0"
19772   ; Since we don't have the proper number of operands for an alu insn,
19773   ; fill in all the blanks.
19774   [(set_attr "type" "alu")
19775    (set_attr "pent_pair" "pu")
19776    (set_attr "memory" "none")
19777    (set_attr "imm_disp" "false")
19778    (set_attr "mode" "SI")
19779    (set_attr "length_immediate" "0")])
19781 (define_insn "*x86_movsicc_0_m1_se"
19782   [(set (match_operand:SI 0 "register_operand" "=r")
19783         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19784                          (const_int 1)
19785                          (const_int 0)))
19786    (clobber (reg:CC FLAGS_REG))]
19787   ""
19788   "sbb{l}\t%0, %0"
19789   [(set_attr "type" "alu")
19790    (set_attr "pent_pair" "pu")
19791    (set_attr "memory" "none")
19792    (set_attr "imm_disp" "false")
19793    (set_attr "mode" "SI")
19794    (set_attr "length_immediate" "0")])
19796 (define_insn "*movsicc_noc"
19797   [(set (match_operand:SI 0 "register_operand" "=r,r")
19798         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19799                                 [(reg FLAGS_REG) (const_int 0)])
19800                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19801                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19802   "TARGET_CMOVE
19803    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19804   "@
19805    cmov%O2%C1\t{%2, %0|%0, %2}
19806    cmov%O2%c1\t{%3, %0|%0, %3}"
19807   [(set_attr "type" "icmov")
19808    (set_attr "mode" "SI")])
19810 (define_expand "movhicc"
19811   [(set (match_operand:HI 0 "register_operand" "")
19812         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19813                          (match_operand:HI 2 "general_operand" "")
19814                          (match_operand:HI 3 "general_operand" "")))]
19815   "TARGET_HIMODE_MATH"
19816   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19818 (define_insn "*movhicc_noc"
19819   [(set (match_operand:HI 0 "register_operand" "=r,r")
19820         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19821                                 [(reg FLAGS_REG) (const_int 0)])
19822                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19823                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19824   "TARGET_CMOVE
19825    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19826   "@
19827    cmov%O2%C1\t{%2, %0|%0, %2}
19828    cmov%O2%c1\t{%3, %0|%0, %3}"
19829   [(set_attr "type" "icmov")
19830    (set_attr "mode" "HI")])
19832 (define_expand "movqicc"
19833   [(set (match_operand:QI 0 "register_operand" "")
19834         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19835                          (match_operand:QI 2 "general_operand" "")
19836                          (match_operand:QI 3 "general_operand" "")))]
19837   "TARGET_QIMODE_MATH"
19838   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19840 (define_insn_and_split "*movqicc_noc"
19841   [(set (match_operand:QI 0 "register_operand" "=r,r")
19842         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19843                                 [(match_operand 4 "flags_reg_operand" "")
19844                                  (const_int 0)])
19845                       (match_operand:QI 2 "register_operand" "r,0")
19846                       (match_operand:QI 3 "register_operand" "0,r")))]
19847   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19848   "#"
19849   "&& reload_completed"
19850   [(set (match_dup 0)
19851         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19852                       (match_dup 2)
19853                       (match_dup 3)))]
19854   "operands[0] = gen_lowpart (SImode, operands[0]);
19855    operands[2] = gen_lowpart (SImode, operands[2]);
19856    operands[3] = gen_lowpart (SImode, operands[3]);"
19857   [(set_attr "type" "icmov")
19858    (set_attr "mode" "SI")])
19860 (define_expand "mov<mode>cc"
19861   [(set (match_operand:X87MODEF 0 "register_operand" "")
19862         (if_then_else:X87MODEF
19863           (match_operand 1 "comparison_operator" "")
19864           (match_operand:X87MODEF 2 "register_operand" "")
19865           (match_operand:X87MODEF 3 "register_operand" "")))]
19866   "(TARGET_80387 && TARGET_CMOVE)
19867    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19868   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19870 (define_insn "*movsfcc_1_387"
19871   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19872         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19873                                 [(reg FLAGS_REG) (const_int 0)])
19874                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19875                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19876   "TARGET_80387 && TARGET_CMOVE
19877    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19878   "@
19879    fcmov%F1\t{%2, %0|%0, %2}
19880    fcmov%f1\t{%3, %0|%0, %3}
19881    cmov%O2%C1\t{%2, %0|%0, %2}
19882    cmov%O2%c1\t{%3, %0|%0, %3}"
19883   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19884    (set_attr "mode" "SF,SF,SI,SI")])
19886 (define_insn "*movdfcc_1"
19887   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19888         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19889                                 [(reg FLAGS_REG) (const_int 0)])
19890                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19891                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19892   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19893    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19894   "@
19895    fcmov%F1\t{%2, %0|%0, %2}
19896    fcmov%f1\t{%3, %0|%0, %3}
19897    #
19898    #"
19899   [(set_attr "type" "fcmov,fcmov,multi,multi")
19900    (set_attr "mode" "DF")])
19902 (define_insn "*movdfcc_1_rex64"
19903   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19904         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19905                                 [(reg FLAGS_REG) (const_int 0)])
19906                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19907                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19908   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19909    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19910   "@
19911    fcmov%F1\t{%2, %0|%0, %2}
19912    fcmov%f1\t{%3, %0|%0, %3}
19913    cmov%O2%C1\t{%2, %0|%0, %2}
19914    cmov%O2%c1\t{%3, %0|%0, %3}"
19915   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19916    (set_attr "mode" "DF")])
19918 (define_split
19919   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19920         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19921                                 [(match_operand 4 "flags_reg_operand" "")
19922                                  (const_int 0)])
19923                       (match_operand:DF 2 "nonimmediate_operand" "")
19924                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19925   "!TARGET_64BIT && reload_completed"
19926   [(set (match_dup 2)
19927         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19928                       (match_dup 5)
19929                       (match_dup 6)))
19930    (set (match_dup 3)
19931         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19932                       (match_dup 7)
19933                       (match_dup 8)))]
19934   "split_di (&operands[2], 2, &operands[5], &operands[7]);
19935    split_di (&operands[0], 1, &operands[2], &operands[3]);")
19937 (define_insn "*movxfcc_1"
19938   [(set (match_operand:XF 0 "register_operand" "=f,f")
19939         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19940                                 [(reg FLAGS_REG) (const_int 0)])
19941                       (match_operand:XF 2 "register_operand" "f,0")
19942                       (match_operand:XF 3 "register_operand" "0,f")))]
19943   "TARGET_80387 && TARGET_CMOVE"
19944   "@
19945    fcmov%F1\t{%2, %0|%0, %2}
19946    fcmov%f1\t{%3, %0|%0, %3}"
19947   [(set_attr "type" "fcmov")
19948    (set_attr "mode" "XF")])
19950 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19951 ;; the scalar versions to have only XMM registers as operands.
19953 ;; SSE5 conditional move
19954 (define_insn "*sse5_pcmov_<mode>"
19955   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19956         (if_then_else:MODEF
19957           (match_operand:MODEF 1 "register_operand" "x,0")
19958           (match_operand:MODEF 2 "register_operand" "0,x")
19959           (match_operand:MODEF 3 "register_operand" "x,x")))]
19960   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
19961   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19962   [(set_attr "type" "sse4arg")])
19964 ;; These versions of the min/max patterns are intentionally ignorant of
19965 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19966 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19967 ;; are undefined in this condition, we're certain this is correct.
19969 (define_insn "*avx_<code><mode>3"
19970   [(set (match_operand:MODEF 0 "register_operand" "=x")
19971         (smaxmin:MODEF
19972           (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19973           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19974   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19975   "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19976   [(set_attr "type" "sseadd")
19977    (set_attr "prefix" "vex")
19978    (set_attr "mode" "<MODE>")])
19980 (define_insn "<code><mode>3"
19981   [(set (match_operand:MODEF 0 "register_operand" "=x")
19982         (smaxmin:MODEF
19983           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19984           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19985   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19986   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19987   [(set_attr "type" "sseadd")
19988    (set_attr "mode" "<MODE>")])
19990 ;; These versions of the min/max patterns implement exactly the operations
19991 ;;   min = (op1 < op2 ? op1 : op2)
19992 ;;   max = (!(op1 < op2) ? op1 : op2)
19993 ;; Their operands are not commutative, and thus they may be used in the
19994 ;; presence of -0.0 and NaN.
19996 (define_insn "*avx_ieee_smin<mode>3"
19997   [(set (match_operand:MODEF 0 "register_operand" "=x")
19998         (unspec:MODEF
19999           [(match_operand:MODEF 1 "register_operand" "x")
20000            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20001          UNSPEC_IEEE_MIN))]
20002   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20003   "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20004   [(set_attr "type" "sseadd")
20005    (set_attr "prefix" "vex")
20006    (set_attr "mode" "<MODE>")])
20008 (define_insn "*ieee_smin<mode>3"
20009   [(set (match_operand:MODEF 0 "register_operand" "=x")
20010         (unspec:MODEF
20011           [(match_operand:MODEF 1 "register_operand" "0")
20012            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20013          UNSPEC_IEEE_MIN))]
20014   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20015   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20016   [(set_attr "type" "sseadd")
20017    (set_attr "mode" "<MODE>")])
20019 (define_insn "*avx_ieee_smax<mode>3"
20020   [(set (match_operand:MODEF 0 "register_operand" "=x")
20021         (unspec:MODEF
20022           [(match_operand:MODEF 1 "register_operand" "0")
20023            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20024          UNSPEC_IEEE_MAX))]
20025   "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20026   "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20027   [(set_attr "type" "sseadd")
20028    (set_attr "prefix" "vex")
20029    (set_attr "mode" "<MODE>")])
20031 (define_insn "*ieee_smax<mode>3"
20032   [(set (match_operand:MODEF 0 "register_operand" "=x")
20033         (unspec:MODEF
20034           [(match_operand:MODEF 1 "register_operand" "0")
20035            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20036          UNSPEC_IEEE_MAX))]
20037   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20038   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20039   [(set_attr "type" "sseadd")
20040    (set_attr "mode" "<MODE>")])
20042 ;; Make two stack loads independent:
20043 ;;   fld aa              fld aa
20044 ;;   fld %st(0)     ->   fld bb
20045 ;;   fmul bb             fmul %st(1), %st
20047 ;; Actually we only match the last two instructions for simplicity.
20048 (define_peephole2
20049   [(set (match_operand 0 "fp_register_operand" "")
20050         (match_operand 1 "fp_register_operand" ""))
20051    (set (match_dup 0)
20052         (match_operator 2 "binary_fp_operator"
20053            [(match_dup 0)
20054             (match_operand 3 "memory_operand" "")]))]
20055   "REGNO (operands[0]) != REGNO (operands[1])"
20056   [(set (match_dup 0) (match_dup 3))
20057    (set (match_dup 0) (match_dup 4))]
20059   ;; The % modifier is not operational anymore in peephole2's, so we have to
20060   ;; swap the operands manually in the case of addition and multiplication.
20061   "if (COMMUTATIVE_ARITH_P (operands[2]))
20062      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20063                                  operands[0], operands[1]);
20064    else
20065      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20066                                  operands[1], operands[0]);")
20068 ;; Conditional addition patterns
20069 (define_expand "add<mode>cc"
20070   [(match_operand:SWI 0 "register_operand" "")
20071    (match_operand 1 "comparison_operator" "")
20072    (match_operand:SWI 2 "register_operand" "")
20073    (match_operand:SWI 3 "const_int_operand" "")]
20074   ""
20075   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20078 ;; Misc patterns (?)
20080 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20081 ;; Otherwise there will be nothing to keep
20083 ;; [(set (reg ebp) (reg esp))]
20084 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20085 ;;  (clobber (eflags)]
20086 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20088 ;; in proper program order.
20089 (define_insn "pro_epilogue_adjust_stack_1"
20090   [(set (match_operand:SI 0 "register_operand" "=r,r")
20091         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20092                  (match_operand:SI 2 "immediate_operand" "i,i")))
20093    (clobber (reg:CC FLAGS_REG))
20094    (clobber (mem:BLK (scratch)))]
20095   "!TARGET_64BIT"
20097   switch (get_attr_type (insn))
20098     {
20099     case TYPE_IMOV:
20100       return "mov{l}\t{%1, %0|%0, %1}";
20102     case TYPE_ALU:
20103       if (CONST_INT_P (operands[2])
20104           && (INTVAL (operands[2]) == 128
20105               || (INTVAL (operands[2]) < 0
20106                   && INTVAL (operands[2]) != -128)))
20107         {
20108           operands[2] = GEN_INT (-INTVAL (operands[2]));
20109           return "sub{l}\t{%2, %0|%0, %2}";
20110         }
20111       return "add{l}\t{%2, %0|%0, %2}";
20113     case TYPE_LEA:
20114       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20115       return "lea{l}\t{%a2, %0|%0, %a2}";
20117     default:
20118       gcc_unreachable ();
20119     }
20121   [(set (attr "type")
20122         (cond [(eq_attr "alternative" "0")
20123                  (const_string "alu")
20124                (match_operand:SI 2 "const0_operand" "")
20125                  (const_string "imov")
20126               ]
20127               (const_string "lea")))
20128    (set_attr "mode" "SI")])
20130 (define_insn "pro_epilogue_adjust_stack_rex64"
20131   [(set (match_operand:DI 0 "register_operand" "=r,r")
20132         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20133                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20134    (clobber (reg:CC FLAGS_REG))
20135    (clobber (mem:BLK (scratch)))]
20136   "TARGET_64BIT"
20138   switch (get_attr_type (insn))
20139     {
20140     case TYPE_IMOV:
20141       return "mov{q}\t{%1, %0|%0, %1}";
20143     case TYPE_ALU:
20144       if (CONST_INT_P (operands[2])
20145           /* Avoid overflows.  */
20146           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20147           && (INTVAL (operands[2]) == 128
20148               || (INTVAL (operands[2]) < 0
20149                   && INTVAL (operands[2]) != -128)))
20150         {
20151           operands[2] = GEN_INT (-INTVAL (operands[2]));
20152           return "sub{q}\t{%2, %0|%0, %2}";
20153         }
20154       return "add{q}\t{%2, %0|%0, %2}";
20156     case TYPE_LEA:
20157       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20158       return "lea{q}\t{%a2, %0|%0, %a2}";
20160     default:
20161       gcc_unreachable ();
20162     }
20164   [(set (attr "type")
20165         (cond [(eq_attr "alternative" "0")
20166                  (const_string "alu")
20167                (match_operand:DI 2 "const0_operand" "")
20168                  (const_string "imov")
20169               ]
20170               (const_string "lea")))
20171    (set_attr "mode" "DI")])
20173 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20174   [(set (match_operand:DI 0 "register_operand" "=r,r")
20175         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20176                  (match_operand:DI 3 "immediate_operand" "i,i")))
20177    (use (match_operand:DI 2 "register_operand" "r,r"))
20178    (clobber (reg:CC FLAGS_REG))
20179    (clobber (mem:BLK (scratch)))]
20180   "TARGET_64BIT"
20182   switch (get_attr_type (insn))
20183     {
20184     case TYPE_ALU:
20185       return "add{q}\t{%2, %0|%0, %2}";
20187     case TYPE_LEA:
20188       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20189       return "lea{q}\t{%a2, %0|%0, %a2}";
20191     default:
20192       gcc_unreachable ();
20193     }
20195   [(set_attr "type" "alu,lea")
20196    (set_attr "mode" "DI")])
20198 (define_insn "allocate_stack_worker_32"
20199   [(set (match_operand:SI 0 "register_operand" "+a")
20200         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
20201    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
20202    (clobber (reg:CC FLAGS_REG))]
20203   "!TARGET_64BIT && TARGET_STACK_PROBE"
20204   "call\t___chkstk"
20205   [(set_attr "type" "multi")
20206    (set_attr "length" "5")])
20208 (define_insn "allocate_stack_worker_64"
20209   [(set (match_operand:DI 0 "register_operand" "+a")
20210         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
20211    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
20212    (clobber (reg:DI R10_REG))
20213    (clobber (reg:DI R11_REG))
20214    (clobber (reg:CC FLAGS_REG))]
20215   "TARGET_64BIT && TARGET_STACK_PROBE"
20216   "call\t___chkstk"
20217   [(set_attr "type" "multi")
20218    (set_attr "length" "5")])
20220 (define_expand "allocate_stack"
20221   [(match_operand 0 "register_operand" "")
20222    (match_operand 1 "general_operand" "")]
20223   "TARGET_STACK_PROBE"
20225   rtx x;
20227 #ifndef CHECK_STACK_LIMIT
20228 #define CHECK_STACK_LIMIT 0
20229 #endif
20231   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
20232       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
20233     {
20234       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
20235                                stack_pointer_rtx, 0, OPTAB_DIRECT);
20236       if (x != stack_pointer_rtx)
20237         emit_move_insn (stack_pointer_rtx, x);
20238     }
20239   else
20240     {
20241       x = copy_to_mode_reg (Pmode, operands[1]);
20242       if (TARGET_64BIT)
20243         x = gen_allocate_stack_worker_64 (x);
20244       else
20245         x = gen_allocate_stack_worker_32 (x);
20246       emit_insn (x);
20247     }
20249   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
20250   DONE;
20253 (define_expand "builtin_setjmp_receiver"
20254   [(label_ref (match_operand 0 "" ""))]
20255   "!TARGET_64BIT && flag_pic"
20257 #if TARGET_MACHO
20258   if (TARGET_MACHO)
20259     {
20260       rtx xops[3];
20261       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
20262       rtx label_rtx = gen_label_rtx ();
20263       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
20264       xops[0] = xops[1] = picreg;
20265       xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
20266       ix86_expand_binary_operator (MINUS, SImode, xops);
20267     }
20268   else
20269 #endif
20270     emit_insn (gen_set_got (pic_offset_table_rtx));
20271   DONE;
20274 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
20276 (define_split
20277   [(set (match_operand 0 "register_operand" "")
20278         (match_operator 3 "promotable_binary_operator"
20279            [(match_operand 1 "register_operand" "")
20280             (match_operand 2 "aligned_operand" "")]))
20281    (clobber (reg:CC FLAGS_REG))]
20282   "! TARGET_PARTIAL_REG_STALL && reload_completed
20283    && ((GET_MODE (operands[0]) == HImode
20284         && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
20285             /* ??? next two lines just !satisfies_constraint_K (...) */
20286             || !CONST_INT_P (operands[2])
20287             || satisfies_constraint_K (operands[2])))
20288        || (GET_MODE (operands[0]) == QImode
20289            && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
20290   [(parallel [(set (match_dup 0)
20291                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20292               (clobber (reg:CC FLAGS_REG))])]
20293   "operands[0] = gen_lowpart (SImode, operands[0]);
20294    operands[1] = gen_lowpart (SImode, operands[1]);
20295    if (GET_CODE (operands[3]) != ASHIFT)
20296      operands[2] = gen_lowpart (SImode, operands[2]);
20297    PUT_MODE (operands[3], SImode);")
20299 ; Promote the QImode tests, as i386 has encoding of the AND
20300 ; instruction with 32-bit sign-extended immediate and thus the
20301 ; instruction size is unchanged, except in the %eax case for
20302 ; which it is increased by one byte, hence the ! optimize_size.
20303 (define_split
20304   [(set (match_operand 0 "flags_reg_operand" "")
20305         (match_operator 2 "compare_operator"
20306           [(and (match_operand 3 "aligned_operand" "")
20307                 (match_operand 4 "const_int_operand" ""))
20308            (const_int 0)]))
20309    (set (match_operand 1 "register_operand" "")
20310         (and (match_dup 3) (match_dup 4)))]
20311   "! TARGET_PARTIAL_REG_STALL && reload_completed
20312    && optimize_insn_for_speed_p ()
20313    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
20314        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
20315    /* Ensure that the operand will remain sign-extended immediate.  */
20316    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
20317   [(parallel [(set (match_dup 0)
20318                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
20319                                     (const_int 0)]))
20320               (set (match_dup 1)
20321                    (and:SI (match_dup 3) (match_dup 4)))])]
20323   operands[4]
20324     = gen_int_mode (INTVAL (operands[4])
20325                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
20326   operands[1] = gen_lowpart (SImode, operands[1]);
20327   operands[3] = gen_lowpart (SImode, operands[3]);
20330 ; Don't promote the QImode tests, as i386 doesn't have encoding of
20331 ; the TEST instruction with 32-bit sign-extended immediate and thus
20332 ; the instruction size would at least double, which is not what we
20333 ; want even with ! optimize_size.
20334 (define_split
20335   [(set (match_operand 0 "flags_reg_operand" "")
20336         (match_operator 1 "compare_operator"
20337           [(and (match_operand:HI 2 "aligned_operand" "")
20338                 (match_operand:HI 3 "const_int_operand" ""))
20339            (const_int 0)]))]
20340   "! TARGET_PARTIAL_REG_STALL && reload_completed
20341    && ! TARGET_FAST_PREFIX
20342    && optimize_insn_for_speed_p ()
20343    /* Ensure that the operand will remain sign-extended immediate.  */
20344    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
20345   [(set (match_dup 0)
20346         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20347                          (const_int 0)]))]
20349   operands[3]
20350     = gen_int_mode (INTVAL (operands[3])
20351                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
20352   operands[2] = gen_lowpart (SImode, operands[2]);
20355 (define_split
20356   [(set (match_operand 0 "register_operand" "")
20357         (neg (match_operand 1 "register_operand" "")))
20358    (clobber (reg:CC FLAGS_REG))]
20359   "! TARGET_PARTIAL_REG_STALL && reload_completed
20360    && (GET_MODE (operands[0]) == HImode
20361        || (GET_MODE (operands[0]) == QImode
20362            && (TARGET_PROMOTE_QImode
20363                || optimize_insn_for_size_p ())))"
20364   [(parallel [(set (match_dup 0)
20365                    (neg:SI (match_dup 1)))
20366               (clobber (reg:CC FLAGS_REG))])]
20367   "operands[0] = gen_lowpart (SImode, operands[0]);
20368    operands[1] = gen_lowpart (SImode, operands[1]);")
20370 (define_split
20371   [(set (match_operand 0 "register_operand" "")
20372         (not (match_operand 1 "register_operand" "")))]
20373   "! TARGET_PARTIAL_REG_STALL && reload_completed
20374    && (GET_MODE (operands[0]) == HImode
20375        || (GET_MODE (operands[0]) == QImode
20376            && (TARGET_PROMOTE_QImode
20377                || optimize_insn_for_size_p ())))"
20378   [(set (match_dup 0)
20379         (not:SI (match_dup 1)))]
20380   "operands[0] = gen_lowpart (SImode, operands[0]);
20381    operands[1] = gen_lowpart (SImode, operands[1]);")
20383 (define_split
20384   [(set (match_operand 0 "register_operand" "")
20385         (if_then_else (match_operator 1 "comparison_operator"
20386                                 [(reg FLAGS_REG) (const_int 0)])
20387                       (match_operand 2 "register_operand" "")
20388                       (match_operand 3 "register_operand" "")))]
20389   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
20390    && (GET_MODE (operands[0]) == HImode
20391        || (GET_MODE (operands[0]) == QImode
20392            && (TARGET_PROMOTE_QImode
20393                || optimize_insn_for_size_p ())))"
20394   [(set (match_dup 0)
20395         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
20396   "operands[0] = gen_lowpart (SImode, operands[0]);
20397    operands[2] = gen_lowpart (SImode, operands[2]);
20398    operands[3] = gen_lowpart (SImode, operands[3]);")
20401 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
20402 ;; transform a complex memory operation into two memory to register operations.
20404 ;; Don't push memory operands
20405 (define_peephole2
20406   [(set (match_operand:SI 0 "push_operand" "")
20407         (match_operand:SI 1 "memory_operand" ""))
20408    (match_scratch:SI 2 "r")]
20409   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20410    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20411   [(set (match_dup 2) (match_dup 1))
20412    (set (match_dup 0) (match_dup 2))]
20413   "")
20415 (define_peephole2
20416   [(set (match_operand:DI 0 "push_operand" "")
20417         (match_operand:DI 1 "memory_operand" ""))
20418    (match_scratch:DI 2 "r")]
20419   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20420    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20421   [(set (match_dup 2) (match_dup 1))
20422    (set (match_dup 0) (match_dup 2))]
20423   "")
20425 ;; We need to handle SFmode only, because DFmode and XFmode is split to
20426 ;; SImode pushes.
20427 (define_peephole2
20428   [(set (match_operand:SF 0 "push_operand" "")
20429         (match_operand:SF 1 "memory_operand" ""))
20430    (match_scratch:SF 2 "r")]
20431   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20432    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20433   [(set (match_dup 2) (match_dup 1))
20434    (set (match_dup 0) (match_dup 2))]
20435   "")
20437 (define_peephole2
20438   [(set (match_operand:HI 0 "push_operand" "")
20439         (match_operand:HI 1 "memory_operand" ""))
20440    (match_scratch:HI 2 "r")]
20441   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20442    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20443   [(set (match_dup 2) (match_dup 1))
20444    (set (match_dup 0) (match_dup 2))]
20445   "")
20447 (define_peephole2
20448   [(set (match_operand:QI 0 "push_operand" "")
20449         (match_operand:QI 1 "memory_operand" ""))
20450    (match_scratch:QI 2 "q")]
20451   "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
20452    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
20453   [(set (match_dup 2) (match_dup 1))
20454    (set (match_dup 0) (match_dup 2))]
20455   "")
20457 ;; Don't move an immediate directly to memory when the instruction
20458 ;; gets too big.
20459 (define_peephole2
20460   [(match_scratch:SI 1 "r")
20461    (set (match_operand:SI 0 "memory_operand" "")
20462         (const_int 0))]
20463   "optimize_insn_for_speed_p ()
20464    && ! TARGET_USE_MOV0
20465    && TARGET_SPLIT_LONG_MOVES
20466    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20467    && peep2_regno_dead_p (0, FLAGS_REG)"
20468   [(parallel [(set (match_dup 1) (const_int 0))
20469               (clobber (reg:CC FLAGS_REG))])
20470    (set (match_dup 0) (match_dup 1))]
20471   "")
20473 (define_peephole2
20474   [(match_scratch:HI 1 "r")
20475    (set (match_operand:HI 0 "memory_operand" "")
20476         (const_int 0))]
20477   "optimize_insn_for_speed_p ()
20478    && ! TARGET_USE_MOV0
20479    && TARGET_SPLIT_LONG_MOVES
20480    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20481    && peep2_regno_dead_p (0, FLAGS_REG)"
20482   [(parallel [(set (match_dup 2) (const_int 0))
20483               (clobber (reg:CC FLAGS_REG))])
20484    (set (match_dup 0) (match_dup 1))]
20485   "operands[2] = gen_lowpart (SImode, operands[1]);")
20487 (define_peephole2
20488   [(match_scratch:QI 1 "q")
20489    (set (match_operand:QI 0 "memory_operand" "")
20490         (const_int 0))]
20491   "optimize_insn_for_speed_p ()
20492    && ! TARGET_USE_MOV0
20493    && TARGET_SPLIT_LONG_MOVES
20494    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20495    && peep2_regno_dead_p (0, FLAGS_REG)"
20496   [(parallel [(set (match_dup 2) (const_int 0))
20497               (clobber (reg:CC FLAGS_REG))])
20498    (set (match_dup 0) (match_dup 1))]
20499   "operands[2] = gen_lowpart (SImode, operands[1]);")
20501 (define_peephole2
20502   [(match_scratch:SI 2 "r")
20503    (set (match_operand:SI 0 "memory_operand" "")
20504         (match_operand:SI 1 "immediate_operand" ""))]
20505   "optimize_insn_for_speed_p ()
20506    && TARGET_SPLIT_LONG_MOVES
20507    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20508   [(set (match_dup 2) (match_dup 1))
20509    (set (match_dup 0) (match_dup 2))]
20510   "")
20512 (define_peephole2
20513   [(match_scratch:HI 2 "r")
20514    (set (match_operand:HI 0 "memory_operand" "")
20515         (match_operand:HI 1 "immediate_operand" ""))]
20516   "optimize_insn_for_speed_p ()
20517    && TARGET_SPLIT_LONG_MOVES
20518    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20519   [(set (match_dup 2) (match_dup 1))
20520    (set (match_dup 0) (match_dup 2))]
20521   "")
20523 (define_peephole2
20524   [(match_scratch:QI 2 "q")
20525    (set (match_operand:QI 0 "memory_operand" "")
20526         (match_operand:QI 1 "immediate_operand" ""))]
20527   "optimize_insn_for_speed_p ()
20528    && TARGET_SPLIT_LONG_MOVES
20529    && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20530   [(set (match_dup 2) (match_dup 1))
20531    (set (match_dup 0) (match_dup 2))]
20532   "")
20534 ;; Don't compare memory with zero, load and use a test instead.
20535 (define_peephole2
20536   [(set (match_operand 0 "flags_reg_operand" "")
20537         (match_operator 1 "compare_operator"
20538           [(match_operand:SI 2 "memory_operand" "")
20539            (const_int 0)]))
20540    (match_scratch:SI 3 "r")]
20541   "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20542   [(set (match_dup 3) (match_dup 2))
20543    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20544   "")
20546 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20547 ;; Don't split NOTs with a displacement operand, because resulting XOR
20548 ;; will not be pairable anyway.
20550 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20551 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20552 ;; so this split helps here as well.
20554 ;; Note: Can't do this as a regular split because we can't get proper
20555 ;; lifetime information then.
20557 (define_peephole2
20558   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20559         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20560   "optimize_insn_for_speed_p ()
20561    && ((TARGET_NOT_UNPAIRABLE
20562         && (!MEM_P (operands[0])
20563             || !memory_displacement_operand (operands[0], SImode)))
20564        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20565    && peep2_regno_dead_p (0, FLAGS_REG)"
20566   [(parallel [(set (match_dup 0)
20567                    (xor:SI (match_dup 1) (const_int -1)))
20568               (clobber (reg:CC FLAGS_REG))])]
20569   "")
20571 (define_peephole2
20572   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20573         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20574   "optimize_insn_for_speed_p ()
20575    && ((TARGET_NOT_UNPAIRABLE
20576         && (!MEM_P (operands[0])
20577             || !memory_displacement_operand (operands[0], HImode)))
20578        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20579    && peep2_regno_dead_p (0, FLAGS_REG)"
20580   [(parallel [(set (match_dup 0)
20581                    (xor:HI (match_dup 1) (const_int -1)))
20582               (clobber (reg:CC FLAGS_REG))])]
20583   "")
20585 (define_peephole2
20586   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20587         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20588   "optimize_insn_for_speed_p ()
20589    && ((TARGET_NOT_UNPAIRABLE
20590         && (!MEM_P (operands[0])
20591             || !memory_displacement_operand (operands[0], QImode)))
20592        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20593    && peep2_regno_dead_p (0, FLAGS_REG)"
20594   [(parallel [(set (match_dup 0)
20595                    (xor:QI (match_dup 1) (const_int -1)))
20596               (clobber (reg:CC FLAGS_REG))])]
20597   "")
20599 ;; Non pairable "test imm, reg" instructions can be translated to
20600 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20601 ;; byte opcode instead of two, have a short form for byte operands),
20602 ;; so do it for other CPUs as well.  Given that the value was dead,
20603 ;; this should not create any new dependencies.  Pass on the sub-word
20604 ;; versions if we're concerned about partial register stalls.
20606 (define_peephole2
20607   [(set (match_operand 0 "flags_reg_operand" "")
20608         (match_operator 1 "compare_operator"
20609           [(and:SI (match_operand:SI 2 "register_operand" "")
20610                    (match_operand:SI 3 "immediate_operand" ""))
20611            (const_int 0)]))]
20612   "ix86_match_ccmode (insn, CCNOmode)
20613    && (true_regnum (operands[2]) != AX_REG
20614        || satisfies_constraint_K (operands[3]))
20615    && peep2_reg_dead_p (1, operands[2])"
20616   [(parallel
20617      [(set (match_dup 0)
20618            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20619                             (const_int 0)]))
20620       (set (match_dup 2)
20621            (and:SI (match_dup 2) (match_dup 3)))])]
20622   "")
20624 ;; We don't need to handle HImode case, because it will be promoted to SImode
20625 ;; on ! TARGET_PARTIAL_REG_STALL
20627 (define_peephole2
20628   [(set (match_operand 0 "flags_reg_operand" "")
20629         (match_operator 1 "compare_operator"
20630           [(and:QI (match_operand:QI 2 "register_operand" "")
20631                    (match_operand:QI 3 "immediate_operand" ""))
20632            (const_int 0)]))]
20633   "! TARGET_PARTIAL_REG_STALL
20634    && ix86_match_ccmode (insn, CCNOmode)
20635    && true_regnum (operands[2]) != AX_REG
20636    && peep2_reg_dead_p (1, operands[2])"
20637   [(parallel
20638      [(set (match_dup 0)
20639            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20640                             (const_int 0)]))
20641       (set (match_dup 2)
20642            (and:QI (match_dup 2) (match_dup 3)))])]
20643   "")
20645 (define_peephole2
20646   [(set (match_operand 0 "flags_reg_operand" "")
20647         (match_operator 1 "compare_operator"
20648           [(and:SI
20649              (zero_extract:SI
20650                (match_operand 2 "ext_register_operand" "")
20651                (const_int 8)
20652                (const_int 8))
20653              (match_operand 3 "const_int_operand" ""))
20654            (const_int 0)]))]
20655   "! TARGET_PARTIAL_REG_STALL
20656    && ix86_match_ccmode (insn, CCNOmode)
20657    && true_regnum (operands[2]) != AX_REG
20658    && peep2_reg_dead_p (1, operands[2])"
20659   [(parallel [(set (match_dup 0)
20660                    (match_op_dup 1
20661                      [(and:SI
20662                         (zero_extract:SI
20663                           (match_dup 2)
20664                           (const_int 8)
20665                           (const_int 8))
20666                         (match_dup 3))
20667                       (const_int 0)]))
20668               (set (zero_extract:SI (match_dup 2)
20669                                     (const_int 8)
20670                                     (const_int 8))
20671                    (and:SI
20672                      (zero_extract:SI
20673                        (match_dup 2)
20674                        (const_int 8)
20675                        (const_int 8))
20676                      (match_dup 3)))])]
20677   "")
20679 ;; Don't do logical operations with memory inputs.
20680 (define_peephole2
20681   [(match_scratch:SI 2 "r")
20682    (parallel [(set (match_operand:SI 0 "register_operand" "")
20683                    (match_operator:SI 3 "arith_or_logical_operator"
20684                      [(match_dup 0)
20685                       (match_operand:SI 1 "memory_operand" "")]))
20686               (clobber (reg:CC FLAGS_REG))])]
20687   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20688   [(set (match_dup 2) (match_dup 1))
20689    (parallel [(set (match_dup 0)
20690                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20691               (clobber (reg:CC FLAGS_REG))])]
20692   "")
20694 (define_peephole2
20695   [(match_scratch:SI 2 "r")
20696    (parallel [(set (match_operand:SI 0 "register_operand" "")
20697                    (match_operator:SI 3 "arith_or_logical_operator"
20698                      [(match_operand:SI 1 "memory_operand" "")
20699                       (match_dup 0)]))
20700               (clobber (reg:CC FLAGS_REG))])]
20701   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20702   [(set (match_dup 2) (match_dup 1))
20703    (parallel [(set (match_dup 0)
20704                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20705               (clobber (reg:CC FLAGS_REG))])]
20706   "")
20708 ; Don't do logical operations with memory outputs
20710 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20711 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20712 ; the same decoder scheduling characteristics as the original.
20714 (define_peephole2
20715   [(match_scratch:SI 2 "r")
20716    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20717                    (match_operator:SI 3 "arith_or_logical_operator"
20718                      [(match_dup 0)
20719                       (match_operand:SI 1 "nonmemory_operand" "")]))
20720               (clobber (reg:CC FLAGS_REG))])]
20721   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20722   [(set (match_dup 2) (match_dup 0))
20723    (parallel [(set (match_dup 2)
20724                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20725               (clobber (reg:CC FLAGS_REG))])
20726    (set (match_dup 0) (match_dup 2))]
20727   "")
20729 (define_peephole2
20730   [(match_scratch:SI 2 "r")
20731    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20732                    (match_operator:SI 3 "arith_or_logical_operator"
20733                      [(match_operand:SI 1 "nonmemory_operand" "")
20734                       (match_dup 0)]))
20735               (clobber (reg:CC FLAGS_REG))])]
20736   "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
20737   [(set (match_dup 2) (match_dup 0))
20738    (parallel [(set (match_dup 2)
20739                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20740               (clobber (reg:CC FLAGS_REG))])
20741    (set (match_dup 0) (match_dup 2))]
20742   "")
20744 ;; Attempt to always use XOR for zeroing registers.
20745 (define_peephole2
20746   [(set (match_operand 0 "register_operand" "")
20747         (match_operand 1 "const0_operand" ""))]
20748   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20749    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20750    && GENERAL_REG_P (operands[0])
20751    && peep2_regno_dead_p (0, FLAGS_REG)"
20752   [(parallel [(set (match_dup 0) (const_int 0))
20753               (clobber (reg:CC FLAGS_REG))])]
20755   operands[0] = gen_lowpart (word_mode, operands[0]);
20758 (define_peephole2
20759   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20760         (const_int 0))]
20761   "(GET_MODE (operands[0]) == QImode
20762     || GET_MODE (operands[0]) == HImode)
20763    && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20764    && peep2_regno_dead_p (0, FLAGS_REG)"
20765   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20766               (clobber (reg:CC FLAGS_REG))])])
20768 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20769 (define_peephole2
20770   [(set (match_operand 0 "register_operand" "")
20771         (const_int -1))]
20772   "(GET_MODE (operands[0]) == HImode
20773     || GET_MODE (operands[0]) == SImode
20774     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20775    && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20776    && peep2_regno_dead_p (0, FLAGS_REG)"
20777   [(parallel [(set (match_dup 0) (const_int -1))
20778               (clobber (reg:CC FLAGS_REG))])]
20779   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20780                               operands[0]);")
20782 ;; Attempt to convert simple leas to adds. These can be created by
20783 ;; move expanders.
20784 (define_peephole2
20785   [(set (match_operand:SI 0 "register_operand" "")
20786         (plus:SI (match_dup 0)
20787                  (match_operand:SI 1 "nonmemory_operand" "")))]
20788   "peep2_regno_dead_p (0, FLAGS_REG)"
20789   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20790               (clobber (reg:CC FLAGS_REG))])]
20791   "")
20793 (define_peephole2
20794   [(set (match_operand:SI 0 "register_operand" "")
20795         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20796                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20797   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20798   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20799               (clobber (reg:CC FLAGS_REG))])]
20800   "operands[2] = gen_lowpart (SImode, operands[2]);")
20802 (define_peephole2
20803   [(set (match_operand:DI 0 "register_operand" "")
20804         (plus:DI (match_dup 0)
20805                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20806   "peep2_regno_dead_p (0, FLAGS_REG)"
20807   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20808               (clobber (reg:CC FLAGS_REG))])]
20809   "")
20811 (define_peephole2
20812   [(set (match_operand:SI 0 "register_operand" "")
20813         (mult:SI (match_dup 0)
20814                  (match_operand:SI 1 "const_int_operand" "")))]
20815   "exact_log2 (INTVAL (operands[1])) >= 0
20816    && peep2_regno_dead_p (0, FLAGS_REG)"
20817   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20818               (clobber (reg:CC FLAGS_REG))])]
20819   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20821 (define_peephole2
20822   [(set (match_operand:DI 0 "register_operand" "")
20823         (mult:DI (match_dup 0)
20824                  (match_operand:DI 1 "const_int_operand" "")))]
20825   "exact_log2 (INTVAL (operands[1])) >= 0
20826    && peep2_regno_dead_p (0, FLAGS_REG)"
20827   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20828               (clobber (reg:CC FLAGS_REG))])]
20829   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20831 (define_peephole2
20832   [(set (match_operand:SI 0 "register_operand" "")
20833         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20834                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20835   "exact_log2 (INTVAL (operands[2])) >= 0
20836    && REGNO (operands[0]) == REGNO (operands[1])
20837    && peep2_regno_dead_p (0, FLAGS_REG)"
20838   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20839               (clobber (reg:CC FLAGS_REG))])]
20840   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20842 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20843 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20844 ;; many CPUs it is also faster, since special hardware to avoid esp
20845 ;; dependencies is present.
20847 ;; While some of these conversions may be done using splitters, we use peepholes
20848 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20850 ;; Convert prologue esp subtractions to push.
20851 ;; We need register to push.  In order to keep verify_flow_info happy we have
20852 ;; two choices
20853 ;; - use scratch and clobber it in order to avoid dependencies
20854 ;; - use already live register
20855 ;; We can't use the second way right now, since there is no reliable way how to
20856 ;; verify that given register is live.  First choice will also most likely in
20857 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20858 ;; call clobbered registers are dead.  We may want to use base pointer as an
20859 ;; alternative when no register is available later.
20861 (define_peephole2
20862   [(match_scratch:SI 0 "r")
20863    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20864               (clobber (reg:CC FLAGS_REG))
20865               (clobber (mem:BLK (scratch)))])]
20866   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20867   [(clobber (match_dup 0))
20868    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20869               (clobber (mem:BLK (scratch)))])])
20871 (define_peephole2
20872   [(match_scratch:SI 0 "r")
20873    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20874               (clobber (reg:CC FLAGS_REG))
20875               (clobber (mem:BLK (scratch)))])]
20876   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20877   [(clobber (match_dup 0))
20878    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20879    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20880               (clobber (mem:BLK (scratch)))])])
20882 ;; Convert esp subtractions to push.
20883 (define_peephole2
20884   [(match_scratch:SI 0 "r")
20885    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20886               (clobber (reg:CC FLAGS_REG))])]
20887   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20888   [(clobber (match_dup 0))
20889    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20891 (define_peephole2
20892   [(match_scratch:SI 0 "r")
20893    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20894               (clobber (reg:CC FLAGS_REG))])]
20895   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20896   [(clobber (match_dup 0))
20897    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20898    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20900 ;; Convert epilogue deallocator to pop.
20901 (define_peephole2
20902   [(match_scratch:SI 0 "r")
20903    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20904               (clobber (reg:CC FLAGS_REG))
20905               (clobber (mem:BLK (scratch)))])]
20906   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20907   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20908               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20909               (clobber (mem:BLK (scratch)))])]
20910   "")
20912 ;; Two pops case is tricky, since pop causes dependency on destination register.
20913 ;; We use two registers if available.
20914 (define_peephole2
20915   [(match_scratch:SI 0 "r")
20916    (match_scratch:SI 1 "r")
20917    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20918               (clobber (reg:CC FLAGS_REG))
20919               (clobber (mem:BLK (scratch)))])]
20920   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20921   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20922               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20923               (clobber (mem:BLK (scratch)))])
20924    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20925               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20926   "")
20928 (define_peephole2
20929   [(match_scratch:SI 0 "r")
20930    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20931               (clobber (reg:CC FLAGS_REG))
20932               (clobber (mem:BLK (scratch)))])]
20933   "optimize_insn_for_size_p ()"
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               (clobber (mem:BLK (scratch)))])
20937    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20938               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20939   "")
20941 ;; Convert esp additions to pop.
20942 (define_peephole2
20943   [(match_scratch:SI 0 "r")
20944    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20945               (clobber (reg:CC FLAGS_REG))])]
20946   ""
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 ;; Two pops case is tricky, since pop causes dependency on destination register.
20952 ;; We use two registers if available.
20953 (define_peephole2
20954   [(match_scratch:SI 0 "r")
20955    (match_scratch:SI 1 "r")
20956    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20957               (clobber (reg:CC FLAGS_REG))])]
20958   ""
20959   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20960               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20961    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20962               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20963   "")
20965 (define_peephole2
20966   [(match_scratch:SI 0 "r")
20967    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20968               (clobber (reg:CC FLAGS_REG))])]
20969   "optimize_insn_for_size_p ()"
20970   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20971               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20972    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20973               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20974   "")
20976 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20977 ;; required and register dies.  Similarly for 128 to -128.
20978 (define_peephole2
20979   [(set (match_operand 0 "flags_reg_operand" "")
20980         (match_operator 1 "compare_operator"
20981           [(match_operand 2 "register_operand" "")
20982            (match_operand 3 "const_int_operand" "")]))]
20983   "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_size)
20984      && incdec_operand (operands[3], GET_MODE (operands[3])))
20985     || (!TARGET_FUSE_CMP_AND_BRANCH
20986         && INTVAL (operands[3]) == 128))
20987    && ix86_match_ccmode (insn, CCGCmode)
20988    && peep2_reg_dead_p (1, operands[2])"
20989   [(parallel [(set (match_dup 0)
20990                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20991               (clobber (match_dup 2))])]
20992   "")
20994 (define_peephole2
20995   [(match_scratch:DI 0 "r")
20996    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20997               (clobber (reg:CC FLAGS_REG))
20998               (clobber (mem:BLK (scratch)))])]
20999   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21000   [(clobber (match_dup 0))
21001    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21002               (clobber (mem:BLK (scratch)))])])
21004 (define_peephole2
21005   [(match_scratch:DI 0 "r")
21006    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21007               (clobber (reg:CC FLAGS_REG))
21008               (clobber (mem:BLK (scratch)))])]
21009   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21010   [(clobber (match_dup 0))
21011    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21012    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21013               (clobber (mem:BLK (scratch)))])])
21015 ;; Convert esp subtractions to push.
21016 (define_peephole2
21017   [(match_scratch:DI 0 "r")
21018    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21019               (clobber (reg:CC FLAGS_REG))])]
21020   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21021   [(clobber (match_dup 0))
21022    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21024 (define_peephole2
21025   [(match_scratch:DI 0 "r")
21026    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21027               (clobber (reg:CC FLAGS_REG))])]
21028   "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21029   [(clobber (match_dup 0))
21030    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21031    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21033 ;; Convert epilogue deallocator to pop.
21034 (define_peephole2
21035   [(match_scratch:DI 0 "r")
21036    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21037               (clobber (reg:CC FLAGS_REG))
21038               (clobber (mem:BLK (scratch)))])]
21039   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21040   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21041               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21042               (clobber (mem:BLK (scratch)))])]
21043   "")
21045 ;; Two pops case is tricky, since pop causes dependency on destination register.
21046 ;; We use two registers if available.
21047 (define_peephole2
21048   [(match_scratch:DI 0 "r")
21049    (match_scratch:DI 1 "r")
21050    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21051               (clobber (reg:CC FLAGS_REG))
21052               (clobber (mem:BLK (scratch)))])]
21053   "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21054   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21055               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21056               (clobber (mem:BLK (scratch)))])
21057    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21058               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21059   "")
21061 (define_peephole2
21062   [(match_scratch:DI 0 "r")
21063    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21064               (clobber (reg:CC FLAGS_REG))
21065               (clobber (mem:BLK (scratch)))])]
21066   "optimize_insn_for_size_p ()"
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               (clobber (mem:BLK (scratch)))])
21070    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21071               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21072   "")
21074 ;; Convert esp additions to pop.
21075 (define_peephole2
21076   [(match_scratch:DI 0 "r")
21077    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21078               (clobber (reg:CC FLAGS_REG))])]
21079   ""
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 ;; Two pops case is tricky, since pop causes dependency on destination register.
21085 ;; We use two registers if available.
21086 (define_peephole2
21087   [(match_scratch:DI 0 "r")
21088    (match_scratch:DI 1 "r")
21089    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21090               (clobber (reg:CC FLAGS_REG))])]
21091   ""
21092   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21093               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21094    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21095               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21096   "")
21098 (define_peephole2
21099   [(match_scratch:DI 0 "r")
21100    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21101               (clobber (reg:CC FLAGS_REG))])]
21102   "optimize_insn_for_size_p ()"
21103   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21104               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21105    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21106               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21107   "")
21109 ;; Convert imul by three, five and nine into lea
21110 (define_peephole2
21111   [(parallel
21112     [(set (match_operand:SI 0 "register_operand" "")
21113           (mult:SI (match_operand:SI 1 "register_operand" "")
21114                    (match_operand:SI 2 "const_int_operand" "")))
21115      (clobber (reg:CC FLAGS_REG))])]
21116   "INTVAL (operands[2]) == 3
21117    || INTVAL (operands[2]) == 5
21118    || INTVAL (operands[2]) == 9"
21119   [(set (match_dup 0)
21120         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21121                  (match_dup 1)))]
21122   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21124 (define_peephole2
21125   [(parallel
21126     [(set (match_operand:SI 0 "register_operand" "")
21127           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21128                    (match_operand:SI 2 "const_int_operand" "")))
21129      (clobber (reg:CC FLAGS_REG))])]
21130   "optimize_insn_for_speed_p ()
21131    && (INTVAL (operands[2]) == 3
21132        || INTVAL (operands[2]) == 5
21133        || INTVAL (operands[2]) == 9)"
21134   [(set (match_dup 0) (match_dup 1))
21135    (set (match_dup 0)
21136         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21137                  (match_dup 0)))]
21138   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21140 (define_peephole2
21141   [(parallel
21142     [(set (match_operand:DI 0 "register_operand" "")
21143           (mult:DI (match_operand:DI 1 "register_operand" "")
21144                    (match_operand:DI 2 "const_int_operand" "")))
21145      (clobber (reg:CC FLAGS_REG))])]
21146   "TARGET_64BIT
21147    && (INTVAL (operands[2]) == 3
21148        || INTVAL (operands[2]) == 5
21149        || INTVAL (operands[2]) == 9)"
21150   [(set (match_dup 0)
21151         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21152                  (match_dup 1)))]
21153   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21155 (define_peephole2
21156   [(parallel
21157     [(set (match_operand:DI 0 "register_operand" "")
21158           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21159                    (match_operand:DI 2 "const_int_operand" "")))
21160      (clobber (reg:CC FLAGS_REG))])]
21161   "TARGET_64BIT
21162    && optimize_insn_for_speed_p ()
21163    && (INTVAL (operands[2]) == 3
21164        || INTVAL (operands[2]) == 5
21165        || INTVAL (operands[2]) == 9)"
21166   [(set (match_dup 0) (match_dup 1))
21167    (set (match_dup 0)
21168         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21169                  (match_dup 0)))]
21170   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21172 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21173 ;; imul $32bit_imm, reg, reg is direct decoded.
21174 (define_peephole2
21175   [(match_scratch:DI 3 "r")
21176    (parallel [(set (match_operand:DI 0 "register_operand" "")
21177                    (mult:DI (match_operand:DI 1 "memory_operand" "")
21178                             (match_operand:DI 2 "immediate_operand" "")))
21179               (clobber (reg:CC FLAGS_REG))])]
21180   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21181    && !satisfies_constraint_K (operands[2])"
21182   [(set (match_dup 3) (match_dup 1))
21183    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
21184               (clobber (reg:CC FLAGS_REG))])]
21187 (define_peephole2
21188   [(match_scratch:SI 3 "r")
21189    (parallel [(set (match_operand:SI 0 "register_operand" "")
21190                    (mult:SI (match_operand:SI 1 "memory_operand" "")
21191                             (match_operand:SI 2 "immediate_operand" "")))
21192               (clobber (reg:CC FLAGS_REG))])]
21193   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21194    && !satisfies_constraint_K (operands[2])"
21195   [(set (match_dup 3) (match_dup 1))
21196    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
21197               (clobber (reg:CC FLAGS_REG))])]
21200 (define_peephole2
21201   [(match_scratch:SI 3 "r")
21202    (parallel [(set (match_operand:DI 0 "register_operand" "")
21203                    (zero_extend:DI
21204                      (mult:SI (match_operand:SI 1 "memory_operand" "")
21205                               (match_operand:SI 2 "immediate_operand" ""))))
21206               (clobber (reg:CC FLAGS_REG))])]
21207   "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
21208    && !satisfies_constraint_K (operands[2])"
21209   [(set (match_dup 3) (match_dup 1))
21210    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
21211               (clobber (reg:CC FLAGS_REG))])]
21214 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
21215 ;; Convert it into imul reg, reg
21216 ;; It would be better to force assembler to encode instruction using long
21217 ;; immediate, but there is apparently no way to do so.
21218 (define_peephole2
21219   [(parallel [(set (match_operand:DI 0 "register_operand" "")
21220                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21221                             (match_operand:DI 2 "const_int_operand" "")))
21222               (clobber (reg:CC FLAGS_REG))])
21223    (match_scratch:DI 3 "r")]
21224   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21225    && satisfies_constraint_K (operands[2])"
21226   [(set (match_dup 3) (match_dup 2))
21227    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
21228               (clobber (reg:CC FLAGS_REG))])]
21230   if (!rtx_equal_p (operands[0], operands[1]))
21231     emit_move_insn (operands[0], operands[1]);
21234 (define_peephole2
21235   [(parallel [(set (match_operand:SI 0 "register_operand" "")
21236                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21237                             (match_operand:SI 2 "const_int_operand" "")))
21238               (clobber (reg:CC FLAGS_REG))])
21239    (match_scratch:SI 3 "r")]
21240   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
21241    && satisfies_constraint_K (operands[2])"
21242   [(set (match_dup 3) (match_dup 2))
21243    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
21244               (clobber (reg:CC FLAGS_REG))])]
21246   if (!rtx_equal_p (operands[0], operands[1]))
21247     emit_move_insn (operands[0], operands[1]);
21250 (define_peephole2
21251   [(parallel [(set (match_operand:HI 0 "register_operand" "")
21252                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
21253                             (match_operand:HI 2 "immediate_operand" "")))
21254               (clobber (reg:CC FLAGS_REG))])
21255    (match_scratch:HI 3 "r")]
21256   "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
21257   [(set (match_dup 3) (match_dup 2))
21258    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
21259               (clobber (reg:CC FLAGS_REG))])]
21261   if (!rtx_equal_p (operands[0], operands[1]))
21262     emit_move_insn (operands[0], operands[1]);
21265 ;; After splitting up read-modify operations, array accesses with memory
21266 ;; operands might end up in form:
21267 ;;  sall    $2, %eax
21268 ;;  movl    4(%esp), %edx
21269 ;;  addl    %edx, %eax
21270 ;; instead of pre-splitting:
21271 ;;  sall    $2, %eax
21272 ;;  addl    4(%esp), %eax
21273 ;; Turn it into:
21274 ;;  movl    4(%esp), %edx
21275 ;;  leal    (%edx,%eax,4), %eax
21277 (define_peephole2
21278   [(parallel [(set (match_operand 0 "register_operand" "")
21279                    (ashift (match_operand 1 "register_operand" "")
21280                            (match_operand 2 "const_int_operand" "")))
21281                (clobber (reg:CC FLAGS_REG))])
21282    (set (match_operand 3 "register_operand")
21283         (match_operand 4 "x86_64_general_operand" ""))
21284    (parallel [(set (match_operand 5 "register_operand" "")
21285                    (plus (match_operand 6 "register_operand" "")
21286                          (match_operand 7 "register_operand" "")))
21287                    (clobber (reg:CC FLAGS_REG))])]
21288   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
21289    /* Validate MODE for lea.  */
21290    && ((!TARGET_PARTIAL_REG_STALL
21291         && (GET_MODE (operands[0]) == QImode
21292             || GET_MODE (operands[0]) == HImode))
21293        || GET_MODE (operands[0]) == SImode
21294        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
21295    /* We reorder load and the shift.  */
21296    && !rtx_equal_p (operands[1], operands[3])
21297    && !reg_overlap_mentioned_p (operands[0], operands[4])
21298    /* Last PLUS must consist of operand 0 and 3.  */
21299    && !rtx_equal_p (operands[0], operands[3])
21300    && (rtx_equal_p (operands[3], operands[6])
21301        || rtx_equal_p (operands[3], operands[7]))
21302    && (rtx_equal_p (operands[0], operands[6])
21303        || rtx_equal_p (operands[0], operands[7]))
21304    /* The intermediate operand 0 must die or be same as output.  */
21305    && (rtx_equal_p (operands[0], operands[5])
21306        || peep2_reg_dead_p (3, operands[0]))"
21307   [(set (match_dup 3) (match_dup 4))
21308    (set (match_dup 0) (match_dup 1))]
21310   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
21311   int scale = 1 << INTVAL (operands[2]);
21312   rtx index = gen_lowpart (Pmode, operands[1]);
21313   rtx base = gen_lowpart (Pmode, operands[3]);
21314   rtx dest = gen_lowpart (mode, operands[5]);
21316   operands[1] = gen_rtx_PLUS (Pmode, base,
21317                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
21318   if (mode != Pmode)
21319     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
21320   operands[0] = dest;
21323 ;; Call-value patterns last so that the wildcard operand does not
21324 ;; disrupt insn-recog's switch tables.
21326 (define_insn "*call_value_pop_0"
21327   [(set (match_operand 0 "" "")
21328         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21329               (match_operand:SI 2 "" "")))
21330    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21331                             (match_operand:SI 3 "immediate_operand" "")))]
21332   "!TARGET_64BIT"
21334   if (SIBLING_CALL_P (insn))
21335     return "jmp\t%P1";
21336   else
21337     return "call\t%P1";
21339   [(set_attr "type" "callv")])
21341 (define_insn "*call_value_pop_1"
21342   [(set (match_operand 0 "" "")
21343         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21344               (match_operand:SI 2 "" "")))
21345    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
21346                             (match_operand:SI 3 "immediate_operand" "i")))]
21347   "!TARGET_64BIT"
21349   if (constant_call_address_operand (operands[1], Pmode))
21350     {
21351       if (SIBLING_CALL_P (insn))
21352         return "jmp\t%P1";
21353       else
21354         return "call\t%P1";
21355     }
21356   if (SIBLING_CALL_P (insn))
21357     return "jmp\t%A1";
21358   else
21359     return "call\t%A1";
21361   [(set_attr "type" "callv")])
21363 (define_insn "*call_value_0"
21364   [(set (match_operand 0 "" "")
21365         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
21366               (match_operand:SI 2 "" "")))]
21367   "!TARGET_64BIT"
21369   if (SIBLING_CALL_P (insn))
21370     return "jmp\t%P1";
21371   else
21372     return "call\t%P1";
21374   [(set_attr "type" "callv")])
21376 (define_insn "*call_value_0_rex64"
21377   [(set (match_operand 0 "" "")
21378         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21379               (match_operand:DI 2 "const_int_operand" "")))]
21380   "TARGET_64BIT"
21382   if (SIBLING_CALL_P (insn))
21383     return "jmp\t%P1";
21384   else
21385     return "call\t%P1";
21387   [(set_attr "type" "callv")])
21389 (define_insn "*call_value_1"
21390   [(set (match_operand 0 "" "")
21391         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
21392               (match_operand:SI 2 "" "")))]
21393   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
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 "*sibcall_value_1"
21402   [(set (match_operand 0 "" "")
21403         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
21404               (match_operand:SI 2 "" "")))]
21405   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
21407   if (constant_call_address_operand (operands[1], Pmode))
21408     return "jmp\t%P1";
21409   return "jmp\t%A1";
21411   [(set_attr "type" "callv")])
21413 (define_insn "*call_value_1_rex64"
21414   [(set (match_operand 0 "" "")
21415         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21416               (match_operand:DI 2 "" "")))]
21417   "!SIBLING_CALL_P (insn) && TARGET_64BIT
21418    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21420   if (constant_call_address_operand (operands[1], Pmode))
21421     return "call\t%P1";
21422   return "call\t%A1";
21424   [(set_attr "type" "callv")])
21426 (define_insn "*call_value_1_rex64_large"
21427   [(set (match_operand 0 "" "")
21428         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21429               (match_operand:DI 2 "" "")))]
21430   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
21431   "call\t%A1"
21432   [(set_attr "type" "callv")])
21434 (define_insn "*sibcall_value_1_rex64"
21435   [(set (match_operand 0 "" "")
21436         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
21437               (match_operand:DI 2 "" "")))]
21438   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21439   "jmp\t%P1"
21440   [(set_attr "type" "callv")])
21442 (define_insn "*sibcall_value_1_rex64_v"
21443   [(set (match_operand 0 "" "")
21444         (call (mem:QI (reg:DI R11_REG))
21445               (match_operand:DI 1 "" "")))]
21446   "SIBLING_CALL_P (insn) && TARGET_64BIT"
21447   "jmp\t{*%%}r11"
21448   [(set_attr "type" "callv")])
21450 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21451 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21452 ;; caught for use by garbage collectors and the like.  Using an insn that
21453 ;; maps to SIGILL makes it more likely the program will rightfully die.
21454 ;; Keeping with tradition, "6" is in honor of #UD.
21455 (define_insn "trap"
21456   [(trap_if (const_int 1) (const_int 6))]
21457   ""
21458   { return ASM_SHORT "0x0b0f"; }
21459   [(set_attr "length" "2")])
21461 (define_expand "sse_prologue_save"
21462   [(parallel [(set (match_operand:BLK 0 "" "")
21463                    (unspec:BLK [(reg:DI 21)
21464                                 (reg:DI 22)
21465                                 (reg:DI 23)
21466                                 (reg:DI 24)
21467                                 (reg:DI 25)
21468                                 (reg:DI 26)
21469                                 (reg:DI 27)
21470                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21471               (use (match_operand:DI 1 "register_operand" ""))
21472               (use (match_operand:DI 2 "immediate_operand" ""))
21473               (use (label_ref:DI (match_operand 3 "" "")))])]
21474   "TARGET_64BIT"
21475   "")
21477 (define_insn "*sse_prologue_save_insn"
21478   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21479                           (match_operand:DI 4 "const_int_operand" "n")))
21480         (unspec:BLK [(reg:DI 21)
21481                      (reg:DI 22)
21482                      (reg:DI 23)
21483                      (reg:DI 24)
21484                      (reg:DI 25)
21485                      (reg:DI 26)
21486                      (reg:DI 27)
21487                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21488    (use (match_operand:DI 1 "register_operand" "r"))
21489    (use (match_operand:DI 2 "const_int_operand" "i"))
21490    (use (label_ref:DI (match_operand 3 "" "X")))]
21491   "TARGET_64BIT
21492    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21493    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21495   int i;
21496   operands[0] = gen_rtx_MEM (Pmode,
21497                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21498   /* VEX instruction with a REX prefix will #UD.  */
21499   if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21500     gcc_unreachable ();
21502   output_asm_insn ("jmp\t%A1", operands);
21503   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21504     {
21505       operands[4] = adjust_address (operands[0], DImode, i*16);
21506       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21507       PUT_MODE (operands[4], TImode);
21508       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21509         output_asm_insn ("rex", operands);
21510       output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21511     }
21512   (*targetm.asm_out.internal_label) (asm_out_file, "L",
21513                                      CODE_LABEL_NUMBER (operands[3]));
21514   return "";
21516   [(set_attr "type" "other")
21517    (set_attr "length_immediate" "0")
21518    (set_attr "length_address" "0")
21519    (set (attr "length")
21520      (if_then_else
21521        (eq (symbol_ref "TARGET_AVX") (const_int 0))
21522        (const_string "34")
21523        (const_string "42")))
21524    (set_attr "memory" "store")
21525    (set_attr "modrm" "0")
21526    (set_attr "prefix" "maybe_vex")
21527    (set_attr "mode" "DI")])
21529 (define_expand "prefetch"
21530   [(prefetch (match_operand 0 "address_operand" "")
21531              (match_operand:SI 1 "const_int_operand" "")
21532              (match_operand:SI 2 "const_int_operand" ""))]
21533   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21535   int rw = INTVAL (operands[1]);
21536   int locality = INTVAL (operands[2]);
21538   gcc_assert (rw == 0 || rw == 1);
21539   gcc_assert (locality >= 0 && locality <= 3);
21540   gcc_assert (GET_MODE (operands[0]) == Pmode
21541               || GET_MODE (operands[0]) == VOIDmode);
21543   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21544      supported by SSE counterpart or the SSE prefetch is not available
21545      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21546      of locality.  */
21547   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21548     operands[2] = GEN_INT (3);
21549   else
21550     operands[1] = const0_rtx;
21553 (define_insn "*prefetch_sse"
21554   [(prefetch (match_operand:SI 0 "address_operand" "p")
21555              (const_int 0)
21556              (match_operand:SI 1 "const_int_operand" ""))]
21557   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21559   static const char * const patterns[4] = {
21560    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21561   };
21563   int locality = INTVAL (operands[1]);
21564   gcc_assert (locality >= 0 && locality <= 3);
21566   return patterns[locality];
21568   [(set_attr "type" "sse")
21569    (set_attr "memory" "none")])
21571 (define_insn "*prefetch_sse_rex"
21572   [(prefetch (match_operand:DI 0 "address_operand" "p")
21573              (const_int 0)
21574              (match_operand:SI 1 "const_int_operand" ""))]
21575   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21577   static const char * const patterns[4] = {
21578    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21579   };
21581   int locality = INTVAL (operands[1]);
21582   gcc_assert (locality >= 0 && locality <= 3);
21584   return patterns[locality];
21586   [(set_attr "type" "sse")
21587    (set_attr "memory" "none")])
21589 (define_insn "*prefetch_3dnow"
21590   [(prefetch (match_operand:SI 0 "address_operand" "p")
21591              (match_operand:SI 1 "const_int_operand" "n")
21592              (const_int 3))]
21593   "TARGET_3DNOW && !TARGET_64BIT"
21595   if (INTVAL (operands[1]) == 0)
21596     return "prefetch\t%a0";
21597   else
21598     return "prefetchw\t%a0";
21600   [(set_attr "type" "mmx")
21601    (set_attr "memory" "none")])
21603 (define_insn "*prefetch_3dnow_rex"
21604   [(prefetch (match_operand:DI 0 "address_operand" "p")
21605              (match_operand:SI 1 "const_int_operand" "n")
21606              (const_int 3))]
21607   "TARGET_3DNOW && TARGET_64BIT"
21609   if (INTVAL (operands[1]) == 0)
21610     return "prefetch\t%a0";
21611   else
21612     return "prefetchw\t%a0";
21614   [(set_attr "type" "mmx")
21615    (set_attr "memory" "none")])
21617 (define_expand "stack_protect_set"
21618   [(match_operand 0 "memory_operand" "")
21619    (match_operand 1 "memory_operand" "")]
21620   ""
21622 #ifdef TARGET_THREAD_SSP_OFFSET
21623   if (TARGET_64BIT)
21624     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21625                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21626   else
21627     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21628                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21629 #else
21630   if (TARGET_64BIT)
21631     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21632   else
21633     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21634 #endif
21635   DONE;
21638 (define_insn "stack_protect_set_si"
21639   [(set (match_operand:SI 0 "memory_operand" "=m")
21640         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21641    (set (match_scratch:SI 2 "=&r") (const_int 0))
21642    (clobber (reg:CC FLAGS_REG))]
21643   ""
21644   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21645   [(set_attr "type" "multi")])
21647 (define_insn "stack_protect_set_di"
21648   [(set (match_operand:DI 0 "memory_operand" "=m")
21649         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21650    (set (match_scratch:DI 2 "=&r") (const_int 0))
21651    (clobber (reg:CC FLAGS_REG))]
21652   "TARGET_64BIT"
21653   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21654   [(set_attr "type" "multi")])
21656 (define_insn "stack_tls_protect_set_si"
21657   [(set (match_operand:SI 0 "memory_operand" "=m")
21658         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21659    (set (match_scratch:SI 2 "=&r") (const_int 0))
21660    (clobber (reg:CC FLAGS_REG))]
21661   ""
21662   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21663   [(set_attr "type" "multi")])
21665 (define_insn "stack_tls_protect_set_di"
21666   [(set (match_operand:DI 0 "memory_operand" "=m")
21667         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21668    (set (match_scratch:DI 2 "=&r") (const_int 0))
21669    (clobber (reg:CC FLAGS_REG))]
21670   "TARGET_64BIT"
21671   {
21672      /* The kernel uses a different segment register for performance reasons; a
21673         system call would not have to trash the userspace segment register,
21674         which would be expensive */
21675      if (ix86_cmodel != CM_KERNEL)
21676         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21677      else
21678         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21679   }
21680   [(set_attr "type" "multi")])
21682 (define_expand "stack_protect_test"
21683   [(match_operand 0 "memory_operand" "")
21684    (match_operand 1 "memory_operand" "")
21685    (match_operand 2 "" "")]
21686   ""
21688   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21689   ix86_compare_op0 = operands[0];
21690   ix86_compare_op1 = operands[1];
21691   ix86_compare_emitted = flags;
21693 #ifdef TARGET_THREAD_SSP_OFFSET
21694   if (TARGET_64BIT)
21695     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21696                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21697   else
21698     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21699                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21700 #else
21701   if (TARGET_64BIT)
21702     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21703   else
21704     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21705 #endif
21706   emit_jump_insn (gen_beq (operands[2]));
21707   DONE;
21710 (define_insn "stack_protect_test_si"
21711   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21712         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21713                      (match_operand:SI 2 "memory_operand" "m")]
21714                     UNSPEC_SP_TEST))
21715    (clobber (match_scratch:SI 3 "=&r"))]
21716   ""
21717   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21718   [(set_attr "type" "multi")])
21720 (define_insn "stack_protect_test_di"
21721   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21722         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21723                      (match_operand:DI 2 "memory_operand" "m")]
21724                     UNSPEC_SP_TEST))
21725    (clobber (match_scratch:DI 3 "=&r"))]
21726   "TARGET_64BIT"
21727   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21728   [(set_attr "type" "multi")])
21730 (define_insn "stack_tls_protect_test_si"
21731   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21732         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21733                      (match_operand:SI 2 "const_int_operand" "i")]
21734                     UNSPEC_SP_TLS_TEST))
21735    (clobber (match_scratch:SI 3 "=r"))]
21736   ""
21737   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21738   [(set_attr "type" "multi")])
21740 (define_insn "stack_tls_protect_test_di"
21741   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21742         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21743                      (match_operand:DI 2 "const_int_operand" "i")]
21744                     UNSPEC_SP_TLS_TEST))
21745    (clobber (match_scratch:DI 3 "=r"))]
21746   "TARGET_64BIT"
21747   {
21748      /* The kernel uses a different segment register for performance reasons; a
21749         system call would not have to trash the userspace segment register,
21750         which would be expensive */
21751      if (ix86_cmodel != CM_KERNEL)
21752         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21753      else
21754         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21755   }
21756   [(set_attr "type" "multi")])
21758 (define_mode_iterator CRC32MODE [QI HI SI])
21759 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21760 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21762 (define_insn "sse4_2_crc32<mode>"
21763   [(set (match_operand:SI 0 "register_operand" "=r")
21764         (unspec:SI
21765           [(match_operand:SI 1 "register_operand" "0")
21766            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21767           UNSPEC_CRC32))]
21768   "TARGET_SSE4_2"
21769   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21770   [(set_attr "type" "sselog1")
21771    (set_attr "prefix_rep" "1")
21772    (set_attr "prefix_extra" "1")
21773    (set_attr "mode" "SI")])
21775 (define_insn "sse4_2_crc32di"
21776   [(set (match_operand:DI 0 "register_operand" "=r")
21777         (unspec:DI
21778           [(match_operand:DI 1 "register_operand" "0")
21779            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21780           UNSPEC_CRC32))]
21781   "TARGET_SSE4_2 && TARGET_64BIT"
21782   "crc32q\t{%2, %0|%0, %2}"
21783   [(set_attr "type" "sselog1")
21784    (set_attr "prefix_rep" "1")
21785    (set_attr "prefix_extra" "1")
21786    (set_attr "mode" "DI")])
21788 (include "mmx.md")
21789 (include "sse.md")
21790 (include "sync.md")