2008-05-30 Vladimir Makarov <vmakarov@redhat.com>
[official-gcc.git] / gcc / config / i386 / i386.md
blob885077d02b2eabc56ccb65a25b7196f7d9523915
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)
62    ; Prologue support
63    (UNSPEC_STACK_ALLOC          11)
64    (UNSPEC_SET_GOT              12)
65    (UNSPEC_SSE_PROLOGUE_SAVE    13)
66    (UNSPEC_REG_SAVE             14)
67    (UNSPEC_DEF_CFA              15)
68    (UNSPEC_SET_RIP              16)
69    (UNSPEC_SET_GOT_OFFSET       17)
71    ; TLS support
72    (UNSPEC_TP                   18)
73    (UNSPEC_TLS_GD               19)
74    (UNSPEC_TLS_LD_BASE          20)
75    (UNSPEC_TLSDESC              21)
77    ; Other random patterns
78    (UNSPEC_SCAS                 30)
79    (UNSPEC_FNSTSW               31)
80    (UNSPEC_SAHF                 32)
81    (UNSPEC_FSTCW                33)
82    (UNSPEC_ADD_CARRY            34)
83    (UNSPEC_FLDCW                35)
84    (UNSPEC_REP                  36)
85    (UNSPEC_EH_RETURN            37)
86    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
87    (UNSPEC_TRUNC_NOOP           39)
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          40)
91    (UNSPEC_MASKMOV              41)
92    (UNSPEC_MOVMSK               42)
93    (UNSPEC_MOVNT                43)
94    (UNSPEC_MOVU                 44)
95    (UNSPEC_RCP                  45)
96    (UNSPEC_RSQRT                46)
97    (UNSPEC_SFENCE               47)
98    (UNSPEC_PFRCP                49)
99    (UNSPEC_PFRCPIT1             40)
100    (UNSPEC_PFRCPIT2             41)
101    (UNSPEC_PFRSQRT              42)
102    (UNSPEC_PFRSQIT1             43)
103    (UNSPEC_MFENCE               44)
104    (UNSPEC_LFENCE               45)
105    (UNSPEC_PSADBW               46)
106    (UNSPEC_LDDQU                47)
108    ; Generic math support
109    (UNSPEC_COPYSIGN             50)
110    (UNSPEC_IEEE_MIN             51)     ; not commutative
111    (UNSPEC_IEEE_MAX             52)     ; not commutative
113    ; x87 Floating point
114    (UNSPEC_SIN                  60)
115    (UNSPEC_COS                  61)
116    (UNSPEC_FPATAN               62)
117    (UNSPEC_FYL2X                63)
118    (UNSPEC_FYL2XP1              64)
119    (UNSPEC_FRNDINT              65)
120    (UNSPEC_FIST                 66)
121    (UNSPEC_F2XM1                67)
122    (UNSPEC_TAN                  68)
123    (UNSPEC_FXAM                 69)
125    ; x87 Rounding
126    (UNSPEC_FRNDINT_FLOOR        70)
127    (UNSPEC_FRNDINT_CEIL         71)
128    (UNSPEC_FRNDINT_TRUNC        72)
129    (UNSPEC_FRNDINT_MASK_PM      73)
130    (UNSPEC_FIST_FLOOR           74)
131    (UNSPEC_FIST_CEIL            75)
133    ; x87 Double output FP
134    (UNSPEC_SINCOS_COS           80)
135    (UNSPEC_SINCOS_SIN           81)
136    (UNSPEC_XTRACT_FRACT         84)
137    (UNSPEC_XTRACT_EXP           85)
138    (UNSPEC_FSCALE_FRACT         86)
139    (UNSPEC_FSCALE_EXP           87)
140    (UNSPEC_FPREM_F              88)
141    (UNSPEC_FPREM_U              89)
142    (UNSPEC_FPREM1_F             90)
143    (UNSPEC_FPREM1_U             91)
145    (UNSPEC_C2_FLAG              95)
147    ; SSP patterns
148    (UNSPEC_SP_SET               100)
149    (UNSPEC_SP_TEST              101)
150    (UNSPEC_SP_TLS_SET           102)
151    (UNSPEC_SP_TLS_TEST          103)
153    ; SSSE3
154    (UNSPEC_PSHUFB               120)
155    (UNSPEC_PSIGN                121)
156    (UNSPEC_PALIGNR              122)
158    ; For SSE4A support
159    (UNSPEC_EXTRQI               130)
160    (UNSPEC_EXTRQ                131)
161    (UNSPEC_INSERTQI             132)
162    (UNSPEC_INSERTQ              133)
164    ; For SSE4.1 support
165    (UNSPEC_BLENDV               134)
166    (UNSPEC_INSERTPS             135)
167    (UNSPEC_DP                   136)
168    (UNSPEC_MOVNTDQA             137)
169    (UNSPEC_MPSADBW              138)
170    (UNSPEC_PHMINPOSUW           139)
171    (UNSPEC_PTEST                140)
172    (UNSPEC_ROUND                141)
174    ; For SSE4.2 support
175    (UNSPEC_CRC32                143)
176    (UNSPEC_PCMPESTR             144)
177    (UNSPEC_PCMPISTR             145)
179    ;; For SSE5
180    (UNSPEC_SSE5_INTRINSIC       150)
181    (UNSPEC_SSE5_UNSIGNED_CMP    151)
182    (UNSPEC_SSE5_TRUEFALSE       152)
183    (UNSPEC_SSE5_PERMUTE         153)
184    (UNSPEC_FRCZ                 154)
185    (UNSPEC_CVTPH2PS             155)
186    (UNSPEC_CVTPS2PH             156)
188    ; For AES support
189    (UNSPEC_AESENC               159)
190    (UNSPEC_AESENCLAST           160)
191    (UNSPEC_AESDEC               161)
192    (UNSPEC_AESDECLAST           162)
193    (UNSPEC_AESIMC               163)
194    (UNSPEC_AESKEYGENASSIST      164)
196    ; For PCLMUL support
197    (UNSPEC_PCLMUL               165)
198   ])
200 (define_constants
201   [(UNSPECV_BLOCKAGE            0)
202    (UNSPECV_STACK_PROBE         1)
203    (UNSPECV_EMMS                2)
204    (UNSPECV_LDMXCSR             3)
205    (UNSPECV_STMXCSR             4)
206    (UNSPECV_FEMMS               5)
207    (UNSPECV_CLFLUSH             6)
208    (UNSPECV_ALIGN               7)
209    (UNSPECV_MONITOR             8)
210    (UNSPECV_MWAIT               9)
211    (UNSPECV_CMPXCHG_1           10)
212    (UNSPECV_CMPXCHG_2           11)
213    (UNSPECV_XCHG                12)
214    (UNSPECV_LOCK                13)
215    (UNSPECV_PROLOGUE_USE        14)
216    (UNSPECV_CLD                 15)
217   ])
219 ;; Constants to represent pcomtrue/pcomfalse variants
220 (define_constants
221   [(PCOM_FALSE                  0)
222    (PCOM_TRUE                   1)
223    (COM_FALSE_S                 2)
224    (COM_FALSE_P                 3)
225    (COM_TRUE_S                  4)
226    (COM_TRUE_P                  5)
227   ])
229 ;; Constants used in the SSE5 pperm instruction
230 (define_constants
231   [(PPERM_SRC                   0x00)   /* copy source */
232    (PPERM_INVERT                0x20)   /* invert source */
233    (PPERM_REVERSE               0x40)   /* bit reverse source */
234    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
235    (PPERM_ZERO                  0x80)   /* all 0's */
236    (PPERM_ONES                  0xa0)   /* all 1's */
237    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
238    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
239    (PPERM_SRC1                  0x00)   /* use first source byte */
240    (PPERM_SRC2                  0x10)   /* use second source byte */
241    ])
243 ;; Registers by name.
244 (define_constants
245   [(AX_REG                       0)
246    (DX_REG                       1)
247    (CX_REG                       2)
248    (SI_REG                       4)
249    (DI_REG                       5)
250    (BP_REG                       6)
251    (SP_REG                       7)
252    (FLAGS_REG                   17)
253    (FPSR_REG                    18)
254    (FPCR_REG                    19)
255    (R10_REG                     39)
256    (R11_REG                     40)
257   ])
259 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
260 ;; from i386.c.
262 ;; In C guard expressions, put expressions which may be compile-time
263 ;; constants first.  This allows for better optimization.  For
264 ;; example, write "TARGET_64BIT && reload_completed", not
265 ;; "reload_completed && TARGET_64BIT".
268 ;; Processor type.  This attribute must exactly match the processor_type
269 ;; enumeration in i386.h.
270 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
271                     nocona,core2,generic32,generic64,amdfam10"
272   (const (symbol_ref "ix86_tune")))
274 ;; A basic instruction type.  Refinements due to arguments to be
275 ;; provided in other attributes.
276 (define_attr "type"
277   "other,multi,
278    alu,alu1,negnot,imov,imovx,lea,
279    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
280    icmp,test,ibr,setcc,icmov,
281    push,pop,call,callv,leave,
282    str,bitmanip,
283    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
284    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
285    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
286    ssemuladd,sse4arg,
287    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
288   (const_string "other"))
290 ;; Main data type used by the insn
291 (define_attr "mode"
292   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
293   (const_string "unknown"))
295 ;; The CPU unit operations uses.
296 (define_attr "unit" "integer,i387,sse,mmx,unknown"
297   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
298            (const_string "i387")
299          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
300                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
301                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
302            (const_string "sse")
303          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
304            (const_string "mmx")
305          (eq_attr "type" "other")
306            (const_string "unknown")]
307          (const_string "integer")))
309 ;; The (bounding maximum) length of an instruction immediate.
310 (define_attr "length_immediate" ""
311   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
312                           bitmanip")
313            (const_int 0)
314          (eq_attr "unit" "i387,sse,mmx")
315            (const_int 0)
316          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
317                           imul,icmp,push,pop")
318            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
319          (eq_attr "type" "imov,test")
320            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
321          (eq_attr "type" "call")
322            (if_then_else (match_operand 0 "constant_call_address_operand" "")
323              (const_int 4)
324              (const_int 0))
325          (eq_attr "type" "callv")
326            (if_then_else (match_operand 1 "constant_call_address_operand" "")
327              (const_int 4)
328              (const_int 0))
329          ;; We don't know the size before shorten_branches.  Expect
330          ;; the instruction to fit for better scheduling.
331          (eq_attr "type" "ibr")
332            (const_int 1)
333          ]
334          (symbol_ref "/* Update immediate_length and other attributes! */
335                       gcc_unreachable (),1")))
337 ;; The (bounding maximum) length of an instruction address.
338 (define_attr "length_address" ""
339   (cond [(eq_attr "type" "str,other,multi,fxch")
340            (const_int 0)
341          (and (eq_attr "type" "call")
342               (match_operand 0 "constant_call_address_operand" ""))
343              (const_int 0)
344          (and (eq_attr "type" "callv")
345               (match_operand 1 "constant_call_address_operand" ""))
346              (const_int 0)
347          ]
348          (symbol_ref "ix86_attr_length_address_default (insn)")))
350 ;; Set when length prefix is used.
351 (define_attr "prefix_data16" ""
352   (if_then_else (ior (eq_attr "mode" "HI")
353                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
354     (const_int 1)
355     (const_int 0)))
357 ;; Set when string REP prefix is used.
358 (define_attr "prefix_rep" ""
359   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
360     (const_int 1)
361     (const_int 0)))
363 ;; Set when 0f opcode prefix is used.
364 (define_attr "prefix_0f" ""
365   (if_then_else
366     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
367          (eq_attr "unit" "sse,mmx"))
368     (const_int 1)
369     (const_int 0)))
371 ;; Set when REX opcode prefix is used.
372 (define_attr "prefix_rex" ""
373   (cond [(and (eq_attr "mode" "DI")
374               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
375            (const_int 1)
376          (and (eq_attr "mode" "QI")
377               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
378                   (const_int 0)))
379            (const_int 1)
380          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
381              (const_int 0))
382            (const_int 1)
383         ]
384         (const_int 0)))
386 ;; There are also additional prefixes in SSSE3.
387 (define_attr "prefix_extra" "" (const_int 0))
389 ;; Set when modrm byte is used.
390 (define_attr "modrm" ""
391   (cond [(eq_attr "type" "str,leave")
392            (const_int 0)
393          (eq_attr "unit" "i387")
394            (const_int 0)
395          (and (eq_attr "type" "incdec")
396               (ior (match_operand:SI 1 "register_operand" "")
397                    (match_operand:HI 1 "register_operand" "")))
398            (const_int 0)
399          (and (eq_attr "type" "push")
400               (not (match_operand 1 "memory_operand" "")))
401            (const_int 0)
402          (and (eq_attr "type" "pop")
403               (not (match_operand 0 "memory_operand" "")))
404            (const_int 0)
405          (and (eq_attr "type" "imov")
406               (ior (and (match_operand 0 "register_operand" "")
407                         (match_operand 1 "immediate_operand" ""))
408                    (ior (and (match_operand 0 "ax_reg_operand" "")
409                              (match_operand 1 "memory_displacement_only_operand" ""))
410                         (and (match_operand 0 "memory_displacement_only_operand" "")
411                              (match_operand 1 "ax_reg_operand" "")))))
412            (const_int 0)
413          (and (eq_attr "type" "call")
414               (match_operand 0 "constant_call_address_operand" ""))
415              (const_int 0)
416          (and (eq_attr "type" "callv")
417               (match_operand 1 "constant_call_address_operand" ""))
418              (const_int 0)
419          ]
420          (const_int 1)))
422 ;; The (bounding maximum) length of an instruction in bytes.
423 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
424 ;; Later we may want to split them and compute proper length as for
425 ;; other insns.
426 (define_attr "length" ""
427   (cond [(eq_attr "type" "other,multi,fistp,frndint")
428            (const_int 16)
429          (eq_attr "type" "fcmp")
430            (const_int 4)
431          (eq_attr "unit" "i387")
432            (plus (const_int 2)
433                  (plus (attr "prefix_data16")
434                        (attr "length_address")))]
435          (plus (plus (attr "modrm")
436                      (plus (attr "prefix_0f")
437                            (plus (attr "prefix_rex")
438                                  (plus (attr "prefix_extra")
439                                        (const_int 1)))))
440                (plus (attr "prefix_rep")
441                      (plus (attr "prefix_data16")
442                            (plus (attr "length_immediate")
443                                  (attr "length_address")))))))
445 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
446 ;; `store' if there is a simple memory reference therein, or `unknown'
447 ;; if the instruction is complex.
449 (define_attr "memory" "none,load,store,both,unknown"
450   (cond [(eq_attr "type" "other,multi,str")
451            (const_string "unknown")
452          (eq_attr "type" "lea,fcmov,fpspc")
453            (const_string "none")
454          (eq_attr "type" "fistp,leave")
455            (const_string "both")
456          (eq_attr "type" "frndint")
457            (const_string "load")
458          (eq_attr "type" "push")
459            (if_then_else (match_operand 1 "memory_operand" "")
460              (const_string "both")
461              (const_string "store"))
462          (eq_attr "type" "pop")
463            (if_then_else (match_operand 0 "memory_operand" "")
464              (const_string "both")
465              (const_string "load"))
466          (eq_attr "type" "setcc")
467            (if_then_else (match_operand 0 "memory_operand" "")
468              (const_string "store")
469              (const_string "none"))
470          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
471            (if_then_else (ior (match_operand 0 "memory_operand" "")
472                               (match_operand 1 "memory_operand" ""))
473              (const_string "load")
474              (const_string "none"))
475          (eq_attr "type" "ibr")
476            (if_then_else (match_operand 0 "memory_operand" "")
477              (const_string "load")
478              (const_string "none"))
479          (eq_attr "type" "call")
480            (if_then_else (match_operand 0 "constant_call_address_operand" "")
481              (const_string "none")
482              (const_string "load"))
483          (eq_attr "type" "callv")
484            (if_then_else (match_operand 1 "constant_call_address_operand" "")
485              (const_string "none")
486              (const_string "load"))
487          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
488               (match_operand 1 "memory_operand" ""))
489            (const_string "both")
490          (and (match_operand 0 "memory_operand" "")
491               (match_operand 1 "memory_operand" ""))
492            (const_string "both")
493          (match_operand 0 "memory_operand" "")
494            (const_string "store")
495          (match_operand 1 "memory_operand" "")
496            (const_string "load")
497          (and (eq_attr "type"
498                  "!alu1,negnot,ishift1,
499                    imov,imovx,icmp,test,bitmanip,
500                    fmov,fcmp,fsgn,
501                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
502                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
503               (match_operand 2 "memory_operand" ""))
504            (const_string "load")
505          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
506               (match_operand 3 "memory_operand" ""))
507            (const_string "load")
508         ]
509         (const_string "none")))
511 ;; Indicates if an instruction has both an immediate and a displacement.
513 (define_attr "imm_disp" "false,true,unknown"
514   (cond [(eq_attr "type" "other,multi")
515            (const_string "unknown")
516          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
517               (and (match_operand 0 "memory_displacement_operand" "")
518                    (match_operand 1 "immediate_operand" "")))
519            (const_string "true")
520          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
521               (and (match_operand 0 "memory_displacement_operand" "")
522                    (match_operand 2 "immediate_operand" "")))
523            (const_string "true")
524         ]
525         (const_string "false")))
527 ;; Indicates if an FP operation has an integer source.
529 (define_attr "fp_int_src" "false,true"
530   (const_string "false"))
532 ;; Defines rounding mode of an FP operation.
534 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
535   (const_string "any"))
537 ;; Describe a user's asm statement.
538 (define_asm_attributes
539   [(set_attr "length" "128")
540    (set_attr "type" "multi")])
542 ;; All integer comparison codes.
543 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
545 ;; All floating-point comparison codes.
546 (define_code_iterator fp_cond [unordered ordered
547                                uneq unge ungt unle unlt ltgt ])
549 (define_code_iterator plusminus [plus minus])
551 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
553 ;; Base name for define_insn
554 (define_code_attr plusminus_insn
555   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
556    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
558 ;; Base name for insn mnemonic.
559 (define_code_attr plusminus_mnemonic
560   [(plus "add") (ss_plus "adds") (us_plus "addus")
561    (minus "sub") (ss_minus "subs") (us_minus "subus")])
563 ;; Mark commutative operators as such in constraints.
564 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
565                         (minus "") (ss_minus "") (us_minus "")])
567 ;; Mapping of signed max and min
568 (define_code_iterator smaxmin [smax smin])
570 ;; Mapping of unsigned max and min
571 (define_code_iterator umaxmin [umax umin])
573 ;; Base name for integer and FP insn mnemonic
574 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
575                                  (umax "maxu") (umin "minu")])
576 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
578 ;; Mapping of parallel logic operators
579 (define_code_iterator plogic [and ior xor])
581 ;; Base name for insn mnemonic.
582 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
584 ;; Mapping of abs neg operators
585 (define_code_iterator absneg [abs neg])
587 ;; Base name for x87 insn mnemonic.
588 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
590 ;; All single word integer modes.
591 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
593 ;; Instruction suffix for integer modes.
594 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
596 ;; Register class for integer modes.
597 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
599 ;; Immediate operand constraint for integer modes.
600 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
602 ;; General operand predicate for integer modes.
603 (define_mode_attr general_operand
604         [(QI "general_operand")
605          (HI "general_operand")
606          (SI "general_operand")
607          (DI "x86_64_general_operand")])
609 ;; SSE and x87 SFmode and DFmode floating point modes
610 (define_mode_iterator MODEF [SF DF])
612 ;; All x87 floating point modes
613 (define_mode_iterator X87MODEF [SF DF XF])
615 ;; All integer modes handled by x87 fisttp operator.
616 (define_mode_iterator X87MODEI [HI SI DI])
618 ;; All integer modes handled by integer x87 operators.
619 (define_mode_iterator X87MODEI12 [HI SI])
621 ;; All integer modes handled by SSE cvtts?2si* operators.
622 (define_mode_iterator SSEMODEI24 [SI DI])
624 ;; SSE asm suffix for floating point modes
625 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
627 ;; SSE vector mode corresponding to a scalar mode
628 (define_mode_attr ssevecmode
629   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
631 ;; Instruction suffix for REX 64bit operators.
632 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
634 ;; Scheduling descriptions
636 (include "pentium.md")
637 (include "ppro.md")
638 (include "k6.md")
639 (include "athlon.md")
640 (include "geode.md")
643 ;; Operand and operator predicates and constraints
645 (include "predicates.md")
646 (include "constraints.md")
649 ;; Compare instructions.
651 ;; All compare insns have expanders that save the operands away without
652 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
653 ;; after the cmp) will actually emit the cmpM.
655 (define_expand "cmpti"
656   [(set (reg:CC FLAGS_REG)
657         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
658                     (match_operand:TI 1 "x86_64_general_operand" "")))]
659   "TARGET_64BIT"
661   if (MEM_P (operands[0]) && MEM_P (operands[1]))
662     operands[0] = force_reg (TImode, operands[0]);
663   ix86_compare_op0 = operands[0];
664   ix86_compare_op1 = operands[1];
665   DONE;
668 (define_expand "cmpdi"
669   [(set (reg:CC FLAGS_REG)
670         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
671                     (match_operand:DI 1 "x86_64_general_operand" "")))]
672   ""
674   if (MEM_P (operands[0]) && MEM_P (operands[1]))
675     operands[0] = force_reg (DImode, operands[0]);
676   ix86_compare_op0 = operands[0];
677   ix86_compare_op1 = operands[1];
678   DONE;
681 (define_expand "cmpsi"
682   [(set (reg:CC FLAGS_REG)
683         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
684                     (match_operand:SI 1 "general_operand" "")))]
685   ""
687   if (MEM_P (operands[0]) && MEM_P (operands[1]))
688     operands[0] = force_reg (SImode, operands[0]);
689   ix86_compare_op0 = operands[0];
690   ix86_compare_op1 = operands[1];
691   DONE;
694 (define_expand "cmphi"
695   [(set (reg:CC FLAGS_REG)
696         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
697                     (match_operand:HI 1 "general_operand" "")))]
698   ""
700   if (MEM_P (operands[0]) && MEM_P (operands[1]))
701     operands[0] = force_reg (HImode, operands[0]);
702   ix86_compare_op0 = operands[0];
703   ix86_compare_op1 = operands[1];
704   DONE;
707 (define_expand "cmpqi"
708   [(set (reg:CC FLAGS_REG)
709         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
710                     (match_operand:QI 1 "general_operand" "")))]
711   "TARGET_QIMODE_MATH"
713   if (MEM_P (operands[0]) && MEM_P (operands[1]))
714     operands[0] = force_reg (QImode, operands[0]);
715   ix86_compare_op0 = operands[0];
716   ix86_compare_op1 = operands[1];
717   DONE;
720 (define_insn "cmpdi_ccno_1_rex64"
721   [(set (reg FLAGS_REG)
722         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
723                  (match_operand:DI 1 "const0_operand" "n,n")))]
724   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
725   "@
726    test{q}\t%0, %0
727    cmp{q}\t{%1, %0|%0, %1}"
728   [(set_attr "type" "test,icmp")
729    (set_attr "length_immediate" "0,1")
730    (set_attr "mode" "DI")])
732 (define_insn "*cmpdi_minus_1_rex64"
733   [(set (reg FLAGS_REG)
734         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
735                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
736                  (const_int 0)))]
737   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
738   "cmp{q}\t{%1, %0|%0, %1}"
739   [(set_attr "type" "icmp")
740    (set_attr "mode" "DI")])
742 (define_expand "cmpdi_1_rex64"
743   [(set (reg:CC FLAGS_REG)
744         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
745                     (match_operand:DI 1 "general_operand" "")))]
746   "TARGET_64BIT"
747   "")
749 (define_insn "cmpdi_1_insn_rex64"
750   [(set (reg FLAGS_REG)
751         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
752                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
753   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
754   "cmp{q}\t{%1, %0|%0, %1}"
755   [(set_attr "type" "icmp")
756    (set_attr "mode" "DI")])
759 (define_insn "*cmpsi_ccno_1"
760   [(set (reg FLAGS_REG)
761         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
762                  (match_operand:SI 1 "const0_operand" "n,n")))]
763   "ix86_match_ccmode (insn, CCNOmode)"
764   "@
765    test{l}\t%0, %0
766    cmp{l}\t{%1, %0|%0, %1}"
767   [(set_attr "type" "test,icmp")
768    (set_attr "length_immediate" "0,1")
769    (set_attr "mode" "SI")])
771 (define_insn "*cmpsi_minus_1"
772   [(set (reg FLAGS_REG)
773         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
774                            (match_operand:SI 1 "general_operand" "ri,mr"))
775                  (const_int 0)))]
776   "ix86_match_ccmode (insn, CCGOCmode)"
777   "cmp{l}\t{%1, %0|%0, %1}"
778   [(set_attr "type" "icmp")
779    (set_attr "mode" "SI")])
781 (define_expand "cmpsi_1"
782   [(set (reg:CC FLAGS_REG)
783         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
784                     (match_operand:SI 1 "general_operand" "")))]
785   ""
786   "")
788 (define_insn "*cmpsi_1_insn"
789   [(set (reg FLAGS_REG)
790         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
791                  (match_operand:SI 1 "general_operand" "ri,mr")))]
792   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
793     && ix86_match_ccmode (insn, CCmode)"
794   "cmp{l}\t{%1, %0|%0, %1}"
795   [(set_attr "type" "icmp")
796    (set_attr "mode" "SI")])
798 (define_insn "*cmphi_ccno_1"
799   [(set (reg FLAGS_REG)
800         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
801                  (match_operand:HI 1 "const0_operand" "n,n")))]
802   "ix86_match_ccmode (insn, CCNOmode)"
803   "@
804    test{w}\t%0, %0
805    cmp{w}\t{%1, %0|%0, %1}"
806   [(set_attr "type" "test,icmp")
807    (set_attr "length_immediate" "0,1")
808    (set_attr "mode" "HI")])
810 (define_insn "*cmphi_minus_1"
811   [(set (reg FLAGS_REG)
812         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
813                            (match_operand:HI 1 "general_operand" "ri,mr"))
814                  (const_int 0)))]
815   "ix86_match_ccmode (insn, CCGOCmode)"
816   "cmp{w}\t{%1, %0|%0, %1}"
817   [(set_attr "type" "icmp")
818    (set_attr "mode" "HI")])
820 (define_insn "*cmphi_1"
821   [(set (reg FLAGS_REG)
822         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
823                  (match_operand:HI 1 "general_operand" "ri,mr")))]
824   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
825    && ix86_match_ccmode (insn, CCmode)"
826   "cmp{w}\t{%1, %0|%0, %1}"
827   [(set_attr "type" "icmp")
828    (set_attr "mode" "HI")])
830 (define_insn "*cmpqi_ccno_1"
831   [(set (reg FLAGS_REG)
832         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
833                  (match_operand:QI 1 "const0_operand" "n,n")))]
834   "ix86_match_ccmode (insn, CCNOmode)"
835   "@
836    test{b}\t%0, %0
837    cmp{b}\t{$0, %0|%0, 0}"
838   [(set_attr "type" "test,icmp")
839    (set_attr "length_immediate" "0,1")
840    (set_attr "mode" "QI")])
842 (define_insn "*cmpqi_1"
843   [(set (reg FLAGS_REG)
844         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
845                  (match_operand:QI 1 "general_operand" "qi,mq")))]
846   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
847     && ix86_match_ccmode (insn, CCmode)"
848   "cmp{b}\t{%1, %0|%0, %1}"
849   [(set_attr "type" "icmp")
850    (set_attr "mode" "QI")])
852 (define_insn "*cmpqi_minus_1"
853   [(set (reg FLAGS_REG)
854         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
855                            (match_operand:QI 1 "general_operand" "qi,mq"))
856                  (const_int 0)))]
857   "ix86_match_ccmode (insn, CCGOCmode)"
858   "cmp{b}\t{%1, %0|%0, %1}"
859   [(set_attr "type" "icmp")
860    (set_attr "mode" "QI")])
862 (define_insn "*cmpqi_ext_1"
863   [(set (reg FLAGS_REG)
864         (compare
865           (match_operand:QI 0 "general_operand" "Qm")
866           (subreg:QI
867             (zero_extract:SI
868               (match_operand 1 "ext_register_operand" "Q")
869               (const_int 8)
870               (const_int 8)) 0)))]
871   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
872   "cmp{b}\t{%h1, %0|%0, %h1}"
873   [(set_attr "type" "icmp")
874    (set_attr "mode" "QI")])
876 (define_insn "*cmpqi_ext_1_rex64"
877   [(set (reg FLAGS_REG)
878         (compare
879           (match_operand:QI 0 "register_operand" "Q")
880           (subreg:QI
881             (zero_extract:SI
882               (match_operand 1 "ext_register_operand" "Q")
883               (const_int 8)
884               (const_int 8)) 0)))]
885   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
886   "cmp{b}\t{%h1, %0|%0, %h1}"
887   [(set_attr "type" "icmp")
888    (set_attr "mode" "QI")])
890 (define_insn "*cmpqi_ext_2"
891   [(set (reg FLAGS_REG)
892         (compare
893           (subreg:QI
894             (zero_extract:SI
895               (match_operand 0 "ext_register_operand" "Q")
896               (const_int 8)
897               (const_int 8)) 0)
898           (match_operand:QI 1 "const0_operand" "n")))]
899   "ix86_match_ccmode (insn, CCNOmode)"
900   "test{b}\t%h0, %h0"
901   [(set_attr "type" "test")
902    (set_attr "length_immediate" "0")
903    (set_attr "mode" "QI")])
905 (define_expand "cmpqi_ext_3"
906   [(set (reg:CC FLAGS_REG)
907         (compare:CC
908           (subreg:QI
909             (zero_extract:SI
910               (match_operand 0 "ext_register_operand" "")
911               (const_int 8)
912               (const_int 8)) 0)
913           (match_operand:QI 1 "general_operand" "")))]
914   ""
915   "")
917 (define_insn "cmpqi_ext_3_insn"
918   [(set (reg FLAGS_REG)
919         (compare
920           (subreg:QI
921             (zero_extract:SI
922               (match_operand 0 "ext_register_operand" "Q")
923               (const_int 8)
924               (const_int 8)) 0)
925           (match_operand:QI 1 "general_operand" "Qmn")))]
926   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
927   "cmp{b}\t{%1, %h0|%h0, %1}"
928   [(set_attr "type" "icmp")
929    (set_attr "mode" "QI")])
931 (define_insn "cmpqi_ext_3_insn_rex64"
932   [(set (reg FLAGS_REG)
933         (compare
934           (subreg:QI
935             (zero_extract:SI
936               (match_operand 0 "ext_register_operand" "Q")
937               (const_int 8)
938               (const_int 8)) 0)
939           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
940   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
941   "cmp{b}\t{%1, %h0|%h0, %1}"
942   [(set_attr "type" "icmp")
943    (set_attr "mode" "QI")])
945 (define_insn "*cmpqi_ext_4"
946   [(set (reg FLAGS_REG)
947         (compare
948           (subreg:QI
949             (zero_extract:SI
950               (match_operand 0 "ext_register_operand" "Q")
951               (const_int 8)
952               (const_int 8)) 0)
953           (subreg:QI
954             (zero_extract:SI
955               (match_operand 1 "ext_register_operand" "Q")
956               (const_int 8)
957               (const_int 8)) 0)))]
958   "ix86_match_ccmode (insn, CCmode)"
959   "cmp{b}\t{%h1, %h0|%h0, %h1}"
960   [(set_attr "type" "icmp")
961    (set_attr "mode" "QI")])
963 ;; These implement float point compares.
964 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
965 ;; which would allow mix and match FP modes on the compares.  Which is what
966 ;; the old patterns did, but with many more of them.
968 (define_expand "cmpxf"
969   [(set (reg:CC FLAGS_REG)
970         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
971                     (match_operand:XF 1 "nonmemory_operand" "")))]
972   "TARGET_80387"
974   ix86_compare_op0 = operands[0];
975   ix86_compare_op1 = operands[1];
976   DONE;
979 (define_expand "cmp<mode>"
980   [(set (reg:CC FLAGS_REG)
981         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
982                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
983   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
985   ix86_compare_op0 = operands[0];
986   ix86_compare_op1 = operands[1];
987   DONE;
990 ;; FP compares, step 1:
991 ;; Set the FP condition codes.
993 ;; CCFPmode     compare with exceptions
994 ;; CCFPUmode    compare with no exceptions
996 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
997 ;; used to manage the reg stack popping would not be preserved.
999 (define_insn "*cmpfp_0"
1000   [(set (match_operand:HI 0 "register_operand" "=a")
1001         (unspec:HI
1002           [(compare:CCFP
1003              (match_operand 1 "register_operand" "f")
1004              (match_operand 2 "const0_operand" "X"))]
1005         UNSPEC_FNSTSW))]
1006   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1007    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1008   "* return output_fp_compare (insn, operands, 0, 0);"
1009   [(set_attr "type" "multi")
1010    (set_attr "unit" "i387")
1011    (set (attr "mode")
1012      (cond [(match_operand:SF 1 "" "")
1013               (const_string "SF")
1014             (match_operand:DF 1 "" "")
1015               (const_string "DF")
1016            ]
1017            (const_string "XF")))])
1019 (define_insn_and_split "*cmpfp_0_cc"
1020   [(set (reg:CCFP FLAGS_REG)
1021         (compare:CCFP
1022           (match_operand 1 "register_operand" "f")
1023           (match_operand 2 "const0_operand" "X")))
1024    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1025   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1026    && TARGET_SAHF && !TARGET_CMOVE
1027    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1028   "#"
1029   "&& reload_completed"
1030   [(set (match_dup 0)
1031         (unspec:HI
1032           [(compare:CCFP (match_dup 1)(match_dup 2))]
1033         UNSPEC_FNSTSW))
1034    (set (reg:CC FLAGS_REG)
1035         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1036   ""
1037   [(set_attr "type" "multi")
1038    (set_attr "unit" "i387")
1039    (set (attr "mode")
1040      (cond [(match_operand:SF 1 "" "")
1041               (const_string "SF")
1042             (match_operand:DF 1 "" "")
1043               (const_string "DF")
1044            ]
1045            (const_string "XF")))])
1047 (define_insn "*cmpfp_xf"
1048   [(set (match_operand:HI 0 "register_operand" "=a")
1049         (unspec:HI
1050           [(compare:CCFP
1051              (match_operand:XF 1 "register_operand" "f")
1052              (match_operand:XF 2 "register_operand" "f"))]
1053           UNSPEC_FNSTSW))]
1054   "TARGET_80387"
1055   "* return output_fp_compare (insn, operands, 0, 0);"
1056   [(set_attr "type" "multi")
1057    (set_attr "unit" "i387")
1058    (set_attr "mode" "XF")])
1060 (define_insn_and_split "*cmpfp_xf_cc"
1061   [(set (reg:CCFP FLAGS_REG)
1062         (compare:CCFP
1063           (match_operand:XF 1 "register_operand" "f")
1064           (match_operand:XF 2 "register_operand" "f")))
1065    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1066   "TARGET_80387
1067    && TARGET_SAHF && !TARGET_CMOVE"
1068   "#"
1069   "&& reload_completed"
1070   [(set (match_dup 0)
1071         (unspec:HI
1072           [(compare:CCFP (match_dup 1)(match_dup 2))]
1073         UNSPEC_FNSTSW))
1074    (set (reg:CC FLAGS_REG)
1075         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1076   ""
1077   [(set_attr "type" "multi")
1078    (set_attr "unit" "i387")
1079    (set_attr "mode" "XF")])
1081 (define_insn "*cmpfp_<mode>"
1082   [(set (match_operand:HI 0 "register_operand" "=a")
1083         (unspec:HI
1084           [(compare:CCFP
1085              (match_operand:MODEF 1 "register_operand" "f")
1086              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1087           UNSPEC_FNSTSW))]
1088   "TARGET_80387"
1089   "* return output_fp_compare (insn, operands, 0, 0);"
1090   [(set_attr "type" "multi")
1091    (set_attr "unit" "i387")
1092    (set_attr "mode" "<MODE>")])
1094 (define_insn_and_split "*cmpfp_<mode>_cc"
1095   [(set (reg:CCFP FLAGS_REG)
1096         (compare:CCFP
1097           (match_operand:MODEF 1 "register_operand" "f")
1098           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1099    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1100   "TARGET_80387
1101    && TARGET_SAHF && !TARGET_CMOVE"
1102   "#"
1103   "&& reload_completed"
1104   [(set (match_dup 0)
1105         (unspec:HI
1106           [(compare:CCFP (match_dup 1)(match_dup 2))]
1107         UNSPEC_FNSTSW))
1108    (set (reg:CC FLAGS_REG)
1109         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1110   ""
1111   [(set_attr "type" "multi")
1112    (set_attr "unit" "i387")
1113    (set_attr "mode" "<MODE>")])
1115 (define_insn "*cmpfp_u"
1116   [(set (match_operand:HI 0 "register_operand" "=a")
1117         (unspec:HI
1118           [(compare:CCFPU
1119              (match_operand 1 "register_operand" "f")
1120              (match_operand 2 "register_operand" "f"))]
1121           UNSPEC_FNSTSW))]
1122   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1123    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1124   "* return output_fp_compare (insn, operands, 0, 1);"
1125   [(set_attr "type" "multi")
1126    (set_attr "unit" "i387")
1127    (set (attr "mode")
1128      (cond [(match_operand:SF 1 "" "")
1129               (const_string "SF")
1130             (match_operand:DF 1 "" "")
1131               (const_string "DF")
1132            ]
1133            (const_string "XF")))])
1135 (define_insn_and_split "*cmpfp_u_cc"
1136   [(set (reg:CCFPU FLAGS_REG)
1137         (compare:CCFPU
1138           (match_operand 1 "register_operand" "f")
1139           (match_operand 2 "register_operand" "f")))
1140    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1141   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1142    && TARGET_SAHF && !TARGET_CMOVE
1143    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1144   "#"
1145   "&& reload_completed"
1146   [(set (match_dup 0)
1147         (unspec:HI
1148           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1149         UNSPEC_FNSTSW))
1150    (set (reg:CC FLAGS_REG)
1151         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1152   ""
1153   [(set_attr "type" "multi")
1154    (set_attr "unit" "i387")
1155    (set (attr "mode")
1156      (cond [(match_operand:SF 1 "" "")
1157               (const_string "SF")
1158             (match_operand:DF 1 "" "")
1159               (const_string "DF")
1160            ]
1161            (const_string "XF")))])
1163 (define_insn "*cmpfp_<mode>"
1164   [(set (match_operand:HI 0 "register_operand" "=a")
1165         (unspec:HI
1166           [(compare:CCFP
1167              (match_operand 1 "register_operand" "f")
1168              (match_operator 3 "float_operator"
1169                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1170           UNSPEC_FNSTSW))]
1171   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1172    && TARGET_USE_<MODE>MODE_FIOP
1173    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1174   "* return output_fp_compare (insn, operands, 0, 0);"
1175   [(set_attr "type" "multi")
1176    (set_attr "unit" "i387")
1177    (set_attr "fp_int_src" "true")
1178    (set_attr "mode" "<MODE>")])
1180 (define_insn_and_split "*cmpfp_<mode>_cc"
1181   [(set (reg:CCFP FLAGS_REG)
1182         (compare:CCFP
1183           (match_operand 1 "register_operand" "f")
1184           (match_operator 3 "float_operator"
1185             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1186    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1187   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1188    && TARGET_SAHF && !TARGET_CMOVE
1189    && TARGET_USE_<MODE>MODE_FIOP
1190    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1191   "#"
1192   "&& reload_completed"
1193   [(set (match_dup 0)
1194         (unspec:HI
1195           [(compare:CCFP
1196              (match_dup 1)
1197              (match_op_dup 3 [(match_dup 2)]))]
1198         UNSPEC_FNSTSW))
1199    (set (reg:CC FLAGS_REG)
1200         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1201   ""
1202   [(set_attr "type" "multi")
1203    (set_attr "unit" "i387")
1204    (set_attr "fp_int_src" "true")
1205    (set_attr "mode" "<MODE>")])
1207 ;; FP compares, step 2
1208 ;; Move the fpsw to ax.
1210 (define_insn "x86_fnstsw_1"
1211   [(set (match_operand:HI 0 "register_operand" "=a")
1212         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1213   "TARGET_80387"
1214   "fnstsw\t%0"
1215   [(set_attr "length" "2")
1216    (set_attr "mode" "SI")
1217    (set_attr "unit" "i387")])
1219 ;; FP compares, step 3
1220 ;; Get ax into flags, general case.
1222 (define_insn "x86_sahf_1"
1223   [(set (reg:CC FLAGS_REG)
1224         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1225                    UNSPEC_SAHF))]
1226   "TARGET_SAHF"
1228 #ifdef HAVE_AS_IX86_SAHF
1229   return "sahf";
1230 #else
1231   return ".byte\t0x9e";
1232 #endif
1234   [(set_attr "length" "1")
1235    (set_attr "athlon_decode" "vector")
1236    (set_attr "amdfam10_decode" "direct")
1237    (set_attr "mode" "SI")])
1239 ;; Pentium Pro can do steps 1 through 3 in one go.
1240 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1241 (define_insn "*cmpfp_i_mixed"
1242   [(set (reg:CCFP FLAGS_REG)
1243         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1244                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1245   "TARGET_MIX_SSE_I387
1246    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1247    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1248   "* return output_fp_compare (insn, operands, 1, 0);"
1249   [(set_attr "type" "fcmp,ssecomi")
1250    (set (attr "mode")
1251      (if_then_else (match_operand:SF 1 "" "")
1252         (const_string "SF")
1253         (const_string "DF")))
1254    (set_attr "athlon_decode" "vector")
1255    (set_attr "amdfam10_decode" "direct")])
1257 (define_insn "*cmpfp_i_sse"
1258   [(set (reg:CCFP FLAGS_REG)
1259         (compare:CCFP (match_operand 0 "register_operand" "x")
1260                       (match_operand 1 "nonimmediate_operand" "xm")))]
1261   "TARGET_SSE_MATH
1262    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1263    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1264   "* return output_fp_compare (insn, operands, 1, 0);"
1265   [(set_attr "type" "ssecomi")
1266    (set (attr "mode")
1267      (if_then_else (match_operand:SF 1 "" "")
1268         (const_string "SF")
1269         (const_string "DF")))
1270    (set_attr "athlon_decode" "vector")
1271    (set_attr "amdfam10_decode" "direct")])
1273 (define_insn "*cmpfp_i_i387"
1274   [(set (reg:CCFP FLAGS_REG)
1275         (compare:CCFP (match_operand 0 "register_operand" "f")
1276                       (match_operand 1 "register_operand" "f")))]
1277   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1278    && TARGET_CMOVE
1279    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1280    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1281   "* return output_fp_compare (insn, operands, 1, 0);"
1282   [(set_attr "type" "fcmp")
1283    (set (attr "mode")
1284      (cond [(match_operand:SF 1 "" "")
1285               (const_string "SF")
1286             (match_operand:DF 1 "" "")
1287               (const_string "DF")
1288            ]
1289            (const_string "XF")))
1290    (set_attr "athlon_decode" "vector")
1291    (set_attr "amdfam10_decode" "direct")])
1293 (define_insn "*cmpfp_iu_mixed"
1294   [(set (reg:CCFPU FLAGS_REG)
1295         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1296                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1297   "TARGET_MIX_SSE_I387
1298    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1299    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1300   "* return output_fp_compare (insn, operands, 1, 1);"
1301   [(set_attr "type" "fcmp,ssecomi")
1302    (set (attr "mode")
1303      (if_then_else (match_operand:SF 1 "" "")
1304         (const_string "SF")
1305         (const_string "DF")))
1306    (set_attr "athlon_decode" "vector")
1307    (set_attr "amdfam10_decode" "direct")])
1309 (define_insn "*cmpfp_iu_sse"
1310   [(set (reg:CCFPU FLAGS_REG)
1311         (compare:CCFPU (match_operand 0 "register_operand" "x")
1312                        (match_operand 1 "nonimmediate_operand" "xm")))]
1313   "TARGET_SSE_MATH
1314    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1315    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1316   "* return output_fp_compare (insn, operands, 1, 1);"
1317   [(set_attr "type" "ssecomi")
1318    (set (attr "mode")
1319      (if_then_else (match_operand:SF 1 "" "")
1320         (const_string "SF")
1321         (const_string "DF")))
1322    (set_attr "athlon_decode" "vector")
1323    (set_attr "amdfam10_decode" "direct")])
1325 (define_insn "*cmpfp_iu_387"
1326   [(set (reg:CCFPU FLAGS_REG)
1327         (compare:CCFPU (match_operand 0 "register_operand" "f")
1328                        (match_operand 1 "register_operand" "f")))]
1329   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1330    && TARGET_CMOVE
1331    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1332    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1333   "* return output_fp_compare (insn, operands, 1, 1);"
1334   [(set_attr "type" "fcmp")
1335    (set (attr "mode")
1336      (cond [(match_operand:SF 1 "" "")
1337               (const_string "SF")
1338             (match_operand:DF 1 "" "")
1339               (const_string "DF")
1340            ]
1341            (const_string "XF")))
1342    (set_attr "athlon_decode" "vector")
1343    (set_attr "amdfam10_decode" "direct")])
1345 ;; Move instructions.
1347 ;; General case of fullword move.
1349 (define_expand "movsi"
1350   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1351         (match_operand:SI 1 "general_operand" ""))]
1352   ""
1353   "ix86_expand_move (SImode, operands); DONE;")
1355 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1356 ;; general_operand.
1358 ;; %%% We don't use a post-inc memory reference because x86 is not a
1359 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1360 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1361 ;; targets without our curiosities, and it is just as easy to represent
1362 ;; this differently.
1364 (define_insn "*pushsi2"
1365   [(set (match_operand:SI 0 "push_operand" "=<")
1366         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1367   "!TARGET_64BIT"
1368   "push{l}\t%1"
1369   [(set_attr "type" "push")
1370    (set_attr "mode" "SI")])
1372 ;; For 64BIT abi we always round up to 8 bytes.
1373 (define_insn "*pushsi2_rex64"
1374   [(set (match_operand:SI 0 "push_operand" "=X")
1375         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1376   "TARGET_64BIT"
1377   "push{q}\t%q1"
1378   [(set_attr "type" "push")
1379    (set_attr "mode" "SI")])
1381 (define_insn "*pushsi2_prologue"
1382   [(set (match_operand:SI 0 "push_operand" "=<")
1383         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1384    (clobber (mem:BLK (scratch)))]
1385   "!TARGET_64BIT"
1386   "push{l}\t%1"
1387   [(set_attr "type" "push")
1388    (set_attr "mode" "SI")])
1390 (define_insn "*popsi1_epilogue"
1391   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1392         (mem:SI (reg:SI SP_REG)))
1393    (set (reg:SI SP_REG)
1394         (plus:SI (reg:SI SP_REG) (const_int 4)))
1395    (clobber (mem:BLK (scratch)))]
1396   "!TARGET_64BIT"
1397   "pop{l}\t%0"
1398   [(set_attr "type" "pop")
1399    (set_attr "mode" "SI")])
1401 (define_insn "popsi1"
1402   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1403         (mem:SI (reg:SI SP_REG)))
1404    (set (reg:SI SP_REG)
1405         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1406   "!TARGET_64BIT"
1407   "pop{l}\t%0"
1408   [(set_attr "type" "pop")
1409    (set_attr "mode" "SI")])
1411 (define_insn "*movsi_xor"
1412   [(set (match_operand:SI 0 "register_operand" "=r")
1413         (match_operand:SI 1 "const0_operand" "i"))
1414    (clobber (reg:CC FLAGS_REG))]
1415   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1416   "xor{l}\t%0, %0"
1417   [(set_attr "type" "alu1")
1418    (set_attr "mode" "SI")
1419    (set_attr "length_immediate" "0")])
1421 (define_insn "*movsi_or"
1422   [(set (match_operand:SI 0 "register_operand" "=r")
1423         (match_operand:SI 1 "immediate_operand" "i"))
1424    (clobber (reg:CC FLAGS_REG))]
1425   "reload_completed
1426    && operands[1] == constm1_rtx
1427    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1429   operands[1] = constm1_rtx;
1430   return "or{l}\t{%1, %0|%0, %1}";
1432   [(set_attr "type" "alu1")
1433    (set_attr "mode" "SI")
1434    (set_attr "length_immediate" "1")])
1436 (define_insn "*movsi_1"
1437   [(set (match_operand:SI 0 "nonimmediate_operand"
1438                         "=r  ,m  ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1439         (match_operand:SI 1 "general_operand"
1440                         "rinm,rin,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1441   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1443   switch (get_attr_type (insn))
1444     {
1445     case TYPE_SSELOG1:
1446       if (get_attr_mode (insn) == MODE_TI)
1447         return "pxor\t%0, %0";
1448       return "xorps\t%0, %0";
1450     case TYPE_SSEMOV:
1451       switch (get_attr_mode (insn))
1452         {
1453         case MODE_TI:
1454           return "movdqa\t{%1, %0|%0, %1}";
1455         case MODE_V4SF:
1456           return "movaps\t{%1, %0|%0, %1}";
1457         case MODE_SI:
1458           return "movd\t{%1, %0|%0, %1}";
1459         case MODE_SF:
1460           return "movss\t{%1, %0|%0, %1}";
1461         default:
1462           gcc_unreachable ();
1463         }
1465     case TYPE_MMXADD:
1466       return "pxor\t%0, %0";
1468     case TYPE_MMXMOV:
1469       if (get_attr_mode (insn) == MODE_DI)
1470         return "movq\t{%1, %0|%0, %1}";
1471       return "movd\t{%1, %0|%0, %1}";
1473     case TYPE_LEA:
1474       return "lea{l}\t{%1, %0|%0, %1}";
1476     default:
1477       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1478       return "mov{l}\t{%1, %0|%0, %1}";
1479     }
1481   [(set (attr "type")
1482      (cond [(eq_attr "alternative" "2")
1483               (const_string "mmxadd")
1484             (eq_attr "alternative" "3,4,5")
1485               (const_string "mmxmov")
1486             (eq_attr "alternative" "6")
1487               (const_string "sselog1")
1488             (eq_attr "alternative" "7,8,9,10,11")
1489               (const_string "ssemov")
1490             (match_operand:DI 1 "pic_32bit_operand" "")
1491               (const_string "lea")
1492            ]
1493            (const_string "imov")))
1494    (set (attr "mode")
1495      (cond [(eq_attr "alternative" "2,3")
1496               (const_string "DI")
1497             (eq_attr "alternative" "6,7")
1498               (if_then_else
1499                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1500                 (const_string "V4SF")
1501                 (const_string "TI"))
1502             (and (eq_attr "alternative" "8,9,10,11")
1503                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1504               (const_string "SF")
1505            ]
1506            (const_string "SI")))])
1508 ;; Stores and loads of ax to arbitrary constant address.
1509 ;; We fake an second form of instruction to force reload to load address
1510 ;; into register when rax is not available
1511 (define_insn "*movabssi_1_rex64"
1512   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1513         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1514   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1515   "@
1516    movabs{l}\t{%1, %P0|%P0, %1}
1517    mov{l}\t{%1, %a0|%a0, %1}"
1518   [(set_attr "type" "imov")
1519    (set_attr "modrm" "0,*")
1520    (set_attr "length_address" "8,0")
1521    (set_attr "length_immediate" "0,*")
1522    (set_attr "memory" "store")
1523    (set_attr "mode" "SI")])
1525 (define_insn "*movabssi_2_rex64"
1526   [(set (match_operand:SI 0 "register_operand" "=a,r")
1527         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1528   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1529   "@
1530    movabs{l}\t{%P1, %0|%0, %P1}
1531    mov{l}\t{%a1, %0|%0, %a1}"
1532   [(set_attr "type" "imov")
1533    (set_attr "modrm" "0,*")
1534    (set_attr "length_address" "8,0")
1535    (set_attr "length_immediate" "0")
1536    (set_attr "memory" "load")
1537    (set_attr "mode" "SI")])
1539 (define_insn "*swapsi"
1540   [(set (match_operand:SI 0 "register_operand" "+r")
1541         (match_operand:SI 1 "register_operand" "+r"))
1542    (set (match_dup 1)
1543         (match_dup 0))]
1544   ""
1545   "xchg{l}\t%1, %0"
1546   [(set_attr "type" "imov")
1547    (set_attr "mode" "SI")
1548    (set_attr "pent_pair" "np")
1549    (set_attr "athlon_decode" "vector")
1550    (set_attr "amdfam10_decode" "double")])
1552 (define_expand "movhi"
1553   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1554         (match_operand:HI 1 "general_operand" ""))]
1555   ""
1556   "ix86_expand_move (HImode, operands); DONE;")
1558 (define_insn "*pushhi2"
1559   [(set (match_operand:HI 0 "push_operand" "=X")
1560         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1561   "!TARGET_64BIT"
1562   "push{l}\t%k1"
1563   [(set_attr "type" "push")
1564    (set_attr "mode" "SI")])
1566 ;; For 64BIT abi we always round up to 8 bytes.
1567 (define_insn "*pushhi2_rex64"
1568   [(set (match_operand:HI 0 "push_operand" "=X")
1569         (match_operand:HI 1 "nonmemory_no_elim_operand" "ri"))]
1570   "TARGET_64BIT"
1571   "push{q}\t%q1"
1572   [(set_attr "type" "push")
1573    (set_attr "mode" "DI")])
1575 (define_insn "*movhi_1"
1576   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1577         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1578   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1580   switch (get_attr_type (insn))
1581     {
1582     case TYPE_IMOVX:
1583       /* movzwl is faster than movw on p2 due to partial word stalls,
1584          though not as fast as an aligned movl.  */
1585       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1586     default:
1587       if (get_attr_mode (insn) == MODE_SI)
1588         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1589       else
1590         return "mov{w}\t{%1, %0|%0, %1}";
1591     }
1593   [(set (attr "type")
1594      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1595               (const_string "imov")
1596             (and (eq_attr "alternative" "0")
1597                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1598                           (const_int 0))
1599                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1600                           (const_int 0))))
1601               (const_string "imov")
1602             (and (eq_attr "alternative" "1,2")
1603                  (match_operand:HI 1 "aligned_operand" ""))
1604               (const_string "imov")
1605             (and (ne (symbol_ref "TARGET_MOVX")
1606                      (const_int 0))
1607                  (eq_attr "alternative" "0,2"))
1608               (const_string "imovx")
1609            ]
1610            (const_string "imov")))
1611     (set (attr "mode")
1612       (cond [(eq_attr "type" "imovx")
1613                (const_string "SI")
1614              (and (eq_attr "alternative" "1,2")
1615                   (match_operand:HI 1 "aligned_operand" ""))
1616                (const_string "SI")
1617              (and (eq_attr "alternative" "0")
1618                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1619                            (const_int 0))
1620                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1621                            (const_int 0))))
1622                (const_string "SI")
1623             ]
1624             (const_string "HI")))])
1626 ;; Stores and loads of ax to arbitrary constant address.
1627 ;; We fake an second form of instruction to force reload to load address
1628 ;; into register when rax is not available
1629 (define_insn "*movabshi_1_rex64"
1630   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1631         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1632   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1633   "@
1634    movabs{w}\t{%1, %P0|%P0, %1}
1635    mov{w}\t{%1, %a0|%a0, %1}"
1636   [(set_attr "type" "imov")
1637    (set_attr "modrm" "0,*")
1638    (set_attr "length_address" "8,0")
1639    (set_attr "length_immediate" "0,*")
1640    (set_attr "memory" "store")
1641    (set_attr "mode" "HI")])
1643 (define_insn "*movabshi_2_rex64"
1644   [(set (match_operand:HI 0 "register_operand" "=a,r")
1645         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1646   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1647   "@
1648    movabs{w}\t{%P1, %0|%0, %P1}
1649    mov{w}\t{%a1, %0|%0, %a1}"
1650   [(set_attr "type" "imov")
1651    (set_attr "modrm" "0,*")
1652    (set_attr "length_address" "8,0")
1653    (set_attr "length_immediate" "0")
1654    (set_attr "memory" "load")
1655    (set_attr "mode" "HI")])
1657 (define_insn "*swaphi_1"
1658   [(set (match_operand:HI 0 "register_operand" "+r")
1659         (match_operand:HI 1 "register_operand" "+r"))
1660    (set (match_dup 1)
1661         (match_dup 0))]
1662   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1663   "xchg{l}\t%k1, %k0"
1664   [(set_attr "type" "imov")
1665    (set_attr "mode" "SI")
1666    (set_attr "pent_pair" "np")
1667    (set_attr "athlon_decode" "vector")
1668    (set_attr "amdfam10_decode" "double")])
1670 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1671 (define_insn "*swaphi_2"
1672   [(set (match_operand:HI 0 "register_operand" "+r")
1673         (match_operand:HI 1 "register_operand" "+r"))
1674    (set (match_dup 1)
1675         (match_dup 0))]
1676   "TARGET_PARTIAL_REG_STALL"
1677   "xchg{w}\t%1, %0"
1678   [(set_attr "type" "imov")
1679    (set_attr "mode" "HI")
1680    (set_attr "pent_pair" "np")
1681    (set_attr "athlon_decode" "vector")])
1683 (define_expand "movstricthi"
1684   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1685         (match_operand:HI 1 "general_operand" ""))]
1686   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1688   /* Don't generate memory->memory moves, go through a register */
1689   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1690     operands[1] = force_reg (HImode, operands[1]);
1693 (define_insn "*movstricthi_1"
1694   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1695         (match_operand:HI 1 "general_operand" "rn,m"))]
1696   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1697    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1698   "mov{w}\t{%1, %0|%0, %1}"
1699   [(set_attr "type" "imov")
1700    (set_attr "mode" "HI")])
1702 (define_insn "*movstricthi_xor"
1703   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1704         (match_operand:HI 1 "const0_operand" "i"))
1705    (clobber (reg:CC FLAGS_REG))]
1706   "reload_completed
1707    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1708   "xor{w}\t%0, %0"
1709   [(set_attr "type" "alu1")
1710    (set_attr "mode" "HI")
1711    (set_attr "length_immediate" "0")])
1713 (define_expand "movqi"
1714   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1715         (match_operand:QI 1 "general_operand" ""))]
1716   ""
1717   "ix86_expand_move (QImode, operands); DONE;")
1719 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1720 ;; "push a byte".  But actually we use pushl, which has the effect
1721 ;; of rounding the amount pushed up to a word.
1723 (define_insn "*pushqi2"
1724   [(set (match_operand:QI 0 "push_operand" "=X")
1725         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1726   "!TARGET_64BIT"
1727   "push{l}\t%k1"
1728   [(set_attr "type" "push")
1729    (set_attr "mode" "SI")])
1731 ;; For 64BIT abi we always round up to 8 bytes.
1732 (define_insn "*pushqi2_rex64"
1733   [(set (match_operand:QI 0 "push_operand" "=X")
1734         (match_operand:QI 1 "nonmemory_no_elim_operand" "qi"))]
1735   "TARGET_64BIT"
1736   "push{q}\t%q1"
1737   [(set_attr "type" "push")
1738    (set_attr "mode" "DI")])
1740 ;; Situation is quite tricky about when to choose full sized (SImode) move
1741 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1742 ;; partial register dependency machines (such as AMD Athlon), where QImode
1743 ;; moves issue extra dependency and for partial register stalls machines
1744 ;; that don't use QImode patterns (and QImode move cause stall on the next
1745 ;; instruction).
1747 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1748 ;; register stall machines with, where we use QImode instructions, since
1749 ;; partial register stall can be caused there.  Then we use movzx.
1750 (define_insn "*movqi_1"
1751   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1752         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1753   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1755   switch (get_attr_type (insn))
1756     {
1757     case TYPE_IMOVX:
1758       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1759       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1760     default:
1761       if (get_attr_mode (insn) == MODE_SI)
1762         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1763       else
1764         return "mov{b}\t{%1, %0|%0, %1}";
1765     }
1767   [(set (attr "type")
1768      (cond [(and (eq_attr "alternative" "5")
1769                  (not (match_operand:QI 1 "aligned_operand" "")))
1770               (const_string "imovx")
1771             (ne (symbol_ref "optimize_size") (const_int 0))
1772               (const_string "imov")
1773             (and (eq_attr "alternative" "3")
1774                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1775                           (const_int 0))
1776                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1777                           (const_int 0))))
1778               (const_string "imov")
1779             (eq_attr "alternative" "3,5")
1780               (const_string "imovx")
1781             (and (ne (symbol_ref "TARGET_MOVX")
1782                      (const_int 0))
1783                  (eq_attr "alternative" "2"))
1784               (const_string "imovx")
1785            ]
1786            (const_string "imov")))
1787    (set (attr "mode")
1788       (cond [(eq_attr "alternative" "3,4,5")
1789                (const_string "SI")
1790              (eq_attr "alternative" "6")
1791                (const_string "QI")
1792              (eq_attr "type" "imovx")
1793                (const_string "SI")
1794              (and (eq_attr "type" "imov")
1795                   (and (eq_attr "alternative" "0,1")
1796                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1797                                 (const_int 0))
1798                             (and (eq (symbol_ref "optimize_size")
1799                                      (const_int 0))
1800                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1801                                      (const_int 0))))))
1802                (const_string "SI")
1803              ;; Avoid partial register stalls when not using QImode arithmetic
1804              (and (eq_attr "type" "imov")
1805                   (and (eq_attr "alternative" "0,1")
1806                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1807                                 (const_int 0))
1808                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1809                                 (const_int 0)))))
1810                (const_string "SI")
1811            ]
1812            (const_string "QI")))])
1814 (define_insn "*swapqi_1"
1815   [(set (match_operand:QI 0 "register_operand" "+r")
1816         (match_operand:QI 1 "register_operand" "+r"))
1817    (set (match_dup 1)
1818         (match_dup 0))]
1819   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1820   "xchg{l}\t%k1, %k0"
1821   [(set_attr "type" "imov")
1822    (set_attr "mode" "SI")
1823    (set_attr "pent_pair" "np")
1824    (set_attr "athlon_decode" "vector")
1825    (set_attr "amdfam10_decode" "vector")])
1827 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1828 (define_insn "*swapqi_2"
1829   [(set (match_operand:QI 0 "register_operand" "+q")
1830         (match_operand:QI 1 "register_operand" "+q"))
1831    (set (match_dup 1)
1832         (match_dup 0))]
1833   "TARGET_PARTIAL_REG_STALL"
1834   "xchg{b}\t%1, %0"
1835   [(set_attr "type" "imov")
1836    (set_attr "mode" "QI")
1837    (set_attr "pent_pair" "np")
1838    (set_attr "athlon_decode" "vector")])
1840 (define_expand "movstrictqi"
1841   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1842         (match_operand:QI 1 "general_operand" ""))]
1843   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1845   /* Don't generate memory->memory moves, go through a register.  */
1846   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1847     operands[1] = force_reg (QImode, operands[1]);
1850 (define_insn "*movstrictqi_1"
1851   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1852         (match_operand:QI 1 "general_operand" "*qn,m"))]
1853   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1854    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1855   "mov{b}\t{%1, %0|%0, %1}"
1856   [(set_attr "type" "imov")
1857    (set_attr "mode" "QI")])
1859 (define_insn "*movstrictqi_xor"
1860   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1861         (match_operand:QI 1 "const0_operand" "i"))
1862    (clobber (reg:CC FLAGS_REG))]
1863   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1864   "xor{b}\t%0, %0"
1865   [(set_attr "type" "alu1")
1866    (set_attr "mode" "QI")
1867    (set_attr "length_immediate" "0")])
1869 (define_insn "*movsi_extv_1"
1870   [(set (match_operand:SI 0 "register_operand" "=R")
1871         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1872                          (const_int 8)
1873                          (const_int 8)))]
1874   ""
1875   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1876   [(set_attr "type" "imovx")
1877    (set_attr "mode" "SI")])
1879 (define_insn "*movhi_extv_1"
1880   [(set (match_operand:HI 0 "register_operand" "=R")
1881         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1882                          (const_int 8)
1883                          (const_int 8)))]
1884   ""
1885   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1886   [(set_attr "type" "imovx")
1887    (set_attr "mode" "SI")])
1889 (define_insn "*movqi_extv_1"
1890   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1891         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1892                          (const_int 8)
1893                          (const_int 8)))]
1894   "!TARGET_64BIT"
1896   switch (get_attr_type (insn))
1897     {
1898     case TYPE_IMOVX:
1899       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1900     default:
1901       return "mov{b}\t{%h1, %0|%0, %h1}";
1902     }
1904   [(set (attr "type")
1905      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1906                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1907                              (ne (symbol_ref "TARGET_MOVX")
1908                                  (const_int 0))))
1909         (const_string "imovx")
1910         (const_string "imov")))
1911    (set (attr "mode")
1912      (if_then_else (eq_attr "type" "imovx")
1913         (const_string "SI")
1914         (const_string "QI")))])
1916 (define_insn "*movqi_extv_1_rex64"
1917   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1918         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1919                          (const_int 8)
1920                          (const_int 8)))]
1921   "TARGET_64BIT"
1923   switch (get_attr_type (insn))
1924     {
1925     case TYPE_IMOVX:
1926       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1927     default:
1928       return "mov{b}\t{%h1, %0|%0, %h1}";
1929     }
1931   [(set (attr "type")
1932      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1933                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1934                              (ne (symbol_ref "TARGET_MOVX")
1935                                  (const_int 0))))
1936         (const_string "imovx")
1937         (const_string "imov")))
1938    (set (attr "mode")
1939      (if_then_else (eq_attr "type" "imovx")
1940         (const_string "SI")
1941         (const_string "QI")))])
1943 ;; Stores and loads of ax to arbitrary constant address.
1944 ;; We fake an second form of instruction to force reload to load address
1945 ;; into register when rax is not available
1946 (define_insn "*movabsqi_1_rex64"
1947   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1948         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1949   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1950   "@
1951    movabs{b}\t{%1, %P0|%P0, %1}
1952    mov{b}\t{%1, %a0|%a0, %1}"
1953   [(set_attr "type" "imov")
1954    (set_attr "modrm" "0,*")
1955    (set_attr "length_address" "8,0")
1956    (set_attr "length_immediate" "0,*")
1957    (set_attr "memory" "store")
1958    (set_attr "mode" "QI")])
1960 (define_insn "*movabsqi_2_rex64"
1961   [(set (match_operand:QI 0 "register_operand" "=a,r")
1962         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1963   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1964   "@
1965    movabs{b}\t{%P1, %0|%0, %P1}
1966    mov{b}\t{%a1, %0|%0, %a1}"
1967   [(set_attr "type" "imov")
1968    (set_attr "modrm" "0,*")
1969    (set_attr "length_address" "8,0")
1970    (set_attr "length_immediate" "0")
1971    (set_attr "memory" "load")
1972    (set_attr "mode" "QI")])
1974 (define_insn "*movdi_extzv_1"
1975   [(set (match_operand:DI 0 "register_operand" "=R")
1976         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1977                          (const_int 8)
1978                          (const_int 8)))]
1979   "TARGET_64BIT"
1980   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1981   [(set_attr "type" "imovx")
1982    (set_attr "mode" "DI")])
1984 (define_insn "*movsi_extzv_1"
1985   [(set (match_operand:SI 0 "register_operand" "=R")
1986         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1987                          (const_int 8)
1988                          (const_int 8)))]
1989   ""
1990   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1991   [(set_attr "type" "imovx")
1992    (set_attr "mode" "SI")])
1994 (define_insn "*movqi_extzv_2"
1995   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
1996         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
1997                                     (const_int 8)
1998                                     (const_int 8)) 0))]
1999   "!TARGET_64BIT"
2001   switch (get_attr_type (insn))
2002     {
2003     case TYPE_IMOVX:
2004       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2005     default:
2006       return "mov{b}\t{%h1, %0|%0, %h1}";
2007     }
2009   [(set (attr "type")
2010      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2011                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2012                              (ne (symbol_ref "TARGET_MOVX")
2013                                  (const_int 0))))
2014         (const_string "imovx")
2015         (const_string "imov")))
2016    (set (attr "mode")
2017      (if_then_else (eq_attr "type" "imovx")
2018         (const_string "SI")
2019         (const_string "QI")))])
2021 (define_insn "*movqi_extzv_2_rex64"
2022   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2023         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2024                                     (const_int 8)
2025                                     (const_int 8)) 0))]
2026   "TARGET_64BIT"
2028   switch (get_attr_type (insn))
2029     {
2030     case TYPE_IMOVX:
2031       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2032     default:
2033       return "mov{b}\t{%h1, %0|%0, %h1}";
2034     }
2036   [(set (attr "type")
2037      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2038                         (ne (symbol_ref "TARGET_MOVX")
2039                             (const_int 0)))
2040         (const_string "imovx")
2041         (const_string "imov")))
2042    (set (attr "mode")
2043      (if_then_else (eq_attr "type" "imovx")
2044         (const_string "SI")
2045         (const_string "QI")))])
2047 (define_insn "movsi_insv_1"
2048   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2049                          (const_int 8)
2050                          (const_int 8))
2051         (match_operand:SI 1 "general_operand" "Qmn"))]
2052   "!TARGET_64BIT"
2053   "mov{b}\t{%b1, %h0|%h0, %b1}"
2054   [(set_attr "type" "imov")
2055    (set_attr "mode" "QI")])
2057 (define_insn "*movsi_insv_1_rex64"
2058   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2059                          (const_int 8)
2060                          (const_int 8))
2061         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2062   "TARGET_64BIT"
2063   "mov{b}\t{%b1, %h0|%h0, %b1}"
2064   [(set_attr "type" "imov")
2065    (set_attr "mode" "QI")])
2067 (define_insn "movdi_insv_1_rex64"
2068   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2069                          (const_int 8)
2070                          (const_int 8))
2071         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2072   "TARGET_64BIT"
2073   "mov{b}\t{%b1, %h0|%h0, %b1}"
2074   [(set_attr "type" "imov")
2075    (set_attr "mode" "QI")])
2077 (define_insn "*movqi_insv_2"
2078   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2079                          (const_int 8)
2080                          (const_int 8))
2081         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2082                      (const_int 8)))]
2083   ""
2084   "mov{b}\t{%h1, %h0|%h0, %h1}"
2085   [(set_attr "type" "imov")
2086    (set_attr "mode" "QI")])
2088 (define_expand "movdi"
2089   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2090         (match_operand:DI 1 "general_operand" ""))]
2091   ""
2092   "ix86_expand_move (DImode, operands); DONE;")
2094 (define_insn "*pushdi"
2095   [(set (match_operand:DI 0 "push_operand" "=<")
2096         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2097   "!TARGET_64BIT"
2098   "#")
2100 (define_insn "*pushdi2_rex64"
2101   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2102         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2103   "TARGET_64BIT"
2104   "@
2105    push{q}\t%1
2106    #"
2107   [(set_attr "type" "push,multi")
2108    (set_attr "mode" "DI")])
2110 ;; Convert impossible pushes of immediate to existing instructions.
2111 ;; First try to get scratch register and go through it.  In case this
2112 ;; fails, push sign extended lower part first and then overwrite
2113 ;; upper part by 32bit move.
2114 (define_peephole2
2115   [(match_scratch:DI 2 "r")
2116    (set (match_operand:DI 0 "push_operand" "")
2117         (match_operand:DI 1 "immediate_operand" ""))]
2118   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2119    && !x86_64_immediate_operand (operands[1], DImode)"
2120   [(set (match_dup 2) (match_dup 1))
2121    (set (match_dup 0) (match_dup 2))]
2122   "")
2124 ;; We need to define this as both peepholer and splitter for case
2125 ;; peephole2 pass is not run.
2126 ;; "&& 1" is needed to keep it from matching the previous pattern.
2127 (define_peephole2
2128   [(set (match_operand:DI 0 "push_operand" "")
2129         (match_operand:DI 1 "immediate_operand" ""))]
2130   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2131    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2132   [(set (match_dup 0) (match_dup 1))
2133    (set (match_dup 2) (match_dup 3))]
2134   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2135    operands[1] = gen_lowpart (DImode, operands[2]);
2136    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2137                                                     GEN_INT (4)));
2138   ")
2140 (define_split
2141   [(set (match_operand:DI 0 "push_operand" "")
2142         (match_operand:DI 1 "immediate_operand" ""))]
2143   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2144                     ? epilogue_completed : reload_completed)
2145    && !symbolic_operand (operands[1], DImode)
2146    && !x86_64_immediate_operand (operands[1], DImode)"
2147   [(set (match_dup 0) (match_dup 1))
2148    (set (match_dup 2) (match_dup 3))]
2149   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2150    operands[1] = gen_lowpart (DImode, operands[2]);
2151    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2152                                                     GEN_INT (4)));
2153   ")
2155 (define_insn "*pushdi2_prologue_rex64"
2156   [(set (match_operand:DI 0 "push_operand" "=<")
2157         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2158    (clobber (mem:BLK (scratch)))]
2159   "TARGET_64BIT"
2160   "push{q}\t%1"
2161   [(set_attr "type" "push")
2162    (set_attr "mode" "DI")])
2164 (define_insn "*popdi1_epilogue_rex64"
2165   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2166         (mem:DI (reg:DI SP_REG)))
2167    (set (reg:DI SP_REG)
2168         (plus:DI (reg:DI SP_REG) (const_int 8)))
2169    (clobber (mem:BLK (scratch)))]
2170   "TARGET_64BIT"
2171   "pop{q}\t%0"
2172   [(set_attr "type" "pop")
2173    (set_attr "mode" "DI")])
2175 (define_insn "popdi1"
2176   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2177         (mem:DI (reg:DI SP_REG)))
2178    (set (reg:DI SP_REG)
2179         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2180   "TARGET_64BIT"
2181   "pop{q}\t%0"
2182   [(set_attr "type" "pop")
2183    (set_attr "mode" "DI")])
2185 (define_insn "*movdi_xor_rex64"
2186   [(set (match_operand:DI 0 "register_operand" "=r")
2187         (match_operand:DI 1 "const0_operand" "i"))
2188    (clobber (reg:CC FLAGS_REG))]
2189   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2190    && reload_completed"
2191   "xor{l}\t%k0, %k0";
2192   [(set_attr "type" "alu1")
2193    (set_attr "mode" "SI")
2194    (set_attr "length_immediate" "0")])
2196 (define_insn "*movdi_or_rex64"
2197   [(set (match_operand:DI 0 "register_operand" "=r")
2198         (match_operand:DI 1 "const_int_operand" "i"))
2199    (clobber (reg:CC FLAGS_REG))]
2200   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2201    && reload_completed
2202    && operands[1] == constm1_rtx"
2204   operands[1] = constm1_rtx;
2205   return "or{q}\t{%1, %0|%0, %1}";
2207   [(set_attr "type" "alu1")
2208    (set_attr "mode" "DI")
2209    (set_attr "length_immediate" "1")])
2211 (define_insn "*movdi_2"
2212   [(set (match_operand:DI 0 "nonimmediate_operand"
2213                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2214         (match_operand:DI 1 "general_operand"
2215                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2216   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2217   "@
2218    #
2219    #
2220    pxor\t%0, %0
2221    movq\t{%1, %0|%0, %1}
2222    movq\t{%1, %0|%0, %1}
2223    pxor\t%0, %0
2224    movq\t{%1, %0|%0, %1}
2225    movdqa\t{%1, %0|%0, %1}
2226    movq\t{%1, %0|%0, %1}
2227    xorps\t%0, %0
2228    movlps\t{%1, %0|%0, %1}
2229    movaps\t{%1, %0|%0, %1}
2230    movlps\t{%1, %0|%0, %1}"
2231   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2232    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2234 (define_split
2235   [(set (match_operand:DI 0 "push_operand" "")
2236         (match_operand:DI 1 "general_operand" ""))]
2237   "!TARGET_64BIT && reload_completed
2238    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2239   [(const_int 0)]
2240   "ix86_split_long_move (operands); DONE;")
2242 ;; %%% This multiword shite has got to go.
2243 (define_split
2244   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2245         (match_operand:DI 1 "general_operand" ""))]
2246   "!TARGET_64BIT && reload_completed
2247    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2248    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2249   [(const_int 0)]
2250   "ix86_split_long_move (operands); DONE;")
2252 (define_insn "*movdi_1_rex64"
2253   [(set (match_operand:DI 0 "nonimmediate_operand"
2254           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2255         (match_operand:DI 1 "general_operand"
2256           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2257   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2259   switch (get_attr_type (insn))
2260     {
2261     case TYPE_SSECVT:
2262       if (SSE_REG_P (operands[0]))
2263         return "movq2dq\t{%1, %0|%0, %1}";
2264       else
2265         return "movdq2q\t{%1, %0|%0, %1}";
2267     case TYPE_SSEMOV:
2268       if (get_attr_mode (insn) == MODE_TI)
2269         return "movdqa\t{%1, %0|%0, %1}";
2270       /* FALLTHRU */
2272     case TYPE_MMXMOV:
2273       /* Moves from and into integer register is done using movd
2274          opcode with REX prefix.  */
2275       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2276         return "movd\t{%1, %0|%0, %1}";
2277       return "movq\t{%1, %0|%0, %1}";
2279     case TYPE_SSELOG1:
2280     case TYPE_MMXADD:
2281       return "pxor\t%0, %0";
2283     case TYPE_MULTI:
2284       return "#";
2286     case TYPE_LEA:
2287       return "lea{q}\t{%a1, %0|%0, %a1}";
2289     default:
2290       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2291       if (get_attr_mode (insn) == MODE_SI)
2292         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2293       else if (which_alternative == 2)
2294         return "movabs{q}\t{%1, %0|%0, %1}";
2295       else
2296         return "mov{q}\t{%1, %0|%0, %1}";
2297     }
2299   [(set (attr "type")
2300      (cond [(eq_attr "alternative" "5")
2301               (const_string "mmxadd")
2302             (eq_attr "alternative" "6,7,8,9,10")
2303               (const_string "mmxmov")
2304             (eq_attr "alternative" "11")
2305               (const_string "sselog1")
2306             (eq_attr "alternative" "12,13,14,15,16")
2307               (const_string "ssemov")
2308             (eq_attr "alternative" "17,18")
2309               (const_string "ssecvt")
2310             (eq_attr "alternative" "4")
2311               (const_string "multi")
2312             (match_operand:DI 1 "pic_32bit_operand" "")
2313               (const_string "lea")
2314            ]
2315            (const_string "imov")))
2316    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2317    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2318    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2320 ;; Stores and loads of ax to arbitrary constant address.
2321 ;; We fake an second form of instruction to force reload to load address
2322 ;; into register when rax is not available
2323 (define_insn "*movabsdi_1_rex64"
2324   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2325         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2326   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2327   "@
2328    movabs{q}\t{%1, %P0|%P0, %1}
2329    mov{q}\t{%1, %a0|%a0, %1}"
2330   [(set_attr "type" "imov")
2331    (set_attr "modrm" "0,*")
2332    (set_attr "length_address" "8,0")
2333    (set_attr "length_immediate" "0,*")
2334    (set_attr "memory" "store")
2335    (set_attr "mode" "DI")])
2337 (define_insn "*movabsdi_2_rex64"
2338   [(set (match_operand:DI 0 "register_operand" "=a,r")
2339         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2340   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2341   "@
2342    movabs{q}\t{%P1, %0|%0, %P1}
2343    mov{q}\t{%a1, %0|%0, %a1}"
2344   [(set_attr "type" "imov")
2345    (set_attr "modrm" "0,*")
2346    (set_attr "length_address" "8,0")
2347    (set_attr "length_immediate" "0")
2348    (set_attr "memory" "load")
2349    (set_attr "mode" "DI")])
2351 ;; Convert impossible stores of immediate to existing instructions.
2352 ;; First try to get scratch register and go through it.  In case this
2353 ;; fails, move by 32bit parts.
2354 (define_peephole2
2355   [(match_scratch:DI 2 "r")
2356    (set (match_operand:DI 0 "memory_operand" "")
2357         (match_operand:DI 1 "immediate_operand" ""))]
2358   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2359    && !x86_64_immediate_operand (operands[1], DImode)"
2360   [(set (match_dup 2) (match_dup 1))
2361    (set (match_dup 0) (match_dup 2))]
2362   "")
2364 ;; We need to define this as both peepholer and splitter for case
2365 ;; peephole2 pass is not run.
2366 ;; "&& 1" is needed to keep it from matching the previous pattern.
2367 (define_peephole2
2368   [(set (match_operand:DI 0 "memory_operand" "")
2369         (match_operand:DI 1 "immediate_operand" ""))]
2370   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2371    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2372   [(set (match_dup 2) (match_dup 3))
2373    (set (match_dup 4) (match_dup 5))]
2374   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2376 (define_split
2377   [(set (match_operand:DI 0 "memory_operand" "")
2378         (match_operand:DI 1 "immediate_operand" ""))]
2379   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2380                     ? epilogue_completed : reload_completed)
2381    && !symbolic_operand (operands[1], DImode)
2382    && !x86_64_immediate_operand (operands[1], DImode)"
2383   [(set (match_dup 2) (match_dup 3))
2384    (set (match_dup 4) (match_dup 5))]
2385   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2387 (define_insn "*swapdi_rex64"
2388   [(set (match_operand:DI 0 "register_operand" "+r")
2389         (match_operand:DI 1 "register_operand" "+r"))
2390    (set (match_dup 1)
2391         (match_dup 0))]
2392   "TARGET_64BIT"
2393   "xchg{q}\t%1, %0"
2394   [(set_attr "type" "imov")
2395    (set_attr "mode" "DI")
2396    (set_attr "pent_pair" "np")
2397    (set_attr "athlon_decode" "vector")
2398    (set_attr "amdfam10_decode" "double")])
2400 (define_expand "movti"
2401   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2402         (match_operand:TI 1 "nonimmediate_operand" ""))]
2403   "TARGET_SSE || TARGET_64BIT"
2405   if (TARGET_64BIT)
2406     ix86_expand_move (TImode, operands);
2407   else if (push_operand (operands[0], TImode))
2408     ix86_expand_push (TImode, operands[1]);
2409   else
2410     ix86_expand_vector_move (TImode, operands);
2411   DONE;
2414 (define_insn "*movti_internal"
2415   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2416         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2417   "TARGET_SSE && !TARGET_64BIT
2418    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2420   switch (which_alternative)
2421     {
2422     case 0:
2423       if (get_attr_mode (insn) == MODE_V4SF)
2424         return "xorps\t%0, %0";
2425       else
2426         return "pxor\t%0, %0";
2427     case 1:
2428     case 2:
2429       /* TDmode values are passed as TImode on the stack.  Moving them
2430          to stack may result in unaligned memory access.  */
2431       if (misaligned_operand (operands[0], TImode)
2432           || misaligned_operand (operands[1], TImode))
2433         { 
2434           if (get_attr_mode (insn) == MODE_V4SF)
2435             return "movups\t{%1, %0|%0, %1}";
2436          else
2437            return "movdqu\t{%1, %0|%0, %1}";
2438         }
2439       else
2440         { 
2441           if (get_attr_mode (insn) == MODE_V4SF)
2442             return "movaps\t{%1, %0|%0, %1}";
2443          else
2444            return "movdqa\t{%1, %0|%0, %1}";
2445         }
2446     default:
2447       gcc_unreachable ();
2448     }
2450   [(set_attr "type" "sselog1,ssemov,ssemov")
2451    (set (attr "mode")
2452         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2453                     (ne (symbol_ref "optimize_size") (const_int 0)))
2454                  (const_string "V4SF")
2455                (and (eq_attr "alternative" "2")
2456                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2457                         (const_int 0)))
2458                  (const_string "V4SF")]
2459               (const_string "TI")))])
2461 (define_insn "*movti_rex64"
2462   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o,x,x,xm")
2463         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2464   "TARGET_64BIT
2465    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2467   switch (which_alternative)
2468     {
2469     case 0:
2470     case 1:
2471       return "#";
2472     case 2:
2473       if (get_attr_mode (insn) == MODE_V4SF)
2474         return "xorps\t%0, %0";
2475       else
2476         return "pxor\t%0, %0";
2477     case 3:
2478     case 4:
2479       /* TDmode values are passed as TImode on the stack.  Moving them
2480          to stack may result in unaligned memory access.  */
2481       if (misaligned_operand (operands[0], TImode)
2482           || misaligned_operand (operands[1], TImode))
2483         { 
2484           if (get_attr_mode (insn) == MODE_V4SF)
2485             return "movups\t{%1, %0|%0, %1}";
2486          else
2487            return "movdqu\t{%1, %0|%0, %1}";
2488         }
2489       else
2490         { 
2491           if (get_attr_mode (insn) == MODE_V4SF)
2492             return "movaps\t{%1, %0|%0, %1}";
2493          else
2494            return "movdqa\t{%1, %0|%0, %1}";
2495         }
2496     default:
2497       gcc_unreachable ();
2498     }
2500   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2501    (set (attr "mode")
2502         (cond [(eq_attr "alternative" "2,3")
2503                  (if_then_else
2504                    (ne (symbol_ref "optimize_size")
2505                        (const_int 0))
2506                    (const_string "V4SF")
2507                    (const_string "TI"))
2508                (eq_attr "alternative" "4")
2509                  (if_then_else
2510                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2511                             (const_int 0))
2512                         (ne (symbol_ref "optimize_size")
2513                             (const_int 0)))
2514                    (const_string "V4SF")
2515                    (const_string "TI"))]
2516                (const_string "DI")))])
2518 (define_split
2519   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2520         (match_operand:TI 1 "general_operand" ""))]
2521   "reload_completed && !SSE_REG_P (operands[0])
2522    && !SSE_REG_P (operands[1])"
2523   [(const_int 0)]
2524   "ix86_split_long_move (operands); DONE;")
2526 ;; This expands to what emit_move_complex would generate if we didn't
2527 ;; have a movti pattern.  Having this avoids problems with reload on
2528 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2529 ;; to have around all the time.
2530 (define_expand "movcdi"
2531   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2532         (match_operand:CDI 1 "general_operand" ""))]
2533   ""
2535   if (push_operand (operands[0], CDImode))
2536     emit_move_complex_push (CDImode, operands[0], operands[1]);
2537   else
2538     emit_move_complex_parts (operands[0], operands[1]);
2539   DONE;
2542 (define_expand "movsf"
2543   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2544         (match_operand:SF 1 "general_operand" ""))]
2545   ""
2546   "ix86_expand_move (SFmode, operands); DONE;")
2548 (define_insn "*pushsf"
2549   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2550         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2551   "!TARGET_64BIT"
2553   /* Anything else should be already split before reg-stack.  */
2554   gcc_assert (which_alternative == 1);
2555   return "push{l}\t%1";
2557   [(set_attr "type" "multi,push,multi")
2558    (set_attr "unit" "i387,*,*")
2559    (set_attr "mode" "SF,SI,SF")])
2561 (define_insn "*pushsf_rex64"
2562   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2563         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2564   "TARGET_64BIT"
2566   /* Anything else should be already split before reg-stack.  */
2567   gcc_assert (which_alternative == 1);
2568   return "push{q}\t%q1";
2570   [(set_attr "type" "multi,push,multi")
2571    (set_attr "unit" "i387,*,*")
2572    (set_attr "mode" "SF,DI,SF")])
2574 (define_split
2575   [(set (match_operand:SF 0 "push_operand" "")
2576         (match_operand:SF 1 "memory_operand" ""))]
2577   "reload_completed
2578    && MEM_P (operands[1])
2579    && (operands[2] = find_constant_src (insn))"
2580   [(set (match_dup 0)
2581         (match_dup 2))])
2584 ;; %%% Kill this when call knows how to work this out.
2585 (define_split
2586   [(set (match_operand:SF 0 "push_operand" "")
2587         (match_operand:SF 1 "any_fp_register_operand" ""))]
2588   "!TARGET_64BIT"
2589   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2590    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2592 (define_split
2593   [(set (match_operand:SF 0 "push_operand" "")
2594         (match_operand:SF 1 "any_fp_register_operand" ""))]
2595   "TARGET_64BIT"
2596   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2597    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2599 (define_insn "*movsf_1"
2600   [(set (match_operand:SF 0 "nonimmediate_operand"
2601           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2602         (match_operand:SF 1 "general_operand"
2603           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2604   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2605    && (reload_in_progress || reload_completed
2606        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2607        || (!TARGET_SSE_MATH && optimize_size
2608            && standard_80387_constant_p (operands[1]))
2609        || GET_CODE (operands[1]) != CONST_DOUBLE
2610        || memory_operand (operands[0], SFmode))"
2612   switch (which_alternative)
2613     {
2614     case 0:
2615     case 1:
2616       return output_387_reg_move (insn, operands);
2618     case 2:
2619       return standard_80387_constant_opcode (operands[1]);
2621     case 3:
2622     case 4:
2623       return "mov{l}\t{%1, %0|%0, %1}";
2624     case 5:
2625       if (get_attr_mode (insn) == MODE_TI)
2626         return "pxor\t%0, %0";
2627       else
2628         return "xorps\t%0, %0";
2629     case 6:
2630       if (get_attr_mode (insn) == MODE_V4SF)
2631         return "movaps\t{%1, %0|%0, %1}";
2632       else
2633         return "movss\t{%1, %0|%0, %1}";
2634     case 7: case 8:
2635       return "movss\t{%1, %0|%0, %1}";
2637     case 9: case 10:
2638     case 12: case 13: case 14: case 15:
2639       return "movd\t{%1, %0|%0, %1}";
2641     case 11:
2642       return "movq\t{%1, %0|%0, %1}";
2644     default:
2645       gcc_unreachable ();
2646     }
2648   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2649    (set (attr "mode")
2650         (cond [(eq_attr "alternative" "3,4,9,10")
2651                  (const_string "SI")
2652                (eq_attr "alternative" "5")
2653                  (if_then_else
2654                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2655                                  (const_int 0))
2656                              (ne (symbol_ref "TARGET_SSE2")
2657                                  (const_int 0)))
2658                         (eq (symbol_ref "optimize_size")
2659                             (const_int 0)))
2660                    (const_string "TI")
2661                    (const_string "V4SF"))
2662                /* For architectures resolving dependencies on
2663                   whole SSE registers use APS move to break dependency
2664                   chains, otherwise use short move to avoid extra work.
2666                   Do the same for architectures resolving dependencies on
2667                   the parts.  While in DF mode it is better to always handle
2668                   just register parts, the SF mode is different due to lack
2669                   of instructions to load just part of the register.  It is
2670                   better to maintain the whole registers in single format
2671                   to avoid problems on using packed logical operations.  */
2672                (eq_attr "alternative" "6")
2673                  (if_then_else
2674                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2675                             (const_int 0))
2676                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2677                             (const_int 0)))
2678                    (const_string "V4SF")
2679                    (const_string "SF"))
2680                (eq_attr "alternative" "11")
2681                  (const_string "DI")]
2682                (const_string "SF")))])
2684 (define_insn "*swapsf"
2685   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2686         (match_operand:SF 1 "fp_register_operand" "+f"))
2687    (set (match_dup 1)
2688         (match_dup 0))]
2689   "reload_completed || TARGET_80387"
2691   if (STACK_TOP_P (operands[0]))
2692     return "fxch\t%1";
2693   else
2694     return "fxch\t%0";
2696   [(set_attr "type" "fxch")
2697    (set_attr "mode" "SF")])
2699 (define_expand "movdf"
2700   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2701         (match_operand:DF 1 "general_operand" ""))]
2702   ""
2703   "ix86_expand_move (DFmode, operands); DONE;")
2705 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2706 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2707 ;; On the average, pushdf using integers can be still shorter.  Allow this
2708 ;; pattern for optimize_size too.
2710 (define_insn "*pushdf_nointeger"
2711   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2712         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2713   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2715   /* This insn should be already split before reg-stack.  */
2716   gcc_unreachable ();
2718   [(set_attr "type" "multi")
2719    (set_attr "unit" "i387,*,*,*")
2720    (set_attr "mode" "DF,SI,SI,DF")])
2722 (define_insn "*pushdf_integer"
2723   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2724         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2725   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2727   /* This insn should be already split before reg-stack.  */
2728   gcc_unreachable ();
2730   [(set_attr "type" "multi")
2731    (set_attr "unit" "i387,*,*")
2732    (set_attr "mode" "DF,SI,DF")])
2734 ;; %%% Kill this when call knows how to work this out.
2735 (define_split
2736   [(set (match_operand:DF 0 "push_operand" "")
2737         (match_operand:DF 1 "any_fp_register_operand" ""))]
2738   "!TARGET_64BIT && reload_completed"
2739   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
2740    (set (mem:DF (reg:SI SP_REG)) (match_dup 1))]
2741   "")
2743 (define_split
2744   [(set (match_operand:DF 0 "push_operand" "")
2745         (match_operand:DF 1 "any_fp_register_operand" ""))]
2746   "TARGET_64BIT && reload_completed"
2747   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2748    (set (mem:DF (reg:DI SP_REG)) (match_dup 1))]
2749   "")
2751 (define_split
2752   [(set (match_operand:DF 0 "push_operand" "")
2753         (match_operand:DF 1 "general_operand" ""))]
2754   "reload_completed"
2755   [(const_int 0)]
2756   "ix86_split_long_move (operands); DONE;")
2758 ;; Moving is usually shorter when only FP registers are used. This separate
2759 ;; movdf pattern avoids the use of integer registers for FP operations
2760 ;; when optimizing for size.
2762 (define_insn "*movdf_nointeger"
2763   [(set (match_operand:DF 0 "nonimmediate_operand"
2764                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2765         (match_operand:DF 1 "general_operand"
2766                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2767   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2768    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2769    && (reload_in_progress || reload_completed
2770        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2771        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2772            && !memory_operand (operands[0], DFmode)
2773            && standard_80387_constant_p (operands[1]))
2774        || GET_CODE (operands[1]) != CONST_DOUBLE
2775        || ((optimize_size
2776             || !TARGET_MEMORY_MISMATCH_STALL
2777             || reload_in_progress || reload_completed)
2778            && memory_operand (operands[0], DFmode)))"
2780   switch (which_alternative)
2781     {
2782     case 0:
2783     case 1:
2784       return output_387_reg_move (insn, operands);
2786     case 2:
2787       return standard_80387_constant_opcode (operands[1]);
2789     case 3:
2790     case 4:
2791       return "#";
2792     case 5:
2793       switch (get_attr_mode (insn))
2794         {
2795         case MODE_V4SF:
2796           return "xorps\t%0, %0";
2797         case MODE_V2DF:
2798           return "xorpd\t%0, %0";
2799         case MODE_TI:
2800           return "pxor\t%0, %0";
2801         default:
2802           gcc_unreachable ();
2803         }
2804     case 6:
2805     case 7:
2806     case 8:
2807       switch (get_attr_mode (insn))
2808         {
2809         case MODE_V4SF:
2810           return "movaps\t{%1, %0|%0, %1}";
2811         case MODE_V2DF:
2812           return "movapd\t{%1, %0|%0, %1}";
2813         case MODE_TI:
2814           return "movdqa\t{%1, %0|%0, %1}";
2815         case MODE_DI:
2816           return "movq\t{%1, %0|%0, %1}";
2817         case MODE_DF:
2818           return "movsd\t{%1, %0|%0, %1}";
2819         case MODE_V1DF:
2820           return "movlpd\t{%1, %0|%0, %1}";
2821         case MODE_V2SF:
2822           return "movlps\t{%1, %0|%0, %1}";
2823         default:
2824           gcc_unreachable ();
2825         }
2827     default:
2828       gcc_unreachable ();
2829     }
2831   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2832    (set (attr "mode")
2833         (cond [(eq_attr "alternative" "0,1,2")
2834                  (const_string "DF")
2835                (eq_attr "alternative" "3,4")
2836                  (const_string "SI")
2838                /* For SSE1, we have many fewer alternatives.  */
2839                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2840                  (cond [(eq_attr "alternative" "5,6")
2841                           (const_string "V4SF")
2842                        ]
2843                    (const_string "V2SF"))
2845                /* xorps is one byte shorter.  */
2846                (eq_attr "alternative" "5")
2847                  (cond [(ne (symbol_ref "optimize_size")
2848                             (const_int 0))
2849                           (const_string "V4SF")
2850                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2851                             (const_int 0))
2852                           (const_string "TI")
2853                        ]
2854                        (const_string "V2DF"))
2856                /* For architectures resolving dependencies on
2857                   whole SSE registers use APD move to break dependency
2858                   chains, otherwise use short move to avoid extra work.
2860                   movaps encodes one byte shorter.  */
2861                (eq_attr "alternative" "6")
2862                  (cond
2863                    [(ne (symbol_ref "optimize_size")
2864                         (const_int 0))
2865                       (const_string "V4SF")
2866                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2867                         (const_int 0))
2868                       (const_string "V2DF")
2869                    ]
2870                    (const_string "DF"))
2871                /* For architectures resolving dependencies on register
2872                   parts we may avoid extra work to zero out upper part
2873                   of register.  */
2874                (eq_attr "alternative" "7")
2875                  (if_then_else
2876                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2877                        (const_int 0))
2878                    (const_string "V1DF")
2879                    (const_string "DF"))
2880               ]
2881               (const_string "DF")))])
2883 (define_insn "*movdf_integer_rex64"
2884   [(set (match_operand:DF 0 "nonimmediate_operand"
2885                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2886         (match_operand:DF 1 "general_operand"
2887                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2888   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2889    && (reload_in_progress || reload_completed
2890        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2891        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2892            && standard_80387_constant_p (operands[1]))
2893        || GET_CODE (operands[1]) != CONST_DOUBLE
2894        || memory_operand (operands[0], DFmode))"
2896   switch (which_alternative)
2897     {
2898     case 0:
2899     case 1:
2900       return output_387_reg_move (insn, operands);
2902     case 2:
2903       return standard_80387_constant_opcode (operands[1]);
2905     case 3:
2906     case 4:
2907       return "#";
2909     case 5:
2910       switch (get_attr_mode (insn))
2911         {
2912         case MODE_V4SF:
2913           return "xorps\t%0, %0";
2914         case MODE_V2DF:
2915           return "xorpd\t%0, %0";
2916         case MODE_TI:
2917           return "pxor\t%0, %0";
2918         default:
2919           gcc_unreachable ();
2920         }
2921     case 6:
2922     case 7:
2923     case 8:
2924       switch (get_attr_mode (insn))
2925         {
2926         case MODE_V4SF:
2927           return "movaps\t{%1, %0|%0, %1}";
2928         case MODE_V2DF:
2929           return "movapd\t{%1, %0|%0, %1}";
2930         case MODE_TI:
2931           return "movdqa\t{%1, %0|%0, %1}";
2932         case MODE_DI:
2933           return "movq\t{%1, %0|%0, %1}";
2934         case MODE_DF:
2935           return "movsd\t{%1, %0|%0, %1}";
2936         case MODE_V1DF:
2937           return "movlpd\t{%1, %0|%0, %1}";
2938         case MODE_V2SF:
2939           return "movlps\t{%1, %0|%0, %1}";
2940         default:
2941           gcc_unreachable ();
2942         }
2944     case 9:
2945     case 10:
2946       return "movd\t{%1, %0|%0, %1}";
2948     default:
2949       gcc_unreachable();
2950     }
2952   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2953    (set (attr "mode")
2954         (cond [(eq_attr "alternative" "0,1,2")
2955                  (const_string "DF")
2956                (eq_attr "alternative" "3,4,9,10")
2957                  (const_string "DI")
2959                /* For SSE1, we have many fewer alternatives.  */
2960                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2961                  (cond [(eq_attr "alternative" "5,6")
2962                           (const_string "V4SF")
2963                        ]
2964                    (const_string "V2SF"))
2966                /* xorps is one byte shorter.  */
2967                (eq_attr "alternative" "5")
2968                  (cond [(ne (symbol_ref "optimize_size")
2969                             (const_int 0))
2970                           (const_string "V4SF")
2971                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2972                             (const_int 0))
2973                           (const_string "TI")
2974                        ]
2975                        (const_string "V2DF"))
2977                /* For architectures resolving dependencies on
2978                   whole SSE registers use APD move to break dependency
2979                   chains, otherwise use short move to avoid extra work.
2981                   movaps encodes one byte shorter.  */
2982                (eq_attr "alternative" "6")
2983                  (cond
2984                    [(ne (symbol_ref "optimize_size")
2985                         (const_int 0))
2986                       (const_string "V4SF")
2987                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2988                         (const_int 0))
2989                       (const_string "V2DF")
2990                    ]
2991                    (const_string "DF"))
2992                /* For architectures resolving dependencies on register
2993                   parts we may avoid extra work to zero out upper part
2994                   of register.  */
2995                (eq_attr "alternative" "7")
2996                  (if_then_else
2997                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2998                        (const_int 0))
2999                    (const_string "V1DF")
3000                    (const_string "DF"))
3001               ]
3002               (const_string "DF")))])
3004 (define_insn "*movdf_integer"
3005   [(set (match_operand:DF 0 "nonimmediate_operand"
3006                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3007         (match_operand:DF 1 "general_operand"
3008                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3009   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3010    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
3011    && (reload_in_progress || reload_completed
3012        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3013        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
3014            && standard_80387_constant_p (operands[1]))
3015        || GET_CODE (operands[1]) != CONST_DOUBLE
3016        || memory_operand (operands[0], DFmode))"
3018   switch (which_alternative)
3019     {
3020     case 0:
3021     case 1:
3022       return output_387_reg_move (insn, operands);
3024     case 2:
3025       return standard_80387_constant_opcode (operands[1]);
3027     case 3:
3028     case 4:
3029       return "#";
3031     case 5:
3032       switch (get_attr_mode (insn))
3033         {
3034         case MODE_V4SF:
3035           return "xorps\t%0, %0";
3036         case MODE_V2DF:
3037           return "xorpd\t%0, %0";
3038         case MODE_TI:
3039           return "pxor\t%0, %0";
3040         default:
3041           gcc_unreachable ();
3042         }
3043     case 6:
3044     case 7:
3045     case 8:
3046       switch (get_attr_mode (insn))
3047         {
3048         case MODE_V4SF:
3049           return "movaps\t{%1, %0|%0, %1}";
3050         case MODE_V2DF:
3051           return "movapd\t{%1, %0|%0, %1}";
3052         case MODE_TI:
3053           return "movdqa\t{%1, %0|%0, %1}";
3054         case MODE_DI:
3055           return "movq\t{%1, %0|%0, %1}";
3056         case MODE_DF:
3057           return "movsd\t{%1, %0|%0, %1}";
3058         case MODE_V1DF:
3059           return "movlpd\t{%1, %0|%0, %1}";
3060         case MODE_V2SF:
3061           return "movlps\t{%1, %0|%0, %1}";
3062         default:
3063           gcc_unreachable ();
3064         }
3066     default:
3067       gcc_unreachable();
3068     }
3070   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3071    (set (attr "mode")
3072         (cond [(eq_attr "alternative" "0,1,2")
3073                  (const_string "DF")
3074                (eq_attr "alternative" "3,4")
3075                  (const_string "SI")
3077                /* For SSE1, we have many fewer alternatives.  */
3078                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3079                  (cond [(eq_attr "alternative" "5,6")
3080                           (const_string "V4SF")
3081                        ]
3082                    (const_string "V2SF"))
3084                /* xorps is one byte shorter.  */
3085                (eq_attr "alternative" "5")
3086                  (cond [(ne (symbol_ref "optimize_size")
3087                             (const_int 0))
3088                           (const_string "V4SF")
3089                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3090                             (const_int 0))
3091                           (const_string "TI")
3092                        ]
3093                        (const_string "V2DF"))
3095                /* For architectures resolving dependencies on
3096                   whole SSE registers use APD move to break dependency
3097                   chains, otherwise use short move to avoid extra work.
3099                   movaps encodes one byte shorter.  */
3100                (eq_attr "alternative" "6")
3101                  (cond
3102                    [(ne (symbol_ref "optimize_size")
3103                         (const_int 0))
3104                       (const_string "V4SF")
3105                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3106                         (const_int 0))
3107                       (const_string "V2DF")
3108                    ]
3109                    (const_string "DF"))
3110                /* For architectures resolving dependencies on register
3111                   parts we may avoid extra work to zero out upper part
3112                   of register.  */
3113                (eq_attr "alternative" "7")
3114                  (if_then_else
3115                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3116                        (const_int 0))
3117                    (const_string "V1DF")
3118                    (const_string "DF"))
3119               ]
3120               (const_string "DF")))])
3122 (define_split
3123   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3124         (match_operand:DF 1 "general_operand" ""))]
3125   "reload_completed
3126    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3127    && ! (ANY_FP_REG_P (operands[0]) ||
3128          (GET_CODE (operands[0]) == SUBREG
3129           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3130    && ! (ANY_FP_REG_P (operands[1]) ||
3131          (GET_CODE (operands[1]) == SUBREG
3132           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3133   [(const_int 0)]
3134   "ix86_split_long_move (operands); DONE;")
3136 (define_insn "*swapdf"
3137   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3138         (match_operand:DF 1 "fp_register_operand" "+f"))
3139    (set (match_dup 1)
3140         (match_dup 0))]
3141   "reload_completed || TARGET_80387"
3143   if (STACK_TOP_P (operands[0]))
3144     return "fxch\t%1";
3145   else
3146     return "fxch\t%0";
3148   [(set_attr "type" "fxch")
3149    (set_attr "mode" "DF")])
3151 (define_expand "movxf"
3152   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3153         (match_operand:XF 1 "general_operand" ""))]
3154   ""
3155   "ix86_expand_move (XFmode, operands); DONE;")
3157 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3158 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3159 ;; Pushing using integer instructions is longer except for constants
3160 ;; and direct memory references.
3161 ;; (assuming that any given constant is pushed only once, but this ought to be
3162 ;;  handled elsewhere).
3164 (define_insn "*pushxf_nointeger"
3165   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3166         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3167   "optimize_size"
3169   /* This insn should be already split before reg-stack.  */
3170   gcc_unreachable ();
3172   [(set_attr "type" "multi")
3173    (set_attr "unit" "i387,*,*")
3174    (set_attr "mode" "XF,SI,SI")])
3176 (define_insn "*pushxf_integer"
3177   [(set (match_operand:XF 0 "push_operand" "=<,<")
3178         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3179   "!optimize_size"
3181   /* This insn should be already split before reg-stack.  */
3182   gcc_unreachable ();
3184   [(set_attr "type" "multi")
3185    (set_attr "unit" "i387,*")
3186    (set_attr "mode" "XF,SI")])
3188 (define_split
3189   [(set (match_operand 0 "push_operand" "")
3190         (match_operand 1 "general_operand" ""))]
3191   "reload_completed
3192    && (GET_MODE (operands[0]) == XFmode
3193        || GET_MODE (operands[0]) == DFmode)
3194    && !ANY_FP_REG_P (operands[1])"
3195   [(const_int 0)]
3196   "ix86_split_long_move (operands); DONE;")
3198 (define_split
3199   [(set (match_operand:XF 0 "push_operand" "")
3200         (match_operand:XF 1 "any_fp_register_operand" ""))]
3201   "!TARGET_64BIT"
3202   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3203    (set (mem:XF (reg:SI SP_REG)) (match_dup 1))]
3204   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3206 (define_split
3207   [(set (match_operand:XF 0 "push_operand" "")
3208         (match_operand:XF 1 "any_fp_register_operand" ""))]
3209   "TARGET_64BIT"
3210   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3211    (set (mem:XF (reg:DI SP_REG)) (match_dup 1))]
3212   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3214 ;; Do not use integer registers when optimizing for size
3215 (define_insn "*movxf_nointeger"
3216   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3217         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3218   "optimize_size
3219    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3220    && (reload_in_progress || reload_completed
3221        || (optimize_size && standard_80387_constant_p (operands[1]))
3222        || GET_CODE (operands[1]) != CONST_DOUBLE
3223        || memory_operand (operands[0], XFmode))"
3225   switch (which_alternative)
3226     {
3227     case 0:
3228     case 1:
3229       return output_387_reg_move (insn, operands);
3231     case 2:
3232       return standard_80387_constant_opcode (operands[1]);
3234     case 3: case 4:
3235       return "#";
3236     default:
3237       gcc_unreachable ();
3238     }
3240   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3241    (set_attr "mode" "XF,XF,XF,SI,SI")])
3243 (define_insn "*movxf_integer"
3244   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3245         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3246   "!optimize_size
3247    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3248    && (reload_in_progress || reload_completed
3249        || (optimize_size && standard_80387_constant_p (operands[1]))
3250        || GET_CODE (operands[1]) != CONST_DOUBLE
3251        || memory_operand (operands[0], XFmode))"
3253   switch (which_alternative)
3254     {
3255     case 0:
3256     case 1:
3257       return output_387_reg_move (insn, operands);
3259     case 2:
3260       return standard_80387_constant_opcode (operands[1]);
3262     case 3: case 4:
3263       return "#";
3265     default:
3266       gcc_unreachable ();
3267     }
3269   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3270    (set_attr "mode" "XF,XF,XF,SI,SI")])
3272 (define_expand "movtf"
3273   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3274         (match_operand:TF 1 "nonimmediate_operand" ""))]
3275   "TARGET_64BIT"
3277   ix86_expand_move (TFmode, operands);
3278   DONE;
3281 (define_insn "*movtf_internal"
3282   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3283         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3284   "TARGET_64BIT
3285    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3287   switch (which_alternative)
3288     {
3289     case 0:
3290     case 1:
3291       if (get_attr_mode (insn) == MODE_V4SF)
3292         return "movaps\t{%1, %0|%0, %1}";
3293       else
3294         return "movdqa\t{%1, %0|%0, %1}";
3295     case 2:
3296       if (get_attr_mode (insn) == MODE_V4SF)
3297         return "xorps\t%0, %0";
3298       else
3299         return "pxor\t%0, %0";
3300     case 3:
3301     case 4:
3302         return "#";
3303     default:
3304       gcc_unreachable ();
3305     }
3307   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3308    (set (attr "mode")
3309         (cond [(eq_attr "alternative" "0,2")
3310                  (if_then_else
3311                    (ne (symbol_ref "optimize_size")
3312                        (const_int 0))
3313                    (const_string "V4SF")
3314                    (const_string "TI"))
3315                (eq_attr "alternative" "1")
3316                  (if_then_else
3317                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3318                             (const_int 0))
3319                         (ne (symbol_ref "optimize_size")
3320                             (const_int 0)))
3321                    (const_string "V4SF")
3322                    (const_string "TI"))]
3323                (const_string "DI")))])
3325 (define_split
3326   [(set (match_operand 0 "nonimmediate_operand" "")
3327         (match_operand 1 "general_operand" ""))]
3328   "reload_completed
3329    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3330    && GET_MODE (operands[0]) == XFmode
3331    && ! (ANY_FP_REG_P (operands[0]) ||
3332          (GET_CODE (operands[0]) == SUBREG
3333           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3334    && ! (ANY_FP_REG_P (operands[1]) ||
3335          (GET_CODE (operands[1]) == SUBREG
3336           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3337   [(const_int 0)]
3338   "ix86_split_long_move (operands); DONE;")
3340 (define_split
3341   [(set (match_operand 0 "register_operand" "")
3342         (match_operand 1 "memory_operand" ""))]
3343   "reload_completed
3344    && MEM_P (operands[1])
3345    && (GET_MODE (operands[0]) == TFmode
3346        || GET_MODE (operands[0]) == XFmode
3347        || GET_MODE (operands[0]) == SFmode
3348        || GET_MODE (operands[0]) == DFmode)
3349    && (operands[2] = find_constant_src (insn))"
3350   [(set (match_dup 0) (match_dup 2))]
3352   rtx c = operands[2];
3353   rtx r = operands[0];
3355   if (GET_CODE (r) == SUBREG)
3356     r = SUBREG_REG (r);
3358   if (SSE_REG_P (r))
3359     {
3360       if (!standard_sse_constant_p (c))
3361         FAIL;
3362     }
3363   else if (FP_REG_P (r))
3364     {
3365       if (!standard_80387_constant_p (c))
3366         FAIL;
3367     }
3368   else if (MMX_REG_P (r))
3369     FAIL;
3372 (define_split
3373   [(set (match_operand 0 "register_operand" "")
3374         (float_extend (match_operand 1 "memory_operand" "")))]
3375   "reload_completed
3376    && MEM_P (operands[1])
3377    && (GET_MODE (operands[0]) == TFmode
3378        || GET_MODE (operands[0]) == XFmode
3379        || GET_MODE (operands[0]) == SFmode
3380        || GET_MODE (operands[0]) == DFmode)
3381    && (operands[2] = find_constant_src (insn))"
3382   [(set (match_dup 0) (match_dup 2))]
3384   rtx c = operands[2];
3385   rtx r = operands[0];
3387   if (GET_CODE (r) == SUBREG)
3388     r = SUBREG_REG (r);
3390   if (SSE_REG_P (r))
3391     {
3392       if (!standard_sse_constant_p (c))
3393         FAIL;
3394     }
3395   else if (FP_REG_P (r))
3396     {
3397       if (!standard_80387_constant_p (c))
3398         FAIL;
3399     }
3400   else if (MMX_REG_P (r))
3401     FAIL;
3404 (define_insn "swapxf"
3405   [(set (match_operand:XF 0 "register_operand" "+f")
3406         (match_operand:XF 1 "register_operand" "+f"))
3407    (set (match_dup 1)
3408         (match_dup 0))]
3409   "TARGET_80387"
3411   if (STACK_TOP_P (operands[0]))
3412     return "fxch\t%1";
3413   else
3414     return "fxch\t%0";
3416   [(set_attr "type" "fxch")
3417    (set_attr "mode" "XF")])
3419 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3420 (define_split
3421   [(set (match_operand:X87MODEF 0 "register_operand" "")
3422         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3423   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3424    && (standard_80387_constant_p (operands[1]) == 8
3425        || standard_80387_constant_p (operands[1]) == 9)"
3426   [(set (match_dup 0)(match_dup 1))
3427    (set (match_dup 0)
3428         (neg:X87MODEF (match_dup 0)))]
3430   REAL_VALUE_TYPE r;
3432   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3433   if (real_isnegzero (&r))
3434     operands[1] = CONST0_RTX (<MODE>mode);
3435   else
3436     operands[1] = CONST1_RTX (<MODE>mode);
3439 (define_split
3440   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3441         (match_operand:TF 1 "general_operand" ""))]
3442   "reload_completed
3443    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3444   [(const_int 0)]
3445   "ix86_split_long_move (operands); DONE;")
3447 ;; Zero extension instructions
3449 (define_expand "zero_extendhisi2"
3450   [(set (match_operand:SI 0 "register_operand" "")
3451      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3452   ""
3454   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3455     {
3456       operands[1] = force_reg (HImode, operands[1]);
3457       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3458       DONE;
3459     }
3462 (define_insn "zero_extendhisi2_and"
3463   [(set (match_operand:SI 0 "register_operand" "=r")
3464      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3465    (clobber (reg:CC FLAGS_REG))]
3466   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3467   "#"
3468   [(set_attr "type" "alu1")
3469    (set_attr "mode" "SI")])
3471 (define_split
3472   [(set (match_operand:SI 0 "register_operand" "")
3473         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3474    (clobber (reg:CC FLAGS_REG))]
3475   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3476   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3477               (clobber (reg:CC FLAGS_REG))])]
3478   "")
3480 (define_insn "*zero_extendhisi2_movzwl"
3481   [(set (match_operand:SI 0 "register_operand" "=r")
3482      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3483   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3484   "movz{wl|x}\t{%1, %0|%0, %1}"
3485   [(set_attr "type" "imovx")
3486    (set_attr "mode" "SI")])
3488 (define_expand "zero_extendqihi2"
3489   [(parallel
3490     [(set (match_operand:HI 0 "register_operand" "")
3491        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3492      (clobber (reg:CC FLAGS_REG))])]
3493   ""
3494   "")
3496 (define_insn "*zero_extendqihi2_and"
3497   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3498      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3499    (clobber (reg:CC FLAGS_REG))]
3500   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3501   "#"
3502   [(set_attr "type" "alu1")
3503    (set_attr "mode" "HI")])
3505 (define_insn "*zero_extendqihi2_movzbw_and"
3506   [(set (match_operand:HI 0 "register_operand" "=r,r")
3507      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3508    (clobber (reg:CC FLAGS_REG))]
3509   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3510   "#"
3511   [(set_attr "type" "imovx,alu1")
3512    (set_attr "mode" "HI")])
3514 ; zero extend to SImode here to avoid partial register stalls
3515 (define_insn "*zero_extendqihi2_movzbl"
3516   [(set (match_operand:HI 0 "register_operand" "=r")
3517      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3518   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3519   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3520   [(set_attr "type" "imovx")
3521    (set_attr "mode" "SI")])
3523 ;; For the movzbw case strip only the clobber
3524 (define_split
3525   [(set (match_operand:HI 0 "register_operand" "")
3526         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3527    (clobber (reg:CC FLAGS_REG))]
3528   "reload_completed
3529    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3530    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3531   [(set (match_operand:HI 0 "register_operand" "")
3532         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3534 ;; When source and destination does not overlap, clear destination
3535 ;; first and then do the movb
3536 (define_split
3537   [(set (match_operand:HI 0 "register_operand" "")
3538         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3539    (clobber (reg:CC FLAGS_REG))]
3540   "reload_completed
3541    && ANY_QI_REG_P (operands[0])
3542    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3543    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3544   [(set (match_dup 0) (const_int 0))
3545    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3546   "operands[2] = gen_lowpart (QImode, operands[0]);")
3548 ;; Rest is handled by single and.
3549 (define_split
3550   [(set (match_operand:HI 0 "register_operand" "")
3551         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3552    (clobber (reg:CC FLAGS_REG))]
3553   "reload_completed
3554    && true_regnum (operands[0]) == true_regnum (operands[1])"
3555   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3556               (clobber (reg:CC FLAGS_REG))])]
3557   "")
3559 (define_expand "zero_extendqisi2"
3560   [(parallel
3561     [(set (match_operand:SI 0 "register_operand" "")
3562        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3563      (clobber (reg:CC FLAGS_REG))])]
3564   ""
3565   "")
3567 (define_insn "*zero_extendqisi2_and"
3568   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3569      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3570    (clobber (reg:CC FLAGS_REG))]
3571   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3572   "#"
3573   [(set_attr "type" "alu1")
3574    (set_attr "mode" "SI")])
3576 (define_insn "*zero_extendqisi2_movzbw_and"
3577   [(set (match_operand:SI 0 "register_operand" "=r,r")
3578      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3579    (clobber (reg:CC FLAGS_REG))]
3580   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3581   "#"
3582   [(set_attr "type" "imovx,alu1")
3583    (set_attr "mode" "SI")])
3585 (define_insn "*zero_extendqisi2_movzbw"
3586   [(set (match_operand:SI 0 "register_operand" "=r")
3587      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3588   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3589   "movz{bl|x}\t{%1, %0|%0, %1}"
3590   [(set_attr "type" "imovx")
3591    (set_attr "mode" "SI")])
3593 ;; For the movzbl case strip only the clobber
3594 (define_split
3595   [(set (match_operand:SI 0 "register_operand" "")
3596         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3597    (clobber (reg:CC FLAGS_REG))]
3598   "reload_completed
3599    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3600    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3601   [(set (match_dup 0)
3602         (zero_extend:SI (match_dup 1)))])
3604 ;; When source and destination does not overlap, clear destination
3605 ;; first and then do the movb
3606 (define_split
3607   [(set (match_operand:SI 0 "register_operand" "")
3608         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3609    (clobber (reg:CC FLAGS_REG))]
3610   "reload_completed
3611    && ANY_QI_REG_P (operands[0])
3612    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3613    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3614    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3615   [(set (match_dup 0) (const_int 0))
3616    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3617   "operands[2] = gen_lowpart (QImode, operands[0]);")
3619 ;; Rest is handled by single and.
3620 (define_split
3621   [(set (match_operand:SI 0 "register_operand" "")
3622         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3623    (clobber (reg:CC FLAGS_REG))]
3624   "reload_completed
3625    && true_regnum (operands[0]) == true_regnum (operands[1])"
3626   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3627               (clobber (reg:CC FLAGS_REG))])]
3628   "")
3630 ;; %%% Kill me once multi-word ops are sane.
3631 (define_expand "zero_extendsidi2"
3632   [(set (match_operand:DI 0 "register_operand" "")
3633      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3634   ""
3636   if (!TARGET_64BIT)
3637     {
3638       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3639       DONE;
3640     }
3643 (define_insn "zero_extendsidi2_32"
3644   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3645         (zero_extend:DI
3646          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3647    (clobber (reg:CC FLAGS_REG))]
3648   "!TARGET_64BIT"
3649   "@
3650    #
3651    #
3652    #
3653    movd\t{%1, %0|%0, %1}
3654    movd\t{%1, %0|%0, %1}
3655    movd\t{%1, %0|%0, %1}
3656    movd\t{%1, %0|%0, %1}"
3657   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3658    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3660 (define_insn "zero_extendsidi2_rex64"
3661   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3662      (zero_extend:DI
3663        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3664   "TARGET_64BIT"
3665   "@
3666    mov\t{%k1, %k0|%k0, %k1}
3667    #
3668    movd\t{%1, %0|%0, %1}
3669    movd\t{%1, %0|%0, %1}
3670    movd\t{%1, %0|%0, %1}
3671    movd\t{%1, %0|%0, %1}"
3672   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3673    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3675 (define_split
3676   [(set (match_operand:DI 0 "memory_operand" "")
3677      (zero_extend:DI (match_dup 0)))]
3678   "TARGET_64BIT"
3679   [(set (match_dup 4) (const_int 0))]
3680   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3682 (define_split
3683   [(set (match_operand:DI 0 "register_operand" "")
3684         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3685    (clobber (reg:CC FLAGS_REG))]
3686   "!TARGET_64BIT && reload_completed
3687    && true_regnum (operands[0]) == true_regnum (operands[1])"
3688   [(set (match_dup 4) (const_int 0))]
3689   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3691 (define_split
3692   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3693         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3694    (clobber (reg:CC FLAGS_REG))]
3695   "!TARGET_64BIT && reload_completed
3696    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3697   [(set (match_dup 3) (match_dup 1))
3698    (set (match_dup 4) (const_int 0))]
3699   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3701 (define_insn "zero_extendhidi2"
3702   [(set (match_operand:DI 0 "register_operand" "=r")
3703      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3704   "TARGET_64BIT"
3705   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3706   [(set_attr "type" "imovx")
3707    (set_attr "mode" "DI")])
3709 (define_insn "zero_extendqidi2"
3710   [(set (match_operand:DI 0 "register_operand" "=r")
3711      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3712   "TARGET_64BIT"
3713   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3714   [(set_attr "type" "imovx")
3715    (set_attr "mode" "DI")])
3717 ;; Sign extension instructions
3719 (define_expand "extendsidi2"
3720   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3721                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3722               (clobber (reg:CC FLAGS_REG))
3723               (clobber (match_scratch:SI 2 ""))])]
3724   ""
3726   if (TARGET_64BIT)
3727     {
3728       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3729       DONE;
3730     }
3733 (define_insn "*extendsidi2_1"
3734   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3735         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3736    (clobber (reg:CC FLAGS_REG))
3737    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3738   "!TARGET_64BIT"
3739   "#")
3741 (define_insn "extendsidi2_rex64"
3742   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3743         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3744   "TARGET_64BIT"
3745   "@
3746    {cltq|cdqe}
3747    movs{lq|x}\t{%1,%0|%0, %1}"
3748   [(set_attr "type" "imovx")
3749    (set_attr "mode" "DI")
3750    (set_attr "prefix_0f" "0")
3751    (set_attr "modrm" "0,1")])
3753 (define_insn "extendhidi2"
3754   [(set (match_operand:DI 0 "register_operand" "=r")
3755         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3756   "TARGET_64BIT"
3757   "movs{wq|x}\t{%1,%0|%0, %1}"
3758   [(set_attr "type" "imovx")
3759    (set_attr "mode" "DI")])
3761 (define_insn "extendqidi2"
3762   [(set (match_operand:DI 0 "register_operand" "=r")
3763         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3764   "TARGET_64BIT"
3765   "movs{bq|x}\t{%1,%0|%0, %1}"
3766    [(set_attr "type" "imovx")
3767     (set_attr "mode" "DI")])
3769 ;; Extend to memory case when source register does die.
3770 (define_split
3771   [(set (match_operand:DI 0 "memory_operand" "")
3772         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3773    (clobber (reg:CC FLAGS_REG))
3774    (clobber (match_operand:SI 2 "register_operand" ""))]
3775   "(reload_completed
3776     && dead_or_set_p (insn, operands[1])
3777     && !reg_mentioned_p (operands[1], operands[0]))"
3778   [(set (match_dup 3) (match_dup 1))
3779    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3780               (clobber (reg:CC FLAGS_REG))])
3781    (set (match_dup 4) (match_dup 1))]
3782   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3784 ;; Extend to memory case when source register does not die.
3785 (define_split
3786   [(set (match_operand:DI 0 "memory_operand" "")
3787         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3788    (clobber (reg:CC FLAGS_REG))
3789    (clobber (match_operand:SI 2 "register_operand" ""))]
3790   "reload_completed"
3791   [(const_int 0)]
3793   split_di (&operands[0], 1, &operands[3], &operands[4]);
3795   emit_move_insn (operands[3], operands[1]);
3797   /* Generate a cltd if possible and doing so it profitable.  */
3798   if ((optimize_size || TARGET_USE_CLTD)
3799       && true_regnum (operands[1]) == AX_REG
3800       && true_regnum (operands[2]) == DX_REG)
3801     {
3802       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3803     }
3804   else
3805     {
3806       emit_move_insn (operands[2], operands[1]);
3807       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3808     }
3809   emit_move_insn (operands[4], operands[2]);
3810   DONE;
3813 ;; Extend to register case.  Optimize case where source and destination
3814 ;; registers match and cases where we can use cltd.
3815 (define_split
3816   [(set (match_operand:DI 0 "register_operand" "")
3817         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3818    (clobber (reg:CC FLAGS_REG))
3819    (clobber (match_scratch:SI 2 ""))]
3820   "reload_completed"
3821   [(const_int 0)]
3823   split_di (&operands[0], 1, &operands[3], &operands[4]);
3825   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3826     emit_move_insn (operands[3], operands[1]);
3828   /* Generate a cltd if possible and doing so it profitable.  */
3829   if ((optimize_size || TARGET_USE_CLTD)
3830       && true_regnum (operands[3]) == AX_REG)
3831     {
3832       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3833       DONE;
3834     }
3836   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3837     emit_move_insn (operands[4], operands[1]);
3839   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3840   DONE;
3843 (define_insn "extendhisi2"
3844   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3845         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3846   ""
3848   switch (get_attr_prefix_0f (insn))
3849     {
3850     case 0:
3851       return "{cwtl|cwde}";
3852     default:
3853       return "movs{wl|x}\t{%1,%0|%0, %1}";
3854     }
3856   [(set_attr "type" "imovx")
3857    (set_attr "mode" "SI")
3858    (set (attr "prefix_0f")
3859      ;; movsx is short decodable while cwtl is vector decoded.
3860      (if_then_else (and (eq_attr "cpu" "!k6")
3861                         (eq_attr "alternative" "0"))
3862         (const_string "0")
3863         (const_string "1")))
3864    (set (attr "modrm")
3865      (if_then_else (eq_attr "prefix_0f" "0")
3866         (const_string "0")
3867         (const_string "1")))])
3869 (define_insn "*extendhisi2_zext"
3870   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3871         (zero_extend:DI
3872           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3873   "TARGET_64BIT"
3875   switch (get_attr_prefix_0f (insn))
3876     {
3877     case 0:
3878       return "{cwtl|cwde}";
3879     default:
3880       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3881     }
3883   [(set_attr "type" "imovx")
3884    (set_attr "mode" "SI")
3885    (set (attr "prefix_0f")
3886      ;; movsx is short decodable while cwtl is vector decoded.
3887      (if_then_else (and (eq_attr "cpu" "!k6")
3888                         (eq_attr "alternative" "0"))
3889         (const_string "0")
3890         (const_string "1")))
3891    (set (attr "modrm")
3892      (if_then_else (eq_attr "prefix_0f" "0")
3893         (const_string "0")
3894         (const_string "1")))])
3896 (define_insn "extendqihi2"
3897   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3898         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3899   ""
3901   switch (get_attr_prefix_0f (insn))
3902     {
3903     case 0:
3904       return "{cbtw|cbw}";
3905     default:
3906       return "movs{bw|x}\t{%1,%0|%0, %1}";
3907     }
3909   [(set_attr "type" "imovx")
3910    (set_attr "mode" "HI")
3911    (set (attr "prefix_0f")
3912      ;; movsx is short decodable while cwtl is vector decoded.
3913      (if_then_else (and (eq_attr "cpu" "!k6")
3914                         (eq_attr "alternative" "0"))
3915         (const_string "0")
3916         (const_string "1")))
3917    (set (attr "modrm")
3918      (if_then_else (eq_attr "prefix_0f" "0")
3919         (const_string "0")
3920         (const_string "1")))])
3922 (define_insn "extendqisi2"
3923   [(set (match_operand:SI 0 "register_operand" "=r")
3924         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3925   ""
3926   "movs{bl|x}\t{%1,%0|%0, %1}"
3927    [(set_attr "type" "imovx")
3928     (set_attr "mode" "SI")])
3930 (define_insn "*extendqisi2_zext"
3931   [(set (match_operand:DI 0 "register_operand" "=r")
3932         (zero_extend:DI
3933           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3934   "TARGET_64BIT"
3935   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3936    [(set_attr "type" "imovx")
3937     (set_attr "mode" "SI")])
3939 ;; Conversions between float and double.
3941 ;; These are all no-ops in the model used for the 80387.  So just
3942 ;; emit moves.
3944 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3945 (define_insn "*dummy_extendsfdf2"
3946   [(set (match_operand:DF 0 "push_operand" "=<")
3947         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3948   "0"
3949   "#")
3951 (define_split
3952   [(set (match_operand:DF 0 "push_operand" "")
3953         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3954   "!TARGET_64BIT"
3955   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
3956    (set (mem:DF (reg:SI SP_REG)) (float_extend:DF (match_dup 1)))])
3958 (define_split
3959   [(set (match_operand:DF 0 "push_operand" "")
3960         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3961   "TARGET_64BIT"
3962   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3963    (set (mem:DF (reg:DI SP_REG)) (float_extend:DF (match_dup 1)))])
3965 (define_insn "*dummy_extendsfxf2"
3966   [(set (match_operand:XF 0 "push_operand" "=<")
3967         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3968   "0"
3969   "#")
3971 (define_split
3972   [(set (match_operand:XF 0 "push_operand" "")
3973         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3974   ""
3975   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3976    (set (mem:XF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3977   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3979 (define_split
3980   [(set (match_operand:XF 0 "push_operand" "")
3981         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3982   "TARGET_64BIT"
3983   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
3984    (set (mem:DF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
3985   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3987 (define_split
3988   [(set (match_operand:XF 0 "push_operand" "")
3989         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3990   ""
3991   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (match_dup 2)))
3992    (set (mem:DF (reg:SI SP_REG)) (float_extend:XF (match_dup 1)))]
3993   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3995 (define_split
3996   [(set (match_operand:XF 0 "push_operand" "")
3997         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3998   "TARGET_64BIT"
3999   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (match_dup 2)))
4000    (set (mem:XF (reg:DI SP_REG)) (float_extend:XF (match_dup 1)))]
4001   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4003 (define_expand "extendsfdf2"
4004   [(set (match_operand:DF 0 "nonimmediate_operand" "")
4005         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4006   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4008   /* ??? Needed for compress_float_constant since all fp constants
4009      are LEGITIMATE_CONSTANT_P.  */
4010   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4011     {
4012       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4013           && standard_80387_constant_p (operands[1]) > 0)
4014         {
4015           operands[1] = simplify_const_unary_operation
4016             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4017           emit_move_insn_1 (operands[0], operands[1]);
4018           DONE;
4019         }
4020       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4021     }
4024 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4025    cvtss2sd:
4026       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4027       cvtps2pd xmm2,xmm1
4028    We do the conversion post reload to avoid producing of 128bit spills
4029    that might lead to ICE on 32bit target.  The sequence unlikely combine
4030    anyway.  */
4031 (define_split
4032   [(set (match_operand:DF 0 "register_operand" "")
4033         (float_extend:DF
4034           (match_operand:SF 1 "nonimmediate_operand" "")))]
4035   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4036    && reload_completed && SSE_REG_P (operands[0])"
4037    [(set (match_dup 2)
4038          (float_extend:V2DF
4039            (vec_select:V2SF
4040              (match_dup 3)
4041              (parallel [(const_int 0) (const_int 1)]))))]
4043   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4044   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4045   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4046      Try to avoid move when unpacking can be done in source.  */
4047   if (REG_P (operands[1]))
4048     {
4049       /* If it is unsafe to overwrite upper half of source, we need
4050          to move to destination and unpack there.  */
4051       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4052            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4053           && true_regnum (operands[0]) != true_regnum (operands[1]))
4054         {
4055           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4056           emit_move_insn (tmp, operands[1]);
4057         }
4058       else
4059         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4060       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4061     }
4062   else
4063     emit_insn (gen_vec_setv4sf_0 (operands[3],
4064                                   CONST0_RTX (V4SFmode), operands[1]));
4067 (define_insn "*extendsfdf2_mixed"
4068   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4069         (float_extend:DF
4070           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4071   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4073   switch (which_alternative)
4074     {
4075     case 0:
4076     case 1:
4077       return output_387_reg_move (insn, operands);
4079     case 2:
4080       return "cvtss2sd\t{%1, %0|%0, %1}";
4082     default:
4083       gcc_unreachable ();
4084     }
4086   [(set_attr "type" "fmov,fmov,ssecvt")
4087    (set_attr "mode" "SF,XF,DF")])
4089 (define_insn "*extendsfdf2_sse"
4090   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4091         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4092   "TARGET_SSE2 && TARGET_SSE_MATH"
4093   "cvtss2sd\t{%1, %0|%0, %1}"
4094   [(set_attr "type" "ssecvt")
4095    (set_attr "mode" "DF")])
4097 (define_insn "*extendsfdf2_i387"
4098   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4099         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4100   "TARGET_80387"
4101   "* return output_387_reg_move (insn, operands);"
4102   [(set_attr "type" "fmov")
4103    (set_attr "mode" "SF,XF")])
4105 (define_expand "extend<mode>xf2"
4106   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4107         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4108   "TARGET_80387"
4110   /* ??? Needed for compress_float_constant since all fp constants
4111      are LEGITIMATE_CONSTANT_P.  */
4112   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4113     {
4114       if (standard_80387_constant_p (operands[1]) > 0)
4115         {
4116           operands[1] = simplify_const_unary_operation
4117             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4118           emit_move_insn_1 (operands[0], operands[1]);
4119           DONE;
4120         }
4121       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4122     }
4125 (define_insn "*extend<mode>xf2_i387"
4126   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4127         (float_extend:XF
4128           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4129   "TARGET_80387"
4130   "* return output_387_reg_move (insn, operands);"
4131   [(set_attr "type" "fmov")
4132    (set_attr "mode" "<MODE>,XF")])
4134 ;; %%% This seems bad bad news.
4135 ;; This cannot output into an f-reg because there is no way to be sure
4136 ;; of truncating in that case.  Otherwise this is just like a simple move
4137 ;; insn.  So we pretend we can output to a reg in order to get better
4138 ;; register preferencing, but we really use a stack slot.
4140 ;; Conversion from DFmode to SFmode.
4142 (define_expand "truncdfsf2"
4143   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4144         (float_truncate:SF
4145           (match_operand:DF 1 "nonimmediate_operand" "")))]
4146   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4148   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4149     ;
4150   else if (flag_unsafe_math_optimizations)
4151     ;
4152   else
4153     {
4154       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4155       rtx temp = assign_386_stack_local (SFmode, slot);
4156       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4157       DONE;
4158     }
4161 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4162    cvtsd2ss:
4163       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4164       cvtpd2ps xmm2,xmm1
4165    We do the conversion post reload to avoid producing of 128bit spills
4166    that might lead to ICE on 32bit target.  The sequence unlikely combine
4167    anyway.  */
4168 (define_split
4169   [(set (match_operand:SF 0 "register_operand" "")
4170         (float_truncate:SF
4171           (match_operand:DF 1 "nonimmediate_operand" "")))]
4172   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4173    && reload_completed && SSE_REG_P (operands[0])"
4174    [(set (match_dup 2)
4175          (vec_concat:V4SF
4176            (float_truncate:V2SF
4177              (match_dup 4))
4178            (match_dup 3)))]
4180   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4181   operands[3] = CONST0_RTX (V2SFmode);
4182   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4183   /* Use movsd for loading from memory, unpcklpd for registers.
4184      Try to avoid move when unpacking can be done in source, or SSE3
4185      movddup is available.  */
4186   if (REG_P (operands[1]))
4187     {
4188       if (!TARGET_SSE3
4189           && true_regnum (operands[0]) != true_regnum (operands[1])
4190           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4191               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4192         {
4193           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4194           emit_move_insn (tmp, operands[1]);
4195           operands[1] = tmp;
4196         }
4197       else if (!TARGET_SSE3)
4198         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4199       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4200     }
4201   else
4202     emit_insn (gen_sse2_loadlpd (operands[4],
4203                                  CONST0_RTX (V2DFmode), operands[1]));
4206 (define_expand "truncdfsf2_with_temp"
4207   [(parallel [(set (match_operand:SF 0 "" "")
4208                    (float_truncate:SF (match_operand:DF 1 "" "")))
4209               (clobber (match_operand:SF 2 "" ""))])]
4210   "")
4212 (define_insn "*truncdfsf_fast_mixed"
4213   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4214         (float_truncate:SF
4215           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4216   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4218   switch (which_alternative)
4219     {
4220     case 0:
4221       return output_387_reg_move (insn, operands);
4222     case 1:
4223       return "cvtsd2ss\t{%1, %0|%0, %1}";
4224     default:
4225       gcc_unreachable ();
4226     }
4228   [(set_attr "type" "fmov,ssecvt")
4229    (set_attr "mode" "SF")])
4231 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4232 ;; because nothing we do here is unsafe.
4233 (define_insn "*truncdfsf_fast_sse"
4234   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4235         (float_truncate:SF
4236           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4237   "TARGET_SSE2 && TARGET_SSE_MATH"
4238   "cvtsd2ss\t{%1, %0|%0, %1}"
4239   [(set_attr "type" "ssecvt")
4240    (set_attr "mode" "SF")])
4242 (define_insn "*truncdfsf_fast_i387"
4243   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4244         (float_truncate:SF
4245           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4246   "TARGET_80387 && flag_unsafe_math_optimizations"
4247   "* return output_387_reg_move (insn, operands);"
4248   [(set_attr "type" "fmov")
4249    (set_attr "mode" "SF")])
4251 (define_insn "*truncdfsf_mixed"
4252   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4253         (float_truncate:SF
4254           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4255    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4256   "TARGET_MIX_SSE_I387"
4258   switch (which_alternative)
4259     {
4260     case 0:
4261       return output_387_reg_move (insn, operands);
4263     case 1:
4264       return "#";
4265     case 2:
4266       return "cvtsd2ss\t{%1, %0|%0, %1}";
4267     default:
4268       gcc_unreachable ();
4269     }
4271   [(set_attr "type" "fmov,multi,ssecvt")
4272    (set_attr "unit" "*,i387,*")
4273    (set_attr "mode" "SF")])
4275 (define_insn "*truncdfsf_i387"
4276   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4277         (float_truncate:SF
4278           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4279    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4280   "TARGET_80387"
4282   switch (which_alternative)
4283     {
4284     case 0:
4285       return output_387_reg_move (insn, operands);
4287     case 1:
4288       return "#";
4289     default:
4290       gcc_unreachable ();
4291     }
4293   [(set_attr "type" "fmov,multi")
4294    (set_attr "unit" "*,i387")
4295    (set_attr "mode" "SF")])
4297 (define_insn "*truncdfsf2_i387_1"
4298   [(set (match_operand:SF 0 "memory_operand" "=m")
4299         (float_truncate:SF
4300           (match_operand:DF 1 "register_operand" "f")))]
4301   "TARGET_80387
4302    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4303    && !TARGET_MIX_SSE_I387"
4304   "* return output_387_reg_move (insn, operands);"
4305   [(set_attr "type" "fmov")
4306    (set_attr "mode" "SF")])
4308 (define_split
4309   [(set (match_operand:SF 0 "register_operand" "")
4310         (float_truncate:SF
4311          (match_operand:DF 1 "fp_register_operand" "")))
4312    (clobber (match_operand 2 "" ""))]
4313   "reload_completed"
4314   [(set (match_dup 2) (match_dup 1))
4315    (set (match_dup 0) (match_dup 2))]
4317   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4320 ;; Conversion from XFmode to {SF,DF}mode
4322 (define_expand "truncxf<mode>2"
4323   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4324                    (float_truncate:MODEF
4325                      (match_operand:XF 1 "register_operand" "")))
4326               (clobber (match_dup 2))])]
4327   "TARGET_80387"
4329   if (flag_unsafe_math_optimizations)
4330     {
4331       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4332       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4333       if (reg != operands[0])
4334         emit_move_insn (operands[0], reg);
4335       DONE;
4336     }
4337   else
4338     {
4339       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4340       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4341     }
4344 (define_insn "*truncxfsf2_mixed"
4345   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4346         (float_truncate:SF
4347           (match_operand:XF 1 "register_operand" "f,f")))
4348    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4349   "TARGET_80387"
4351   gcc_assert (!which_alternative);
4352   return output_387_reg_move (insn, operands);
4354   [(set_attr "type" "fmov,multi")
4355    (set_attr "unit" "*,i387")
4356    (set_attr "mode" "SF")])
4358 (define_insn "*truncxfdf2_mixed"
4359   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4360         (float_truncate:DF
4361           (match_operand:XF 1 "register_operand" "f,f")))
4362    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4363   "TARGET_80387"
4365   gcc_assert (!which_alternative);
4366   return output_387_reg_move (insn, operands);
4368   [(set_attr "type" "fmov,multi")
4369    (set_attr "unit" "*,i387")
4370    (set_attr "mode" "DF")])
4372 (define_insn "truncxf<mode>2_i387_noop"
4373   [(set (match_operand:MODEF 0 "register_operand" "=f")
4374         (float_truncate:MODEF
4375           (match_operand:XF 1 "register_operand" "f")))]
4376   "TARGET_80387 && flag_unsafe_math_optimizations"
4377   "* return output_387_reg_move (insn, operands);"
4378   [(set_attr "type" "fmov")
4379    (set_attr "mode" "<MODE>")])
4381 (define_insn "*truncxf<mode>2_i387"
4382   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4383         (float_truncate:MODEF
4384           (match_operand:XF 1 "register_operand" "f")))]
4385   "TARGET_80387"
4386   "* return output_387_reg_move (insn, operands);"
4387   [(set_attr "type" "fmov")
4388    (set_attr "mode" "<MODE>")])
4390 (define_split
4391   [(set (match_operand:MODEF 0 "register_operand" "")
4392         (float_truncate:MODEF
4393           (match_operand:XF 1 "register_operand" "")))
4394    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4395   "TARGET_80387 && reload_completed"
4396   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4397    (set (match_dup 0) (match_dup 2))]
4398   "")
4400 (define_split
4401   [(set (match_operand:MODEF 0 "memory_operand" "")
4402         (float_truncate:MODEF
4403           (match_operand:XF 1 "register_operand" "")))
4404    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4405   "TARGET_80387"
4406   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4407   "")
4409 ;; Signed conversion to DImode.
4411 (define_expand "fix_truncxfdi2"
4412   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4413                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4414               (clobber (reg:CC FLAGS_REG))])]
4415   "TARGET_80387"
4417   if (TARGET_FISTTP)
4418    {
4419      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4420      DONE;
4421    }
4424 (define_expand "fix_trunc<mode>di2"
4425   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4426                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4427               (clobber (reg:CC FLAGS_REG))])]
4428   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4430   if (TARGET_FISTTP
4431       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4432    {
4433      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4434      DONE;
4435    }
4436   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4437    {
4438      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4439      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4440      if (out != operands[0])
4441         emit_move_insn (operands[0], out);
4442      DONE;
4443    }
4446 ;; Signed conversion to SImode.
4448 (define_expand "fix_truncxfsi2"
4449   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4450                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4451               (clobber (reg:CC FLAGS_REG))])]
4452   "TARGET_80387"
4454   if (TARGET_FISTTP)
4455    {
4456      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4457      DONE;
4458    }
4461 (define_expand "fix_trunc<mode>si2"
4462   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4463                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4464               (clobber (reg:CC FLAGS_REG))])]
4465   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4467   if (TARGET_FISTTP
4468       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4469    {
4470      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4471      DONE;
4472    }
4473   if (SSE_FLOAT_MODE_P (<MODE>mode))
4474    {
4475      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4476      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4477      if (out != operands[0])
4478         emit_move_insn (operands[0], out);
4479      DONE;
4480    }
4483 ;; Signed conversion to HImode.
4485 (define_expand "fix_trunc<mode>hi2"
4486   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4487                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4488               (clobber (reg:CC FLAGS_REG))])]
4489   "TARGET_80387
4490    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4492   if (TARGET_FISTTP)
4493    {
4494      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4495      DONE;
4496    }
4499 ;; Unsigned conversion to SImode.
4501 (define_expand "fixuns_trunc<mode>si2"
4502   [(parallel
4503     [(set (match_operand:SI 0 "register_operand" "")
4504           (unsigned_fix:SI
4505             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4506      (use (match_dup 2))
4507      (clobber (match_scratch:<ssevecmode> 3 ""))
4508      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4509   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4511   enum machine_mode mode = <MODE>mode;
4512   enum machine_mode vecmode = <ssevecmode>mode;
4513   REAL_VALUE_TYPE TWO31r;
4514   rtx two31;
4516   real_ldexp (&TWO31r, &dconst1, 31);
4517   two31 = const_double_from_real_value (TWO31r, mode);
4518   two31 = ix86_build_const_vector (mode, true, two31);
4519   operands[2] = force_reg (vecmode, two31);
4522 (define_insn_and_split "*fixuns_trunc<mode>_1"
4523   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4524         (unsigned_fix:SI
4525           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4526    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4527    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4528    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4529   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4530   "#"
4531   "&& reload_completed"
4532   [(const_int 0)]
4534   ix86_split_convert_uns_si_sse (operands);
4535   DONE;
4538 ;; Unsigned conversion to HImode.
4539 ;; Without these patterns, we'll try the unsigned SI conversion which
4540 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4542 (define_expand "fixuns_trunc<mode>hi2"
4543   [(set (match_dup 2)
4544         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4545    (set (match_operand:HI 0 "nonimmediate_operand" "")
4546         (subreg:HI (match_dup 2) 0))]
4547   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4548   "operands[2] = gen_reg_rtx (SImode);")
4550 ;; When SSE is available, it is always faster to use it!
4551 (define_insn "fix_trunc<mode>di_sse"
4552   [(set (match_operand:DI 0 "register_operand" "=r,r")
4553         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4554   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4555    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4556   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4557   [(set_attr "type" "sseicvt")
4558    (set_attr "mode" "<MODE>")
4559    (set_attr "athlon_decode" "double,vector")
4560    (set_attr "amdfam10_decode" "double,double")])
4562 (define_insn "fix_trunc<mode>si_sse"
4563   [(set (match_operand:SI 0 "register_operand" "=r,r")
4564         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4565   "SSE_FLOAT_MODE_P (<MODE>mode)
4566    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4567   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4568   [(set_attr "type" "sseicvt")
4569    (set_attr "mode" "<MODE>")
4570    (set_attr "athlon_decode" "double,vector")
4571    (set_attr "amdfam10_decode" "double,double")])
4573 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4574 (define_peephole2
4575   [(set (match_operand:MODEF 0 "register_operand" "")
4576         (match_operand:MODEF 1 "memory_operand" ""))
4577    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4578         (fix:SSEMODEI24 (match_dup 0)))]
4579   "TARGET_SHORTEN_X87_SSE
4580    && peep2_reg_dead_p (2, operands[0])"
4581   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4582   "")
4584 ;; Avoid vector decoded forms of the instruction.
4585 (define_peephole2
4586   [(match_scratch:DF 2 "Y2")
4587    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4588         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4589   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4590   [(set (match_dup 2) (match_dup 1))
4591    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4592   "")
4594 (define_peephole2
4595   [(match_scratch:SF 2 "x")
4596    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4597         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4598   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4599   [(set (match_dup 2) (match_dup 1))
4600    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4601   "")
4603 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4604   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4605         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4606   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4607    && TARGET_FISTTP
4608    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4609          && (TARGET_64BIT || <MODE>mode != DImode))
4610         && TARGET_SSE_MATH)
4611    && !(reload_completed || reload_in_progress)"
4612   "#"
4613   "&& 1"
4614   [(const_int 0)]
4616   if (memory_operand (operands[0], VOIDmode))
4617     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4618   else
4619     {
4620       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4621       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4622                                                             operands[1],
4623                                                             operands[2]));
4624     }
4625   DONE;
4627   [(set_attr "type" "fisttp")
4628    (set_attr "mode" "<MODE>")])
4630 (define_insn "fix_trunc<mode>_i387_fisttp"
4631   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4632         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4633    (clobber (match_scratch:XF 2 "=&1f"))]
4634   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4635    && TARGET_FISTTP
4636    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4637          && (TARGET_64BIT || <MODE>mode != DImode))
4638         && TARGET_SSE_MATH)"
4639   "* return output_fix_trunc (insn, operands, 1);"
4640   [(set_attr "type" "fisttp")
4641    (set_attr "mode" "<MODE>")])
4643 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4644   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4645         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4646    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4647    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4648   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4649    && TARGET_FISTTP
4650    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4651         && (TARGET_64BIT || <MODE>mode != DImode))
4652         && TARGET_SSE_MATH)"
4653   "#"
4654   [(set_attr "type" "fisttp")
4655    (set_attr "mode" "<MODE>")])
4657 (define_split
4658   [(set (match_operand:X87MODEI 0 "register_operand" "")
4659         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4660    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4661    (clobber (match_scratch 3 ""))]
4662   "reload_completed"
4663   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4664               (clobber (match_dup 3))])
4665    (set (match_dup 0) (match_dup 2))]
4666   "")
4668 (define_split
4669   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4670         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4671    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4672    (clobber (match_scratch 3 ""))]
4673   "reload_completed"
4674   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4675               (clobber (match_dup 3))])]
4676   "")
4678 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4679 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4680 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4681 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4682 ;; function in i386.c.
4683 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4684   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4685         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4686    (clobber (reg:CC FLAGS_REG))]
4687   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4688    && !TARGET_FISTTP
4689    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4690          && (TARGET_64BIT || <MODE>mode != DImode))
4691    && !(reload_completed || reload_in_progress)"
4692   "#"
4693   "&& 1"
4694   [(const_int 0)]
4696   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4698   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4699   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4700   if (memory_operand (operands[0], VOIDmode))
4701     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4702                                          operands[2], operands[3]));
4703   else
4704     {
4705       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4706       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4707                                                      operands[2], operands[3],
4708                                                      operands[4]));
4709     }
4710   DONE;
4712   [(set_attr "type" "fistp")
4713    (set_attr "i387_cw" "trunc")
4714    (set_attr "mode" "<MODE>")])
4716 (define_insn "fix_truncdi_i387"
4717   [(set (match_operand:DI 0 "memory_operand" "=m")
4718         (fix:DI (match_operand 1 "register_operand" "f")))
4719    (use (match_operand:HI 2 "memory_operand" "m"))
4720    (use (match_operand:HI 3 "memory_operand" "m"))
4721    (clobber (match_scratch:XF 4 "=&1f"))]
4722   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4723    && !TARGET_FISTTP
4724    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4725   "* return output_fix_trunc (insn, operands, 0);"
4726   [(set_attr "type" "fistp")
4727    (set_attr "i387_cw" "trunc")
4728    (set_attr "mode" "DI")])
4730 (define_insn "fix_truncdi_i387_with_temp"
4731   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4732         (fix:DI (match_operand 1 "register_operand" "f,f")))
4733    (use (match_operand:HI 2 "memory_operand" "m,m"))
4734    (use (match_operand:HI 3 "memory_operand" "m,m"))
4735    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4736    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4737   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4738    && !TARGET_FISTTP
4739    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4740   "#"
4741   [(set_attr "type" "fistp")
4742    (set_attr "i387_cw" "trunc")
4743    (set_attr "mode" "DI")])
4745 (define_split
4746   [(set (match_operand:DI 0 "register_operand" "")
4747         (fix:DI (match_operand 1 "register_operand" "")))
4748    (use (match_operand:HI 2 "memory_operand" ""))
4749    (use (match_operand:HI 3 "memory_operand" ""))
4750    (clobber (match_operand:DI 4 "memory_operand" ""))
4751    (clobber (match_scratch 5 ""))]
4752   "reload_completed"
4753   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4754               (use (match_dup 2))
4755               (use (match_dup 3))
4756               (clobber (match_dup 5))])
4757    (set (match_dup 0) (match_dup 4))]
4758   "")
4760 (define_split
4761   [(set (match_operand:DI 0 "memory_operand" "")
4762         (fix:DI (match_operand 1 "register_operand" "")))
4763    (use (match_operand:HI 2 "memory_operand" ""))
4764    (use (match_operand:HI 3 "memory_operand" ""))
4765    (clobber (match_operand:DI 4 "memory_operand" ""))
4766    (clobber (match_scratch 5 ""))]
4767   "reload_completed"
4768   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4769               (use (match_dup 2))
4770               (use (match_dup 3))
4771               (clobber (match_dup 5))])]
4772   "")
4774 (define_insn "fix_trunc<mode>_i387"
4775   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4776         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4777    (use (match_operand:HI 2 "memory_operand" "m"))
4778    (use (match_operand:HI 3 "memory_operand" "m"))]
4779   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4780    && !TARGET_FISTTP
4781    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4782   "* return output_fix_trunc (insn, operands, 0);"
4783   [(set_attr "type" "fistp")
4784    (set_attr "i387_cw" "trunc")
4785    (set_attr "mode" "<MODE>")])
4787 (define_insn "fix_trunc<mode>_i387_with_temp"
4788   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4789         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4790    (use (match_operand:HI 2 "memory_operand" "m,m"))
4791    (use (match_operand:HI 3 "memory_operand" "m,m"))
4792    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4793   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4794    && !TARGET_FISTTP
4795    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4796   "#"
4797   [(set_attr "type" "fistp")
4798    (set_attr "i387_cw" "trunc")
4799    (set_attr "mode" "<MODE>")])
4801 (define_split
4802   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4803         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4804    (use (match_operand:HI 2 "memory_operand" ""))
4805    (use (match_operand:HI 3 "memory_operand" ""))
4806    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4807   "reload_completed"
4808   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4809               (use (match_dup 2))
4810               (use (match_dup 3))])
4811    (set (match_dup 0) (match_dup 4))]
4812   "")
4814 (define_split
4815   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4816         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4817    (use (match_operand:HI 2 "memory_operand" ""))
4818    (use (match_operand:HI 3 "memory_operand" ""))
4819    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4820   "reload_completed"
4821   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4822               (use (match_dup 2))
4823               (use (match_dup 3))])]
4824   "")
4826 (define_insn "x86_fnstcw_1"
4827   [(set (match_operand:HI 0 "memory_operand" "=m")
4828         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4829   "TARGET_80387"
4830   "fnstcw\t%0"
4831   [(set_attr "length" "2")
4832    (set_attr "mode" "HI")
4833    (set_attr "unit" "i387")])
4835 (define_insn "x86_fldcw_1"
4836   [(set (reg:HI FPCR_REG)
4837         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4838   "TARGET_80387"
4839   "fldcw\t%0"
4840   [(set_attr "length" "2")
4841    (set_attr "mode" "HI")
4842    (set_attr "unit" "i387")
4843    (set_attr "athlon_decode" "vector")
4844    (set_attr "amdfam10_decode" "vector")])
4846 ;; Conversion between fixed point and floating point.
4848 ;; Even though we only accept memory inputs, the backend _really_
4849 ;; wants to be able to do this between registers.
4851 (define_expand "floathi<mode>2"
4852   [(set (match_operand:X87MODEF 0 "register_operand" "")
4853         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4854   "TARGET_80387
4855    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4856        || TARGET_MIX_SSE_I387)"
4857   "")
4859 ;; Pre-reload splitter to add memory clobber to the pattern.
4860 (define_insn_and_split "*floathi<mode>2_1"
4861   [(set (match_operand:X87MODEF 0 "register_operand" "")
4862         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4863   "TARGET_80387
4864    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4865        || TARGET_MIX_SSE_I387)
4866    && !(reload_completed || reload_in_progress)"
4867   "#"
4868   "&& 1"
4869   [(parallel [(set (match_dup 0)
4870               (float:X87MODEF (match_dup 1)))
4871    (clobber (match_dup 2))])]
4872   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4874 (define_insn "*floathi<mode>2_i387_with_temp"
4875   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4876         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4877   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4878   "TARGET_80387
4879    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4880        || TARGET_MIX_SSE_I387)"
4881   "#"
4882   [(set_attr "type" "fmov,multi")
4883    (set_attr "mode" "<MODE>")
4884    (set_attr "unit" "*,i387")
4885    (set_attr "fp_int_src" "true")])
4887 (define_insn "*floathi<mode>2_i387"
4888   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4889         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4890   "TARGET_80387
4891    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4892        || TARGET_MIX_SSE_I387)"
4893   "fild%z1\t%1"
4894   [(set_attr "type" "fmov")
4895    (set_attr "mode" "<MODE>")
4896    (set_attr "fp_int_src" "true")])
4898 (define_split
4899   [(set (match_operand:X87MODEF 0 "register_operand" "")
4900         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4901    (clobber (match_operand:HI 2 "memory_operand" ""))]
4902   "TARGET_80387
4903    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4904        || TARGET_MIX_SSE_I387)
4905    && reload_completed"
4906   [(set (match_dup 2) (match_dup 1))
4907    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4908   "")
4910 (define_split
4911   [(set (match_operand:X87MODEF 0 "register_operand" "")
4912         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4913    (clobber (match_operand:HI 2 "memory_operand" ""))]
4914    "TARGET_80387
4915     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4916         || TARGET_MIX_SSE_I387)
4917     && reload_completed"
4918   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
4919   "")
4921 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4922   [(set (match_operand:X87MODEF 0 "register_operand" "")
4923         (float:X87MODEF
4924           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4925   "TARGET_80387
4926    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4927        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4928   "")
4930 ;; Pre-reload splitter to add memory clobber to the pattern.
4931 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4932   [(set (match_operand:X87MODEF 0 "register_operand" "")
4933         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4934   "((TARGET_80387
4935      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4936            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4937          || TARGET_MIX_SSE_I387))
4938     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4939         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4940         && ((<SSEMODEI24:MODE>mode == SImode
4941              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4942              && flag_trapping_math)
4943             || !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size))))
4944    && !(reload_completed || reload_in_progress)"
4945   "#"
4946   "&& 1"
4947   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4948               (clobber (match_dup 2))])]
4950   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4952   /* Avoid store forwarding (partial memory) stall penalty
4953      by passing DImode value through XMM registers.  */
4954   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT 
4955       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 
4956       && !optimize_size)
4957     {
4958       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4959                                                             operands[1],
4960                                                             operands[2]));
4961       DONE;
4962     }
4965 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4966   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4967         (float:MODEF
4968           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4969    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4970   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4971    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4972   "#"
4973   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4974    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4975    (set_attr "unit" "*,i387,*,*,*")
4976    (set_attr "athlon_decode" "*,*,double,direct,double")
4977    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4978    (set_attr "fp_int_src" "true")])
4980 (define_insn "*floatsi<mode>2_vector_mixed"
4981   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4982         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4983   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4984    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4985   "@
4986    fild%z1\t%1
4987    #"
4988   [(set_attr "type" "fmov,sseicvt")
4989    (set_attr "mode" "<MODE>,<ssevecmode>")
4990    (set_attr "unit" "i387,*")
4991    (set_attr "athlon_decode" "*,direct")
4992    (set_attr "amdfam10_decode" "*,double")
4993    (set_attr "fp_int_src" "true")])
4995 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4996   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4997         (float:MODEF
4998           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4999   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5000   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5001    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5002   "#"
5003   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5004    (set_attr "mode" "<MODEF:MODE>")
5005    (set_attr "unit" "*,i387,*,*")
5006    (set_attr "athlon_decode" "*,*,double,direct")
5007    (set_attr "amdfam10_decode" "*,*,vector,double")
5008    (set_attr "fp_int_src" "true")])
5010 (define_split
5011   [(set (match_operand:MODEF 0 "register_operand" "")
5012         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5013    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5014   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5015    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5016    && TARGET_INTER_UNIT_CONVERSIONS
5017    && reload_completed
5018    && (SSE_REG_P (operands[0])
5019        || (GET_CODE (operands[0]) == SUBREG
5020            && SSE_REG_P (operands[0])))"
5021   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5022   "")
5024 (define_split
5025   [(set (match_operand:MODEF 0 "register_operand" "")
5026         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5027    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5028   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5029    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5030    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5031    && reload_completed
5032    && (SSE_REG_P (operands[0])
5033        || (GET_CODE (operands[0]) == SUBREG
5034            && SSE_REG_P (operands[0])))"
5035   [(set (match_dup 2) (match_dup 1))
5036    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5037   "")
5039 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5040   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5041         (float:MODEF
5042           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5043   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5044    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5045    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5046   "@
5047    fild%z1\t%1
5048    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5049    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5050   [(set_attr "type" "fmov,sseicvt,sseicvt")
5051    (set_attr "mode" "<MODEF:MODE>")
5052    (set_attr "unit" "i387,*,*")
5053    (set_attr "athlon_decode" "*,double,direct")
5054    (set_attr "amdfam10_decode" "*,vector,double")
5055    (set_attr "fp_int_src" "true")])
5057 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5058   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5059         (float:MODEF
5060           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5061   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5062    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5063    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5064   "@
5065    fild%z1\t%1
5066    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5067   [(set_attr "type" "fmov,sseicvt")
5068    (set_attr "mode" "<MODEF:MODE>")
5069    (set_attr "athlon_decode" "*,direct")
5070    (set_attr "amdfam10_decode" "*,double")
5071    (set_attr "fp_int_src" "true")])
5073 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5074   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5075         (float:MODEF
5076           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5077    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5078   "TARGET_SSE2 && TARGET_SSE_MATH
5079    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5080   "#"
5081   [(set_attr "type" "sseicvt")
5082    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5083    (set_attr "athlon_decode" "double,direct,double")
5084    (set_attr "amdfam10_decode" "vector,double,double")
5085    (set_attr "fp_int_src" "true")])
5087 (define_insn "*floatsi<mode>2_vector_sse"
5088   [(set (match_operand:MODEF 0 "register_operand" "=x")
5089         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5090   "TARGET_SSE2 && TARGET_SSE_MATH
5091    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5092   "#"
5093   [(set_attr "type" "sseicvt")
5094    (set_attr "mode" "<MODE>")
5095    (set_attr "athlon_decode" "direct")
5096    (set_attr "amdfam10_decode" "double")
5097    (set_attr "fp_int_src" "true")])
5099 (define_split
5100   [(set (match_operand:MODEF 0 "register_operand" "")
5101         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5102    (clobber (match_operand:SI 2 "memory_operand" ""))]
5103   "TARGET_SSE2 && TARGET_SSE_MATH
5104    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5105    && reload_completed
5106    && (SSE_REG_P (operands[0])
5107        || (GET_CODE (operands[0]) == SUBREG
5108            && SSE_REG_P (operands[0])))"
5109   [(const_int 0)]
5111   rtx op1 = operands[1];
5113   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5114                                      <MODE>mode, 0);
5115   if (GET_CODE (op1) == SUBREG)
5116     op1 = SUBREG_REG (op1);
5118   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5119     {
5120       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5121       emit_insn (gen_sse2_loadld (operands[4],
5122                                   CONST0_RTX (V4SImode), operands[1]));
5123     }
5124   /* We can ignore possible trapping value in the
5125      high part of SSE register for non-trapping math. */
5126   else if (SSE_REG_P (op1) && !flag_trapping_math)
5127     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5128   else
5129     {
5130       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5131       emit_move_insn (operands[2], operands[1]);
5132       emit_insn (gen_sse2_loadld (operands[4],
5133                                   CONST0_RTX (V4SImode), operands[2]));
5134     }
5135   emit_insn
5136     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5137   DONE;
5140 (define_split
5141   [(set (match_operand:MODEF 0 "register_operand" "")
5142         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5143    (clobber (match_operand:SI 2 "memory_operand" ""))]
5144   "TARGET_SSE2 && TARGET_SSE_MATH
5145    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5146    && reload_completed
5147    && (SSE_REG_P (operands[0])
5148        || (GET_CODE (operands[0]) == SUBREG
5149            && SSE_REG_P (operands[0])))"
5150   [(const_int 0)]
5152   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5153                                      <MODE>mode, 0);
5154   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5156   emit_insn (gen_sse2_loadld (operands[4],
5157                               CONST0_RTX (V4SImode), operands[1]));
5158   emit_insn
5159     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5160   DONE;
5163 (define_split
5164   [(set (match_operand:MODEF 0 "register_operand" "")
5165         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5166   "TARGET_SSE2 && TARGET_SSE_MATH
5167    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5168    && reload_completed
5169    && (SSE_REG_P (operands[0])
5170        || (GET_CODE (operands[0]) == SUBREG
5171            && SSE_REG_P (operands[0])))"
5172   [(const_int 0)]
5174   rtx op1 = operands[1];
5176   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5177                                      <MODE>mode, 0);
5178   if (GET_CODE (op1) == SUBREG)
5179     op1 = SUBREG_REG (op1);
5181   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5182     {
5183       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5184       emit_insn (gen_sse2_loadld (operands[4],
5185                                   CONST0_RTX (V4SImode), operands[1]));
5186     }
5187   /* We can ignore possible trapping value in the
5188      high part of SSE register for non-trapping math. */
5189   else if (SSE_REG_P (op1) && !flag_trapping_math)
5190     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5191   else
5192     gcc_unreachable ();
5195 (define_split
5196   [(set (match_operand:MODEF 0 "register_operand" "")
5197         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5198   "TARGET_SSE2 && TARGET_SSE_MATH
5199    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5200    && reload_completed
5201    && (SSE_REG_P (operands[0])
5202        || (GET_CODE (operands[0]) == SUBREG
5203            && SSE_REG_P (operands[0])))"
5204   [(const_int 0)]
5206   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5207                                      <MODE>mode, 0);
5208   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5210   emit_insn (gen_sse2_loadld (operands[4],
5211                               CONST0_RTX (V4SImode), operands[1]));
5212   emit_insn
5213     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5214   DONE;
5217 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5218   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5219         (float:MODEF
5220           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5221   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5222   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5223    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5224   "#"
5225   [(set_attr "type" "sseicvt")
5226    (set_attr "mode" "<MODEF:MODE>")
5227    (set_attr "athlon_decode" "double,direct")
5228    (set_attr "amdfam10_decode" "vector,double")
5229    (set_attr "fp_int_src" "true")])
5231 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5232   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5233         (float:MODEF
5234           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5235   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5236    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5237    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5238   "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5239   [(set_attr "type" "sseicvt")
5240    (set_attr "mode" "<MODEF:MODE>")
5241    (set_attr "athlon_decode" "double,direct")
5242    (set_attr "amdfam10_decode" "vector,double")
5243    (set_attr "fp_int_src" "true")])
5245 (define_split
5246   [(set (match_operand:MODEF 0 "register_operand" "")
5247         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5248    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5249   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5250    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5251    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5252    && reload_completed
5253    && (SSE_REG_P (operands[0])
5254        || (GET_CODE (operands[0]) == SUBREG
5255            && SSE_REG_P (operands[0])))"
5256   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5257   "")
5259 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5260   [(set (match_operand:MODEF 0 "register_operand" "=x")
5261         (float:MODEF
5262           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5263   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5264    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5265    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5266   "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5267   [(set_attr "type" "sseicvt")
5268    (set_attr "mode" "<MODEF:MODE>")
5269    (set_attr "athlon_decode" "direct")
5270    (set_attr "amdfam10_decode" "double")
5271    (set_attr "fp_int_src" "true")])
5273 (define_split
5274   [(set (match_operand:MODEF 0 "register_operand" "")
5275         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5276    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5277   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5278    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5279    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5280    && reload_completed
5281    && (SSE_REG_P (operands[0])
5282        || (GET_CODE (operands[0]) == SUBREG
5283            && SSE_REG_P (operands[0])))"
5284   [(set (match_dup 2) (match_dup 1))
5285    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5286   "")
5288 (define_split
5289   [(set (match_operand:MODEF 0 "register_operand" "")
5290         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5291    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5292   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5293    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5294    && reload_completed
5295    && (SSE_REG_P (operands[0])
5296        || (GET_CODE (operands[0]) == SUBREG
5297            && SSE_REG_P (operands[0])))"
5298   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5299   "")
5301 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5302   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5303         (float:X87MODEF
5304           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5305   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5306   "TARGET_80387"
5307   "@
5308    fild%z1\t%1
5309    #"
5310   [(set_attr "type" "fmov,multi")
5311    (set_attr "mode" "<X87MODEF:MODE>")
5312    (set_attr "unit" "*,i387")
5313    (set_attr "fp_int_src" "true")])
5315 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5316   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5317         (float:X87MODEF
5318           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5319   "TARGET_80387"
5320   "fild%z1\t%1"
5321   [(set_attr "type" "fmov")
5322    (set_attr "mode" "<X87MODEF:MODE>")
5323    (set_attr "fp_int_src" "true")])
5325 (define_split
5326   [(set (match_operand:X87MODEF 0 "register_operand" "")
5327         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5328    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5329   "TARGET_80387
5330    && reload_completed
5331    && FP_REG_P (operands[0])"
5332   [(set (match_dup 2) (match_dup 1))
5333    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5334   "")
5336 (define_split
5337   [(set (match_operand:X87MODEF 0 "register_operand" "")
5338         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5339    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5340   "TARGET_80387
5341    && reload_completed
5342    && FP_REG_P (operands[0])"
5343   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5344   "")
5346 ;; Avoid store forwarding (partial memory) stall penalty
5347 ;; by passing DImode value through XMM registers.  */
5349 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5350   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5351         (float:X87MODEF
5352           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5353    (clobber (match_scratch:V4SI 3 "=X,x"))
5354    (clobber (match_scratch:V4SI 4 "=X,x"))
5355    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5356   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5357    && !TARGET_64BIT && !optimize_size"
5358   "#"
5359   [(set_attr "type" "multi")
5360    (set_attr "mode" "<X87MODEF:MODE>")
5361    (set_attr "unit" "i387")
5362    (set_attr "fp_int_src" "true")])
5364 (define_split
5365   [(set (match_operand:X87MODEF 0 "register_operand" "")
5366         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5367    (clobber (match_scratch:V4SI 3 ""))
5368    (clobber (match_scratch:V4SI 4 ""))
5369    (clobber (match_operand:DI 2 "memory_operand" ""))]
5370   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5371    && !TARGET_64BIT && !optimize_size
5372    && reload_completed
5373    && FP_REG_P (operands[0])"
5374   [(set (match_dup 2) (match_dup 3))
5375    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5377   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5378      Assemble the 64-bit DImode value in an xmm register.  */
5379   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5380                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5381   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5382                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5383   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5385   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5388 (define_split
5389   [(set (match_operand:X87MODEF 0 "register_operand" "")
5390         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5391    (clobber (match_scratch:V4SI 3 ""))
5392    (clobber (match_scratch:V4SI 4 ""))
5393    (clobber (match_operand:DI 2 "memory_operand" ""))]
5394   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5395    && !TARGET_64BIT && !optimize_size
5396    && reload_completed
5397    && FP_REG_P (operands[0])"
5398   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5399   "")
5401 ;; Avoid store forwarding (partial memory) stall penalty by extending
5402 ;; SImode value to DImode through XMM register instead of pushing two
5403 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5404 ;; targets benefit from this optimization. Also note that fild
5405 ;; loads from memory only.
5407 (define_insn "*floatunssi<mode>2_1"
5408   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5409         (unsigned_float:X87MODEF
5410           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5411    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5412    (clobber (match_scratch:SI 3 "=X,x"))]
5413   "!TARGET_64BIT
5414    && TARGET_80387 && TARGET_SSE"
5415   "#"
5416   [(set_attr "type" "multi")
5417    (set_attr "mode" "<MODE>")])
5419 (define_split
5420   [(set (match_operand:X87MODEF 0 "register_operand" "")
5421         (unsigned_float:X87MODEF
5422           (match_operand:SI 1 "register_operand" "")))
5423    (clobber (match_operand:DI 2 "memory_operand" ""))
5424    (clobber (match_scratch:SI 3 ""))]
5425   "!TARGET_64BIT
5426    && TARGET_80387 && TARGET_SSE
5427    && reload_completed"
5428   [(set (match_dup 2) (match_dup 1))
5429    (set (match_dup 0)
5430         (float:X87MODEF (match_dup 2)))]
5431   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5433 (define_split
5434   [(set (match_operand:X87MODEF 0 "register_operand" "")
5435         (unsigned_float:X87MODEF
5436           (match_operand:SI 1 "memory_operand" "")))
5437    (clobber (match_operand:DI 2 "memory_operand" ""))
5438    (clobber (match_scratch:SI 3 ""))]
5439   "!TARGET_64BIT
5440    && TARGET_80387 && TARGET_SSE
5441    && reload_completed"
5442   [(set (match_dup 2) (match_dup 3))
5443    (set (match_dup 0)
5444         (float:X87MODEF (match_dup 2)))]
5446   emit_move_insn (operands[3], operands[1]);
5447   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5450 (define_expand "floatunssi<mode>2"
5451   [(parallel
5452      [(set (match_operand:X87MODEF 0 "register_operand" "")
5453            (unsigned_float:X87MODEF
5454              (match_operand:SI 1 "nonimmediate_operand" "")))
5455       (clobber (match_dup 2))
5456       (clobber (match_scratch:SI 3 ""))])]
5457   "!TARGET_64BIT
5458    && ((TARGET_80387 && TARGET_SSE)
5459        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5461   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5462     {
5463       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5464       DONE;
5465     }
5466   else
5467     {
5468       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5469       operands[2] = assign_386_stack_local (DImode, slot);
5470     }
5473 (define_expand "floatunsdisf2"
5474   [(use (match_operand:SF 0 "register_operand" ""))
5475    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5476   "TARGET_64BIT && TARGET_SSE_MATH"
5477   "x86_emit_floatuns (operands); DONE;")
5479 (define_expand "floatunsdidf2"
5480   [(use (match_operand:DF 0 "register_operand" ""))
5481    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5482   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5483    && TARGET_SSE2 && TARGET_SSE_MATH"
5485   if (TARGET_64BIT)
5486     x86_emit_floatuns (operands);
5487   else
5488     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5489   DONE;
5492 ;; Add instructions
5494 ;; %%% splits for addditi3
5496 (define_expand "addti3"
5497   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5498         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5499                  (match_operand:TI 2 "x86_64_general_operand" "")))
5500    (clobber (reg:CC FLAGS_REG))]
5501   "TARGET_64BIT"
5502   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5504 (define_insn "*addti3_1"
5505   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5506         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5507                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5508    (clobber (reg:CC FLAGS_REG))]
5509   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5510   "#")
5512 (define_split
5513   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5514         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5515                  (match_operand:TI 2 "x86_64_general_operand" "")))
5516    (clobber (reg:CC FLAGS_REG))]
5517   "TARGET_64BIT && reload_completed"
5518   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5519                                           UNSPEC_ADD_CARRY))
5520               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5521    (parallel [(set (match_dup 3)
5522                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5523                                      (match_dup 4))
5524                             (match_dup 5)))
5525               (clobber (reg:CC FLAGS_REG))])]
5526   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5528 ;; %%% splits for addsidi3
5529 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5530 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5531 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5533 (define_expand "adddi3"
5534   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5535         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5536                  (match_operand:DI 2 "x86_64_general_operand" "")))
5537    (clobber (reg:CC FLAGS_REG))]
5538   ""
5539   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5541 (define_insn "*adddi3_1"
5542   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5543         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5544                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5545    (clobber (reg:CC FLAGS_REG))]
5546   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5547   "#")
5549 (define_split
5550   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5551         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5552                  (match_operand:DI 2 "general_operand" "")))
5553    (clobber (reg:CC FLAGS_REG))]
5554   "!TARGET_64BIT && reload_completed"
5555   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5556                                           UNSPEC_ADD_CARRY))
5557               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5558    (parallel [(set (match_dup 3)
5559                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5560                                      (match_dup 4))
5561                             (match_dup 5)))
5562               (clobber (reg:CC FLAGS_REG))])]
5563   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5565 (define_insn "adddi3_carry_rex64"
5566   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5567           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5568                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5569                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5570    (clobber (reg:CC FLAGS_REG))]
5571   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5572   "adc{q}\t{%2, %0|%0, %2}"
5573   [(set_attr "type" "alu")
5574    (set_attr "pent_pair" "pu")
5575    (set_attr "mode" "DI")])
5577 (define_insn "*adddi3_cc_rex64"
5578   [(set (reg:CC FLAGS_REG)
5579         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5580                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5581                    UNSPEC_ADD_CARRY))
5582    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5583         (plus:DI (match_dup 1) (match_dup 2)))]
5584   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5585   "add{q}\t{%2, %0|%0, %2}"
5586   [(set_attr "type" "alu")
5587    (set_attr "mode" "DI")])
5589 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5590   [(set (reg:CCC FLAGS_REG)
5591         (compare:CCC
5592             (plusminus:SWI
5593                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5594                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5595             (match_dup 1)))
5596    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5597         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5598   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5599   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5600   [(set_attr "type" "alu")
5601    (set_attr "mode" "<MODE>")])
5603 (define_insn "*add<mode>3_cconly_overflow"
5604   [(set (reg:CCC FLAGS_REG)
5605         (compare:CCC
5606                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5607                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5608                 (match_dup 1)))
5609    (clobber (match_scratch:SWI 0 "=<r>"))]
5610   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5611   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5612   [(set_attr "type" "alu")
5613    (set_attr "mode" "<MODE>")])
5615 (define_insn "*sub<mode>3_cconly_overflow"
5616   [(set (reg:CCC FLAGS_REG)
5617         (compare:CCC
5618              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5619                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5620              (match_dup 0)))]
5621   ""
5622   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5623   [(set_attr "type" "icmp")
5624    (set_attr "mode" "<MODE>")])
5626 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5627   [(set (reg:CCC FLAGS_REG)
5628         (compare:CCC
5629             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5630                           (match_operand:SI 2 "general_operand" "g"))
5631             (match_dup 1)))
5632    (set (match_operand:DI 0 "register_operand" "=r")
5633         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5634   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5635   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5636   [(set_attr "type" "alu")
5637    (set_attr "mode" "SI")])
5639 (define_insn "addqi3_carry"
5640   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5641           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5642                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5643                    (match_operand:QI 2 "general_operand" "qi,qm")))
5644    (clobber (reg:CC FLAGS_REG))]
5645   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5646   "adc{b}\t{%2, %0|%0, %2}"
5647   [(set_attr "type" "alu")
5648    (set_attr "pent_pair" "pu")
5649    (set_attr "mode" "QI")])
5651 (define_insn "addhi3_carry"
5652   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5653           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5654                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5655                    (match_operand:HI 2 "general_operand" "ri,rm")))
5656    (clobber (reg:CC FLAGS_REG))]
5657   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5658   "adc{w}\t{%2, %0|%0, %2}"
5659   [(set_attr "type" "alu")
5660    (set_attr "pent_pair" "pu")
5661    (set_attr "mode" "HI")])
5663 (define_insn "addsi3_carry"
5664   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5665           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5666                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5667                    (match_operand:SI 2 "general_operand" "ri,rm")))
5668    (clobber (reg:CC FLAGS_REG))]
5669   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5670   "adc{l}\t{%2, %0|%0, %2}"
5671   [(set_attr "type" "alu")
5672    (set_attr "pent_pair" "pu")
5673    (set_attr "mode" "SI")])
5675 (define_insn "*addsi3_carry_zext"
5676   [(set (match_operand:DI 0 "register_operand" "=r")
5677           (zero_extend:DI
5678             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5679                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5680                      (match_operand:SI 2 "general_operand" "g"))))
5681    (clobber (reg:CC FLAGS_REG))]
5682   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5683   "adc{l}\t{%2, %k0|%k0, %2}"
5684   [(set_attr "type" "alu")
5685    (set_attr "pent_pair" "pu")
5686    (set_attr "mode" "SI")])
5688 (define_insn "*addsi3_cc"
5689   [(set (reg:CC FLAGS_REG)
5690         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5691                     (match_operand:SI 2 "general_operand" "ri,rm")]
5692                    UNSPEC_ADD_CARRY))
5693    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5694         (plus:SI (match_dup 1) (match_dup 2)))]
5695   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5696   "add{l}\t{%2, %0|%0, %2}"
5697   [(set_attr "type" "alu")
5698    (set_attr "mode" "SI")])
5700 (define_insn "addqi3_cc"
5701   [(set (reg:CC FLAGS_REG)
5702         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5703                     (match_operand:QI 2 "general_operand" "qi,qm")]
5704                    UNSPEC_ADD_CARRY))
5705    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5706         (plus:QI (match_dup 1) (match_dup 2)))]
5707   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5708   "add{b}\t{%2, %0|%0, %2}"
5709   [(set_attr "type" "alu")
5710    (set_attr "mode" "QI")])
5712 (define_expand "addsi3"
5713   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5714                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5715                             (match_operand:SI 2 "general_operand" "")))
5716               (clobber (reg:CC FLAGS_REG))])]
5717   ""
5718   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5720 (define_insn "*lea_1"
5721   [(set (match_operand:SI 0 "register_operand" "=r")
5722         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5723   "!TARGET_64BIT"
5724   "lea{l}\t{%a1, %0|%0, %a1}"
5725   [(set_attr "type" "lea")
5726    (set_attr "mode" "SI")])
5728 (define_insn "*lea_1_rex64"
5729   [(set (match_operand:SI 0 "register_operand" "=r")
5730         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5731   "TARGET_64BIT"
5732   "lea{l}\t{%a1, %0|%0, %a1}"
5733   [(set_attr "type" "lea")
5734    (set_attr "mode" "SI")])
5736 (define_insn "*lea_1_zext"
5737   [(set (match_operand:DI 0 "register_operand" "=r")
5738         (zero_extend:DI
5739          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5740   "TARGET_64BIT"
5741   "lea{l}\t{%a1, %k0|%k0, %a1}"
5742   [(set_attr "type" "lea")
5743    (set_attr "mode" "SI")])
5745 (define_insn "*lea_2_rex64"
5746   [(set (match_operand:DI 0 "register_operand" "=r")
5747         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5748   "TARGET_64BIT"
5749   "lea{q}\t{%a1, %0|%0, %a1}"
5750   [(set_attr "type" "lea")
5751    (set_attr "mode" "DI")])
5753 ;; The lea patterns for non-Pmodes needs to be matched by several
5754 ;; insns converted to real lea by splitters.
5756 (define_insn_and_split "*lea_general_1"
5757   [(set (match_operand 0 "register_operand" "=r")
5758         (plus (plus (match_operand 1 "index_register_operand" "l")
5759                     (match_operand 2 "register_operand" "r"))
5760               (match_operand 3 "immediate_operand" "i")))]
5761   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5762     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5763    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5764    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5765    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5766    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5767        || GET_MODE (operands[3]) == VOIDmode)"
5768   "#"
5769   "&& reload_completed"
5770   [(const_int 0)]
5772   rtx pat;
5773   operands[0] = gen_lowpart (SImode, operands[0]);
5774   operands[1] = gen_lowpart (Pmode, operands[1]);
5775   operands[2] = gen_lowpart (Pmode, operands[2]);
5776   operands[3] = gen_lowpart (Pmode, operands[3]);
5777   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5778                       operands[3]);
5779   if (Pmode != SImode)
5780     pat = gen_rtx_SUBREG (SImode, pat, 0);
5781   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5782   DONE;
5784   [(set_attr "type" "lea")
5785    (set_attr "mode" "SI")])
5787 (define_insn_and_split "*lea_general_1_zext"
5788   [(set (match_operand:DI 0 "register_operand" "=r")
5789         (zero_extend:DI
5790           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5791                             (match_operand:SI 2 "register_operand" "r"))
5792                    (match_operand:SI 3 "immediate_operand" "i"))))]
5793   "TARGET_64BIT"
5794   "#"
5795   "&& reload_completed"
5796   [(set (match_dup 0)
5797         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5798                                                      (match_dup 2))
5799                                             (match_dup 3)) 0)))]
5801   operands[1] = gen_lowpart (Pmode, operands[1]);
5802   operands[2] = gen_lowpart (Pmode, operands[2]);
5803   operands[3] = gen_lowpart (Pmode, operands[3]);
5805   [(set_attr "type" "lea")
5806    (set_attr "mode" "SI")])
5808 (define_insn_and_split "*lea_general_2"
5809   [(set (match_operand 0 "register_operand" "=r")
5810         (plus (mult (match_operand 1 "index_register_operand" "l")
5811                     (match_operand 2 "const248_operand" "i"))
5812               (match_operand 3 "nonmemory_operand" "ri")))]
5813   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5814     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5815    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5816    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5817    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5818        || GET_MODE (operands[3]) == VOIDmode)"
5819   "#"
5820   "&& reload_completed"
5821   [(const_int 0)]
5823   rtx pat;
5824   operands[0] = gen_lowpart (SImode, operands[0]);
5825   operands[1] = gen_lowpart (Pmode, operands[1]);
5826   operands[3] = gen_lowpart (Pmode, operands[3]);
5827   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5828                       operands[3]);
5829   if (Pmode != SImode)
5830     pat = gen_rtx_SUBREG (SImode, pat, 0);
5831   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5832   DONE;
5834   [(set_attr "type" "lea")
5835    (set_attr "mode" "SI")])
5837 (define_insn_and_split "*lea_general_2_zext"
5838   [(set (match_operand:DI 0 "register_operand" "=r")
5839         (zero_extend:DI
5840           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5841                             (match_operand:SI 2 "const248_operand" "n"))
5842                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5843   "TARGET_64BIT"
5844   "#"
5845   "&& reload_completed"
5846   [(set (match_dup 0)
5847         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5848                                                      (match_dup 2))
5849                                             (match_dup 3)) 0)))]
5851   operands[1] = gen_lowpart (Pmode, operands[1]);
5852   operands[3] = gen_lowpart (Pmode, operands[3]);
5854   [(set_attr "type" "lea")
5855    (set_attr "mode" "SI")])
5857 (define_insn_and_split "*lea_general_3"
5858   [(set (match_operand 0 "register_operand" "=r")
5859         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5860                           (match_operand 2 "const248_operand" "i"))
5861                     (match_operand 3 "register_operand" "r"))
5862               (match_operand 4 "immediate_operand" "i")))]
5863   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5864     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5865    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5866    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5867    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5868   "#"
5869   "&& reload_completed"
5870   [(const_int 0)]
5872   rtx pat;
5873   operands[0] = gen_lowpart (SImode, operands[0]);
5874   operands[1] = gen_lowpart (Pmode, operands[1]);
5875   operands[3] = gen_lowpart (Pmode, operands[3]);
5876   operands[4] = gen_lowpart (Pmode, operands[4]);
5877   pat = gen_rtx_PLUS (Pmode,
5878                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5879                                                          operands[2]),
5880                                     operands[3]),
5881                       operands[4]);
5882   if (Pmode != SImode)
5883     pat = gen_rtx_SUBREG (SImode, pat, 0);
5884   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5885   DONE;
5887   [(set_attr "type" "lea")
5888    (set_attr "mode" "SI")])
5890 (define_insn_and_split "*lea_general_3_zext"
5891   [(set (match_operand:DI 0 "register_operand" "=r")
5892         (zero_extend:DI
5893           (plus:SI (plus:SI (mult:SI
5894                               (match_operand:SI 1 "index_register_operand" "l")
5895                               (match_operand:SI 2 "const248_operand" "n"))
5896                             (match_operand:SI 3 "register_operand" "r"))
5897                    (match_operand:SI 4 "immediate_operand" "i"))))]
5898   "TARGET_64BIT"
5899   "#"
5900   "&& reload_completed"
5901   [(set (match_dup 0)
5902         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5903                                                               (match_dup 2))
5904                                                      (match_dup 3))
5905                                             (match_dup 4)) 0)))]
5907   operands[1] = gen_lowpart (Pmode, operands[1]);
5908   operands[3] = gen_lowpart (Pmode, operands[3]);
5909   operands[4] = gen_lowpart (Pmode, operands[4]);
5911   [(set_attr "type" "lea")
5912    (set_attr "mode" "SI")])
5914 (define_insn "*adddi_1_rex64"
5915   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5916         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5917                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5918    (clobber (reg:CC FLAGS_REG))]
5919   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5921   switch (get_attr_type (insn))
5922     {
5923     case TYPE_LEA:
5924       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5925       return "lea{q}\t{%a2, %0|%0, %a2}";
5927     case TYPE_INCDEC:
5928       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5929       if (operands[2] == const1_rtx)
5930         return "inc{q}\t%0";
5931       else
5932         {
5933           gcc_assert (operands[2] == constm1_rtx);
5934           return "dec{q}\t%0";
5935         }
5937     default:
5938       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5940       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5941          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5942       if (CONST_INT_P (operands[2])
5943           /* Avoid overflows.  */
5944           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5945           && (INTVAL (operands[2]) == 128
5946               || (INTVAL (operands[2]) < 0
5947                   && INTVAL (operands[2]) != -128)))
5948         {
5949           operands[2] = GEN_INT (-INTVAL (operands[2]));
5950           return "sub{q}\t{%2, %0|%0, %2}";
5951         }
5952       return "add{q}\t{%2, %0|%0, %2}";
5953     }
5955   [(set (attr "type")
5956      (cond [(eq_attr "alternative" "2")
5957               (const_string "lea")
5958             ; Current assemblers are broken and do not allow @GOTOFF in
5959             ; ought but a memory context.
5960             (match_operand:DI 2 "pic_symbolic_operand" "")
5961               (const_string "lea")
5962             (match_operand:DI 2 "incdec_operand" "")
5963               (const_string "incdec")
5964            ]
5965            (const_string "alu")))
5966    (set_attr "mode" "DI")])
5968 ;; Convert lea to the lea pattern to avoid flags dependency.
5969 (define_split
5970   [(set (match_operand:DI 0 "register_operand" "")
5971         (plus:DI (match_operand:DI 1 "register_operand" "")
5972                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5973    (clobber (reg:CC FLAGS_REG))]
5974   "TARGET_64BIT && reload_completed
5975    && true_regnum (operands[0]) != true_regnum (operands[1])"
5976   [(set (match_dup 0)
5977         (plus:DI (match_dup 1)
5978                  (match_dup 2)))]
5979   "")
5981 (define_insn "*adddi_2_rex64"
5982   [(set (reg FLAGS_REG)
5983         (compare
5984           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5985                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5986           (const_int 0)))
5987    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5988         (plus:DI (match_dup 1) (match_dup 2)))]
5989   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5990    && ix86_binary_operator_ok (PLUS, DImode, operands)
5991    /* Current assemblers are broken and do not allow @GOTOFF in
5992       ought but a memory context.  */
5993    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5995   switch (get_attr_type (insn))
5996     {
5997     case TYPE_INCDEC:
5998       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5999       if (operands[2] == const1_rtx)
6000         return "inc{q}\t%0";
6001       else
6002         {
6003           gcc_assert (operands[2] == constm1_rtx);
6004           return "dec{q}\t%0";
6005         }
6007     default:
6008       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6009       /* ???? We ought to handle there the 32bit case too
6010          - do we need new constraint?  */
6011       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6012          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6013       if (CONST_INT_P (operands[2])
6014           /* Avoid overflows.  */
6015           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6016           && (INTVAL (operands[2]) == 128
6017               || (INTVAL (operands[2]) < 0
6018                   && INTVAL (operands[2]) != -128)))
6019         {
6020           operands[2] = GEN_INT (-INTVAL (operands[2]));
6021           return "sub{q}\t{%2, %0|%0, %2}";
6022         }
6023       return "add{q}\t{%2, %0|%0, %2}";
6024     }
6026   [(set (attr "type")
6027      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6028         (const_string "incdec")
6029         (const_string "alu")))
6030    (set_attr "mode" "DI")])
6032 (define_insn "*adddi_3_rex64"
6033   [(set (reg FLAGS_REG)
6034         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6035                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6036    (clobber (match_scratch:DI 0 "=r"))]
6037   "TARGET_64BIT
6038    && ix86_match_ccmode (insn, CCZmode)
6039    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6040    /* Current assemblers are broken and do not allow @GOTOFF in
6041       ought but a memory context.  */
6042    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6044   switch (get_attr_type (insn))
6045     {
6046     case TYPE_INCDEC:
6047       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6048       if (operands[2] == const1_rtx)
6049         return "inc{q}\t%0";
6050       else
6051         {
6052           gcc_assert (operands[2] == constm1_rtx);
6053           return "dec{q}\t%0";
6054         }
6056     default:
6057       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6058       /* ???? We ought to handle there the 32bit case too
6059          - do we need new constraint?  */
6060       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6061          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6062       if (CONST_INT_P (operands[2])
6063           /* Avoid overflows.  */
6064           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6065           && (INTVAL (operands[2]) == 128
6066               || (INTVAL (operands[2]) < 0
6067                   && INTVAL (operands[2]) != -128)))
6068         {
6069           operands[2] = GEN_INT (-INTVAL (operands[2]));
6070           return "sub{q}\t{%2, %0|%0, %2}";
6071         }
6072       return "add{q}\t{%2, %0|%0, %2}";
6073     }
6075   [(set (attr "type")
6076      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6077         (const_string "incdec")
6078         (const_string "alu")))
6079    (set_attr "mode" "DI")])
6081 ; For comparisons against 1, -1 and 128, we may generate better code
6082 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6083 ; is matched then.  We can't accept general immediate, because for
6084 ; case of overflows,  the result is messed up.
6085 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6086 ; when negated.
6087 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6088 ; only for comparisons not depending on it.
6089 (define_insn "*adddi_4_rex64"
6090   [(set (reg FLAGS_REG)
6091         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6092                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6093    (clobber (match_scratch:DI 0 "=rm"))]
6094   "TARGET_64BIT
6095    &&  ix86_match_ccmode (insn, CCGCmode)"
6097   switch (get_attr_type (insn))
6098     {
6099     case TYPE_INCDEC:
6100       if (operands[2] == constm1_rtx)
6101         return "inc{q}\t%0";
6102       else
6103         {
6104           gcc_assert (operands[2] == const1_rtx);
6105           return "dec{q}\t%0";
6106         }
6108     default:
6109       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6110       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6111          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6112       if ((INTVAL (operands[2]) == -128
6113            || (INTVAL (operands[2]) > 0
6114                && INTVAL (operands[2]) != 128))
6115           /* Avoid overflows.  */
6116           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6117         return "sub{q}\t{%2, %0|%0, %2}";
6118       operands[2] = GEN_INT (-INTVAL (operands[2]));
6119       return "add{q}\t{%2, %0|%0, %2}";
6120     }
6122   [(set (attr "type")
6123      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6124         (const_string "incdec")
6125         (const_string "alu")))
6126    (set_attr "mode" "DI")])
6128 (define_insn "*adddi_5_rex64"
6129   [(set (reg FLAGS_REG)
6130         (compare
6131           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6132                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6133           (const_int 0)))
6134    (clobber (match_scratch:DI 0 "=r"))]
6135   "TARGET_64BIT
6136    && ix86_match_ccmode (insn, CCGOCmode)
6137    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6138    /* Current assemblers are broken and do not allow @GOTOFF in
6139       ought but a memory context.  */
6140    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6142   switch (get_attr_type (insn))
6143     {
6144     case TYPE_INCDEC:
6145       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6146       if (operands[2] == const1_rtx)
6147         return "inc{q}\t%0";
6148       else
6149         {
6150           gcc_assert (operands[2] == constm1_rtx);
6151           return "dec{q}\t%0";
6152         }
6154     default:
6155       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6156       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6157          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6158       if (CONST_INT_P (operands[2])
6159           /* Avoid overflows.  */
6160           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6161           && (INTVAL (operands[2]) == 128
6162               || (INTVAL (operands[2]) < 0
6163                   && INTVAL (operands[2]) != -128)))
6164         {
6165           operands[2] = GEN_INT (-INTVAL (operands[2]));
6166           return "sub{q}\t{%2, %0|%0, %2}";
6167         }
6168       return "add{q}\t{%2, %0|%0, %2}";
6169     }
6171   [(set (attr "type")
6172      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6173         (const_string "incdec")
6174         (const_string "alu")))
6175    (set_attr "mode" "DI")])
6178 (define_insn "*addsi_1"
6179   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6180         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6181                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6182    (clobber (reg:CC FLAGS_REG))]
6183   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6185   switch (get_attr_type (insn))
6186     {
6187     case TYPE_LEA:
6188       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6189       return "lea{l}\t{%a2, %0|%0, %a2}";
6191     case TYPE_INCDEC:
6192       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6193       if (operands[2] == const1_rtx)
6194         return "inc{l}\t%0";
6195       else
6196         {
6197           gcc_assert (operands[2] == constm1_rtx);
6198           return "dec{l}\t%0";
6199         }
6201     default:
6202       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6204       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6205          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6206       if (CONST_INT_P (operands[2])
6207           && (INTVAL (operands[2]) == 128
6208               || (INTVAL (operands[2]) < 0
6209                   && INTVAL (operands[2]) != -128)))
6210         {
6211           operands[2] = GEN_INT (-INTVAL (operands[2]));
6212           return "sub{l}\t{%2, %0|%0, %2}";
6213         }
6214       return "add{l}\t{%2, %0|%0, %2}";
6215     }
6217   [(set (attr "type")
6218      (cond [(eq_attr "alternative" "2")
6219               (const_string "lea")
6220             ; Current assemblers are broken and do not allow @GOTOFF in
6221             ; ought but a memory context.
6222             (match_operand:SI 2 "pic_symbolic_operand" "")
6223               (const_string "lea")
6224             (match_operand:SI 2 "incdec_operand" "")
6225               (const_string "incdec")
6226            ]
6227            (const_string "alu")))
6228    (set_attr "mode" "SI")])
6230 ;; Convert lea to the lea pattern to avoid flags dependency.
6231 (define_split
6232   [(set (match_operand 0 "register_operand" "")
6233         (plus (match_operand 1 "register_operand" "")
6234               (match_operand 2 "nonmemory_operand" "")))
6235    (clobber (reg:CC FLAGS_REG))]
6236   "reload_completed
6237    && true_regnum (operands[0]) != true_regnum (operands[1])"
6238   [(const_int 0)]
6240   rtx pat;
6241   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6242      may confuse gen_lowpart.  */
6243   if (GET_MODE (operands[0]) != Pmode)
6244     {
6245       operands[1] = gen_lowpart (Pmode, operands[1]);
6246       operands[2] = gen_lowpart (Pmode, operands[2]);
6247     }
6248   operands[0] = gen_lowpart (SImode, operands[0]);
6249   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6250   if (Pmode != SImode)
6251     pat = gen_rtx_SUBREG (SImode, pat, 0);
6252   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6253   DONE;
6256 ;; It may seem that nonimmediate operand is proper one for operand 1.
6257 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6258 ;; we take care in ix86_binary_operator_ok to not allow two memory
6259 ;; operands so proper swapping will be done in reload.  This allow
6260 ;; patterns constructed from addsi_1 to match.
6261 (define_insn "addsi_1_zext"
6262   [(set (match_operand:DI 0 "register_operand" "=r,r")
6263         (zero_extend:DI
6264           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6265                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
6266    (clobber (reg:CC FLAGS_REG))]
6267   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6269   switch (get_attr_type (insn))
6270     {
6271     case TYPE_LEA:
6272       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6273       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6275     case TYPE_INCDEC:
6276       if (operands[2] == const1_rtx)
6277         return "inc{l}\t%k0";
6278       else
6279         {
6280           gcc_assert (operands[2] == constm1_rtx);
6281           return "dec{l}\t%k0";
6282         }
6284     default:
6285       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6286          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6287       if (CONST_INT_P (operands[2])
6288           && (INTVAL (operands[2]) == 128
6289               || (INTVAL (operands[2]) < 0
6290                   && INTVAL (operands[2]) != -128)))
6291         {
6292           operands[2] = GEN_INT (-INTVAL (operands[2]));
6293           return "sub{l}\t{%2, %k0|%k0, %2}";
6294         }
6295       return "add{l}\t{%2, %k0|%k0, %2}";
6296     }
6298   [(set (attr "type")
6299      (cond [(eq_attr "alternative" "1")
6300               (const_string "lea")
6301             ; Current assemblers are broken and do not allow @GOTOFF in
6302             ; ought but a memory context.
6303             (match_operand:SI 2 "pic_symbolic_operand" "")
6304               (const_string "lea")
6305             (match_operand:SI 2 "incdec_operand" "")
6306               (const_string "incdec")
6307            ]
6308            (const_string "alu")))
6309    (set_attr "mode" "SI")])
6311 ;; Convert lea to the lea pattern to avoid flags dependency.
6312 (define_split
6313   [(set (match_operand:DI 0 "register_operand" "")
6314         (zero_extend:DI
6315           (plus:SI (match_operand:SI 1 "register_operand" "")
6316                    (match_operand:SI 2 "nonmemory_operand" ""))))
6317    (clobber (reg:CC FLAGS_REG))]
6318   "TARGET_64BIT && reload_completed
6319    && true_regnum (operands[0]) != true_regnum (operands[1])"
6320   [(set (match_dup 0)
6321         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6323   operands[1] = gen_lowpart (Pmode, operands[1]);
6324   operands[2] = gen_lowpart (Pmode, operands[2]);
6327 (define_insn "*addsi_2"
6328   [(set (reg FLAGS_REG)
6329         (compare
6330           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6331                    (match_operand:SI 2 "general_operand" "rmni,rni"))
6332           (const_int 0)))
6333    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6334         (plus:SI (match_dup 1) (match_dup 2)))]
6335   "ix86_match_ccmode (insn, CCGOCmode)
6336    && ix86_binary_operator_ok (PLUS, SImode, operands)
6337    /* Current assemblers are broken and do not allow @GOTOFF in
6338       ought but a memory context.  */
6339    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6341   switch (get_attr_type (insn))
6342     {
6343     case TYPE_INCDEC:
6344       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6345       if (operands[2] == const1_rtx)
6346         return "inc{l}\t%0";
6347       else
6348         {
6349           gcc_assert (operands[2] == constm1_rtx);
6350           return "dec{l}\t%0";
6351         }
6353     default:
6354       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6355       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6356          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6357       if (CONST_INT_P (operands[2])
6358           && (INTVAL (operands[2]) == 128
6359               || (INTVAL (operands[2]) < 0
6360                   && INTVAL (operands[2]) != -128)))
6361         {
6362           operands[2] = GEN_INT (-INTVAL (operands[2]));
6363           return "sub{l}\t{%2, %0|%0, %2}";
6364         }
6365       return "add{l}\t{%2, %0|%0, %2}";
6366     }
6368   [(set (attr "type")
6369      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6370         (const_string "incdec")
6371         (const_string "alu")))
6372    (set_attr "mode" "SI")])
6374 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6375 (define_insn "*addsi_2_zext"
6376   [(set (reg FLAGS_REG)
6377         (compare
6378           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6379                    (match_operand:SI 2 "general_operand" "rmni"))
6380           (const_int 0)))
6381    (set (match_operand:DI 0 "register_operand" "=r")
6382         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6383   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6384    && ix86_binary_operator_ok (PLUS, SImode, operands)
6385    /* Current assemblers are broken and do not allow @GOTOFF in
6386       ought but a memory context.  */
6387    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6389   switch (get_attr_type (insn))
6390     {
6391     case TYPE_INCDEC:
6392       if (operands[2] == const1_rtx)
6393         return "inc{l}\t%k0";
6394       else
6395         {
6396           gcc_assert (operands[2] == constm1_rtx);
6397           return "dec{l}\t%k0";
6398         }
6400     default:
6401       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6402          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6403       if (CONST_INT_P (operands[2])
6404           && (INTVAL (operands[2]) == 128
6405               || (INTVAL (operands[2]) < 0
6406                   && INTVAL (operands[2]) != -128)))
6407         {
6408           operands[2] = GEN_INT (-INTVAL (operands[2]));
6409           return "sub{l}\t{%2, %k0|%k0, %2}";
6410         }
6411       return "add{l}\t{%2, %k0|%k0, %2}";
6412     }
6414   [(set (attr "type")
6415      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6416         (const_string "incdec")
6417         (const_string "alu")))
6418    (set_attr "mode" "SI")])
6420 (define_insn "*addsi_3"
6421   [(set (reg FLAGS_REG)
6422         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6423                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6424    (clobber (match_scratch:SI 0 "=r"))]
6425   "ix86_match_ccmode (insn, CCZmode)
6426    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6427    /* Current assemblers are broken and do not allow @GOTOFF in
6428       ought but a memory context.  */
6429    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6431   switch (get_attr_type (insn))
6432     {
6433     case TYPE_INCDEC:
6434       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6435       if (operands[2] == const1_rtx)
6436         return "inc{l}\t%0";
6437       else
6438         {
6439           gcc_assert (operands[2] == constm1_rtx);
6440           return "dec{l}\t%0";
6441         }
6443     default:
6444       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6445       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6446          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6447       if (CONST_INT_P (operands[2])
6448           && (INTVAL (operands[2]) == 128
6449               || (INTVAL (operands[2]) < 0
6450                   && INTVAL (operands[2]) != -128)))
6451         {
6452           operands[2] = GEN_INT (-INTVAL (operands[2]));
6453           return "sub{l}\t{%2, %0|%0, %2}";
6454         }
6455       return "add{l}\t{%2, %0|%0, %2}";
6456     }
6458   [(set (attr "type")
6459      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6460         (const_string "incdec")
6461         (const_string "alu")))
6462    (set_attr "mode" "SI")])
6464 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6465 (define_insn "*addsi_3_zext"
6466   [(set (reg FLAGS_REG)
6467         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6468                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6469    (set (match_operand:DI 0 "register_operand" "=r")
6470         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6471   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6472    && ix86_binary_operator_ok (PLUS, SImode, operands)
6473    /* Current assemblers are broken and do not allow @GOTOFF in
6474       ought but a memory context.  */
6475    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6477   switch (get_attr_type (insn))
6478     {
6479     case TYPE_INCDEC:
6480       if (operands[2] == const1_rtx)
6481         return "inc{l}\t%k0";
6482       else
6483         {
6484           gcc_assert (operands[2] == constm1_rtx);
6485           return "dec{l}\t%k0";
6486         }
6488     default:
6489       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6490          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6491       if (CONST_INT_P (operands[2])
6492           && (INTVAL (operands[2]) == 128
6493               || (INTVAL (operands[2]) < 0
6494                   && INTVAL (operands[2]) != -128)))
6495         {
6496           operands[2] = GEN_INT (-INTVAL (operands[2]));
6497           return "sub{l}\t{%2, %k0|%k0, %2}";
6498         }
6499       return "add{l}\t{%2, %k0|%k0, %2}";
6500     }
6502   [(set (attr "type")
6503      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6504         (const_string "incdec")
6505         (const_string "alu")))
6506    (set_attr "mode" "SI")])
6508 ; For comparisons against 1, -1 and 128, we may generate better code
6509 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6510 ; is matched then.  We can't accept general immediate, because for
6511 ; case of overflows,  the result is messed up.
6512 ; This pattern also don't hold of 0x80000000, since the value overflows
6513 ; when negated.
6514 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6515 ; only for comparisons not depending on it.
6516 (define_insn "*addsi_4"
6517   [(set (reg FLAGS_REG)
6518         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6519                  (match_operand:SI 2 "const_int_operand" "n")))
6520    (clobber (match_scratch:SI 0 "=rm"))]
6521   "ix86_match_ccmode (insn, CCGCmode)
6522    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6524   switch (get_attr_type (insn))
6525     {
6526     case TYPE_INCDEC:
6527       if (operands[2] == constm1_rtx)
6528         return "inc{l}\t%0";
6529       else
6530         {
6531           gcc_assert (operands[2] == const1_rtx);
6532           return "dec{l}\t%0";
6533         }
6535     default:
6536       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6537       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6538          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6539       if ((INTVAL (operands[2]) == -128
6540            || (INTVAL (operands[2]) > 0
6541                && INTVAL (operands[2]) != 128)))
6542         return "sub{l}\t{%2, %0|%0, %2}";
6543       operands[2] = GEN_INT (-INTVAL (operands[2]));
6544       return "add{l}\t{%2, %0|%0, %2}";
6545     }
6547   [(set (attr "type")
6548      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6549         (const_string "incdec")
6550         (const_string "alu")))
6551    (set_attr "mode" "SI")])
6553 (define_insn "*addsi_5"
6554   [(set (reg FLAGS_REG)
6555         (compare
6556           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6557                    (match_operand:SI 2 "general_operand" "rmni"))
6558           (const_int 0)))
6559    (clobber (match_scratch:SI 0 "=r"))]
6560   "ix86_match_ccmode (insn, CCGOCmode)
6561    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6562    /* Current assemblers are broken and do not allow @GOTOFF in
6563       ought but a memory context.  */
6564    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6566   switch (get_attr_type (insn))
6567     {
6568     case TYPE_INCDEC:
6569       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6570       if (operands[2] == const1_rtx)
6571         return "inc{l}\t%0";
6572       else
6573         {
6574           gcc_assert (operands[2] == constm1_rtx);
6575           return "dec{l}\t%0";
6576         }
6578     default:
6579       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6580       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6581          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6582       if (CONST_INT_P (operands[2])
6583           && (INTVAL (operands[2]) == 128
6584               || (INTVAL (operands[2]) < 0
6585                   && INTVAL (operands[2]) != -128)))
6586         {
6587           operands[2] = GEN_INT (-INTVAL (operands[2]));
6588           return "sub{l}\t{%2, %0|%0, %2}";
6589         }
6590       return "add{l}\t{%2, %0|%0, %2}";
6591     }
6593   [(set (attr "type")
6594      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6595         (const_string "incdec")
6596         (const_string "alu")))
6597    (set_attr "mode" "SI")])
6599 (define_expand "addhi3"
6600   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6601                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6602                             (match_operand:HI 2 "general_operand" "")))
6603               (clobber (reg:CC FLAGS_REG))])]
6604   "TARGET_HIMODE_MATH"
6605   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6607 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6608 ;; type optimizations enabled by define-splits.  This is not important
6609 ;; for PII, and in fact harmful because of partial register stalls.
6611 (define_insn "*addhi_1_lea"
6612   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6613         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6614                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6615    (clobber (reg:CC FLAGS_REG))]
6616   "!TARGET_PARTIAL_REG_STALL
6617    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6619   switch (get_attr_type (insn))
6620     {
6621     case TYPE_LEA:
6622       return "#";
6623     case TYPE_INCDEC:
6624       if (operands[2] == const1_rtx)
6625         return "inc{w}\t%0";
6626       else
6627         {
6628           gcc_assert (operands[2] == constm1_rtx);
6629           return "dec{w}\t%0";
6630         }
6632     default:
6633       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6634          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6635       if (CONST_INT_P (operands[2])
6636           && (INTVAL (operands[2]) == 128
6637               || (INTVAL (operands[2]) < 0
6638                   && INTVAL (operands[2]) != -128)))
6639         {
6640           operands[2] = GEN_INT (-INTVAL (operands[2]));
6641           return "sub{w}\t{%2, %0|%0, %2}";
6642         }
6643       return "add{w}\t{%2, %0|%0, %2}";
6644     }
6646   [(set (attr "type")
6647      (if_then_else (eq_attr "alternative" "2")
6648         (const_string "lea")
6649         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6650            (const_string "incdec")
6651            (const_string "alu"))))
6652    (set_attr "mode" "HI,HI,SI")])
6654 (define_insn "*addhi_1"
6655   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6656         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6657                  (match_operand:HI 2 "general_operand" "ri,rm")))
6658    (clobber (reg:CC FLAGS_REG))]
6659   "TARGET_PARTIAL_REG_STALL
6660    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6662   switch (get_attr_type (insn))
6663     {
6664     case TYPE_INCDEC:
6665       if (operands[2] == const1_rtx)
6666         return "inc{w}\t%0";
6667       else
6668         {
6669           gcc_assert (operands[2] == constm1_rtx);
6670           return "dec{w}\t%0";
6671         }
6673     default:
6674       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6675          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6676       if (CONST_INT_P (operands[2])
6677           && (INTVAL (operands[2]) == 128
6678               || (INTVAL (operands[2]) < 0
6679                   && INTVAL (operands[2]) != -128)))
6680         {
6681           operands[2] = GEN_INT (-INTVAL (operands[2]));
6682           return "sub{w}\t{%2, %0|%0, %2}";
6683         }
6684       return "add{w}\t{%2, %0|%0, %2}";
6685     }
6687   [(set (attr "type")
6688      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6689         (const_string "incdec")
6690         (const_string "alu")))
6691    (set_attr "mode" "HI")])
6693 (define_insn "*addhi_2"
6694   [(set (reg FLAGS_REG)
6695         (compare
6696           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6697                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6698           (const_int 0)))
6699    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6700         (plus:HI (match_dup 1) (match_dup 2)))]
6701   "ix86_match_ccmode (insn, CCGOCmode)
6702    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6704   switch (get_attr_type (insn))
6705     {
6706     case TYPE_INCDEC:
6707       if (operands[2] == const1_rtx)
6708         return "inc{w}\t%0";
6709       else
6710         {
6711           gcc_assert (operands[2] == constm1_rtx);
6712           return "dec{w}\t%0";
6713         }
6715     default:
6716       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6717          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6718       if (CONST_INT_P (operands[2])
6719           && (INTVAL (operands[2]) == 128
6720               || (INTVAL (operands[2]) < 0
6721                   && INTVAL (operands[2]) != -128)))
6722         {
6723           operands[2] = GEN_INT (-INTVAL (operands[2]));
6724           return "sub{w}\t{%2, %0|%0, %2}";
6725         }
6726       return "add{w}\t{%2, %0|%0, %2}";
6727     }
6729   [(set (attr "type")
6730      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6731         (const_string "incdec")
6732         (const_string "alu")))
6733    (set_attr "mode" "HI")])
6735 (define_insn "*addhi_3"
6736   [(set (reg FLAGS_REG)
6737         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6738                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6739    (clobber (match_scratch:HI 0 "=r"))]
6740   "ix86_match_ccmode (insn, CCZmode)
6741    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6743   switch (get_attr_type (insn))
6744     {
6745     case TYPE_INCDEC:
6746       if (operands[2] == const1_rtx)
6747         return "inc{w}\t%0";
6748       else
6749         {
6750           gcc_assert (operands[2] == constm1_rtx);
6751           return "dec{w}\t%0";
6752         }
6754     default:
6755       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6756          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6757       if (CONST_INT_P (operands[2])
6758           && (INTVAL (operands[2]) == 128
6759               || (INTVAL (operands[2]) < 0
6760                   && INTVAL (operands[2]) != -128)))
6761         {
6762           operands[2] = GEN_INT (-INTVAL (operands[2]));
6763           return "sub{w}\t{%2, %0|%0, %2}";
6764         }
6765       return "add{w}\t{%2, %0|%0, %2}";
6766     }
6768   [(set (attr "type")
6769      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6770         (const_string "incdec")
6771         (const_string "alu")))
6772    (set_attr "mode" "HI")])
6774 ; See comments above addsi_4 for details.
6775 (define_insn "*addhi_4"
6776   [(set (reg FLAGS_REG)
6777         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6778                  (match_operand:HI 2 "const_int_operand" "n")))
6779    (clobber (match_scratch:HI 0 "=rm"))]
6780   "ix86_match_ccmode (insn, CCGCmode)
6781    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6783   switch (get_attr_type (insn))
6784     {
6785     case TYPE_INCDEC:
6786       if (operands[2] == constm1_rtx)
6787         return "inc{w}\t%0";
6788       else
6789         {
6790           gcc_assert (operands[2] == const1_rtx);
6791           return "dec{w}\t%0";
6792         }
6794     default:
6795       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6796       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6797          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6798       if ((INTVAL (operands[2]) == -128
6799            || (INTVAL (operands[2]) > 0
6800                && INTVAL (operands[2]) != 128)))
6801         return "sub{w}\t{%2, %0|%0, %2}";
6802       operands[2] = GEN_INT (-INTVAL (operands[2]));
6803       return "add{w}\t{%2, %0|%0, %2}";
6804     }
6806   [(set (attr "type")
6807      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6808         (const_string "incdec")
6809         (const_string "alu")))
6810    (set_attr "mode" "SI")])
6813 (define_insn "*addhi_5"
6814   [(set (reg FLAGS_REG)
6815         (compare
6816           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6817                    (match_operand:HI 2 "general_operand" "rmni"))
6818           (const_int 0)))
6819    (clobber (match_scratch:HI 0 "=r"))]
6820   "ix86_match_ccmode (insn, CCGOCmode)
6821    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6823   switch (get_attr_type (insn))
6824     {
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 (match_operand:HI 2 "incdec_operand" "")
6850         (const_string "incdec")
6851         (const_string "alu")))
6852    (set_attr "mode" "HI")])
6854 (define_expand "addqi3"
6855   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6856                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6857                             (match_operand:QI 2 "general_operand" "")))
6858               (clobber (reg:CC FLAGS_REG))])]
6859   "TARGET_QIMODE_MATH"
6860   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6862 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6863 (define_insn "*addqi_1_lea"
6864   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6865         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6866                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6867    (clobber (reg:CC FLAGS_REG))]
6868   "!TARGET_PARTIAL_REG_STALL
6869    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6871   int widen = (which_alternative == 2);
6872   switch (get_attr_type (insn))
6873     {
6874     case TYPE_LEA:
6875       return "#";
6876     case TYPE_INCDEC:
6877       if (operands[2] == const1_rtx)
6878         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6879       else
6880         {
6881           gcc_assert (operands[2] == constm1_rtx);
6882           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6883         }
6885     default:
6886       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6887          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6888       if (CONST_INT_P (operands[2])
6889           && (INTVAL (operands[2]) == 128
6890               || (INTVAL (operands[2]) < 0
6891                   && INTVAL (operands[2]) != -128)))
6892         {
6893           operands[2] = GEN_INT (-INTVAL (operands[2]));
6894           if (widen)
6895             return "sub{l}\t{%2, %k0|%k0, %2}";
6896           else
6897             return "sub{b}\t{%2, %0|%0, %2}";
6898         }
6899       if (widen)
6900         return "add{l}\t{%k2, %k0|%k0, %k2}";
6901       else
6902         return "add{b}\t{%2, %0|%0, %2}";
6903     }
6905   [(set (attr "type")
6906      (if_then_else (eq_attr "alternative" "3")
6907         (const_string "lea")
6908         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6909            (const_string "incdec")
6910            (const_string "alu"))))
6911    (set_attr "mode" "QI,QI,SI,SI")])
6913 (define_insn "*addqi_1"
6914   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6915         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6916                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6917    (clobber (reg:CC FLAGS_REG))]
6918   "TARGET_PARTIAL_REG_STALL
6919    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6921   int widen = (which_alternative == 2);
6922   switch (get_attr_type (insn))
6923     {
6924     case TYPE_INCDEC:
6925       if (operands[2] == const1_rtx)
6926         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6927       else
6928         {
6929           gcc_assert (operands[2] == constm1_rtx);
6930           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6931         }
6933     default:
6934       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6935          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6936       if (CONST_INT_P (operands[2])
6937           && (INTVAL (operands[2]) == 128
6938               || (INTVAL (operands[2]) < 0
6939                   && INTVAL (operands[2]) != -128)))
6940         {
6941           operands[2] = GEN_INT (-INTVAL (operands[2]));
6942           if (widen)
6943             return "sub{l}\t{%2, %k0|%k0, %2}";
6944           else
6945             return "sub{b}\t{%2, %0|%0, %2}";
6946         }
6947       if (widen)
6948         return "add{l}\t{%k2, %k0|%k0, %k2}";
6949       else
6950         return "add{b}\t{%2, %0|%0, %2}";
6951     }
6953   [(set (attr "type")
6954      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6955         (const_string "incdec")
6956         (const_string "alu")))
6957    (set_attr "mode" "QI,QI,SI")])
6959 (define_insn "*addqi_1_slp"
6960   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6961         (plus:QI (match_dup 0)
6962                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6963    (clobber (reg:CC FLAGS_REG))]
6964   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6965    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6967   switch (get_attr_type (insn))
6968     {
6969     case TYPE_INCDEC:
6970       if (operands[1] == const1_rtx)
6971         return "inc{b}\t%0";
6972       else
6973         {
6974           gcc_assert (operands[1] == constm1_rtx);
6975           return "dec{b}\t%0";
6976         }
6978     default:
6979       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6980       if (CONST_INT_P (operands[1])
6981           && INTVAL (operands[1]) < 0)
6982         {
6983           operands[1] = GEN_INT (-INTVAL (operands[1]));
6984           return "sub{b}\t{%1, %0|%0, %1}";
6985         }
6986       return "add{b}\t{%1, %0|%0, %1}";
6987     }
6989   [(set (attr "type")
6990      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6991         (const_string "incdec")
6992         (const_string "alu1")))
6993    (set (attr "memory")
6994      (if_then_else (match_operand 1 "memory_operand" "")
6995         (const_string "load")
6996         (const_string "none")))
6997    (set_attr "mode" "QI")])
6999 (define_insn "*addqi_2"
7000   [(set (reg FLAGS_REG)
7001         (compare
7002           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7003                    (match_operand:QI 2 "general_operand" "qmni,qni"))
7004           (const_int 0)))
7005    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7006         (plus:QI (match_dup 1) (match_dup 2)))]
7007   "ix86_match_ccmode (insn, CCGOCmode)
7008    && ix86_binary_operator_ok (PLUS, QImode, operands)"
7010   switch (get_attr_type (insn))
7011     {
7012     case TYPE_INCDEC:
7013       if (operands[2] == const1_rtx)
7014         return "inc{b}\t%0";
7015       else
7016         {
7017           gcc_assert (operands[2] == constm1_rtx
7018                       || (CONST_INT_P (operands[2])
7019                           && INTVAL (operands[2]) == 255));
7020           return "dec{b}\t%0";
7021         }
7023     default:
7024       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7025       if (CONST_INT_P (operands[2])
7026           && INTVAL (operands[2]) < 0)
7027         {
7028           operands[2] = GEN_INT (-INTVAL (operands[2]));
7029           return "sub{b}\t{%2, %0|%0, %2}";
7030         }
7031       return "add{b}\t{%2, %0|%0, %2}";
7032     }
7034   [(set (attr "type")
7035      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7036         (const_string "incdec")
7037         (const_string "alu")))
7038    (set_attr "mode" "QI")])
7040 (define_insn "*addqi_3"
7041   [(set (reg FLAGS_REG)
7042         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
7043                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7044    (clobber (match_scratch:QI 0 "=q"))]
7045   "ix86_match_ccmode (insn, CCZmode)
7046    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7048   switch (get_attr_type (insn))
7049     {
7050     case TYPE_INCDEC:
7051       if (operands[2] == const1_rtx)
7052         return "inc{b}\t%0";
7053       else
7054         {
7055           gcc_assert (operands[2] == constm1_rtx
7056                       || (CONST_INT_P (operands[2])
7057                           && INTVAL (operands[2]) == 255));
7058           return "dec{b}\t%0";
7059         }
7061     default:
7062       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7063       if (CONST_INT_P (operands[2])
7064           && INTVAL (operands[2]) < 0)
7065         {
7066           operands[2] = GEN_INT (-INTVAL (operands[2]));
7067           return "sub{b}\t{%2, %0|%0, %2}";
7068         }
7069       return "add{b}\t{%2, %0|%0, %2}";
7070     }
7072   [(set (attr "type")
7073      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7074         (const_string "incdec")
7075         (const_string "alu")))
7076    (set_attr "mode" "QI")])
7078 ; See comments above addsi_4 for details.
7079 (define_insn "*addqi_4"
7080   [(set (reg FLAGS_REG)
7081         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7082                  (match_operand:QI 2 "const_int_operand" "n")))
7083    (clobber (match_scratch:QI 0 "=qm"))]
7084   "ix86_match_ccmode (insn, CCGCmode)
7085    && (INTVAL (operands[2]) & 0xff) != 0x80"
7087   switch (get_attr_type (insn))
7088     {
7089     case TYPE_INCDEC:
7090       if (operands[2] == constm1_rtx
7091           || (CONST_INT_P (operands[2])
7092               && INTVAL (operands[2]) == 255))
7093         return "inc{b}\t%0";
7094       else
7095         {
7096           gcc_assert (operands[2] == const1_rtx);
7097           return "dec{b}\t%0";
7098         }
7100     default:
7101       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7102       if (INTVAL (operands[2]) < 0)
7103         {
7104           operands[2] = GEN_INT (-INTVAL (operands[2]));
7105           return "add{b}\t{%2, %0|%0, %2}";
7106         }
7107       return "sub{b}\t{%2, %0|%0, %2}";
7108     }
7110   [(set (attr "type")
7111      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7112         (const_string "incdec")
7113         (const_string "alu")))
7114    (set_attr "mode" "QI")])
7117 (define_insn "*addqi_5"
7118   [(set (reg FLAGS_REG)
7119         (compare
7120           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7121                    (match_operand:QI 2 "general_operand" "qmni"))
7122           (const_int 0)))
7123    (clobber (match_scratch:QI 0 "=q"))]
7124   "ix86_match_ccmode (insn, CCGOCmode)
7125    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7127   switch (get_attr_type (insn))
7128     {
7129     case TYPE_INCDEC:
7130       if (operands[2] == const1_rtx)
7131         return "inc{b}\t%0";
7132       else
7133         {
7134           gcc_assert (operands[2] == constm1_rtx
7135                       || (CONST_INT_P (operands[2])
7136                           && INTVAL (operands[2]) == 255));
7137           return "dec{b}\t%0";
7138         }
7140     default:
7141       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7142       if (CONST_INT_P (operands[2])
7143           && INTVAL (operands[2]) < 0)
7144         {
7145           operands[2] = GEN_INT (-INTVAL (operands[2]));
7146           return "sub{b}\t{%2, %0|%0, %2}";
7147         }
7148       return "add{b}\t{%2, %0|%0, %2}";
7149     }
7151   [(set (attr "type")
7152      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7153         (const_string "incdec")
7154         (const_string "alu")))
7155    (set_attr "mode" "QI")])
7158 (define_insn "addqi_ext_1"
7159   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7160                          (const_int 8)
7161                          (const_int 8))
7162         (plus:SI
7163           (zero_extract:SI
7164             (match_operand 1 "ext_register_operand" "0")
7165             (const_int 8)
7166             (const_int 8))
7167           (match_operand:QI 2 "general_operand" "Qmn")))
7168    (clobber (reg:CC FLAGS_REG))]
7169   "!TARGET_64BIT"
7171   switch (get_attr_type (insn))
7172     {
7173     case TYPE_INCDEC:
7174       if (operands[2] == const1_rtx)
7175         return "inc{b}\t%h0";
7176       else
7177         {
7178           gcc_assert (operands[2] == constm1_rtx
7179                       || (CONST_INT_P (operands[2])
7180                           && INTVAL (operands[2]) == 255));
7181           return "dec{b}\t%h0";
7182         }
7184     default:
7185       return "add{b}\t{%2, %h0|%h0, %2}";
7186     }
7188   [(set (attr "type")
7189      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7190         (const_string "incdec")
7191         (const_string "alu")))
7192    (set_attr "mode" "QI")])
7194 (define_insn "*addqi_ext_1_rex64"
7195   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7196                          (const_int 8)
7197                          (const_int 8))
7198         (plus:SI
7199           (zero_extract:SI
7200             (match_operand 1 "ext_register_operand" "0")
7201             (const_int 8)
7202             (const_int 8))
7203           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7204    (clobber (reg:CC FLAGS_REG))]
7205   "TARGET_64BIT"
7207   switch (get_attr_type (insn))
7208     {
7209     case TYPE_INCDEC:
7210       if (operands[2] == const1_rtx)
7211         return "inc{b}\t%h0";
7212       else
7213         {
7214           gcc_assert (operands[2] == constm1_rtx
7215                       || (CONST_INT_P (operands[2])
7216                           && INTVAL (operands[2]) == 255));
7217           return "dec{b}\t%h0";
7218         }
7220     default:
7221       return "add{b}\t{%2, %h0|%h0, %2}";
7222     }
7224   [(set (attr "type")
7225      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7226         (const_string "incdec")
7227         (const_string "alu")))
7228    (set_attr "mode" "QI")])
7230 (define_insn "*addqi_ext_2"
7231   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7232                          (const_int 8)
7233                          (const_int 8))
7234         (plus:SI
7235           (zero_extract:SI
7236             (match_operand 1 "ext_register_operand" "%0")
7237             (const_int 8)
7238             (const_int 8))
7239           (zero_extract:SI
7240             (match_operand 2 "ext_register_operand" "Q")
7241             (const_int 8)
7242             (const_int 8))))
7243    (clobber (reg:CC FLAGS_REG))]
7244   ""
7245   "add{b}\t{%h2, %h0|%h0, %h2}"
7246   [(set_attr "type" "alu")
7247    (set_attr "mode" "QI")])
7249 ;; The patterns that match these are at the end of this file.
7251 (define_expand "addxf3"
7252   [(set (match_operand:XF 0 "register_operand" "")
7253         (plus:XF (match_operand:XF 1 "register_operand" "")
7254                  (match_operand:XF 2 "register_operand" "")))]
7255   "TARGET_80387"
7256   "")
7258 (define_expand "add<mode>3"
7259   [(set (match_operand:MODEF 0 "register_operand" "")
7260         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7261                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7262   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7263   "")
7265 ;; Subtract instructions
7267 ;; %%% splits for subditi3
7269 (define_expand "subti3"
7270   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7271                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7272                              (match_operand:TI 2 "x86_64_general_operand" "")))
7273               (clobber (reg:CC FLAGS_REG))])]
7274   "TARGET_64BIT"
7275   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7277 (define_insn "*subti3_1"
7278   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7279         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7280                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7281    (clobber (reg:CC FLAGS_REG))]
7282   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7283   "#")
7285 (define_split
7286   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7287         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7288                   (match_operand:TI 2 "x86_64_general_operand" "")))
7289    (clobber (reg:CC FLAGS_REG))]
7290   "TARGET_64BIT && reload_completed"
7291   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7292               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7293    (parallel [(set (match_dup 3)
7294                    (minus:DI (match_dup 4)
7295                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7296                                       (match_dup 5))))
7297               (clobber (reg:CC FLAGS_REG))])]
7298   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7300 ;; %%% splits for subsidi3
7302 (define_expand "subdi3"
7303   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7304                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7305                              (match_operand:DI 2 "x86_64_general_operand" "")))
7306               (clobber (reg:CC FLAGS_REG))])]
7307   ""
7308   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7310 (define_insn "*subdi3_1"
7311   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7312         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7313                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7314    (clobber (reg:CC FLAGS_REG))]
7315   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7316   "#")
7318 (define_split
7319   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7320         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7321                   (match_operand:DI 2 "general_operand" "")))
7322    (clobber (reg:CC FLAGS_REG))]
7323   "!TARGET_64BIT && reload_completed"
7324   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7325               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7326    (parallel [(set (match_dup 3)
7327                    (minus:SI (match_dup 4)
7328                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7329                                       (match_dup 5))))
7330               (clobber (reg:CC FLAGS_REG))])]
7331   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7333 (define_insn "subdi3_carry_rex64"
7334   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7335           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7336             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7337                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7338    (clobber (reg:CC FLAGS_REG))]
7339   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7340   "sbb{q}\t{%2, %0|%0, %2}"
7341   [(set_attr "type" "alu")
7342    (set_attr "pent_pair" "pu")
7343    (set_attr "mode" "DI")])
7345 (define_insn "*subdi_1_rex64"
7346   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7347         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7348                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7349    (clobber (reg:CC FLAGS_REG))]
7350   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7351   "sub{q}\t{%2, %0|%0, %2}"
7352   [(set_attr "type" "alu")
7353    (set_attr "mode" "DI")])
7355 (define_insn "*subdi_2_rex64"
7356   [(set (reg FLAGS_REG)
7357         (compare
7358           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7359                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7360           (const_int 0)))
7361    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7362         (minus:DI (match_dup 1) (match_dup 2)))]
7363   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7364    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7365   "sub{q}\t{%2, %0|%0, %2}"
7366   [(set_attr "type" "alu")
7367    (set_attr "mode" "DI")])
7369 (define_insn "*subdi_3_rex63"
7370   [(set (reg FLAGS_REG)
7371         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7372                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7373    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7374         (minus:DI (match_dup 1) (match_dup 2)))]
7375   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7376    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7377   "sub{q}\t{%2, %0|%0, %2}"
7378   [(set_attr "type" "alu")
7379    (set_attr "mode" "DI")])
7381 (define_insn "subqi3_carry"
7382   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7383           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7384             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7385                (match_operand:QI 2 "general_operand" "qi,qm"))))
7386    (clobber (reg:CC FLAGS_REG))]
7387   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7388   "sbb{b}\t{%2, %0|%0, %2}"
7389   [(set_attr "type" "alu")
7390    (set_attr "pent_pair" "pu")
7391    (set_attr "mode" "QI")])
7393 (define_insn "subhi3_carry"
7394   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7395           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7396             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7397                (match_operand:HI 2 "general_operand" "ri,rm"))))
7398    (clobber (reg:CC FLAGS_REG))]
7399   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7400   "sbb{w}\t{%2, %0|%0, %2}"
7401   [(set_attr "type" "alu")
7402    (set_attr "pent_pair" "pu")
7403    (set_attr "mode" "HI")])
7405 (define_insn "subsi3_carry"
7406   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7407           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7408             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7409                (match_operand:SI 2 "general_operand" "ri,rm"))))
7410    (clobber (reg:CC FLAGS_REG))]
7411   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7412   "sbb{l}\t{%2, %0|%0, %2}"
7413   [(set_attr "type" "alu")
7414    (set_attr "pent_pair" "pu")
7415    (set_attr "mode" "SI")])
7417 (define_insn "subsi3_carry_zext"
7418   [(set (match_operand:DI 0 "register_operand" "=r")
7419           (zero_extend:DI
7420             (minus:SI (match_operand:SI 1 "register_operand" "0")
7421               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7422                  (match_operand:SI 2 "general_operand" "g")))))
7423    (clobber (reg:CC FLAGS_REG))]
7424   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7425   "sbb{l}\t{%2, %k0|%k0, %2}"
7426   [(set_attr "type" "alu")
7427    (set_attr "pent_pair" "pu")
7428    (set_attr "mode" "SI")])
7430 (define_expand "subsi3"
7431   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7432                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7433                              (match_operand:SI 2 "general_operand" "")))
7434               (clobber (reg:CC FLAGS_REG))])]
7435   ""
7436   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7438 (define_insn "*subsi_1"
7439   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7440         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7441                   (match_operand:SI 2 "general_operand" "ri,rm")))
7442    (clobber (reg:CC FLAGS_REG))]
7443   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7444   "sub{l}\t{%2, %0|%0, %2}"
7445   [(set_attr "type" "alu")
7446    (set_attr "mode" "SI")])
7448 (define_insn "*subsi_1_zext"
7449   [(set (match_operand:DI 0 "register_operand" "=r")
7450         (zero_extend:DI
7451           (minus:SI (match_operand:SI 1 "register_operand" "0")
7452                     (match_operand:SI 2 "general_operand" "g"))))
7453    (clobber (reg:CC FLAGS_REG))]
7454   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7455   "sub{l}\t{%2, %k0|%k0, %2}"
7456   [(set_attr "type" "alu")
7457    (set_attr "mode" "SI")])
7459 (define_insn "*subsi_2"
7460   [(set (reg FLAGS_REG)
7461         (compare
7462           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7463                     (match_operand:SI 2 "general_operand" "ri,rm"))
7464           (const_int 0)))
7465    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7466         (minus:SI (match_dup 1) (match_dup 2)))]
7467   "ix86_match_ccmode (insn, CCGOCmode)
7468    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7469   "sub{l}\t{%2, %0|%0, %2}"
7470   [(set_attr "type" "alu")
7471    (set_attr "mode" "SI")])
7473 (define_insn "*subsi_2_zext"
7474   [(set (reg FLAGS_REG)
7475         (compare
7476           (minus:SI (match_operand:SI 1 "register_operand" "0")
7477                     (match_operand:SI 2 "general_operand" "g"))
7478           (const_int 0)))
7479    (set (match_operand:DI 0 "register_operand" "=r")
7480         (zero_extend:DI
7481           (minus:SI (match_dup 1)
7482                     (match_dup 2))))]
7483   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7484    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7485   "sub{l}\t{%2, %k0|%k0, %2}"
7486   [(set_attr "type" "alu")
7487    (set_attr "mode" "SI")])
7489 (define_insn "*subsi_3"
7490   [(set (reg FLAGS_REG)
7491         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7492                  (match_operand:SI 2 "general_operand" "ri,rm")))
7493    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7494         (minus:SI (match_dup 1) (match_dup 2)))]
7495   "ix86_match_ccmode (insn, CCmode)
7496    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7497   "sub{l}\t{%2, %0|%0, %2}"
7498   [(set_attr "type" "alu")
7499    (set_attr "mode" "SI")])
7501 (define_insn "*subsi_3_zext"
7502   [(set (reg FLAGS_REG)
7503         (compare (match_operand:SI 1 "register_operand" "0")
7504                  (match_operand:SI 2 "general_operand" "g")))
7505    (set (match_operand:DI 0 "register_operand" "=r")
7506         (zero_extend:DI
7507           (minus:SI (match_dup 1)
7508                     (match_dup 2))))]
7509   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7510    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7511   "sub{l}\t{%2, %1|%1, %2}"
7512   [(set_attr "type" "alu")
7513    (set_attr "mode" "DI")])
7515 (define_expand "subhi3"
7516   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7517                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7518                              (match_operand:HI 2 "general_operand" "")))
7519               (clobber (reg:CC FLAGS_REG))])]
7520   "TARGET_HIMODE_MATH"
7521   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7523 (define_insn "*subhi_1"
7524   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7525         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7526                   (match_operand:HI 2 "general_operand" "ri,rm")))
7527    (clobber (reg:CC FLAGS_REG))]
7528   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7529   "sub{w}\t{%2, %0|%0, %2}"
7530   [(set_attr "type" "alu")
7531    (set_attr "mode" "HI")])
7533 (define_insn "*subhi_2"
7534   [(set (reg FLAGS_REG)
7535         (compare
7536           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7537                     (match_operand:HI 2 "general_operand" "ri,rm"))
7538           (const_int 0)))
7539    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7540         (minus:HI (match_dup 1) (match_dup 2)))]
7541   "ix86_match_ccmode (insn, CCGOCmode)
7542    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7543   "sub{w}\t{%2, %0|%0, %2}"
7544   [(set_attr "type" "alu")
7545    (set_attr "mode" "HI")])
7547 (define_insn "*subhi_3"
7548   [(set (reg FLAGS_REG)
7549         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7550                  (match_operand:HI 2 "general_operand" "ri,rm")))
7551    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7552         (minus:HI (match_dup 1) (match_dup 2)))]
7553   "ix86_match_ccmode (insn, CCmode)
7554    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7555   "sub{w}\t{%2, %0|%0, %2}"
7556   [(set_attr "type" "alu")
7557    (set_attr "mode" "HI")])
7559 (define_expand "subqi3"
7560   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7561                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7562                              (match_operand:QI 2 "general_operand" "")))
7563               (clobber (reg:CC FLAGS_REG))])]
7564   "TARGET_QIMODE_MATH"
7565   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7567 (define_insn "*subqi_1"
7568   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7569         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7570                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7571    (clobber (reg:CC FLAGS_REG))]
7572   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7573   "sub{b}\t{%2, %0|%0, %2}"
7574   [(set_attr "type" "alu")
7575    (set_attr "mode" "QI")])
7577 (define_insn "*subqi_1_slp"
7578   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7579         (minus:QI (match_dup 0)
7580                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7581    (clobber (reg:CC FLAGS_REG))]
7582   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7583    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7584   "sub{b}\t{%1, %0|%0, %1}"
7585   [(set_attr "type" "alu1")
7586    (set_attr "mode" "QI")])
7588 (define_insn "*subqi_2"
7589   [(set (reg FLAGS_REG)
7590         (compare
7591           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7592                     (match_operand:QI 2 "general_operand" "qi,qm"))
7593           (const_int 0)))
7594    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7595         (minus:HI (match_dup 1) (match_dup 2)))]
7596   "ix86_match_ccmode (insn, CCGOCmode)
7597    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7598   "sub{b}\t{%2, %0|%0, %2}"
7599   [(set_attr "type" "alu")
7600    (set_attr "mode" "QI")])
7602 (define_insn "*subqi_3"
7603   [(set (reg FLAGS_REG)
7604         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7605                  (match_operand:QI 2 "general_operand" "qi,qm")))
7606    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7607         (minus:HI (match_dup 1) (match_dup 2)))]
7608   "ix86_match_ccmode (insn, CCmode)
7609    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7610   "sub{b}\t{%2, %0|%0, %2}"
7611   [(set_attr "type" "alu")
7612    (set_attr "mode" "QI")])
7614 ;; The patterns that match these are at the end of this file.
7616 (define_expand "subxf3"
7617   [(set (match_operand:XF 0 "register_operand" "")
7618         (minus:XF (match_operand:XF 1 "register_operand" "")
7619                   (match_operand:XF 2 "register_operand" "")))]
7620   "TARGET_80387"
7621   "")
7623 (define_expand "sub<mode>3"
7624   [(set (match_operand:MODEF 0 "register_operand" "")
7625         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7626                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7627   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7628   "")
7630 ;; Multiply instructions
7632 (define_expand "muldi3"
7633   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7634                    (mult:DI (match_operand:DI 1 "register_operand" "")
7635                             (match_operand:DI 2 "x86_64_general_operand" "")))
7636               (clobber (reg:CC FLAGS_REG))])]
7637   "TARGET_64BIT"
7638   "")
7640 ;; On AMDFAM10
7641 ;; IMUL reg64, reg64, imm8      Direct
7642 ;; IMUL reg64, mem64, imm8      VectorPath
7643 ;; IMUL reg64, reg64, imm32     Direct
7644 ;; IMUL reg64, mem64, imm32     VectorPath
7645 ;; IMUL reg64, reg64            Direct
7646 ;; IMUL reg64, mem64            Direct
7648 (define_insn "*muldi3_1_rex64"
7649   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7650         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7651                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7652    (clobber (reg:CC FLAGS_REG))]
7653   "TARGET_64BIT
7654    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7655   "@
7656    imul{q}\t{%2, %1, %0|%0, %1, %2}
7657    imul{q}\t{%2, %1, %0|%0, %1, %2}
7658    imul{q}\t{%2, %0|%0, %2}"
7659   [(set_attr "type" "imul")
7660    (set_attr "prefix_0f" "0,0,1")
7661    (set (attr "athlon_decode")
7662         (cond [(eq_attr "cpu" "athlon")
7663                   (const_string "vector")
7664                (eq_attr "alternative" "1")
7665                   (const_string "vector")
7666                (and (eq_attr "alternative" "2")
7667                     (match_operand 1 "memory_operand" ""))
7668                   (const_string "vector")]
7669               (const_string "direct")))
7670    (set (attr "amdfam10_decode")
7671         (cond [(and (eq_attr "alternative" "0,1")
7672                     (match_operand 1 "memory_operand" ""))
7673                   (const_string "vector")]
7674               (const_string "direct")))
7675    (set_attr "mode" "DI")])
7677 (define_expand "mulsi3"
7678   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7679                    (mult:SI (match_operand:SI 1 "register_operand" "")
7680                             (match_operand:SI 2 "general_operand" "")))
7681               (clobber (reg:CC FLAGS_REG))])]
7682   ""
7683   "")
7685 ;; On AMDFAM10
7686 ;; IMUL reg32, reg32, imm8      Direct
7687 ;; IMUL reg32, mem32, imm8      VectorPath
7688 ;; IMUL reg32, reg32, imm32     Direct
7689 ;; IMUL reg32, mem32, imm32     VectorPath
7690 ;; IMUL reg32, reg32            Direct
7691 ;; IMUL reg32, mem32            Direct
7693 (define_insn "*mulsi3_1"
7694   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7695         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7696                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7697    (clobber (reg:CC FLAGS_REG))]
7698   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7699   "@
7700    imul{l}\t{%2, %1, %0|%0, %1, %2}
7701    imul{l}\t{%2, %1, %0|%0, %1, %2}
7702    imul{l}\t{%2, %0|%0, %2}"
7703   [(set_attr "type" "imul")
7704    (set_attr "prefix_0f" "0,0,1")
7705    (set (attr "athlon_decode")
7706         (cond [(eq_attr "cpu" "athlon")
7707                   (const_string "vector")
7708                (eq_attr "alternative" "1")
7709                   (const_string "vector")
7710                (and (eq_attr "alternative" "2")
7711                     (match_operand 1 "memory_operand" ""))
7712                   (const_string "vector")]
7713               (const_string "direct")))
7714    (set (attr "amdfam10_decode")
7715         (cond [(and (eq_attr "alternative" "0,1")
7716                     (match_operand 1 "memory_operand" ""))
7717                   (const_string "vector")]
7718               (const_string "direct")))
7719    (set_attr "mode" "SI")])
7721 (define_insn "*mulsi3_1_zext"
7722   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7723         (zero_extend:DI
7724           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7725                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7726    (clobber (reg:CC FLAGS_REG))]
7727   "TARGET_64BIT
7728    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7729   "@
7730    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7731    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7732    imul{l}\t{%2, %k0|%k0, %2}"
7733   [(set_attr "type" "imul")
7734    (set_attr "prefix_0f" "0,0,1")
7735    (set (attr "athlon_decode")
7736         (cond [(eq_attr "cpu" "athlon")
7737                   (const_string "vector")
7738                (eq_attr "alternative" "1")
7739                   (const_string "vector")
7740                (and (eq_attr "alternative" "2")
7741                     (match_operand 1 "memory_operand" ""))
7742                   (const_string "vector")]
7743               (const_string "direct")))
7744    (set (attr "amdfam10_decode")
7745         (cond [(and (eq_attr "alternative" "0,1")
7746                     (match_operand 1 "memory_operand" ""))
7747                   (const_string "vector")]
7748               (const_string "direct")))
7749    (set_attr "mode" "SI")])
7751 (define_expand "mulhi3"
7752   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7753                    (mult:HI (match_operand:HI 1 "register_operand" "")
7754                             (match_operand:HI 2 "general_operand" "")))
7755               (clobber (reg:CC FLAGS_REG))])]
7756   "TARGET_HIMODE_MATH"
7757   "")
7759 ;; On AMDFAM10
7760 ;; IMUL reg16, reg16, imm8      VectorPath
7761 ;; IMUL reg16, mem16, imm8      VectorPath
7762 ;; IMUL reg16, reg16, imm16     VectorPath
7763 ;; IMUL reg16, mem16, imm16     VectorPath
7764 ;; IMUL reg16, reg16            Direct
7765 ;; IMUL reg16, mem16            Direct
7766 (define_insn "*mulhi3_1"
7767   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7768         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7769                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7770    (clobber (reg:CC FLAGS_REG))]
7771   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7772   "@
7773    imul{w}\t{%2, %1, %0|%0, %1, %2}
7774    imul{w}\t{%2, %1, %0|%0, %1, %2}
7775    imul{w}\t{%2, %0|%0, %2}"
7776   [(set_attr "type" "imul")
7777    (set_attr "prefix_0f" "0,0,1")
7778    (set (attr "athlon_decode")
7779         (cond [(eq_attr "cpu" "athlon")
7780                   (const_string "vector")
7781                (eq_attr "alternative" "1,2")
7782                   (const_string "vector")]
7783               (const_string "direct")))
7784    (set (attr "amdfam10_decode")
7785         (cond [(eq_attr "alternative" "0,1")
7786                   (const_string "vector")]
7787               (const_string "direct")))
7788    (set_attr "mode" "HI")])
7790 (define_expand "mulqi3"
7791   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7792                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7793                             (match_operand:QI 2 "register_operand" "")))
7794               (clobber (reg:CC FLAGS_REG))])]
7795   "TARGET_QIMODE_MATH"
7796   "")
7798 ;;On AMDFAM10
7799 ;; MUL reg8     Direct
7800 ;; MUL mem8     Direct
7802 (define_insn "*mulqi3_1"
7803   [(set (match_operand:QI 0 "register_operand" "=a")
7804         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7805                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7806    (clobber (reg:CC FLAGS_REG))]
7807   "TARGET_QIMODE_MATH
7808    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7809   "mul{b}\t%2"
7810   [(set_attr "type" "imul")
7811    (set_attr "length_immediate" "0")
7812    (set (attr "athlon_decode")
7813      (if_then_else (eq_attr "cpu" "athlon")
7814         (const_string "vector")
7815         (const_string "direct")))
7816    (set_attr "amdfam10_decode" "direct")
7817    (set_attr "mode" "QI")])
7819 (define_expand "umulqihi3"
7820   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7821                    (mult:HI (zero_extend:HI
7822                               (match_operand:QI 1 "nonimmediate_operand" ""))
7823                             (zero_extend:HI
7824                               (match_operand:QI 2 "register_operand" ""))))
7825               (clobber (reg:CC FLAGS_REG))])]
7826   "TARGET_QIMODE_MATH"
7827   "")
7829 (define_insn "*umulqihi3_1"
7830   [(set (match_operand:HI 0 "register_operand" "=a")
7831         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7832                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7833    (clobber (reg:CC FLAGS_REG))]
7834   "TARGET_QIMODE_MATH
7835    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7836   "mul{b}\t%2"
7837   [(set_attr "type" "imul")
7838    (set_attr "length_immediate" "0")
7839    (set (attr "athlon_decode")
7840      (if_then_else (eq_attr "cpu" "athlon")
7841         (const_string "vector")
7842         (const_string "direct")))
7843    (set_attr "amdfam10_decode" "direct")
7844    (set_attr "mode" "QI")])
7846 (define_expand "mulqihi3"
7847   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7848                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7849                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7850               (clobber (reg:CC FLAGS_REG))])]
7851   "TARGET_QIMODE_MATH"
7852   "")
7854 (define_insn "*mulqihi3_insn"
7855   [(set (match_operand:HI 0 "register_operand" "=a")
7856         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7857                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7858    (clobber (reg:CC FLAGS_REG))]
7859   "TARGET_QIMODE_MATH
7860    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7861   "imul{b}\t%2"
7862   [(set_attr "type" "imul")
7863    (set_attr "length_immediate" "0")
7864    (set (attr "athlon_decode")
7865      (if_then_else (eq_attr "cpu" "athlon")
7866         (const_string "vector")
7867         (const_string "direct")))
7868    (set_attr "amdfam10_decode" "direct")
7869    (set_attr "mode" "QI")])
7871 (define_expand "umulditi3"
7872   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7873                    (mult:TI (zero_extend:TI
7874                               (match_operand:DI 1 "nonimmediate_operand" ""))
7875                             (zero_extend:TI
7876                               (match_operand:DI 2 "register_operand" ""))))
7877               (clobber (reg:CC FLAGS_REG))])]
7878   "TARGET_64BIT"
7879   "")
7881 (define_insn "*umulditi3_insn"
7882   [(set (match_operand:TI 0 "register_operand" "=A")
7883         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7884                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7885    (clobber (reg:CC FLAGS_REG))]
7886   "TARGET_64BIT
7887    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7888   "mul{q}\t%2"
7889   [(set_attr "type" "imul")
7890    (set_attr "length_immediate" "0")
7891    (set (attr "athlon_decode")
7892      (if_then_else (eq_attr "cpu" "athlon")
7893         (const_string "vector")
7894         (const_string "double")))
7895    (set_attr "amdfam10_decode" "double")
7896    (set_attr "mode" "DI")])
7898 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7899 (define_expand "umulsidi3"
7900   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7901                    (mult:DI (zero_extend:DI
7902                               (match_operand:SI 1 "nonimmediate_operand" ""))
7903                             (zero_extend:DI
7904                               (match_operand:SI 2 "register_operand" ""))))
7905               (clobber (reg:CC FLAGS_REG))])]
7906   "!TARGET_64BIT"
7907   "")
7909 (define_insn "*umulsidi3_insn"
7910   [(set (match_operand:DI 0 "register_operand" "=A")
7911         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7912                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7913    (clobber (reg:CC FLAGS_REG))]
7914   "!TARGET_64BIT
7915    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7916   "mul{l}\t%2"
7917   [(set_attr "type" "imul")
7918    (set_attr "length_immediate" "0")
7919    (set (attr "athlon_decode")
7920      (if_then_else (eq_attr "cpu" "athlon")
7921         (const_string "vector")
7922         (const_string "double")))
7923    (set_attr "amdfam10_decode" "double")
7924    (set_attr "mode" "SI")])
7926 (define_expand "mulditi3"
7927   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7928                    (mult:TI (sign_extend:TI
7929                               (match_operand:DI 1 "nonimmediate_operand" ""))
7930                             (sign_extend:TI
7931                               (match_operand:DI 2 "register_operand" ""))))
7932               (clobber (reg:CC FLAGS_REG))])]
7933   "TARGET_64BIT"
7934   "")
7936 (define_insn "*mulditi3_insn"
7937   [(set (match_operand:TI 0 "register_operand" "=A")
7938         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7939                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7940    (clobber (reg:CC FLAGS_REG))]
7941   "TARGET_64BIT
7942    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7943   "imul{q}\t%2"
7944   [(set_attr "type" "imul")
7945    (set_attr "length_immediate" "0")
7946    (set (attr "athlon_decode")
7947      (if_then_else (eq_attr "cpu" "athlon")
7948         (const_string "vector")
7949         (const_string "double")))
7950    (set_attr "amdfam10_decode" "double")
7951    (set_attr "mode" "DI")])
7953 (define_expand "mulsidi3"
7954   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7955                    (mult:DI (sign_extend:DI
7956                               (match_operand:SI 1 "nonimmediate_operand" ""))
7957                             (sign_extend:DI
7958                               (match_operand:SI 2 "register_operand" ""))))
7959               (clobber (reg:CC FLAGS_REG))])]
7960   "!TARGET_64BIT"
7961   "")
7963 (define_insn "*mulsidi3_insn"
7964   [(set (match_operand:DI 0 "register_operand" "=A")
7965         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7966                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7967    (clobber (reg:CC FLAGS_REG))]
7968   "!TARGET_64BIT
7969    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7970   "imul{l}\t%2"
7971   [(set_attr "type" "imul")
7972    (set_attr "length_immediate" "0")
7973    (set (attr "athlon_decode")
7974      (if_then_else (eq_attr "cpu" "athlon")
7975         (const_string "vector")
7976         (const_string "double")))
7977    (set_attr "amdfam10_decode" "double")
7978    (set_attr "mode" "SI")])
7980 (define_expand "umuldi3_highpart"
7981   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7982                    (truncate:DI
7983                      (lshiftrt:TI
7984                        (mult:TI (zero_extend:TI
7985                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7986                                 (zero_extend:TI
7987                                   (match_operand:DI 2 "register_operand" "")))
7988                        (const_int 64))))
7989               (clobber (match_scratch:DI 3 ""))
7990               (clobber (reg:CC FLAGS_REG))])]
7991   "TARGET_64BIT"
7992   "")
7994 (define_insn "*umuldi3_highpart_rex64"
7995   [(set (match_operand:DI 0 "register_operand" "=d")
7996         (truncate:DI
7997           (lshiftrt:TI
7998             (mult:TI (zero_extend:TI
7999                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8000                      (zero_extend:TI
8001                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8002             (const_int 64))))
8003    (clobber (match_scratch:DI 3 "=1"))
8004    (clobber (reg:CC FLAGS_REG))]
8005   "TARGET_64BIT
8006    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8007   "mul{q}\t%2"
8008   [(set_attr "type" "imul")
8009    (set_attr "length_immediate" "0")
8010    (set (attr "athlon_decode")
8011      (if_then_else (eq_attr "cpu" "athlon")
8012         (const_string "vector")
8013         (const_string "double")))
8014    (set_attr "amdfam10_decode" "double")
8015    (set_attr "mode" "DI")])
8017 (define_expand "umulsi3_highpart"
8018   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8019                    (truncate:SI
8020                      (lshiftrt:DI
8021                        (mult:DI (zero_extend:DI
8022                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8023                                 (zero_extend:DI
8024                                   (match_operand:SI 2 "register_operand" "")))
8025                        (const_int 32))))
8026               (clobber (match_scratch:SI 3 ""))
8027               (clobber (reg:CC FLAGS_REG))])]
8028   ""
8029   "")
8031 (define_insn "*umulsi3_highpart_insn"
8032   [(set (match_operand:SI 0 "register_operand" "=d")
8033         (truncate:SI
8034           (lshiftrt:DI
8035             (mult:DI (zero_extend:DI
8036                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8037                      (zero_extend:DI
8038                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8039             (const_int 32))))
8040    (clobber (match_scratch:SI 3 "=1"))
8041    (clobber (reg:CC FLAGS_REG))]
8042   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8043   "mul{l}\t%2"
8044   [(set_attr "type" "imul")
8045    (set_attr "length_immediate" "0")
8046    (set (attr "athlon_decode")
8047      (if_then_else (eq_attr "cpu" "athlon")
8048         (const_string "vector")
8049         (const_string "double")))
8050    (set_attr "amdfam10_decode" "double")
8051    (set_attr "mode" "SI")])
8053 (define_insn "*umulsi3_highpart_zext"
8054   [(set (match_operand:DI 0 "register_operand" "=d")
8055         (zero_extend:DI (truncate:SI
8056           (lshiftrt:DI
8057             (mult:DI (zero_extend:DI
8058                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8059                      (zero_extend:DI
8060                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8061             (const_int 32)))))
8062    (clobber (match_scratch:SI 3 "=1"))
8063    (clobber (reg:CC FLAGS_REG))]
8064   "TARGET_64BIT
8065    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8066   "mul{l}\t%2"
8067   [(set_attr "type" "imul")
8068    (set_attr "length_immediate" "0")
8069    (set (attr "athlon_decode")
8070      (if_then_else (eq_attr "cpu" "athlon")
8071         (const_string "vector")
8072         (const_string "double")))
8073    (set_attr "amdfam10_decode" "double")
8074    (set_attr "mode" "SI")])
8076 (define_expand "smuldi3_highpart"
8077   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8078                    (truncate:DI
8079                      (lshiftrt:TI
8080                        (mult:TI (sign_extend:TI
8081                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8082                                 (sign_extend:TI
8083                                   (match_operand:DI 2 "register_operand" "")))
8084                        (const_int 64))))
8085               (clobber (match_scratch:DI 3 ""))
8086               (clobber (reg:CC FLAGS_REG))])]
8087   "TARGET_64BIT"
8088   "")
8090 (define_insn "*smuldi3_highpart_rex64"
8091   [(set (match_operand:DI 0 "register_operand" "=d")
8092         (truncate:DI
8093           (lshiftrt:TI
8094             (mult:TI (sign_extend:TI
8095                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8096                      (sign_extend:TI
8097                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8098             (const_int 64))))
8099    (clobber (match_scratch:DI 3 "=1"))
8100    (clobber (reg:CC FLAGS_REG))]
8101   "TARGET_64BIT
8102    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8103   "imul{q}\t%2"
8104   [(set_attr "type" "imul")
8105    (set (attr "athlon_decode")
8106      (if_then_else (eq_attr "cpu" "athlon")
8107         (const_string "vector")
8108         (const_string "double")))
8109    (set_attr "amdfam10_decode" "double")
8110    (set_attr "mode" "DI")])
8112 (define_expand "smulsi3_highpart"
8113   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8114                    (truncate:SI
8115                      (lshiftrt:DI
8116                        (mult:DI (sign_extend:DI
8117                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8118                                 (sign_extend:DI
8119                                   (match_operand:SI 2 "register_operand" "")))
8120                        (const_int 32))))
8121               (clobber (match_scratch:SI 3 ""))
8122               (clobber (reg:CC FLAGS_REG))])]
8123   ""
8124   "")
8126 (define_insn "*smulsi3_highpart_insn"
8127   [(set (match_operand:SI 0 "register_operand" "=d")
8128         (truncate:SI
8129           (lshiftrt:DI
8130             (mult:DI (sign_extend:DI
8131                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8132                      (sign_extend:DI
8133                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8134             (const_int 32))))
8135    (clobber (match_scratch:SI 3 "=1"))
8136    (clobber (reg:CC FLAGS_REG))]
8137   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8138   "imul{l}\t%2"
8139   [(set_attr "type" "imul")
8140    (set (attr "athlon_decode")
8141      (if_then_else (eq_attr "cpu" "athlon")
8142         (const_string "vector")
8143         (const_string "double")))
8144    (set_attr "amdfam10_decode" "double")
8145    (set_attr "mode" "SI")])
8147 (define_insn "*smulsi3_highpart_zext"
8148   [(set (match_operand:DI 0 "register_operand" "=d")
8149         (zero_extend:DI (truncate:SI
8150           (lshiftrt:DI
8151             (mult:DI (sign_extend:DI
8152                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8153                      (sign_extend:DI
8154                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8155             (const_int 32)))))
8156    (clobber (match_scratch:SI 3 "=1"))
8157    (clobber (reg:CC FLAGS_REG))]
8158   "TARGET_64BIT
8159    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8160   "imul{l}\t%2"
8161   [(set_attr "type" "imul")
8162    (set (attr "athlon_decode")
8163      (if_then_else (eq_attr "cpu" "athlon")
8164         (const_string "vector")
8165         (const_string "double")))
8166    (set_attr "amdfam10_decode" "double")
8167    (set_attr "mode" "SI")])
8169 ;; The patterns that match these are at the end of this file.
8171 (define_expand "mulxf3"
8172   [(set (match_operand:XF 0 "register_operand" "")
8173         (mult:XF (match_operand:XF 1 "register_operand" "")
8174                  (match_operand:XF 2 "register_operand" "")))]
8175   "TARGET_80387"
8176   "")
8178 (define_expand "mul<mode>3"
8179   [(set (match_operand:MODEF 0 "register_operand" "")
8180         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8181                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8182   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8183   "")
8185 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8188 ;; Divide instructions
8190 (define_insn "divqi3"
8191   [(set (match_operand:QI 0 "register_operand" "=a")
8192         (div:QI (match_operand:HI 1 "register_operand" "0")
8193                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8194    (clobber (reg:CC FLAGS_REG))]
8195   "TARGET_QIMODE_MATH"
8196   "idiv{b}\t%2"
8197   [(set_attr "type" "idiv")
8198    (set_attr "mode" "QI")])
8200 (define_insn "udivqi3"
8201   [(set (match_operand:QI 0 "register_operand" "=a")
8202         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8203                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8204    (clobber (reg:CC FLAGS_REG))]
8205   "TARGET_QIMODE_MATH"
8206   "div{b}\t%2"
8207   [(set_attr "type" "idiv")
8208    (set_attr "mode" "QI")])
8210 ;; The patterns that match these are at the end of this file.
8212 (define_expand "divxf3"
8213   [(set (match_operand:XF 0 "register_operand" "")
8214         (div:XF (match_operand:XF 1 "register_operand" "")
8215                 (match_operand:XF 2 "register_operand" "")))]
8216   "TARGET_80387"
8217   "")
8219 (define_expand "divdf3"
8220   [(set (match_operand:DF 0 "register_operand" "")
8221         (div:DF (match_operand:DF 1 "register_operand" "")
8222                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8223    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8224    "")
8226 (define_expand "divsf3"
8227   [(set (match_operand:SF 0 "register_operand" "")
8228         (div:SF (match_operand:SF 1 "register_operand" "")
8229                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8230   "TARGET_80387 || TARGET_SSE_MATH"
8232   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8233       && flag_finite_math_only && !flag_trapping_math
8234       && flag_unsafe_math_optimizations)
8235     {
8236       ix86_emit_swdivsf (operands[0], operands[1],
8237                          operands[2], SFmode);
8238       DONE;
8239     }
8242 ;; Remainder instructions.
8244 (define_expand "divmoddi4"
8245   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8246                    (div:DI (match_operand:DI 1 "register_operand" "")
8247                            (match_operand:DI 2 "nonimmediate_operand" "")))
8248               (set (match_operand:DI 3 "register_operand" "")
8249                    (mod:DI (match_dup 1) (match_dup 2)))
8250               (clobber (reg:CC FLAGS_REG))])]
8251   "TARGET_64BIT"
8252   "")
8254 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8255 ;; Penalize eax case slightly because it results in worse scheduling
8256 ;; of code.
8257 (define_insn "*divmoddi4_nocltd_rex64"
8258   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8259         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8260                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8261    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8262         (mod:DI (match_dup 2) (match_dup 3)))
8263    (clobber (reg:CC FLAGS_REG))]
8264   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8265   "#"
8266   [(set_attr "type" "multi")])
8268 (define_insn "*divmoddi4_cltd_rex64"
8269   [(set (match_operand:DI 0 "register_operand" "=a")
8270         (div:DI (match_operand:DI 2 "register_operand" "a")
8271                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8272    (set (match_operand:DI 1 "register_operand" "=&d")
8273         (mod:DI (match_dup 2) (match_dup 3)))
8274    (clobber (reg:CC FLAGS_REG))]
8275   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8276   "#"
8277   [(set_attr "type" "multi")])
8279 (define_insn "*divmoddi_noext_rex64"
8280   [(set (match_operand:DI 0 "register_operand" "=a")
8281         (div:DI (match_operand:DI 1 "register_operand" "0")
8282                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8283    (set (match_operand:DI 3 "register_operand" "=d")
8284         (mod:DI (match_dup 1) (match_dup 2)))
8285    (use (match_operand:DI 4 "register_operand" "3"))
8286    (clobber (reg:CC FLAGS_REG))]
8287   "TARGET_64BIT"
8288   "idiv{q}\t%2"
8289   [(set_attr "type" "idiv")
8290    (set_attr "mode" "DI")])
8292 (define_split
8293   [(set (match_operand:DI 0 "register_operand" "")
8294         (div:DI (match_operand:DI 1 "register_operand" "")
8295                 (match_operand:DI 2 "nonimmediate_operand" "")))
8296    (set (match_operand:DI 3 "register_operand" "")
8297         (mod:DI (match_dup 1) (match_dup 2)))
8298    (clobber (reg:CC FLAGS_REG))]
8299   "TARGET_64BIT && reload_completed"
8300   [(parallel [(set (match_dup 3)
8301                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8302               (clobber (reg:CC FLAGS_REG))])
8303    (parallel [(set (match_dup 0)
8304                    (div:DI (reg:DI 0) (match_dup 2)))
8305               (set (match_dup 3)
8306                    (mod:DI (reg:DI 0) (match_dup 2)))
8307               (use (match_dup 3))
8308               (clobber (reg:CC FLAGS_REG))])]
8310   /* Avoid use of cltd in favor of a mov+shift.  */
8311   if (!TARGET_USE_CLTD && !optimize_size)
8312     {
8313       if (true_regnum (operands[1]))
8314         emit_move_insn (operands[0], operands[1]);
8315       else
8316         emit_move_insn (operands[3], operands[1]);
8317       operands[4] = operands[3];
8318     }
8319   else
8320     {
8321       gcc_assert (!true_regnum (operands[1]));
8322       operands[4] = operands[1];
8323     }
8327 (define_expand "divmodsi4"
8328   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8329                    (div:SI (match_operand:SI 1 "register_operand" "")
8330                            (match_operand:SI 2 "nonimmediate_operand" "")))
8331               (set (match_operand:SI 3 "register_operand" "")
8332                    (mod:SI (match_dup 1) (match_dup 2)))
8333               (clobber (reg:CC FLAGS_REG))])]
8334   ""
8335   "")
8337 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8338 ;; Penalize eax case slightly because it results in worse scheduling
8339 ;; of code.
8340 (define_insn "*divmodsi4_nocltd"
8341   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8342         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8343                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8344    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8345         (mod:SI (match_dup 2) (match_dup 3)))
8346    (clobber (reg:CC FLAGS_REG))]
8347   "!optimize_size && !TARGET_USE_CLTD"
8348   "#"
8349   [(set_attr "type" "multi")])
8351 (define_insn "*divmodsi4_cltd"
8352   [(set (match_operand:SI 0 "register_operand" "=a")
8353         (div:SI (match_operand:SI 2 "register_operand" "a")
8354                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8355    (set (match_operand:SI 1 "register_operand" "=&d")
8356         (mod:SI (match_dup 2) (match_dup 3)))
8357    (clobber (reg:CC FLAGS_REG))]
8358   "optimize_size || TARGET_USE_CLTD"
8359   "#"
8360   [(set_attr "type" "multi")])
8362 (define_insn "*divmodsi_noext"
8363   [(set (match_operand:SI 0 "register_operand" "=a")
8364         (div:SI (match_operand:SI 1 "register_operand" "0")
8365                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8366    (set (match_operand:SI 3 "register_operand" "=d")
8367         (mod:SI (match_dup 1) (match_dup 2)))
8368    (use (match_operand:SI 4 "register_operand" "3"))
8369    (clobber (reg:CC FLAGS_REG))]
8370   ""
8371   "idiv{l}\t%2"
8372   [(set_attr "type" "idiv")
8373    (set_attr "mode" "SI")])
8375 (define_split
8376   [(set (match_operand:SI 0 "register_operand" "")
8377         (div:SI (match_operand:SI 1 "register_operand" "")
8378                 (match_operand:SI 2 "nonimmediate_operand" "")))
8379    (set (match_operand:SI 3 "register_operand" "")
8380         (mod:SI (match_dup 1) (match_dup 2)))
8381    (clobber (reg:CC FLAGS_REG))]
8382   "reload_completed"
8383   [(parallel [(set (match_dup 3)
8384                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8385               (clobber (reg:CC FLAGS_REG))])
8386    (parallel [(set (match_dup 0)
8387                    (div:SI (reg:SI 0) (match_dup 2)))
8388               (set (match_dup 3)
8389                    (mod:SI (reg:SI 0) (match_dup 2)))
8390               (use (match_dup 3))
8391               (clobber (reg:CC FLAGS_REG))])]
8393   /* Avoid use of cltd in favor of a mov+shift.  */
8394   if (!TARGET_USE_CLTD && !optimize_size)
8395     {
8396       if (true_regnum (operands[1]))
8397         emit_move_insn (operands[0], operands[1]);
8398       else
8399         emit_move_insn (operands[3], operands[1]);
8400       operands[4] = operands[3];
8401     }
8402   else
8403     {
8404       gcc_assert (!true_regnum (operands[1]));
8405       operands[4] = operands[1];
8406     }
8408 ;; %%% Split me.
8409 (define_insn "divmodhi4"
8410   [(set (match_operand:HI 0 "register_operand" "=a")
8411         (div:HI (match_operand:HI 1 "register_operand" "0")
8412                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8413    (set (match_operand:HI 3 "register_operand" "=&d")
8414         (mod:HI (match_dup 1) (match_dup 2)))
8415    (clobber (reg:CC FLAGS_REG))]
8416   "TARGET_HIMODE_MATH"
8417   "cwtd\;idiv{w}\t%2"
8418   [(set_attr "type" "multi")
8419    (set_attr "length_immediate" "0")
8420    (set_attr "mode" "SI")])
8422 (define_insn "udivmoddi4"
8423   [(set (match_operand:DI 0 "register_operand" "=a")
8424         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8425                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8426    (set (match_operand:DI 3 "register_operand" "=&d")
8427         (umod:DI (match_dup 1) (match_dup 2)))
8428    (clobber (reg:CC FLAGS_REG))]
8429   "TARGET_64BIT"
8430   "xor{q}\t%3, %3\;div{q}\t%2"
8431   [(set_attr "type" "multi")
8432    (set_attr "length_immediate" "0")
8433    (set_attr "mode" "DI")])
8435 (define_insn "*udivmoddi4_noext"
8436   [(set (match_operand:DI 0 "register_operand" "=a")
8437         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8438                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8439    (set (match_operand:DI 3 "register_operand" "=d")
8440         (umod:DI (match_dup 1) (match_dup 2)))
8441    (use (match_dup 3))
8442    (clobber (reg:CC FLAGS_REG))]
8443   "TARGET_64BIT"
8444   "div{q}\t%2"
8445   [(set_attr "type" "idiv")
8446    (set_attr "mode" "DI")])
8448 (define_split
8449   [(set (match_operand:DI 0 "register_operand" "")
8450         (udiv:DI (match_operand:DI 1 "register_operand" "")
8451                  (match_operand:DI 2 "nonimmediate_operand" "")))
8452    (set (match_operand:DI 3 "register_operand" "")
8453         (umod:DI (match_dup 1) (match_dup 2)))
8454    (clobber (reg:CC FLAGS_REG))]
8455   "TARGET_64BIT && reload_completed"
8456   [(set (match_dup 3) (const_int 0))
8457    (parallel [(set (match_dup 0)
8458                    (udiv:DI (match_dup 1) (match_dup 2)))
8459               (set (match_dup 3)
8460                    (umod:DI (match_dup 1) (match_dup 2)))
8461               (use (match_dup 3))
8462               (clobber (reg:CC FLAGS_REG))])]
8463   "")
8465 (define_insn "udivmodsi4"
8466   [(set (match_operand:SI 0 "register_operand" "=a")
8467         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8468                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8469    (set (match_operand:SI 3 "register_operand" "=&d")
8470         (umod:SI (match_dup 1) (match_dup 2)))
8471    (clobber (reg:CC FLAGS_REG))]
8472   ""
8473   "xor{l}\t%3, %3\;div{l}\t%2"
8474   [(set_attr "type" "multi")
8475    (set_attr "length_immediate" "0")
8476    (set_attr "mode" "SI")])
8478 (define_insn "*udivmodsi4_noext"
8479   [(set (match_operand:SI 0 "register_operand" "=a")
8480         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8481                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8482    (set (match_operand:SI 3 "register_operand" "=d")
8483         (umod:SI (match_dup 1) (match_dup 2)))
8484    (use (match_dup 3))
8485    (clobber (reg:CC FLAGS_REG))]
8486   ""
8487   "div{l}\t%2"
8488   [(set_attr "type" "idiv")
8489    (set_attr "mode" "SI")])
8491 (define_split
8492   [(set (match_operand:SI 0 "register_operand" "")
8493         (udiv:SI (match_operand:SI 1 "register_operand" "")
8494                  (match_operand:SI 2 "nonimmediate_operand" "")))
8495    (set (match_operand:SI 3 "register_operand" "")
8496         (umod:SI (match_dup 1) (match_dup 2)))
8497    (clobber (reg:CC FLAGS_REG))]
8498   "reload_completed"
8499   [(set (match_dup 3) (const_int 0))
8500    (parallel [(set (match_dup 0)
8501                    (udiv:SI (match_dup 1) (match_dup 2)))
8502               (set (match_dup 3)
8503                    (umod:SI (match_dup 1) (match_dup 2)))
8504               (use (match_dup 3))
8505               (clobber (reg:CC FLAGS_REG))])]
8506   "")
8508 (define_expand "udivmodhi4"
8509   [(set (match_dup 4) (const_int 0))
8510    (parallel [(set (match_operand:HI 0 "register_operand" "")
8511                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8512                             (match_operand:HI 2 "nonimmediate_operand" "")))
8513               (set (match_operand:HI 3 "register_operand" "")
8514                    (umod:HI (match_dup 1) (match_dup 2)))
8515               (use (match_dup 4))
8516               (clobber (reg:CC FLAGS_REG))])]
8517   "TARGET_HIMODE_MATH"
8518   "operands[4] = gen_reg_rtx (HImode);")
8520 (define_insn "*udivmodhi_noext"
8521   [(set (match_operand:HI 0 "register_operand" "=a")
8522         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8523                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8524    (set (match_operand:HI 3 "register_operand" "=d")
8525         (umod:HI (match_dup 1) (match_dup 2)))
8526    (use (match_operand:HI 4 "register_operand" "3"))
8527    (clobber (reg:CC FLAGS_REG))]
8528   ""
8529   "div{w}\t%2"
8530   [(set_attr "type" "idiv")
8531    (set_attr "mode" "HI")])
8533 ;; We cannot use div/idiv for double division, because it causes
8534 ;; "division by zero" on the overflow and that's not what we expect
8535 ;; from truncate.  Because true (non truncating) double division is
8536 ;; never generated, we can't create this insn anyway.
8538 ;(define_insn ""
8539 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8540 ;       (truncate:SI
8541 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8542 ;                  (zero_extend:DI
8543 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8544 ;   (set (match_operand:SI 3 "register_operand" "=d")
8545 ;       (truncate:SI
8546 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8547 ;   (clobber (reg:CC FLAGS_REG))]
8548 ;  ""
8549 ;  "div{l}\t{%2, %0|%0, %2}"
8550 ;  [(set_attr "type" "idiv")])
8552 ;;- Logical AND instructions
8554 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8555 ;; Note that this excludes ah.
8557 (define_insn "*testdi_1_rex64"
8558   [(set (reg FLAGS_REG)
8559         (compare
8560           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8561                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8562           (const_int 0)))]
8563   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8564    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8565   "@
8566    test{l}\t{%k1, %k0|%k0, %k1}
8567    test{l}\t{%k1, %k0|%k0, %k1}
8568    test{q}\t{%1, %0|%0, %1}
8569    test{q}\t{%1, %0|%0, %1}
8570    test{q}\t{%1, %0|%0, %1}"
8571   [(set_attr "type" "test")
8572    (set_attr "modrm" "0,1,0,1,1")
8573    (set_attr "mode" "SI,SI,DI,DI,DI")
8574    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8576 (define_insn "testsi_1"
8577   [(set (reg FLAGS_REG)
8578         (compare
8579           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8580                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8581           (const_int 0)))]
8582   "ix86_match_ccmode (insn, CCNOmode)
8583    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8584   "test{l}\t{%1, %0|%0, %1}"
8585   [(set_attr "type" "test")
8586    (set_attr "modrm" "0,1,1")
8587    (set_attr "mode" "SI")
8588    (set_attr "pent_pair" "uv,np,uv")])
8590 (define_expand "testsi_ccno_1"
8591   [(set (reg:CCNO FLAGS_REG)
8592         (compare:CCNO
8593           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8594                   (match_operand:SI 1 "nonmemory_operand" ""))
8595           (const_int 0)))]
8596   ""
8597   "")
8599 (define_insn "*testhi_1"
8600   [(set (reg FLAGS_REG)
8601         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8602                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8603                  (const_int 0)))]
8604   "ix86_match_ccmode (insn, CCNOmode)
8605    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8606   "test{w}\t{%1, %0|%0, %1}"
8607   [(set_attr "type" "test")
8608    (set_attr "modrm" "0,1,1")
8609    (set_attr "mode" "HI")
8610    (set_attr "pent_pair" "uv,np,uv")])
8612 (define_expand "testqi_ccz_1"
8613   [(set (reg:CCZ FLAGS_REG)
8614         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8615                              (match_operand:QI 1 "nonmemory_operand" ""))
8616                  (const_int 0)))]
8617   ""
8618   "")
8620 (define_insn "*testqi_1_maybe_si"
8621   [(set (reg FLAGS_REG)
8622         (compare
8623           (and:QI
8624             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8625             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8626           (const_int 0)))]
8627    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8628     && ix86_match_ccmode (insn,
8629                          CONST_INT_P (operands[1])
8630                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8632   if (which_alternative == 3)
8633     {
8634       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8635         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8636       return "test{l}\t{%1, %k0|%k0, %1}";
8637     }
8638   return "test{b}\t{%1, %0|%0, %1}";
8640   [(set_attr "type" "test")
8641    (set_attr "modrm" "0,1,1,1")
8642    (set_attr "mode" "QI,QI,QI,SI")
8643    (set_attr "pent_pair" "uv,np,uv,np")])
8645 (define_insn "*testqi_1"
8646   [(set (reg FLAGS_REG)
8647         (compare
8648           (and:QI
8649             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8650             (match_operand:QI 1 "general_operand" "n,n,qn"))
8651           (const_int 0)))]
8652   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8653    && ix86_match_ccmode (insn, CCNOmode)"
8654   "test{b}\t{%1, %0|%0, %1}"
8655   [(set_attr "type" "test")
8656    (set_attr "modrm" "0,1,1")
8657    (set_attr "mode" "QI")
8658    (set_attr "pent_pair" "uv,np,uv")])
8660 (define_expand "testqi_ext_ccno_0"
8661   [(set (reg:CCNO FLAGS_REG)
8662         (compare:CCNO
8663           (and:SI
8664             (zero_extract:SI
8665               (match_operand 0 "ext_register_operand" "")
8666               (const_int 8)
8667               (const_int 8))
8668             (match_operand 1 "const_int_operand" ""))
8669           (const_int 0)))]
8670   ""
8671   "")
8673 (define_insn "*testqi_ext_0"
8674   [(set (reg FLAGS_REG)
8675         (compare
8676           (and:SI
8677             (zero_extract:SI
8678               (match_operand 0 "ext_register_operand" "Q")
8679               (const_int 8)
8680               (const_int 8))
8681             (match_operand 1 "const_int_operand" "n"))
8682           (const_int 0)))]
8683   "ix86_match_ccmode (insn, CCNOmode)"
8684   "test{b}\t{%1, %h0|%h0, %1}"
8685   [(set_attr "type" "test")
8686    (set_attr "mode" "QI")
8687    (set_attr "length_immediate" "1")
8688    (set_attr "pent_pair" "np")])
8690 (define_insn "*testqi_ext_1"
8691   [(set (reg FLAGS_REG)
8692         (compare
8693           (and:SI
8694             (zero_extract:SI
8695               (match_operand 0 "ext_register_operand" "Q")
8696               (const_int 8)
8697               (const_int 8))
8698             (zero_extend:SI
8699               (match_operand:QI 1 "general_operand" "Qm")))
8700           (const_int 0)))]
8701   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8702    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8703   "test{b}\t{%1, %h0|%h0, %1}"
8704   [(set_attr "type" "test")
8705    (set_attr "mode" "QI")])
8707 (define_insn "*testqi_ext_1_rex64"
8708   [(set (reg FLAGS_REG)
8709         (compare
8710           (and:SI
8711             (zero_extract:SI
8712               (match_operand 0 "ext_register_operand" "Q")
8713               (const_int 8)
8714               (const_int 8))
8715             (zero_extend:SI
8716               (match_operand:QI 1 "register_operand" "Q")))
8717           (const_int 0)))]
8718   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8719   "test{b}\t{%1, %h0|%h0, %1}"
8720   [(set_attr "type" "test")
8721    (set_attr "mode" "QI")])
8723 (define_insn "*testqi_ext_2"
8724   [(set (reg FLAGS_REG)
8725         (compare
8726           (and:SI
8727             (zero_extract:SI
8728               (match_operand 0 "ext_register_operand" "Q")
8729               (const_int 8)
8730               (const_int 8))
8731             (zero_extract:SI
8732               (match_operand 1 "ext_register_operand" "Q")
8733               (const_int 8)
8734               (const_int 8)))
8735           (const_int 0)))]
8736   "ix86_match_ccmode (insn, CCNOmode)"
8737   "test{b}\t{%h1, %h0|%h0, %h1}"
8738   [(set_attr "type" "test")
8739    (set_attr "mode" "QI")])
8741 ;; Combine likes to form bit extractions for some tests.  Humor it.
8742 (define_insn "*testqi_ext_3"
8743   [(set (reg FLAGS_REG)
8744         (compare (zero_extract:SI
8745                    (match_operand 0 "nonimmediate_operand" "rm")
8746                    (match_operand:SI 1 "const_int_operand" "")
8747                    (match_operand:SI 2 "const_int_operand" ""))
8748                  (const_int 0)))]
8749   "ix86_match_ccmode (insn, CCNOmode)
8750    && INTVAL (operands[1]) > 0
8751    && INTVAL (operands[2]) >= 0
8752    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8753    && (GET_MODE (operands[0]) == SImode
8754        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8755        || GET_MODE (operands[0]) == HImode
8756        || GET_MODE (operands[0]) == QImode)"
8757   "#")
8759 (define_insn "*testqi_ext_3_rex64"
8760   [(set (reg FLAGS_REG)
8761         (compare (zero_extract:DI
8762                    (match_operand 0 "nonimmediate_operand" "rm")
8763                    (match_operand:DI 1 "const_int_operand" "")
8764                    (match_operand:DI 2 "const_int_operand" ""))
8765                  (const_int 0)))]
8766   "TARGET_64BIT
8767    && ix86_match_ccmode (insn, CCNOmode)
8768    && INTVAL (operands[1]) > 0
8769    && INTVAL (operands[2]) >= 0
8770    /* Ensure that resulting mask is zero or sign extended operand.  */
8771    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8772        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8773            && INTVAL (operands[1]) > 32))
8774    && (GET_MODE (operands[0]) == SImode
8775        || GET_MODE (operands[0]) == DImode
8776        || GET_MODE (operands[0]) == HImode
8777        || GET_MODE (operands[0]) == QImode)"
8778   "#")
8780 (define_split
8781   [(set (match_operand 0 "flags_reg_operand" "")
8782         (match_operator 1 "compare_operator"
8783           [(zero_extract
8784              (match_operand 2 "nonimmediate_operand" "")
8785              (match_operand 3 "const_int_operand" "")
8786              (match_operand 4 "const_int_operand" ""))
8787            (const_int 0)]))]
8788   "ix86_match_ccmode (insn, CCNOmode)"
8789   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8791   rtx val = operands[2];
8792   HOST_WIDE_INT len = INTVAL (operands[3]);
8793   HOST_WIDE_INT pos = INTVAL (operands[4]);
8794   HOST_WIDE_INT mask;
8795   enum machine_mode mode, submode;
8797   mode = GET_MODE (val);
8798   if (MEM_P (val))
8799     {
8800       /* ??? Combine likes to put non-volatile mem extractions in QImode
8801          no matter the size of the test.  So find a mode that works.  */
8802       if (! MEM_VOLATILE_P (val))
8803         {
8804           mode = smallest_mode_for_size (pos + len, MODE_INT);
8805           val = adjust_address (val, mode, 0);
8806         }
8807     }
8808   else if (GET_CODE (val) == SUBREG
8809            && (submode = GET_MODE (SUBREG_REG (val)),
8810                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8811            && pos + len <= GET_MODE_BITSIZE (submode))
8812     {
8813       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8814       mode = submode;
8815       val = SUBREG_REG (val);
8816     }
8817   else if (mode == HImode && pos + len <= 8)
8818     {
8819       /* Small HImode tests can be converted to QImode.  */
8820       mode = QImode;
8821       val = gen_lowpart (QImode, val);
8822     }
8824   if (len == HOST_BITS_PER_WIDE_INT)
8825     mask = -1;
8826   else
8827     mask = ((HOST_WIDE_INT)1 << len) - 1;
8828   mask <<= pos;
8830   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8833 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8834 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8835 ;; this is relatively important trick.
8836 ;; Do the conversion only post-reload to avoid limiting of the register class
8837 ;; to QI regs.
8838 (define_split
8839   [(set (match_operand 0 "flags_reg_operand" "")
8840         (match_operator 1 "compare_operator"
8841           [(and (match_operand 2 "register_operand" "")
8842                 (match_operand 3 "const_int_operand" ""))
8843            (const_int 0)]))]
8844    "reload_completed
8845     && QI_REG_P (operands[2])
8846     && GET_MODE (operands[2]) != QImode
8847     && ((ix86_match_ccmode (insn, CCZmode)
8848          && !(INTVAL (operands[3]) & ~(255 << 8)))
8849         || (ix86_match_ccmode (insn, CCNOmode)
8850             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8851   [(set (match_dup 0)
8852         (match_op_dup 1
8853           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8854                    (match_dup 3))
8855            (const_int 0)]))]
8856   "operands[2] = gen_lowpart (SImode, operands[2]);
8857    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8859 (define_split
8860   [(set (match_operand 0 "flags_reg_operand" "")
8861         (match_operator 1 "compare_operator"
8862           [(and (match_operand 2 "nonimmediate_operand" "")
8863                 (match_operand 3 "const_int_operand" ""))
8864            (const_int 0)]))]
8865    "reload_completed
8866     && GET_MODE (operands[2]) != QImode
8867     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8868     && ((ix86_match_ccmode (insn, CCZmode)
8869          && !(INTVAL (operands[3]) & ~255))
8870         || (ix86_match_ccmode (insn, CCNOmode)
8871             && !(INTVAL (operands[3]) & ~127)))"
8872   [(set (match_dup 0)
8873         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8874                          (const_int 0)]))]
8875   "operands[2] = gen_lowpart (QImode, operands[2]);
8876    operands[3] = gen_lowpart (QImode, operands[3]);")
8879 ;; %%% This used to optimize known byte-wide and operations to memory,
8880 ;; and sometimes to QImode registers.  If this is considered useful,
8881 ;; it should be done with splitters.
8883 (define_expand "anddi3"
8884   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8885         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8886                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8887    (clobber (reg:CC FLAGS_REG))]
8888   "TARGET_64BIT"
8889   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8891 (define_insn "*anddi_1_rex64"
8892   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8893         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8894                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8895    (clobber (reg:CC FLAGS_REG))]
8896   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8898   switch (get_attr_type (insn))
8899     {
8900     case TYPE_IMOVX:
8901       {
8902         enum machine_mode mode;
8904         gcc_assert (CONST_INT_P (operands[2]));
8905         if (INTVAL (operands[2]) == 0xff)
8906           mode = QImode;
8907         else
8908           {
8909             gcc_assert (INTVAL (operands[2]) == 0xffff);
8910             mode = HImode;
8911           }
8913         operands[1] = gen_lowpart (mode, operands[1]);
8914         if (mode == QImode)
8915           return "movz{bq|x}\t{%1,%0|%0, %1}";
8916         else
8917           return "movz{wq|x}\t{%1,%0|%0, %1}";
8918       }
8920     default:
8921       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8922       if (get_attr_mode (insn) == MODE_SI)
8923         return "and{l}\t{%k2, %k0|%k0, %k2}";
8924       else
8925         return "and{q}\t{%2, %0|%0, %2}";
8926     }
8928   [(set_attr "type" "alu,alu,alu,imovx")
8929    (set_attr "length_immediate" "*,*,*,0")
8930    (set_attr "mode" "SI,DI,DI,DI")])
8932 (define_insn "*anddi_2"
8933   [(set (reg FLAGS_REG)
8934         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8935                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8936                  (const_int 0)))
8937    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8938         (and:DI (match_dup 1) (match_dup 2)))]
8939   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8940    && ix86_binary_operator_ok (AND, DImode, operands)"
8941   "@
8942    and{l}\t{%k2, %k0|%k0, %k2}
8943    and{q}\t{%2, %0|%0, %2}
8944    and{q}\t{%2, %0|%0, %2}"
8945   [(set_attr "type" "alu")
8946    (set_attr "mode" "SI,DI,DI")])
8948 (define_expand "andsi3"
8949   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8950         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8951                 (match_operand:SI 2 "general_operand" "")))
8952    (clobber (reg:CC FLAGS_REG))]
8953   ""
8954   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8956 (define_insn "*andsi_1"
8957   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8958         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8959                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8960    (clobber (reg:CC FLAGS_REG))]
8961   "ix86_binary_operator_ok (AND, SImode, operands)"
8963   switch (get_attr_type (insn))
8964     {
8965     case TYPE_IMOVX:
8966       {
8967         enum machine_mode mode;
8969         gcc_assert (CONST_INT_P (operands[2]));
8970         if (INTVAL (operands[2]) == 0xff)
8971           mode = QImode;
8972         else
8973           {
8974             gcc_assert (INTVAL (operands[2]) == 0xffff);
8975             mode = HImode;
8976           }
8978         operands[1] = gen_lowpart (mode, operands[1]);
8979         if (mode == QImode)
8980           return "movz{bl|x}\t{%1,%0|%0, %1}";
8981         else
8982           return "movz{wl|x}\t{%1,%0|%0, %1}";
8983       }
8985     default:
8986       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8987       return "and{l}\t{%2, %0|%0, %2}";
8988     }
8990   [(set_attr "type" "alu,alu,imovx")
8991    (set_attr "length_immediate" "*,*,0")
8992    (set_attr "mode" "SI")])
8994 (define_split
8995   [(set (match_operand 0 "register_operand" "")
8996         (and (match_dup 0)
8997              (const_int -65536)))
8998    (clobber (reg:CC FLAGS_REG))]
8999   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9000   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9001   "operands[1] = gen_lowpart (HImode, operands[0]);")
9003 (define_split
9004   [(set (match_operand 0 "ext_register_operand" "")
9005         (and (match_dup 0)
9006              (const_int -256)))
9007    (clobber (reg:CC FLAGS_REG))]
9008   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9009   [(set (strict_low_part (match_dup 1)) (const_int 0))]
9010   "operands[1] = gen_lowpart (QImode, operands[0]);")
9012 (define_split
9013   [(set (match_operand 0 "ext_register_operand" "")
9014         (and (match_dup 0)
9015              (const_int -65281)))
9016    (clobber (reg:CC FLAGS_REG))]
9017   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9018   [(parallel [(set (zero_extract:SI (match_dup 0)
9019                                     (const_int 8)
9020                                     (const_int 8))
9021                    (xor:SI
9022                      (zero_extract:SI (match_dup 0)
9023                                       (const_int 8)
9024                                       (const_int 8))
9025                      (zero_extract:SI (match_dup 0)
9026                                       (const_int 8)
9027                                       (const_int 8))))
9028               (clobber (reg:CC FLAGS_REG))])]
9029   "operands[0] = gen_lowpart (SImode, operands[0]);")
9031 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9032 (define_insn "*andsi_1_zext"
9033   [(set (match_operand:DI 0 "register_operand" "=r")
9034         (zero_extend:DI
9035           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9036                   (match_operand:SI 2 "general_operand" "g"))))
9037    (clobber (reg:CC FLAGS_REG))]
9038   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9039   "and{l}\t{%2, %k0|%k0, %2}"
9040   [(set_attr "type" "alu")
9041    (set_attr "mode" "SI")])
9043 (define_insn "*andsi_2"
9044   [(set (reg FLAGS_REG)
9045         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9046                          (match_operand:SI 2 "general_operand" "g,ri"))
9047                  (const_int 0)))
9048    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9049         (and:SI (match_dup 1) (match_dup 2)))]
9050   "ix86_match_ccmode (insn, CCNOmode)
9051    && ix86_binary_operator_ok (AND, SImode, operands)"
9052   "and{l}\t{%2, %0|%0, %2}"
9053   [(set_attr "type" "alu")
9054    (set_attr "mode" "SI")])
9056 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9057 (define_insn "*andsi_2_zext"
9058   [(set (reg FLAGS_REG)
9059         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9060                          (match_operand:SI 2 "general_operand" "g"))
9061                  (const_int 0)))
9062    (set (match_operand:DI 0 "register_operand" "=r")
9063         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9064   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9065    && ix86_binary_operator_ok (AND, SImode, operands)"
9066   "and{l}\t{%2, %k0|%k0, %2}"
9067   [(set_attr "type" "alu")
9068    (set_attr "mode" "SI")])
9070 (define_expand "andhi3"
9071   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9072         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9073                 (match_operand:HI 2 "general_operand" "")))
9074    (clobber (reg:CC FLAGS_REG))]
9075   "TARGET_HIMODE_MATH"
9076   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9078 (define_insn "*andhi_1"
9079   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9080         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9081                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
9082    (clobber (reg:CC FLAGS_REG))]
9083   "ix86_binary_operator_ok (AND, HImode, operands)"
9085   switch (get_attr_type (insn))
9086     {
9087     case TYPE_IMOVX:
9088       gcc_assert (CONST_INT_P (operands[2]));
9089       gcc_assert (INTVAL (operands[2]) == 0xff);
9090       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9092     default:
9093       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9095       return "and{w}\t{%2, %0|%0, %2}";
9096     }
9098   [(set_attr "type" "alu,alu,imovx")
9099    (set_attr "length_immediate" "*,*,0")
9100    (set_attr "mode" "HI,HI,SI")])
9102 (define_insn "*andhi_2"
9103   [(set (reg FLAGS_REG)
9104         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9105                          (match_operand:HI 2 "general_operand" "g,ri"))
9106                  (const_int 0)))
9107    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9108         (and:HI (match_dup 1) (match_dup 2)))]
9109   "ix86_match_ccmode (insn, CCNOmode)
9110    && ix86_binary_operator_ok (AND, HImode, operands)"
9111   "and{w}\t{%2, %0|%0, %2}"
9112   [(set_attr "type" "alu")
9113    (set_attr "mode" "HI")])
9115 (define_expand "andqi3"
9116   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9117         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9118                 (match_operand:QI 2 "general_operand" "")))
9119    (clobber (reg:CC FLAGS_REG))]
9120   "TARGET_QIMODE_MATH"
9121   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9123 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9124 (define_insn "*andqi_1"
9125   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9126         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9127                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
9128    (clobber (reg:CC FLAGS_REG))]
9129   "ix86_binary_operator_ok (AND, QImode, operands)"
9130   "@
9131    and{b}\t{%2, %0|%0, %2}
9132    and{b}\t{%2, %0|%0, %2}
9133    and{l}\t{%k2, %k0|%k0, %k2}"
9134   [(set_attr "type" "alu")
9135    (set_attr "mode" "QI,QI,SI")])
9137 (define_insn "*andqi_1_slp"
9138   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9139         (and:QI (match_dup 0)
9140                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9141    (clobber (reg:CC FLAGS_REG))]
9142   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9143    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9144   "and{b}\t{%1, %0|%0, %1}"
9145   [(set_attr "type" "alu1")
9146    (set_attr "mode" "QI")])
9148 (define_insn "*andqi_2_maybe_si"
9149   [(set (reg FLAGS_REG)
9150         (compare (and:QI
9151                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9152                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
9153                  (const_int 0)))
9154    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9155         (and:QI (match_dup 1) (match_dup 2)))]
9156   "ix86_binary_operator_ok (AND, QImode, operands)
9157    && ix86_match_ccmode (insn,
9158                          CONST_INT_P (operands[2])
9159                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9161   if (which_alternative == 2)
9162     {
9163       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9164         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9165       return "and{l}\t{%2, %k0|%k0, %2}";
9166     }
9167   return "and{b}\t{%2, %0|%0, %2}";
9169   [(set_attr "type" "alu")
9170    (set_attr "mode" "QI,QI,SI")])
9172 (define_insn "*andqi_2"
9173   [(set (reg FLAGS_REG)
9174         (compare (and:QI
9175                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9176                    (match_operand:QI 2 "general_operand" "qim,qi"))
9177                  (const_int 0)))
9178    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9179         (and:QI (match_dup 1) (match_dup 2)))]
9180   "ix86_match_ccmode (insn, CCNOmode)
9181    && ix86_binary_operator_ok (AND, QImode, operands)"
9182   "and{b}\t{%2, %0|%0, %2}"
9183   [(set_attr "type" "alu")
9184    (set_attr "mode" "QI")])
9186 (define_insn "*andqi_2_slp"
9187   [(set (reg FLAGS_REG)
9188         (compare (and:QI
9189                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9190                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9191                  (const_int 0)))
9192    (set (strict_low_part (match_dup 0))
9193         (and:QI (match_dup 0) (match_dup 1)))]
9194   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9195    && ix86_match_ccmode (insn, CCNOmode)
9196    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9197   "and{b}\t{%1, %0|%0, %1}"
9198   [(set_attr "type" "alu1")
9199    (set_attr "mode" "QI")])
9201 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9202 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9203 ;; for a QImode operand, which of course failed.
9205 (define_insn "andqi_ext_0"
9206   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9207                          (const_int 8)
9208                          (const_int 8))
9209         (and:SI
9210           (zero_extract:SI
9211             (match_operand 1 "ext_register_operand" "0")
9212             (const_int 8)
9213             (const_int 8))
9214           (match_operand 2 "const_int_operand" "n")))
9215    (clobber (reg:CC FLAGS_REG))]
9216   ""
9217   "and{b}\t{%2, %h0|%h0, %2}"
9218   [(set_attr "type" "alu")
9219    (set_attr "length_immediate" "1")
9220    (set_attr "mode" "QI")])
9222 ;; Generated by peephole translating test to and.  This shows up
9223 ;; often in fp comparisons.
9225 (define_insn "*andqi_ext_0_cc"
9226   [(set (reg FLAGS_REG)
9227         (compare
9228           (and:SI
9229             (zero_extract:SI
9230               (match_operand 1 "ext_register_operand" "0")
9231               (const_int 8)
9232               (const_int 8))
9233             (match_operand 2 "const_int_operand" "n"))
9234           (const_int 0)))
9235    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9236                          (const_int 8)
9237                          (const_int 8))
9238         (and:SI
9239           (zero_extract:SI
9240             (match_dup 1)
9241             (const_int 8)
9242             (const_int 8))
9243           (match_dup 2)))]
9244   "ix86_match_ccmode (insn, CCNOmode)"
9245   "and{b}\t{%2, %h0|%h0, %2}"
9246   [(set_attr "type" "alu")
9247    (set_attr "length_immediate" "1")
9248    (set_attr "mode" "QI")])
9250 (define_insn "*andqi_ext_1"
9251   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9252                          (const_int 8)
9253                          (const_int 8))
9254         (and:SI
9255           (zero_extract:SI
9256             (match_operand 1 "ext_register_operand" "0")
9257             (const_int 8)
9258             (const_int 8))
9259           (zero_extend:SI
9260             (match_operand:QI 2 "general_operand" "Qm"))))
9261    (clobber (reg:CC FLAGS_REG))]
9262   "!TARGET_64BIT"
9263   "and{b}\t{%2, %h0|%h0, %2}"
9264   [(set_attr "type" "alu")
9265    (set_attr "length_immediate" "0")
9266    (set_attr "mode" "QI")])
9268 (define_insn "*andqi_ext_1_rex64"
9269   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9270                          (const_int 8)
9271                          (const_int 8))
9272         (and:SI
9273           (zero_extract:SI
9274             (match_operand 1 "ext_register_operand" "0")
9275             (const_int 8)
9276             (const_int 8))
9277           (zero_extend:SI
9278             (match_operand 2 "ext_register_operand" "Q"))))
9279    (clobber (reg:CC FLAGS_REG))]
9280   "TARGET_64BIT"
9281   "and{b}\t{%2, %h0|%h0, %2}"
9282   [(set_attr "type" "alu")
9283    (set_attr "length_immediate" "0")
9284    (set_attr "mode" "QI")])
9286 (define_insn "*andqi_ext_2"
9287   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9288                          (const_int 8)
9289                          (const_int 8))
9290         (and:SI
9291           (zero_extract:SI
9292             (match_operand 1 "ext_register_operand" "%0")
9293             (const_int 8)
9294             (const_int 8))
9295           (zero_extract:SI
9296             (match_operand 2 "ext_register_operand" "Q")
9297             (const_int 8)
9298             (const_int 8))))
9299    (clobber (reg:CC FLAGS_REG))]
9300   ""
9301   "and{b}\t{%h2, %h0|%h0, %h2}"
9302   [(set_attr "type" "alu")
9303    (set_attr "length_immediate" "0")
9304    (set_attr "mode" "QI")])
9306 ;; Convert wide AND instructions with immediate operand to shorter QImode
9307 ;; equivalents when possible.
9308 ;; Don't do the splitting with memory operands, since it introduces risk
9309 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9310 ;; for size, but that can (should?) be handled by generic code instead.
9311 (define_split
9312   [(set (match_operand 0 "register_operand" "")
9313         (and (match_operand 1 "register_operand" "")
9314              (match_operand 2 "const_int_operand" "")))
9315    (clobber (reg:CC FLAGS_REG))]
9316    "reload_completed
9317     && QI_REG_P (operands[0])
9318     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9319     && !(~INTVAL (operands[2]) & ~(255 << 8))
9320     && GET_MODE (operands[0]) != QImode"
9321   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9322                    (and:SI (zero_extract:SI (match_dup 1)
9323                                             (const_int 8) (const_int 8))
9324                            (match_dup 2)))
9325               (clobber (reg:CC FLAGS_REG))])]
9326   "operands[0] = gen_lowpart (SImode, operands[0]);
9327    operands[1] = gen_lowpart (SImode, operands[1]);
9328    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9330 ;; Since AND can be encoded with sign extended immediate, this is only
9331 ;; profitable when 7th bit is not set.
9332 (define_split
9333   [(set (match_operand 0 "register_operand" "")
9334         (and (match_operand 1 "general_operand" "")
9335              (match_operand 2 "const_int_operand" "")))
9336    (clobber (reg:CC FLAGS_REG))]
9337    "reload_completed
9338     && ANY_QI_REG_P (operands[0])
9339     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9340     && !(~INTVAL (operands[2]) & ~255)
9341     && !(INTVAL (operands[2]) & 128)
9342     && GET_MODE (operands[0]) != QImode"
9343   [(parallel [(set (strict_low_part (match_dup 0))
9344                    (and:QI (match_dup 1)
9345                            (match_dup 2)))
9346               (clobber (reg:CC FLAGS_REG))])]
9347   "operands[0] = gen_lowpart (QImode, operands[0]);
9348    operands[1] = gen_lowpart (QImode, operands[1]);
9349    operands[2] = gen_lowpart (QImode, operands[2]);")
9351 ;; Logical inclusive OR instructions
9353 ;; %%% This used to optimize known byte-wide and operations to memory.
9354 ;; If this is considered useful, it should be done with splitters.
9356 (define_expand "iordi3"
9357   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9358         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9359                 (match_operand:DI 2 "x86_64_general_operand" "")))
9360    (clobber (reg:CC FLAGS_REG))]
9361   "TARGET_64BIT"
9362   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9364 (define_insn "*iordi_1_rex64"
9365   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9366         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9367                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9368    (clobber (reg:CC FLAGS_REG))]
9369   "TARGET_64BIT
9370    && ix86_binary_operator_ok (IOR, DImode, operands)"
9371   "or{q}\t{%2, %0|%0, %2}"
9372   [(set_attr "type" "alu")
9373    (set_attr "mode" "DI")])
9375 (define_insn "*iordi_2_rex64"
9376   [(set (reg FLAGS_REG)
9377         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9378                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9379                  (const_int 0)))
9380    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9381         (ior:DI (match_dup 1) (match_dup 2)))]
9382   "TARGET_64BIT
9383    && ix86_match_ccmode (insn, CCNOmode)
9384    && ix86_binary_operator_ok (IOR, DImode, operands)"
9385   "or{q}\t{%2, %0|%0, %2}"
9386   [(set_attr "type" "alu")
9387    (set_attr "mode" "DI")])
9389 (define_insn "*iordi_3_rex64"
9390   [(set (reg FLAGS_REG)
9391         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9392                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9393                  (const_int 0)))
9394    (clobber (match_scratch:DI 0 "=r"))]
9395   "TARGET_64BIT
9396    && ix86_match_ccmode (insn, CCNOmode)
9397    && ix86_binary_operator_ok (IOR, DImode, operands)"
9398   "or{q}\t{%2, %0|%0, %2}"
9399   [(set_attr "type" "alu")
9400    (set_attr "mode" "DI")])
9403 (define_expand "iorsi3"
9404   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9405         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9406                 (match_operand:SI 2 "general_operand" "")))
9407    (clobber (reg:CC FLAGS_REG))]
9408   ""
9409   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9411 (define_insn "*iorsi_1"
9412   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9413         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9414                 (match_operand:SI 2 "general_operand" "ri,g")))
9415    (clobber (reg:CC FLAGS_REG))]
9416   "ix86_binary_operator_ok (IOR, SImode, operands)"
9417   "or{l}\t{%2, %0|%0, %2}"
9418   [(set_attr "type" "alu")
9419    (set_attr "mode" "SI")])
9421 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9422 (define_insn "*iorsi_1_zext"
9423   [(set (match_operand:DI 0 "register_operand" "=r")
9424         (zero_extend:DI
9425           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9426                   (match_operand:SI 2 "general_operand" "g"))))
9427    (clobber (reg:CC FLAGS_REG))]
9428   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9429   "or{l}\t{%2, %k0|%k0, %2}"
9430   [(set_attr "type" "alu")
9431    (set_attr "mode" "SI")])
9433 (define_insn "*iorsi_1_zext_imm"
9434   [(set (match_operand:DI 0 "register_operand" "=r")
9435         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9436                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9437    (clobber (reg:CC FLAGS_REG))]
9438   "TARGET_64BIT"
9439   "or{l}\t{%2, %k0|%k0, %2}"
9440   [(set_attr "type" "alu")
9441    (set_attr "mode" "SI")])
9443 (define_insn "*iorsi_2"
9444   [(set (reg FLAGS_REG)
9445         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9446                          (match_operand:SI 2 "general_operand" "g,ri"))
9447                  (const_int 0)))
9448    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9449         (ior:SI (match_dup 1) (match_dup 2)))]
9450   "ix86_match_ccmode (insn, CCNOmode)
9451    && ix86_binary_operator_ok (IOR, SImode, operands)"
9452   "or{l}\t{%2, %0|%0, %2}"
9453   [(set_attr "type" "alu")
9454    (set_attr "mode" "SI")])
9456 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9457 ;; ??? Special case for immediate operand is missing - it is tricky.
9458 (define_insn "*iorsi_2_zext"
9459   [(set (reg FLAGS_REG)
9460         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9461                          (match_operand:SI 2 "general_operand" "g"))
9462                  (const_int 0)))
9463    (set (match_operand:DI 0 "register_operand" "=r")
9464         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9465   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9466    && ix86_binary_operator_ok (IOR, SImode, operands)"
9467   "or{l}\t{%2, %k0|%k0, %2}"
9468   [(set_attr "type" "alu")
9469    (set_attr "mode" "SI")])
9471 (define_insn "*iorsi_2_zext_imm"
9472   [(set (reg FLAGS_REG)
9473         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9474                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9475                  (const_int 0)))
9476    (set (match_operand:DI 0 "register_operand" "=r")
9477         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9478   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9479    && ix86_binary_operator_ok (IOR, SImode, operands)"
9480   "or{l}\t{%2, %k0|%k0, %2}"
9481   [(set_attr "type" "alu")
9482    (set_attr "mode" "SI")])
9484 (define_insn "*iorsi_3"
9485   [(set (reg FLAGS_REG)
9486         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9487                          (match_operand:SI 2 "general_operand" "g"))
9488                  (const_int 0)))
9489    (clobber (match_scratch:SI 0 "=r"))]
9490   "ix86_match_ccmode (insn, CCNOmode)
9491    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9492   "or{l}\t{%2, %0|%0, %2}"
9493   [(set_attr "type" "alu")
9494    (set_attr "mode" "SI")])
9496 (define_expand "iorhi3"
9497   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9498         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9499                 (match_operand:HI 2 "general_operand" "")))
9500    (clobber (reg:CC FLAGS_REG))]
9501   "TARGET_HIMODE_MATH"
9502   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9504 (define_insn "*iorhi_1"
9505   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9506         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9507                 (match_operand:HI 2 "general_operand" "g,ri")))
9508    (clobber (reg:CC FLAGS_REG))]
9509   "ix86_binary_operator_ok (IOR, HImode, operands)"
9510   "or{w}\t{%2, %0|%0, %2}"
9511   [(set_attr "type" "alu")
9512    (set_attr "mode" "HI")])
9514 (define_insn "*iorhi_2"
9515   [(set (reg FLAGS_REG)
9516         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9517                          (match_operand:HI 2 "general_operand" "g,ri"))
9518                  (const_int 0)))
9519    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9520         (ior:HI (match_dup 1) (match_dup 2)))]
9521   "ix86_match_ccmode (insn, CCNOmode)
9522    && ix86_binary_operator_ok (IOR, HImode, operands)"
9523   "or{w}\t{%2, %0|%0, %2}"
9524   [(set_attr "type" "alu")
9525    (set_attr "mode" "HI")])
9527 (define_insn "*iorhi_3"
9528   [(set (reg FLAGS_REG)
9529         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9530                          (match_operand:HI 2 "general_operand" "g"))
9531                  (const_int 0)))
9532    (clobber (match_scratch:HI 0 "=r"))]
9533   "ix86_match_ccmode (insn, CCNOmode)
9534    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9535   "or{w}\t{%2, %0|%0, %2}"
9536   [(set_attr "type" "alu")
9537    (set_attr "mode" "HI")])
9539 (define_expand "iorqi3"
9540   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9541         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9542                 (match_operand:QI 2 "general_operand" "")))
9543    (clobber (reg:CC FLAGS_REG))]
9544   "TARGET_QIMODE_MATH"
9545   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9547 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9548 (define_insn "*iorqi_1"
9549   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9550         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9551                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9552    (clobber (reg:CC FLAGS_REG))]
9553   "ix86_binary_operator_ok (IOR, QImode, operands)"
9554   "@
9555    or{b}\t{%2, %0|%0, %2}
9556    or{b}\t{%2, %0|%0, %2}
9557    or{l}\t{%k2, %k0|%k0, %k2}"
9558   [(set_attr "type" "alu")
9559    (set_attr "mode" "QI,QI,SI")])
9561 (define_insn "*iorqi_1_slp"
9562   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9563         (ior:QI (match_dup 0)
9564                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9565    (clobber (reg:CC FLAGS_REG))]
9566   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9567    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9568   "or{b}\t{%1, %0|%0, %1}"
9569   [(set_attr "type" "alu1")
9570    (set_attr "mode" "QI")])
9572 (define_insn "*iorqi_2"
9573   [(set (reg FLAGS_REG)
9574         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9575                          (match_operand:QI 2 "general_operand" "qim,qi"))
9576                  (const_int 0)))
9577    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9578         (ior:QI (match_dup 1) (match_dup 2)))]
9579   "ix86_match_ccmode (insn, CCNOmode)
9580    && ix86_binary_operator_ok (IOR, QImode, operands)"
9581   "or{b}\t{%2, %0|%0, %2}"
9582   [(set_attr "type" "alu")
9583    (set_attr "mode" "QI")])
9585 (define_insn "*iorqi_2_slp"
9586   [(set (reg FLAGS_REG)
9587         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9588                          (match_operand:QI 1 "general_operand" "qim,qi"))
9589                  (const_int 0)))
9590    (set (strict_low_part (match_dup 0))
9591         (ior:QI (match_dup 0) (match_dup 1)))]
9592   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9593    && ix86_match_ccmode (insn, CCNOmode)
9594    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9595   "or{b}\t{%1, %0|%0, %1}"
9596   [(set_attr "type" "alu1")
9597    (set_attr "mode" "QI")])
9599 (define_insn "*iorqi_3"
9600   [(set (reg FLAGS_REG)
9601         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9602                          (match_operand:QI 2 "general_operand" "qim"))
9603                  (const_int 0)))
9604    (clobber (match_scratch:QI 0 "=q"))]
9605   "ix86_match_ccmode (insn, CCNOmode)
9606    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9607   "or{b}\t{%2, %0|%0, %2}"
9608   [(set_attr "type" "alu")
9609    (set_attr "mode" "QI")])
9611 (define_insn "iorqi_ext_0"
9612   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9613                          (const_int 8)
9614                          (const_int 8))
9615         (ior:SI
9616           (zero_extract:SI
9617             (match_operand 1 "ext_register_operand" "0")
9618             (const_int 8)
9619             (const_int 8))
9620           (match_operand 2 "const_int_operand" "n")))
9621    (clobber (reg:CC FLAGS_REG))]
9622   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9623   "or{b}\t{%2, %h0|%h0, %2}"
9624   [(set_attr "type" "alu")
9625    (set_attr "length_immediate" "1")
9626    (set_attr "mode" "QI")])
9628 (define_insn "*iorqi_ext_1"
9629   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9630                          (const_int 8)
9631                          (const_int 8))
9632         (ior:SI
9633           (zero_extract:SI
9634             (match_operand 1 "ext_register_operand" "0")
9635             (const_int 8)
9636             (const_int 8))
9637           (zero_extend:SI
9638             (match_operand:QI 2 "general_operand" "Qm"))))
9639    (clobber (reg:CC FLAGS_REG))]
9640   "!TARGET_64BIT
9641    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9642   "or{b}\t{%2, %h0|%h0, %2}"
9643   [(set_attr "type" "alu")
9644    (set_attr "length_immediate" "0")
9645    (set_attr "mode" "QI")])
9647 (define_insn "*iorqi_ext_1_rex64"
9648   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9649                          (const_int 8)
9650                          (const_int 8))
9651         (ior:SI
9652           (zero_extract:SI
9653             (match_operand 1 "ext_register_operand" "0")
9654             (const_int 8)
9655             (const_int 8))
9656           (zero_extend:SI
9657             (match_operand 2 "ext_register_operand" "Q"))))
9658    (clobber (reg:CC FLAGS_REG))]
9659   "TARGET_64BIT
9660    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9661   "or{b}\t{%2, %h0|%h0, %2}"
9662   [(set_attr "type" "alu")
9663    (set_attr "length_immediate" "0")
9664    (set_attr "mode" "QI")])
9666 (define_insn "*iorqi_ext_2"
9667   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9668                          (const_int 8)
9669                          (const_int 8))
9670         (ior:SI
9671           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9672                            (const_int 8)
9673                            (const_int 8))
9674           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9675                            (const_int 8)
9676                            (const_int 8))))
9677    (clobber (reg:CC FLAGS_REG))]
9678   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9679   "ior{b}\t{%h2, %h0|%h0, %h2}"
9680   [(set_attr "type" "alu")
9681    (set_attr "length_immediate" "0")
9682    (set_attr "mode" "QI")])
9684 (define_split
9685   [(set (match_operand 0 "register_operand" "")
9686         (ior (match_operand 1 "register_operand" "")
9687              (match_operand 2 "const_int_operand" "")))
9688    (clobber (reg:CC FLAGS_REG))]
9689    "reload_completed
9690     && QI_REG_P (operands[0])
9691     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9692     && !(INTVAL (operands[2]) & ~(255 << 8))
9693     && GET_MODE (operands[0]) != QImode"
9694   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9695                    (ior:SI (zero_extract:SI (match_dup 1)
9696                                             (const_int 8) (const_int 8))
9697                            (match_dup 2)))
9698               (clobber (reg:CC FLAGS_REG))])]
9699   "operands[0] = gen_lowpart (SImode, operands[0]);
9700    operands[1] = gen_lowpart (SImode, operands[1]);
9701    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9703 ;; Since OR can be encoded with sign extended immediate, this is only
9704 ;; profitable when 7th bit is set.
9705 (define_split
9706   [(set (match_operand 0 "register_operand" "")
9707         (ior (match_operand 1 "general_operand" "")
9708              (match_operand 2 "const_int_operand" "")))
9709    (clobber (reg:CC FLAGS_REG))]
9710    "reload_completed
9711     && ANY_QI_REG_P (operands[0])
9712     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9713     && !(INTVAL (operands[2]) & ~255)
9714     && (INTVAL (operands[2]) & 128)
9715     && GET_MODE (operands[0]) != QImode"
9716   [(parallel [(set (strict_low_part (match_dup 0))
9717                    (ior:QI (match_dup 1)
9718                            (match_dup 2)))
9719               (clobber (reg:CC FLAGS_REG))])]
9720   "operands[0] = gen_lowpart (QImode, operands[0]);
9721    operands[1] = gen_lowpart (QImode, operands[1]);
9722    operands[2] = gen_lowpart (QImode, operands[2]);")
9724 ;; Logical XOR instructions
9726 ;; %%% This used to optimize known byte-wide and operations to memory.
9727 ;; If this is considered useful, it should be done with splitters.
9729 (define_expand "xordi3"
9730   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9731         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9732                 (match_operand:DI 2 "x86_64_general_operand" "")))
9733    (clobber (reg:CC FLAGS_REG))]
9734   "TARGET_64BIT"
9735   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9737 (define_insn "*xordi_1_rex64"
9738   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9739         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9740                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9741    (clobber (reg:CC FLAGS_REG))]
9742   "TARGET_64BIT
9743    && ix86_binary_operator_ok (XOR, DImode, operands)"
9744   "xor{q}\t{%2, %0|%0, %2}"
9745   [(set_attr "type" "alu")
9746    (set_attr "mode" "DI")])
9748 (define_insn "*xordi_2_rex64"
9749   [(set (reg FLAGS_REG)
9750         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9751                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9752                  (const_int 0)))
9753    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9754         (xor:DI (match_dup 1) (match_dup 2)))]
9755   "TARGET_64BIT
9756    && ix86_match_ccmode (insn, CCNOmode)
9757    && ix86_binary_operator_ok (XOR, DImode, operands)"
9758   "xor{q}\t{%2, %0|%0, %2}"
9759   [(set_attr "type" "alu")
9760    (set_attr "mode" "DI")])
9762 (define_insn "*xordi_3_rex64"
9763   [(set (reg FLAGS_REG)
9764         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9765                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9766                  (const_int 0)))
9767    (clobber (match_scratch:DI 0 "=r"))]
9768   "TARGET_64BIT
9769    && ix86_match_ccmode (insn, CCNOmode)
9770    && ix86_binary_operator_ok (XOR, DImode, operands)"
9771   "xor{q}\t{%2, %0|%0, %2}"
9772   [(set_attr "type" "alu")
9773    (set_attr "mode" "DI")])
9775 (define_expand "xorsi3"
9776   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9777         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9778                 (match_operand:SI 2 "general_operand" "")))
9779    (clobber (reg:CC FLAGS_REG))]
9780   ""
9781   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9783 (define_insn "*xorsi_1"
9784   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9785         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9786                 (match_operand:SI 2 "general_operand" "ri,rm")))
9787    (clobber (reg:CC FLAGS_REG))]
9788   "ix86_binary_operator_ok (XOR, SImode, operands)"
9789   "xor{l}\t{%2, %0|%0, %2}"
9790   [(set_attr "type" "alu")
9791    (set_attr "mode" "SI")])
9793 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9794 ;; Add speccase for immediates
9795 (define_insn "*xorsi_1_zext"
9796   [(set (match_operand:DI 0 "register_operand" "=r")
9797         (zero_extend:DI
9798           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9799                   (match_operand:SI 2 "general_operand" "g"))))
9800    (clobber (reg:CC FLAGS_REG))]
9801   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9802   "xor{l}\t{%2, %k0|%k0, %2}"
9803   [(set_attr "type" "alu")
9804    (set_attr "mode" "SI")])
9806 (define_insn "*xorsi_1_zext_imm"
9807   [(set (match_operand:DI 0 "register_operand" "=r")
9808         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9809                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9810    (clobber (reg:CC FLAGS_REG))]
9811   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9812   "xor{l}\t{%2, %k0|%k0, %2}"
9813   [(set_attr "type" "alu")
9814    (set_attr "mode" "SI")])
9816 (define_insn "*xorsi_2"
9817   [(set (reg FLAGS_REG)
9818         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9819                          (match_operand:SI 2 "general_operand" "g,ri"))
9820                  (const_int 0)))
9821    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9822         (xor:SI (match_dup 1) (match_dup 2)))]
9823   "ix86_match_ccmode (insn, CCNOmode)
9824    && ix86_binary_operator_ok (XOR, SImode, operands)"
9825   "xor{l}\t{%2, %0|%0, %2}"
9826   [(set_attr "type" "alu")
9827    (set_attr "mode" "SI")])
9829 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9830 ;; ??? Special case for immediate operand is missing - it is tricky.
9831 (define_insn "*xorsi_2_zext"
9832   [(set (reg FLAGS_REG)
9833         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9834                          (match_operand:SI 2 "general_operand" "g"))
9835                  (const_int 0)))
9836    (set (match_operand:DI 0 "register_operand" "=r")
9837         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9838   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9839    && ix86_binary_operator_ok (XOR, SImode, operands)"
9840   "xor{l}\t{%2, %k0|%k0, %2}"
9841   [(set_attr "type" "alu")
9842    (set_attr "mode" "SI")])
9844 (define_insn "*xorsi_2_zext_imm"
9845   [(set (reg FLAGS_REG)
9846         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9847                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9848                  (const_int 0)))
9849    (set (match_operand:DI 0 "register_operand" "=r")
9850         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9851   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9852    && ix86_binary_operator_ok (XOR, SImode, operands)"
9853   "xor{l}\t{%2, %k0|%k0, %2}"
9854   [(set_attr "type" "alu")
9855    (set_attr "mode" "SI")])
9857 (define_insn "*xorsi_3"
9858   [(set (reg FLAGS_REG)
9859         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9860                          (match_operand:SI 2 "general_operand" "g"))
9861                  (const_int 0)))
9862    (clobber (match_scratch:SI 0 "=r"))]
9863   "ix86_match_ccmode (insn, CCNOmode)
9864    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9865   "xor{l}\t{%2, %0|%0, %2}"
9866   [(set_attr "type" "alu")
9867    (set_attr "mode" "SI")])
9869 (define_expand "xorhi3"
9870   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9871         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9872                 (match_operand:HI 2 "general_operand" "")))
9873    (clobber (reg:CC FLAGS_REG))]
9874   "TARGET_HIMODE_MATH"
9875   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9877 (define_insn "*xorhi_1"
9878   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9879         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9880                 (match_operand:HI 2 "general_operand" "g,ri")))
9881    (clobber (reg:CC FLAGS_REG))]
9882   "ix86_binary_operator_ok (XOR, HImode, operands)"
9883   "xor{w}\t{%2, %0|%0, %2}"
9884   [(set_attr "type" "alu")
9885    (set_attr "mode" "HI")])
9887 (define_insn "*xorhi_2"
9888   [(set (reg FLAGS_REG)
9889         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9890                          (match_operand:HI 2 "general_operand" "g,ri"))
9891                  (const_int 0)))
9892    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9893         (xor:HI (match_dup 1) (match_dup 2)))]
9894   "ix86_match_ccmode (insn, CCNOmode)
9895    && ix86_binary_operator_ok (XOR, HImode, operands)"
9896   "xor{w}\t{%2, %0|%0, %2}"
9897   [(set_attr "type" "alu")
9898    (set_attr "mode" "HI")])
9900 (define_insn "*xorhi_3"
9901   [(set (reg FLAGS_REG)
9902         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9903                          (match_operand:HI 2 "general_operand" "g"))
9904                  (const_int 0)))
9905    (clobber (match_scratch:HI 0 "=r"))]
9906   "ix86_match_ccmode (insn, CCNOmode)
9907    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9908   "xor{w}\t{%2, %0|%0, %2}"
9909   [(set_attr "type" "alu")
9910    (set_attr "mode" "HI")])
9912 (define_expand "xorqi3"
9913   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9914         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9915                 (match_operand:QI 2 "general_operand" "")))
9916    (clobber (reg:CC FLAGS_REG))]
9917   "TARGET_QIMODE_MATH"
9918   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9920 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9921 (define_insn "*xorqi_1"
9922   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9923         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9924                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9925    (clobber (reg:CC FLAGS_REG))]
9926   "ix86_binary_operator_ok (XOR, QImode, operands)"
9927   "@
9928    xor{b}\t{%2, %0|%0, %2}
9929    xor{b}\t{%2, %0|%0, %2}
9930    xor{l}\t{%k2, %k0|%k0, %k2}"
9931   [(set_attr "type" "alu")
9932    (set_attr "mode" "QI,QI,SI")])
9934 (define_insn "*xorqi_1_slp"
9935   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9936         (xor:QI (match_dup 0)
9937                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9938    (clobber (reg:CC FLAGS_REG))]
9939   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9940    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9941   "xor{b}\t{%1, %0|%0, %1}"
9942   [(set_attr "type" "alu1")
9943    (set_attr "mode" "QI")])
9945 (define_insn "xorqi_ext_0"
9946   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9947                          (const_int 8)
9948                          (const_int 8))
9949         (xor:SI
9950           (zero_extract:SI
9951             (match_operand 1 "ext_register_operand" "0")
9952             (const_int 8)
9953             (const_int 8))
9954           (match_operand 2 "const_int_operand" "n")))
9955    (clobber (reg:CC FLAGS_REG))]
9956   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9957   "xor{b}\t{%2, %h0|%h0, %2}"
9958   [(set_attr "type" "alu")
9959    (set_attr "length_immediate" "1")
9960    (set_attr "mode" "QI")])
9962 (define_insn "*xorqi_ext_1"
9963   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9964                          (const_int 8)
9965                          (const_int 8))
9966         (xor:SI
9967           (zero_extract:SI
9968             (match_operand 1 "ext_register_operand" "0")
9969             (const_int 8)
9970             (const_int 8))
9971           (zero_extend:SI
9972             (match_operand:QI 2 "general_operand" "Qm"))))
9973    (clobber (reg:CC FLAGS_REG))]
9974   "!TARGET_64BIT
9975    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9976   "xor{b}\t{%2, %h0|%h0, %2}"
9977   [(set_attr "type" "alu")
9978    (set_attr "length_immediate" "0")
9979    (set_attr "mode" "QI")])
9981 (define_insn "*xorqi_ext_1_rex64"
9982   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9983                          (const_int 8)
9984                          (const_int 8))
9985         (xor:SI
9986           (zero_extract:SI
9987             (match_operand 1 "ext_register_operand" "0")
9988             (const_int 8)
9989             (const_int 8))
9990           (zero_extend:SI
9991             (match_operand 2 "ext_register_operand" "Q"))))
9992    (clobber (reg:CC FLAGS_REG))]
9993   "TARGET_64BIT
9994    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9995   "xor{b}\t{%2, %h0|%h0, %2}"
9996   [(set_attr "type" "alu")
9997    (set_attr "length_immediate" "0")
9998    (set_attr "mode" "QI")])
10000 (define_insn "*xorqi_ext_2"
10001   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10002                          (const_int 8)
10003                          (const_int 8))
10004         (xor:SI
10005           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10006                            (const_int 8)
10007                            (const_int 8))
10008           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10009                            (const_int 8)
10010                            (const_int 8))))
10011    (clobber (reg:CC FLAGS_REG))]
10012   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
10013   "xor{b}\t{%h2, %h0|%h0, %h2}"
10014   [(set_attr "type" "alu")
10015    (set_attr "length_immediate" "0")
10016    (set_attr "mode" "QI")])
10018 (define_insn "*xorqi_cc_1"
10019   [(set (reg FLAGS_REG)
10020         (compare
10021           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10022                   (match_operand:QI 2 "general_operand" "qim,qi"))
10023           (const_int 0)))
10024    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10025         (xor:QI (match_dup 1) (match_dup 2)))]
10026   "ix86_match_ccmode (insn, CCNOmode)
10027    && ix86_binary_operator_ok (XOR, QImode, operands)"
10028   "xor{b}\t{%2, %0|%0, %2}"
10029   [(set_attr "type" "alu")
10030    (set_attr "mode" "QI")])
10032 (define_insn "*xorqi_2_slp"
10033   [(set (reg FLAGS_REG)
10034         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10035                          (match_operand:QI 1 "general_operand" "qim,qi"))
10036                  (const_int 0)))
10037    (set (strict_low_part (match_dup 0))
10038         (xor:QI (match_dup 0) (match_dup 1)))]
10039   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
10040    && ix86_match_ccmode (insn, CCNOmode)
10041    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10042   "xor{b}\t{%1, %0|%0, %1}"
10043   [(set_attr "type" "alu1")
10044    (set_attr "mode" "QI")])
10046 (define_insn "*xorqi_cc_2"
10047   [(set (reg FLAGS_REG)
10048         (compare
10049           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10050                   (match_operand:QI 2 "general_operand" "qim"))
10051           (const_int 0)))
10052    (clobber (match_scratch:QI 0 "=q"))]
10053   "ix86_match_ccmode (insn, CCNOmode)
10054    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10055   "xor{b}\t{%2, %0|%0, %2}"
10056   [(set_attr "type" "alu")
10057    (set_attr "mode" "QI")])
10059 (define_insn "*xorqi_cc_ext_1"
10060   [(set (reg FLAGS_REG)
10061         (compare
10062           (xor:SI
10063             (zero_extract:SI
10064               (match_operand 1 "ext_register_operand" "0")
10065               (const_int 8)
10066               (const_int 8))
10067             (match_operand:QI 2 "general_operand" "qmn"))
10068           (const_int 0)))
10069    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10070                          (const_int 8)
10071                          (const_int 8))
10072         (xor:SI
10073           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10074           (match_dup 2)))]
10075   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10076   "xor{b}\t{%2, %h0|%h0, %2}"
10077   [(set_attr "type" "alu")
10078    (set_attr "mode" "QI")])
10080 (define_insn "*xorqi_cc_ext_1_rex64"
10081   [(set (reg FLAGS_REG)
10082         (compare
10083           (xor:SI
10084             (zero_extract:SI
10085               (match_operand 1 "ext_register_operand" "0")
10086               (const_int 8)
10087               (const_int 8))
10088             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10089           (const_int 0)))
10090    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10091                          (const_int 8)
10092                          (const_int 8))
10093         (xor:SI
10094           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10095           (match_dup 2)))]
10096   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10097   "xor{b}\t{%2, %h0|%h0, %2}"
10098   [(set_attr "type" "alu")
10099    (set_attr "mode" "QI")])
10101 (define_expand "xorqi_cc_ext_1"
10102   [(parallel [
10103      (set (reg:CCNO FLAGS_REG)
10104           (compare:CCNO
10105             (xor:SI
10106               (zero_extract:SI
10107                 (match_operand 1 "ext_register_operand" "")
10108                 (const_int 8)
10109                 (const_int 8))
10110               (match_operand:QI 2 "general_operand" ""))
10111             (const_int 0)))
10112      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10113                            (const_int 8)
10114                            (const_int 8))
10115           (xor:SI
10116             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10117             (match_dup 2)))])]
10118   ""
10119   "")
10121 (define_split
10122   [(set (match_operand 0 "register_operand" "")
10123         (xor (match_operand 1 "register_operand" "")
10124              (match_operand 2 "const_int_operand" "")))
10125    (clobber (reg:CC FLAGS_REG))]
10126    "reload_completed
10127     && QI_REG_P (operands[0])
10128     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10129     && !(INTVAL (operands[2]) & ~(255 << 8))
10130     && GET_MODE (operands[0]) != QImode"
10131   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10132                    (xor:SI (zero_extract:SI (match_dup 1)
10133                                             (const_int 8) (const_int 8))
10134                            (match_dup 2)))
10135               (clobber (reg:CC FLAGS_REG))])]
10136   "operands[0] = gen_lowpart (SImode, operands[0]);
10137    operands[1] = gen_lowpart (SImode, operands[1]);
10138    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10140 ;; Since XOR can be encoded with sign extended immediate, this is only
10141 ;; profitable when 7th bit is set.
10142 (define_split
10143   [(set (match_operand 0 "register_operand" "")
10144         (xor (match_operand 1 "general_operand" "")
10145              (match_operand 2 "const_int_operand" "")))
10146    (clobber (reg:CC FLAGS_REG))]
10147    "reload_completed
10148     && ANY_QI_REG_P (operands[0])
10149     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10150     && !(INTVAL (operands[2]) & ~255)
10151     && (INTVAL (operands[2]) & 128)
10152     && GET_MODE (operands[0]) != QImode"
10153   [(parallel [(set (strict_low_part (match_dup 0))
10154                    (xor:QI (match_dup 1)
10155                            (match_dup 2)))
10156               (clobber (reg:CC FLAGS_REG))])]
10157   "operands[0] = gen_lowpart (QImode, operands[0]);
10158    operands[1] = gen_lowpart (QImode, operands[1]);
10159    operands[2] = gen_lowpart (QImode, operands[2]);")
10161 ;; Negation instructions
10163 (define_expand "negti2"
10164   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10165                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10166               (clobber (reg:CC FLAGS_REG))])]
10167   "TARGET_64BIT"
10168   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10170 (define_insn "*negti2_1"
10171   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10172         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10173    (clobber (reg:CC FLAGS_REG))]
10174   "TARGET_64BIT
10175    && ix86_unary_operator_ok (NEG, TImode, operands)"
10176   "#")
10178 (define_split
10179   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10180         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10181    (clobber (reg:CC FLAGS_REG))]
10182   "TARGET_64BIT && reload_completed"
10183   [(parallel
10184     [(set (reg:CCZ FLAGS_REG)
10185           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10186      (set (match_dup 0) (neg:DI (match_dup 1)))])
10187    (parallel
10188     [(set (match_dup 2)
10189           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10190                             (match_dup 3))
10191                    (const_int 0)))
10192      (clobber (reg:CC FLAGS_REG))])
10193    (parallel
10194     [(set (match_dup 2)
10195           (neg:DI (match_dup 2)))
10196      (clobber (reg:CC FLAGS_REG))])]
10197   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10199 (define_expand "negdi2"
10200   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10201                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10202               (clobber (reg:CC FLAGS_REG))])]
10203   ""
10204   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10206 (define_insn "*negdi2_1"
10207   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10208         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10209    (clobber (reg:CC FLAGS_REG))]
10210   "!TARGET_64BIT
10211    && ix86_unary_operator_ok (NEG, DImode, operands)"
10212   "#")
10214 (define_split
10215   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10216         (neg:DI (match_operand:DI 1 "general_operand" "")))
10217    (clobber (reg:CC FLAGS_REG))]
10218   "!TARGET_64BIT && reload_completed"
10219   [(parallel
10220     [(set (reg:CCZ FLAGS_REG)
10221           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10222      (set (match_dup 0) (neg:SI (match_dup 1)))])
10223    (parallel
10224     [(set (match_dup 2)
10225           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10226                             (match_dup 3))
10227                    (const_int 0)))
10228      (clobber (reg:CC FLAGS_REG))])
10229    (parallel
10230     [(set (match_dup 2)
10231           (neg:SI (match_dup 2)))
10232      (clobber (reg:CC FLAGS_REG))])]
10233   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10235 (define_insn "*negdi2_1_rex64"
10236   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10237         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10238    (clobber (reg:CC FLAGS_REG))]
10239   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10240   "neg{q}\t%0"
10241   [(set_attr "type" "negnot")
10242    (set_attr "mode" "DI")])
10244 ;; The problem with neg is that it does not perform (compare x 0),
10245 ;; it really performs (compare 0 x), which leaves us with the zero
10246 ;; flag being the only useful item.
10248 (define_insn "*negdi2_cmpz_rex64"
10249   [(set (reg:CCZ FLAGS_REG)
10250         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10251                      (const_int 0)))
10252    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10253         (neg:DI (match_dup 1)))]
10254   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10255   "neg{q}\t%0"
10256   [(set_attr "type" "negnot")
10257    (set_attr "mode" "DI")])
10260 (define_expand "negsi2"
10261   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10262                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10263               (clobber (reg:CC FLAGS_REG))])]
10264   ""
10265   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10267 (define_insn "*negsi2_1"
10268   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10269         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10270    (clobber (reg:CC FLAGS_REG))]
10271   "ix86_unary_operator_ok (NEG, SImode, operands)"
10272   "neg{l}\t%0"
10273   [(set_attr "type" "negnot")
10274    (set_attr "mode" "SI")])
10276 ;; Combine is quite creative about this pattern.
10277 (define_insn "*negsi2_1_zext"
10278   [(set (match_operand:DI 0 "register_operand" "=r")
10279         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10280                                         (const_int 32)))
10281                      (const_int 32)))
10282    (clobber (reg:CC FLAGS_REG))]
10283   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10284   "neg{l}\t%k0"
10285   [(set_attr "type" "negnot")
10286    (set_attr "mode" "SI")])
10288 ;; The problem with neg is that it does not perform (compare x 0),
10289 ;; it really performs (compare 0 x), which leaves us with the zero
10290 ;; flag being the only useful item.
10292 (define_insn "*negsi2_cmpz"
10293   [(set (reg:CCZ FLAGS_REG)
10294         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10295                      (const_int 0)))
10296    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10297         (neg:SI (match_dup 1)))]
10298   "ix86_unary_operator_ok (NEG, SImode, operands)"
10299   "neg{l}\t%0"
10300   [(set_attr "type" "negnot")
10301    (set_attr "mode" "SI")])
10303 (define_insn "*negsi2_cmpz_zext"
10304   [(set (reg:CCZ FLAGS_REG)
10305         (compare:CCZ (lshiftrt:DI
10306                        (neg:DI (ashift:DI
10307                                  (match_operand:DI 1 "register_operand" "0")
10308                                  (const_int 32)))
10309                        (const_int 32))
10310                      (const_int 0)))
10311    (set (match_operand:DI 0 "register_operand" "=r")
10312         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10313                                         (const_int 32)))
10314                      (const_int 32)))]
10315   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10316   "neg{l}\t%k0"
10317   [(set_attr "type" "negnot")
10318    (set_attr "mode" "SI")])
10320 (define_expand "neghi2"
10321   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10322                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10323               (clobber (reg:CC FLAGS_REG))])]
10324   "TARGET_HIMODE_MATH"
10325   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10327 (define_insn "*neghi2_1"
10328   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10329         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10330    (clobber (reg:CC FLAGS_REG))]
10331   "ix86_unary_operator_ok (NEG, HImode, operands)"
10332   "neg{w}\t%0"
10333   [(set_attr "type" "negnot")
10334    (set_attr "mode" "HI")])
10336 (define_insn "*neghi2_cmpz"
10337   [(set (reg:CCZ FLAGS_REG)
10338         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10339                      (const_int 0)))
10340    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10341         (neg:HI (match_dup 1)))]
10342   "ix86_unary_operator_ok (NEG, HImode, operands)"
10343   "neg{w}\t%0"
10344   [(set_attr "type" "negnot")
10345    (set_attr "mode" "HI")])
10347 (define_expand "negqi2"
10348   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10349                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10350               (clobber (reg:CC FLAGS_REG))])]
10351   "TARGET_QIMODE_MATH"
10352   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10354 (define_insn "*negqi2_1"
10355   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10356         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10357    (clobber (reg:CC FLAGS_REG))]
10358   "ix86_unary_operator_ok (NEG, QImode, operands)"
10359   "neg{b}\t%0"
10360   [(set_attr "type" "negnot")
10361    (set_attr "mode" "QI")])
10363 (define_insn "*negqi2_cmpz"
10364   [(set (reg:CCZ FLAGS_REG)
10365         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10366                      (const_int 0)))
10367    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10368         (neg:QI (match_dup 1)))]
10369   "ix86_unary_operator_ok (NEG, QImode, operands)"
10370   "neg{b}\t%0"
10371   [(set_attr "type" "negnot")
10372    (set_attr "mode" "QI")])
10374 ;; Changing of sign for FP values is doable using integer unit too.
10376 (define_expand "<code><mode>2"
10377   [(set (match_operand:X87MODEF 0 "register_operand" "")
10378         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10379   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10380   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10382 (define_insn "*absneg<mode>2_mixed"
10383   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10384         (match_operator:MODEF 3 "absneg_operator"
10385           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10386    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10387    (clobber (reg:CC FLAGS_REG))]
10388   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10389   "#")
10391 (define_insn "*absneg<mode>2_sse"
10392   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10393         (match_operator:MODEF 3 "absneg_operator"
10394           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10395    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10396    (clobber (reg:CC FLAGS_REG))]
10397   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10398   "#")
10400 (define_insn "*absneg<mode>2_i387"
10401   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10402         (match_operator:X87MODEF 3 "absneg_operator"
10403           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10404    (use (match_operand 2 "" ""))
10405    (clobber (reg:CC FLAGS_REG))]
10406   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10407   "#")
10409 (define_expand "<code>tf2"
10410   [(set (match_operand:TF 0 "register_operand" "")
10411         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10412   "TARGET_64BIT"
10413   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10415 (define_insn "*absnegtf2_sse"
10416   [(set (match_operand:TF 0 "register_operand" "=x,x")
10417         (match_operator:TF 3 "absneg_operator"
10418           [(match_operand:TF 1 "register_operand" "0,x")]))
10419    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10420    (clobber (reg:CC FLAGS_REG))]
10421   "TARGET_64BIT"
10422   "#")
10424 ;; Splitters for fp abs and neg.
10426 (define_split
10427   [(set (match_operand 0 "fp_register_operand" "")
10428         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10429    (use (match_operand 2 "" ""))
10430    (clobber (reg:CC FLAGS_REG))]
10431   "reload_completed"
10432   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10434 (define_split
10435   [(set (match_operand 0 "register_operand" "")
10436         (match_operator 3 "absneg_operator"
10437           [(match_operand 1 "register_operand" "")]))
10438    (use (match_operand 2 "nonimmediate_operand" ""))
10439    (clobber (reg:CC FLAGS_REG))]
10440   "reload_completed && SSE_REG_P (operands[0])"
10441   [(set (match_dup 0) (match_dup 3))]
10443   enum machine_mode mode = GET_MODE (operands[0]);
10444   enum machine_mode vmode = GET_MODE (operands[2]);
10445   rtx tmp;
10447   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10448   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10449   if (operands_match_p (operands[0], operands[2]))
10450     {
10451       tmp = operands[1];
10452       operands[1] = operands[2];
10453       operands[2] = tmp;
10454     }
10455   if (GET_CODE (operands[3]) == ABS)
10456     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10457   else
10458     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10459   operands[3] = tmp;
10462 (define_split
10463   [(set (match_operand:SF 0 "register_operand" "")
10464         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10465    (use (match_operand:V4SF 2 "" ""))
10466    (clobber (reg:CC FLAGS_REG))]
10467   "reload_completed"
10468   [(parallel [(set (match_dup 0) (match_dup 1))
10469               (clobber (reg:CC FLAGS_REG))])]
10471   rtx tmp;
10472   operands[0] = gen_lowpart (SImode, operands[0]);
10473   if (GET_CODE (operands[1]) == ABS)
10474     {
10475       tmp = gen_int_mode (0x7fffffff, SImode);
10476       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10477     }
10478   else
10479     {
10480       tmp = gen_int_mode (0x80000000, SImode);
10481       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10482     }
10483   operands[1] = tmp;
10486 (define_split
10487   [(set (match_operand:DF 0 "register_operand" "")
10488         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10489    (use (match_operand 2 "" ""))
10490    (clobber (reg:CC FLAGS_REG))]
10491   "reload_completed"
10492   [(parallel [(set (match_dup 0) (match_dup 1))
10493               (clobber (reg:CC FLAGS_REG))])]
10495   rtx tmp;
10496   if (TARGET_64BIT)
10497     {
10498       tmp = gen_lowpart (DImode, operands[0]);
10499       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10500       operands[0] = tmp;
10502       if (GET_CODE (operands[1]) == ABS)
10503         tmp = const0_rtx;
10504       else
10505         tmp = gen_rtx_NOT (DImode, tmp);
10506     }
10507   else
10508     {
10509       operands[0] = gen_highpart (SImode, operands[0]);
10510       if (GET_CODE (operands[1]) == ABS)
10511         {
10512           tmp = gen_int_mode (0x7fffffff, SImode);
10513           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10514         }
10515       else
10516         {
10517           tmp = gen_int_mode (0x80000000, SImode);
10518           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10519         }
10520     }
10521   operands[1] = tmp;
10524 (define_split
10525   [(set (match_operand:XF 0 "register_operand" "")
10526         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10527    (use (match_operand 2 "" ""))
10528    (clobber (reg:CC FLAGS_REG))]
10529   "reload_completed"
10530   [(parallel [(set (match_dup 0) (match_dup 1))
10531               (clobber (reg:CC FLAGS_REG))])]
10533   rtx tmp;
10534   operands[0] = gen_rtx_REG (SImode,
10535                              true_regnum (operands[0])
10536                              + (TARGET_64BIT ? 1 : 2));
10537   if (GET_CODE (operands[1]) == ABS)
10538     {
10539       tmp = GEN_INT (0x7fff);
10540       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10541     }
10542   else
10543     {
10544       tmp = GEN_INT (0x8000);
10545       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10546     }
10547   operands[1] = tmp;
10550 ;; Conditionalize these after reload. If they match before reload, we
10551 ;; lose the clobber and ability to use integer instructions.
10553 (define_insn "*<code><mode>2_1"
10554   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10555         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10556   "TARGET_80387
10557    && (reload_completed
10558        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10559   "f<absnegprefix>"
10560   [(set_attr "type" "fsgn")
10561    (set_attr "mode" "<MODE>")])
10563 (define_insn "*<code>extendsfdf2"
10564   [(set (match_operand:DF 0 "register_operand" "=f")
10565         (absneg:DF (float_extend:DF
10566                      (match_operand:SF 1 "register_operand" "0"))))]
10567   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10568   "f<absnegprefix>"
10569   [(set_attr "type" "fsgn")
10570    (set_attr "mode" "DF")])
10572 (define_insn "*<code>extendsfxf2"
10573   [(set (match_operand:XF 0 "register_operand" "=f")
10574         (absneg:XF (float_extend:XF
10575                      (match_operand:SF 1 "register_operand" "0"))))]
10576   "TARGET_80387"
10577   "f<absnegprefix>"
10578   [(set_attr "type" "fsgn")
10579    (set_attr "mode" "XF")])
10581 (define_insn "*<code>extenddfxf2"
10582   [(set (match_operand:XF 0 "register_operand" "=f")
10583         (absneg:XF (float_extend:XF
10584                       (match_operand:DF 1 "register_operand" "0"))))]
10585   "TARGET_80387"
10586   "f<absnegprefix>"
10587   [(set_attr "type" "fsgn")
10588    (set_attr "mode" "XF")])
10590 ;; Copysign instructions
10592 (define_mode_iterator CSGNMODE [SF DF TF])
10593 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10595 (define_expand "copysign<mode>3"
10596   [(match_operand:CSGNMODE 0 "register_operand" "")
10597    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10598    (match_operand:CSGNMODE 2 "register_operand" "")]
10599   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10600    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10602   ix86_expand_copysign (operands);
10603   DONE;
10606 (define_insn_and_split "copysign<mode>3_const"
10607   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10608         (unspec:CSGNMODE
10609           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10610            (match_operand:CSGNMODE 2 "register_operand" "0")
10611            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10612           UNSPEC_COPYSIGN))]
10613   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10614    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10615   "#"
10616   "&& reload_completed"
10617   [(const_int 0)]
10619   ix86_split_copysign_const (operands);
10620   DONE;
10623 (define_insn "copysign<mode>3_var"
10624   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10625         (unspec:CSGNMODE
10626           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10627            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10628            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10629            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10630           UNSPEC_COPYSIGN))
10631    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10632   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10633    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10634   "#")
10636 (define_split
10637   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10638         (unspec:CSGNMODE
10639           [(match_operand:CSGNMODE 2 "register_operand" "")
10640            (match_operand:CSGNMODE 3 "register_operand" "")
10641            (match_operand:<CSGNVMODE> 4 "" "")
10642            (match_operand:<CSGNVMODE> 5 "" "")]
10643           UNSPEC_COPYSIGN))
10644    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10645   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10646     || (TARGET_64BIT && (<MODE>mode == TFmode)))
10647    && reload_completed"
10648   [(const_int 0)]
10650   ix86_split_copysign_var (operands);
10651   DONE;
10654 ;; One complement instructions
10656 (define_expand "one_cmpldi2"
10657   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10658         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10659   "TARGET_64BIT"
10660   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10662 (define_insn "*one_cmpldi2_1_rex64"
10663   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10664         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10665   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10666   "not{q}\t%0"
10667   [(set_attr "type" "negnot")
10668    (set_attr "mode" "DI")])
10670 (define_insn "*one_cmpldi2_2_rex64"
10671   [(set (reg FLAGS_REG)
10672         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10673                  (const_int 0)))
10674    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10675         (not:DI (match_dup 1)))]
10676   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10677    && ix86_unary_operator_ok (NOT, DImode, operands)"
10678   "#"
10679   [(set_attr "type" "alu1")
10680    (set_attr "mode" "DI")])
10682 (define_split
10683   [(set (match_operand 0 "flags_reg_operand" "")
10684         (match_operator 2 "compare_operator"
10685           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10686            (const_int 0)]))
10687    (set (match_operand:DI 1 "nonimmediate_operand" "")
10688         (not:DI (match_dup 3)))]
10689   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10690   [(parallel [(set (match_dup 0)
10691                    (match_op_dup 2
10692                      [(xor:DI (match_dup 3) (const_int -1))
10693                       (const_int 0)]))
10694               (set (match_dup 1)
10695                    (xor:DI (match_dup 3) (const_int -1)))])]
10696   "")
10698 (define_expand "one_cmplsi2"
10699   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10700         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10701   ""
10702   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10704 (define_insn "*one_cmplsi2_1"
10705   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10706         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10707   "ix86_unary_operator_ok (NOT, SImode, operands)"
10708   "not{l}\t%0"
10709   [(set_attr "type" "negnot")
10710    (set_attr "mode" "SI")])
10712 ;; ??? Currently never generated - xor is used instead.
10713 (define_insn "*one_cmplsi2_1_zext"
10714   [(set (match_operand:DI 0 "register_operand" "=r")
10715         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10716   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10717   "not{l}\t%k0"
10718   [(set_attr "type" "negnot")
10719    (set_attr "mode" "SI")])
10721 (define_insn "*one_cmplsi2_2"
10722   [(set (reg FLAGS_REG)
10723         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10724                  (const_int 0)))
10725    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10726         (not:SI (match_dup 1)))]
10727   "ix86_match_ccmode (insn, CCNOmode)
10728    && ix86_unary_operator_ok (NOT, SImode, operands)"
10729   "#"
10730   [(set_attr "type" "alu1")
10731    (set_attr "mode" "SI")])
10733 (define_split
10734   [(set (match_operand 0 "flags_reg_operand" "")
10735         (match_operator 2 "compare_operator"
10736           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10737            (const_int 0)]))
10738    (set (match_operand:SI 1 "nonimmediate_operand" "")
10739         (not:SI (match_dup 3)))]
10740   "ix86_match_ccmode (insn, CCNOmode)"
10741   [(parallel [(set (match_dup 0)
10742                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10743                                     (const_int 0)]))
10744               (set (match_dup 1)
10745                    (xor:SI (match_dup 3) (const_int -1)))])]
10746   "")
10748 ;; ??? Currently never generated - xor is used instead.
10749 (define_insn "*one_cmplsi2_2_zext"
10750   [(set (reg FLAGS_REG)
10751         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10752                  (const_int 0)))
10753    (set (match_operand:DI 0 "register_operand" "=r")
10754         (zero_extend:DI (not:SI (match_dup 1))))]
10755   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10756    && ix86_unary_operator_ok (NOT, SImode, operands)"
10757   "#"
10758   [(set_attr "type" "alu1")
10759    (set_attr "mode" "SI")])
10761 (define_split
10762   [(set (match_operand 0 "flags_reg_operand" "")
10763         (match_operator 2 "compare_operator"
10764           [(not:SI (match_operand:SI 3 "register_operand" ""))
10765            (const_int 0)]))
10766    (set (match_operand:DI 1 "register_operand" "")
10767         (zero_extend:DI (not:SI (match_dup 3))))]
10768   "ix86_match_ccmode (insn, CCNOmode)"
10769   [(parallel [(set (match_dup 0)
10770                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10771                                     (const_int 0)]))
10772               (set (match_dup 1)
10773                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10774   "")
10776 (define_expand "one_cmplhi2"
10777   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10778         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10779   "TARGET_HIMODE_MATH"
10780   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10782 (define_insn "*one_cmplhi2_1"
10783   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10784         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10785   "ix86_unary_operator_ok (NOT, HImode, operands)"
10786   "not{w}\t%0"
10787   [(set_attr "type" "negnot")
10788    (set_attr "mode" "HI")])
10790 (define_insn "*one_cmplhi2_2"
10791   [(set (reg FLAGS_REG)
10792         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10793                  (const_int 0)))
10794    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10795         (not:HI (match_dup 1)))]
10796   "ix86_match_ccmode (insn, CCNOmode)
10797    && ix86_unary_operator_ok (NEG, HImode, operands)"
10798   "#"
10799   [(set_attr "type" "alu1")
10800    (set_attr "mode" "HI")])
10802 (define_split
10803   [(set (match_operand 0 "flags_reg_operand" "")
10804         (match_operator 2 "compare_operator"
10805           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10806            (const_int 0)]))
10807    (set (match_operand:HI 1 "nonimmediate_operand" "")
10808         (not:HI (match_dup 3)))]
10809   "ix86_match_ccmode (insn, CCNOmode)"
10810   [(parallel [(set (match_dup 0)
10811                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10812                                     (const_int 0)]))
10813               (set (match_dup 1)
10814                    (xor:HI (match_dup 3) (const_int -1)))])]
10815   "")
10817 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10818 (define_expand "one_cmplqi2"
10819   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10820         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10821   "TARGET_QIMODE_MATH"
10822   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10824 (define_insn "*one_cmplqi2_1"
10825   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10826         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10827   "ix86_unary_operator_ok (NOT, QImode, operands)"
10828   "@
10829    not{b}\t%0
10830    not{l}\t%k0"
10831   [(set_attr "type" "negnot")
10832    (set_attr "mode" "QI,SI")])
10834 (define_insn "*one_cmplqi2_2"
10835   [(set (reg FLAGS_REG)
10836         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10837                  (const_int 0)))
10838    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10839         (not:QI (match_dup 1)))]
10840   "ix86_match_ccmode (insn, CCNOmode)
10841    && ix86_unary_operator_ok (NOT, QImode, operands)"
10842   "#"
10843   [(set_attr "type" "alu1")
10844    (set_attr "mode" "QI")])
10846 (define_split
10847   [(set (match_operand 0 "flags_reg_operand" "")
10848         (match_operator 2 "compare_operator"
10849           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10850            (const_int 0)]))
10851    (set (match_operand:QI 1 "nonimmediate_operand" "")
10852         (not:QI (match_dup 3)))]
10853   "ix86_match_ccmode (insn, CCNOmode)"
10854   [(parallel [(set (match_dup 0)
10855                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10856                                     (const_int 0)]))
10857               (set (match_dup 1)
10858                    (xor:QI (match_dup 3) (const_int -1)))])]
10859   "")
10861 ;; Arithmetic shift instructions
10863 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10864 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10865 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10866 ;; from the assembler input.
10868 ;; This instruction shifts the target reg/mem as usual, but instead of
10869 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10870 ;; is a left shift double, bits are taken from the high order bits of
10871 ;; reg, else if the insn is a shift right double, bits are taken from the
10872 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10873 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10875 ;; Since sh[lr]d does not change the `reg' operand, that is done
10876 ;; separately, making all shifts emit pairs of shift double and normal
10877 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10878 ;; support a 63 bit shift, each shift where the count is in a reg expands
10879 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10881 ;; If the shift count is a constant, we need never emit more than one
10882 ;; shift pair, instead using moves and sign extension for counts greater
10883 ;; than 31.
10885 (define_expand "ashlti3"
10886   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10887                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10888                               (match_operand:QI 2 "nonmemory_operand" "")))
10889               (clobber (reg:CC FLAGS_REG))])]
10890   "TARGET_64BIT"
10892   if (! immediate_operand (operands[2], QImode))
10893     {
10894       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10895       DONE;
10896     }
10897   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10898   DONE;
10901 (define_insn "ashlti3_1"
10902   [(set (match_operand:TI 0 "register_operand" "=r")
10903         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10904                    (match_operand:QI 2 "register_operand" "c")))
10905    (clobber (match_scratch:DI 3 "=&r"))
10906    (clobber (reg:CC FLAGS_REG))]
10907   "TARGET_64BIT"
10908   "#"
10909   [(set_attr "type" "multi")])
10911 ;; This pattern must be defined before *ashlti3_2 to prevent
10912 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10914 (define_insn "sse2_ashlti3"
10915   [(set (match_operand:TI 0 "register_operand" "=x")
10916         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10917                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10918   "TARGET_SSE2"
10920   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10921   return "pslldq\t{%2, %0|%0, %2}";
10923   [(set_attr "type" "sseishft")
10924    (set_attr "prefix_data16" "1")
10925    (set_attr "mode" "TI")])
10927 (define_insn "*ashlti3_2"
10928   [(set (match_operand:TI 0 "register_operand" "=r")
10929         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10930                    (match_operand:QI 2 "immediate_operand" "O")))
10931    (clobber (reg:CC FLAGS_REG))]
10932   "TARGET_64BIT"
10933   "#"
10934   [(set_attr "type" "multi")])
10936 (define_split
10937   [(set (match_operand:TI 0 "register_operand" "")
10938         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10939                    (match_operand:QI 2 "register_operand" "")))
10940    (clobber (match_scratch:DI 3 ""))
10941    (clobber (reg:CC FLAGS_REG))]
10942   "TARGET_64BIT && reload_completed"
10943   [(const_int 0)]
10944   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10946 (define_split
10947   [(set (match_operand:TI 0 "register_operand" "")
10948         (ashift:TI (match_operand:TI 1 "register_operand" "")
10949                    (match_operand:QI 2 "immediate_operand" "")))
10950    (clobber (reg:CC FLAGS_REG))]
10951   "TARGET_64BIT && reload_completed"
10952   [(const_int 0)]
10953   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10955 (define_insn "x86_64_shld"
10956   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10957         (ior:DI (ashift:DI (match_dup 0)
10958                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10959                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10960                   (minus:QI (const_int 64) (match_dup 2)))))
10961    (clobber (reg:CC FLAGS_REG))]
10962   "TARGET_64BIT"
10963   "@
10964    shld{q}\t{%2, %1, %0|%0, %1, %2}
10965    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10966   [(set_attr "type" "ishift")
10967    (set_attr "prefix_0f" "1")
10968    (set_attr "mode" "DI")
10969    (set_attr "athlon_decode" "vector")
10970    (set_attr "amdfam10_decode" "vector")])
10972 (define_expand "x86_64_shift_adj"
10973   [(set (reg:CCZ FLAGS_REG)
10974         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10975                              (const_int 64))
10976                      (const_int 0)))
10977    (set (match_operand:DI 0 "register_operand" "")
10978         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10979                          (match_operand:DI 1 "register_operand" "")
10980                          (match_dup 0)))
10981    (set (match_dup 1)
10982         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10983                          (match_operand:DI 3 "register_operand" "r")
10984                          (match_dup 1)))]
10985   "TARGET_64BIT"
10986   "")
10988 (define_expand "ashldi3"
10989   [(set (match_operand:DI 0 "shiftdi_operand" "")
10990         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10991                    (match_operand:QI 2 "nonmemory_operand" "")))]
10992   ""
10993   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10995 (define_insn "*ashldi3_1_rex64"
10996   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10997         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10998                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10999    (clobber (reg:CC FLAGS_REG))]
11000   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11002   switch (get_attr_type (insn))
11003     {
11004     case TYPE_ALU:
11005       gcc_assert (operands[2] == const1_rtx);
11006       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11007       return "add{q}\t%0, %0";
11009     case TYPE_LEA:
11010       gcc_assert (CONST_INT_P (operands[2]));
11011       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11012       operands[1] = gen_rtx_MULT (DImode, operands[1],
11013                                   GEN_INT (1 << INTVAL (operands[2])));
11014       return "lea{q}\t{%a1, %0|%0, %a1}";
11016     default:
11017       if (REG_P (operands[2]))
11018         return "sal{q}\t{%b2, %0|%0, %b2}";
11019       else if (operands[2] == const1_rtx
11020                && (TARGET_SHIFT1 || optimize_size))
11021         return "sal{q}\t%0";
11022       else
11023         return "sal{q}\t{%2, %0|%0, %2}";
11024     }
11026   [(set (attr "type")
11027      (cond [(eq_attr "alternative" "1")
11028               (const_string "lea")
11029             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11030                           (const_int 0))
11031                       (match_operand 0 "register_operand" ""))
11032                  (match_operand 2 "const1_operand" ""))
11033               (const_string "alu")
11034            ]
11035            (const_string "ishift")))
11036    (set_attr "mode" "DI")])
11038 ;; Convert lea to the lea pattern to avoid flags dependency.
11039 (define_split
11040   [(set (match_operand:DI 0 "register_operand" "")
11041         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11042                    (match_operand:QI 2 "immediate_operand" "")))
11043    (clobber (reg:CC FLAGS_REG))]
11044   "TARGET_64BIT && reload_completed
11045    && true_regnum (operands[0]) != true_regnum (operands[1])"
11046   [(set (match_dup 0)
11047         (mult:DI (match_dup 1)
11048                  (match_dup 2)))]
11049   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11051 ;; This pattern can't accept a variable shift count, since shifts by
11052 ;; zero don't affect the flags.  We assume that shifts by constant
11053 ;; zero are optimized away.
11054 (define_insn "*ashldi3_cmp_rex64"
11055   [(set (reg FLAGS_REG)
11056         (compare
11057           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11058                      (match_operand:QI 2 "immediate_operand" "e"))
11059           (const_int 0)))
11060    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11061         (ashift:DI (match_dup 1) (match_dup 2)))]
11062   "TARGET_64BIT
11063    && (optimize_size
11064        || !TARGET_PARTIAL_FLAG_REG_STALL
11065        || (operands[2] == const1_rtx
11066            && (TARGET_SHIFT1
11067                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11068    && ix86_match_ccmode (insn, CCGOCmode)
11069    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11071   switch (get_attr_type (insn))
11072     {
11073     case TYPE_ALU:
11074       gcc_assert (operands[2] == const1_rtx);
11075       return "add{q}\t%0, %0";
11077     default:
11078       if (REG_P (operands[2]))
11079         return "sal{q}\t{%b2, %0|%0, %b2}";
11080       else if (operands[2] == const1_rtx
11081                && (TARGET_SHIFT1 || optimize_size))
11082         return "sal{q}\t%0";
11083       else
11084         return "sal{q}\t{%2, %0|%0, %2}";
11085     }
11087   [(set (attr "type")
11088      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11089                           (const_int 0))
11090                       (match_operand 0 "register_operand" ""))
11091                  (match_operand 2 "const1_operand" ""))
11092               (const_string "alu")
11093            ]
11094            (const_string "ishift")))
11095    (set_attr "mode" "DI")])
11097 (define_insn "*ashldi3_cconly_rex64"
11098   [(set (reg FLAGS_REG)
11099         (compare
11100           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11101                      (match_operand:QI 2 "immediate_operand" "e"))
11102           (const_int 0)))
11103    (clobber (match_scratch:DI 0 "=r"))]
11104   "TARGET_64BIT
11105    && (optimize_size
11106        || !TARGET_PARTIAL_FLAG_REG_STALL
11107        || (operands[2] == const1_rtx
11108            && (TARGET_SHIFT1
11109                || TARGET_DOUBLE_WITH_ADD)))
11110    && ix86_match_ccmode (insn, CCGOCmode)
11111    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11113   switch (get_attr_type (insn))
11114     {
11115     case TYPE_ALU:
11116       gcc_assert (operands[2] == const1_rtx);
11117       return "add{q}\t%0, %0";
11119     default:
11120       if (REG_P (operands[2]))
11121         return "sal{q}\t{%b2, %0|%0, %b2}";
11122       else if (operands[2] == const1_rtx
11123                && (TARGET_SHIFT1 || optimize_size))
11124         return "sal{q}\t%0";
11125       else
11126         return "sal{q}\t{%2, %0|%0, %2}";
11127     }
11129   [(set (attr "type")
11130      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11131                           (const_int 0))
11132                       (match_operand 0 "register_operand" ""))
11133                  (match_operand 2 "const1_operand" ""))
11134               (const_string "alu")
11135            ]
11136            (const_string "ishift")))
11137    (set_attr "mode" "DI")])
11139 (define_insn "*ashldi3_1"
11140   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11141         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11142                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11143    (clobber (reg:CC FLAGS_REG))]
11144   "!TARGET_64BIT"
11145   "#"
11146   [(set_attr "type" "multi")])
11148 ;; By default we don't ask for a scratch register, because when DImode
11149 ;; values are manipulated, registers are already at a premium.  But if
11150 ;; we have one handy, we won't turn it away.
11151 (define_peephole2
11152   [(match_scratch:SI 3 "r")
11153    (parallel [(set (match_operand:DI 0 "register_operand" "")
11154                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11155                               (match_operand:QI 2 "nonmemory_operand" "")))
11156               (clobber (reg:CC FLAGS_REG))])
11157    (match_dup 3)]
11158   "!TARGET_64BIT && TARGET_CMOVE"
11159   [(const_int 0)]
11160   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11162 (define_split
11163   [(set (match_operand:DI 0 "register_operand" "")
11164         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11165                    (match_operand:QI 2 "nonmemory_operand" "")))
11166    (clobber (reg:CC FLAGS_REG))]
11167   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11168                      ? epilogue_completed : reload_completed)"
11169   [(const_int 0)]
11170   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11172 (define_insn "x86_shld_1"
11173   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11174         (ior:SI (ashift:SI (match_dup 0)
11175                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11176                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11177                   (minus:QI (const_int 32) (match_dup 2)))))
11178    (clobber (reg:CC FLAGS_REG))]
11179   ""
11180   "@
11181    shld{l}\t{%2, %1, %0|%0, %1, %2}
11182    shld{l}\t{%s2%1, %0|%0, %1, %2}"
11183   [(set_attr "type" "ishift")
11184    (set_attr "prefix_0f" "1")
11185    (set_attr "mode" "SI")
11186    (set_attr "pent_pair" "np")
11187    (set_attr "athlon_decode" "vector")
11188    (set_attr "amdfam10_decode" "vector")])
11190 (define_expand "x86_shift_adj_1"
11191   [(set (reg:CCZ FLAGS_REG)
11192         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11193                              (const_int 32))
11194                      (const_int 0)))
11195    (set (match_operand:SI 0 "register_operand" "")
11196         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11197                          (match_operand:SI 1 "register_operand" "")
11198                          (match_dup 0)))
11199    (set (match_dup 1)
11200         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11201                          (match_operand:SI 3 "register_operand" "r")
11202                          (match_dup 1)))]
11203   "TARGET_CMOVE"
11204   "")
11206 (define_expand "x86_shift_adj_2"
11207   [(use (match_operand:SI 0 "register_operand" ""))
11208    (use (match_operand:SI 1 "register_operand" ""))
11209    (use (match_operand:QI 2 "register_operand" ""))]
11210   ""
11212   rtx label = gen_label_rtx ();
11213   rtx tmp;
11215   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11217   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11218   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11219   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11220                               gen_rtx_LABEL_REF (VOIDmode, label),
11221                               pc_rtx);
11222   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11223   JUMP_LABEL (tmp) = label;
11225   emit_move_insn (operands[0], operands[1]);
11226   ix86_expand_clear (operands[1]);
11228   emit_label (label);
11229   LABEL_NUSES (label) = 1;
11231   DONE;
11234 (define_expand "ashlsi3"
11235   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11236         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11237                    (match_operand:QI 2 "nonmemory_operand" "")))
11238    (clobber (reg:CC FLAGS_REG))]
11239   ""
11240   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11242 (define_insn "*ashlsi3_1"
11243   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11244         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11245                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11246    (clobber (reg:CC FLAGS_REG))]
11247   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11249   switch (get_attr_type (insn))
11250     {
11251     case TYPE_ALU:
11252       gcc_assert (operands[2] == const1_rtx);
11253       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11254       return "add{l}\t%0, %0";
11256     case TYPE_LEA:
11257       return "#";
11259     default:
11260       if (REG_P (operands[2]))
11261         return "sal{l}\t{%b2, %0|%0, %b2}";
11262       else if (operands[2] == const1_rtx
11263                && (TARGET_SHIFT1 || optimize_size))
11264         return "sal{l}\t%0";
11265       else
11266         return "sal{l}\t{%2, %0|%0, %2}";
11267     }
11269   [(set (attr "type")
11270      (cond [(eq_attr "alternative" "1")
11271               (const_string "lea")
11272             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11273                           (const_int 0))
11274                       (match_operand 0 "register_operand" ""))
11275                  (match_operand 2 "const1_operand" ""))
11276               (const_string "alu")
11277            ]
11278            (const_string "ishift")))
11279    (set_attr "mode" "SI")])
11281 ;; Convert lea to the lea pattern to avoid flags dependency.
11282 (define_split
11283   [(set (match_operand 0 "register_operand" "")
11284         (ashift (match_operand 1 "index_register_operand" "")
11285                 (match_operand:QI 2 "const_int_operand" "")))
11286    (clobber (reg:CC FLAGS_REG))]
11287   "reload_completed
11288    && true_regnum (operands[0]) != true_regnum (operands[1])
11289    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11290   [(const_int 0)]
11292   rtx pat;
11293   enum machine_mode mode = GET_MODE (operands[0]);
11295   if (GET_MODE_SIZE (mode) < 4)
11296     operands[0] = gen_lowpart (SImode, operands[0]);
11297   if (mode != Pmode)
11298     operands[1] = gen_lowpart (Pmode, operands[1]);
11299   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11301   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11302   if (Pmode != SImode)
11303     pat = gen_rtx_SUBREG (SImode, pat, 0);
11304   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11305   DONE;
11308 ;; Rare case of shifting RSP is handled by generating move and shift
11309 (define_split
11310   [(set (match_operand 0 "register_operand" "")
11311         (ashift (match_operand 1 "register_operand" "")
11312                 (match_operand:QI 2 "const_int_operand" "")))
11313    (clobber (reg:CC FLAGS_REG))]
11314   "reload_completed
11315    && true_regnum (operands[0]) != true_regnum (operands[1])"
11316   [(const_int 0)]
11318   rtx pat, clob;
11319   emit_move_insn (operands[0], operands[1]);
11320   pat = gen_rtx_SET (VOIDmode, operands[0],
11321                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11322                                      operands[0], operands[2]));
11323   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11324   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11325   DONE;
11328 (define_insn "*ashlsi3_1_zext"
11329   [(set (match_operand:DI 0 "register_operand" "=r,r")
11330         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11331                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11332    (clobber (reg:CC FLAGS_REG))]
11333   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11335   switch (get_attr_type (insn))
11336     {
11337     case TYPE_ALU:
11338       gcc_assert (operands[2] == const1_rtx);
11339       return "add{l}\t%k0, %k0";
11341     case TYPE_LEA:
11342       return "#";
11344     default:
11345       if (REG_P (operands[2]))
11346         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11347       else if (operands[2] == const1_rtx
11348                && (TARGET_SHIFT1 || optimize_size))
11349         return "sal{l}\t%k0";
11350       else
11351         return "sal{l}\t{%2, %k0|%k0, %2}";
11352     }
11354   [(set (attr "type")
11355      (cond [(eq_attr "alternative" "1")
11356               (const_string "lea")
11357             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11358                      (const_int 0))
11359                  (match_operand 2 "const1_operand" ""))
11360               (const_string "alu")
11361            ]
11362            (const_string "ishift")))
11363    (set_attr "mode" "SI")])
11365 ;; Convert lea to the lea pattern to avoid flags dependency.
11366 (define_split
11367   [(set (match_operand:DI 0 "register_operand" "")
11368         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11369                                 (match_operand:QI 2 "const_int_operand" ""))))
11370    (clobber (reg:CC FLAGS_REG))]
11371   "TARGET_64BIT && reload_completed
11372    && true_regnum (operands[0]) != true_regnum (operands[1])"
11373   [(set (match_dup 0) (zero_extend:DI
11374                         (subreg:SI (mult:SI (match_dup 1)
11375                                             (match_dup 2)) 0)))]
11377   operands[1] = gen_lowpart (Pmode, operands[1]);
11378   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11381 ;; This pattern can't accept a variable shift count, since shifts by
11382 ;; zero don't affect the flags.  We assume that shifts by constant
11383 ;; zero are optimized away.
11384 (define_insn "*ashlsi3_cmp"
11385   [(set (reg FLAGS_REG)
11386         (compare
11387           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11388                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11389           (const_int 0)))
11390    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11391         (ashift:SI (match_dup 1) (match_dup 2)))]
11392    "(optimize_size
11393      || !TARGET_PARTIAL_FLAG_REG_STALL
11394      || (operands[2] == const1_rtx
11395          && (TARGET_SHIFT1
11396              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11397    && ix86_match_ccmode (insn, CCGOCmode)
11398    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11400   switch (get_attr_type (insn))
11401     {
11402     case TYPE_ALU:
11403       gcc_assert (operands[2] == const1_rtx);
11404       return "add{l}\t%0, %0";
11406     default:
11407       if (REG_P (operands[2]))
11408         return "sal{l}\t{%b2, %0|%0, %b2}";
11409       else if (operands[2] == const1_rtx
11410                && (TARGET_SHIFT1 || optimize_size))
11411         return "sal{l}\t%0";
11412       else
11413         return "sal{l}\t{%2, %0|%0, %2}";
11414     }
11416   [(set (attr "type")
11417      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11418                           (const_int 0))
11419                       (match_operand 0 "register_operand" ""))
11420                  (match_operand 2 "const1_operand" ""))
11421               (const_string "alu")
11422            ]
11423            (const_string "ishift")))
11424    (set_attr "mode" "SI")])
11426 (define_insn "*ashlsi3_cconly"
11427   [(set (reg FLAGS_REG)
11428         (compare
11429           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11430                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11431           (const_int 0)))
11432    (clobber (match_scratch:SI 0 "=r"))]
11433   "(optimize_size
11434     || !TARGET_PARTIAL_FLAG_REG_STALL
11435     || (operands[2] == const1_rtx
11436         && (TARGET_SHIFT1
11437             || TARGET_DOUBLE_WITH_ADD)))
11438    && ix86_match_ccmode (insn, CCGOCmode)
11439    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11441   switch (get_attr_type (insn))
11442     {
11443     case TYPE_ALU:
11444       gcc_assert (operands[2] == const1_rtx);
11445       return "add{l}\t%0, %0";
11447     default:
11448       if (REG_P (operands[2]))
11449         return "sal{l}\t{%b2, %0|%0, %b2}";
11450       else if (operands[2] == const1_rtx
11451                && (TARGET_SHIFT1 || optimize_size))
11452         return "sal{l}\t%0";
11453       else
11454         return "sal{l}\t{%2, %0|%0, %2}";
11455     }
11457   [(set (attr "type")
11458      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11459                           (const_int 0))
11460                       (match_operand 0 "register_operand" ""))
11461                  (match_operand 2 "const1_operand" ""))
11462               (const_string "alu")
11463            ]
11464            (const_string "ishift")))
11465    (set_attr "mode" "SI")])
11467 (define_insn "*ashlsi3_cmp_zext"
11468   [(set (reg FLAGS_REG)
11469         (compare
11470           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11471                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11472           (const_int 0)))
11473    (set (match_operand:DI 0 "register_operand" "=r")
11474         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11475   "TARGET_64BIT
11476    && (optimize_size
11477        || !TARGET_PARTIAL_FLAG_REG_STALL
11478        || (operands[2] == const1_rtx
11479            && (TARGET_SHIFT1
11480                || TARGET_DOUBLE_WITH_ADD)))
11481    && ix86_match_ccmode (insn, CCGOCmode)
11482    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11484   switch (get_attr_type (insn))
11485     {
11486     case TYPE_ALU:
11487       gcc_assert (operands[2] == const1_rtx);
11488       return "add{l}\t%k0, %k0";
11490     default:
11491       if (REG_P (operands[2]))
11492         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11493       else if (operands[2] == const1_rtx
11494                && (TARGET_SHIFT1 || optimize_size))
11495         return "sal{l}\t%k0";
11496       else
11497         return "sal{l}\t{%2, %k0|%k0, %2}";
11498     }
11500   [(set (attr "type")
11501      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11502                      (const_int 0))
11503                  (match_operand 2 "const1_operand" ""))
11504               (const_string "alu")
11505            ]
11506            (const_string "ishift")))
11507    (set_attr "mode" "SI")])
11509 (define_expand "ashlhi3"
11510   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11511         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11512                    (match_operand:QI 2 "nonmemory_operand" "")))
11513    (clobber (reg:CC FLAGS_REG))]
11514   "TARGET_HIMODE_MATH"
11515   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11517 (define_insn "*ashlhi3_1_lea"
11518   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11519         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11520                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11521    (clobber (reg:CC FLAGS_REG))]
11522   "!TARGET_PARTIAL_REG_STALL
11523    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11525   switch (get_attr_type (insn))
11526     {
11527     case TYPE_LEA:
11528       return "#";
11529     case TYPE_ALU:
11530       gcc_assert (operands[2] == const1_rtx);
11531       return "add{w}\t%0, %0";
11533     default:
11534       if (REG_P (operands[2]))
11535         return "sal{w}\t{%b2, %0|%0, %b2}";
11536       else if (operands[2] == const1_rtx
11537                && (TARGET_SHIFT1 || optimize_size))
11538         return "sal{w}\t%0";
11539       else
11540         return "sal{w}\t{%2, %0|%0, %2}";
11541     }
11543   [(set (attr "type")
11544      (cond [(eq_attr "alternative" "1")
11545               (const_string "lea")
11546             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11547                           (const_int 0))
11548                       (match_operand 0 "register_operand" ""))
11549                  (match_operand 2 "const1_operand" ""))
11550               (const_string "alu")
11551            ]
11552            (const_string "ishift")))
11553    (set_attr "mode" "HI,SI")])
11555 (define_insn "*ashlhi3_1"
11556   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11557         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11558                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11559    (clobber (reg:CC FLAGS_REG))]
11560   "TARGET_PARTIAL_REG_STALL
11561    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11563   switch (get_attr_type (insn))
11564     {
11565     case TYPE_ALU:
11566       gcc_assert (operands[2] == const1_rtx);
11567       return "add{w}\t%0, %0";
11569     default:
11570       if (REG_P (operands[2]))
11571         return "sal{w}\t{%b2, %0|%0, %b2}";
11572       else if (operands[2] == const1_rtx
11573                && (TARGET_SHIFT1 || optimize_size))
11574         return "sal{w}\t%0";
11575       else
11576         return "sal{w}\t{%2, %0|%0, %2}";
11577     }
11579   [(set (attr "type")
11580      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11581                           (const_int 0))
11582                       (match_operand 0 "register_operand" ""))
11583                  (match_operand 2 "const1_operand" ""))
11584               (const_string "alu")
11585            ]
11586            (const_string "ishift")))
11587    (set_attr "mode" "HI")])
11589 ;; This pattern can't accept a variable shift count, since shifts by
11590 ;; zero don't affect the flags.  We assume that shifts by constant
11591 ;; zero are optimized away.
11592 (define_insn "*ashlhi3_cmp"
11593   [(set (reg FLAGS_REG)
11594         (compare
11595           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11596                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11597           (const_int 0)))
11598    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11599         (ashift:HI (match_dup 1) (match_dup 2)))]
11600   "(optimize_size
11601     || !TARGET_PARTIAL_FLAG_REG_STALL
11602     || (operands[2] == const1_rtx
11603         && (TARGET_SHIFT1
11604             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11605    && ix86_match_ccmode (insn, CCGOCmode)
11606    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11608   switch (get_attr_type (insn))
11609     {
11610     case TYPE_ALU:
11611       gcc_assert (operands[2] == const1_rtx);
11612       return "add{w}\t%0, %0";
11614     default:
11615       if (REG_P (operands[2]))
11616         return "sal{w}\t{%b2, %0|%0, %b2}";
11617       else if (operands[2] == const1_rtx
11618                && (TARGET_SHIFT1 || optimize_size))
11619         return "sal{w}\t%0";
11620       else
11621         return "sal{w}\t{%2, %0|%0, %2}";
11622     }
11624   [(set (attr "type")
11625      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11626                           (const_int 0))
11627                       (match_operand 0 "register_operand" ""))
11628                  (match_operand 2 "const1_operand" ""))
11629               (const_string "alu")
11630            ]
11631            (const_string "ishift")))
11632    (set_attr "mode" "HI")])
11634 (define_insn "*ashlhi3_cconly"
11635   [(set (reg FLAGS_REG)
11636         (compare
11637           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11638                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11639           (const_int 0)))
11640    (clobber (match_scratch:HI 0 "=r"))]
11641   "(optimize_size
11642     || !TARGET_PARTIAL_FLAG_REG_STALL
11643     || (operands[2] == const1_rtx
11644         && (TARGET_SHIFT1
11645             || TARGET_DOUBLE_WITH_ADD)))
11646    && ix86_match_ccmode (insn, CCGOCmode)
11647    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11649   switch (get_attr_type (insn))
11650     {
11651     case TYPE_ALU:
11652       gcc_assert (operands[2] == const1_rtx);
11653       return "add{w}\t%0, %0";
11655     default:
11656       if (REG_P (operands[2]))
11657         return "sal{w}\t{%b2, %0|%0, %b2}";
11658       else if (operands[2] == const1_rtx
11659                && (TARGET_SHIFT1 || optimize_size))
11660         return "sal{w}\t%0";
11661       else
11662         return "sal{w}\t{%2, %0|%0, %2}";
11663     }
11665   [(set (attr "type")
11666      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11667                           (const_int 0))
11668                       (match_operand 0 "register_operand" ""))
11669                  (match_operand 2 "const1_operand" ""))
11670               (const_string "alu")
11671            ]
11672            (const_string "ishift")))
11673    (set_attr "mode" "HI")])
11675 (define_expand "ashlqi3"
11676   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11677         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11678                    (match_operand:QI 2 "nonmemory_operand" "")))
11679    (clobber (reg:CC FLAGS_REG))]
11680   "TARGET_QIMODE_MATH"
11681   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11683 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11685 (define_insn "*ashlqi3_1_lea"
11686   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11687         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11688                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11689    (clobber (reg:CC FLAGS_REG))]
11690   "!TARGET_PARTIAL_REG_STALL
11691    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11693   switch (get_attr_type (insn))
11694     {
11695     case TYPE_LEA:
11696       return "#";
11697     case TYPE_ALU:
11698       gcc_assert (operands[2] == const1_rtx);
11699       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11700         return "add{l}\t%k0, %k0";
11701       else
11702         return "add{b}\t%0, %0";
11704     default:
11705       if (REG_P (operands[2]))
11706         {
11707           if (get_attr_mode (insn) == MODE_SI)
11708             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11709           else
11710             return "sal{b}\t{%b2, %0|%0, %b2}";
11711         }
11712       else if (operands[2] == const1_rtx
11713                && (TARGET_SHIFT1 || optimize_size))
11714         {
11715           if (get_attr_mode (insn) == MODE_SI)
11716             return "sal{l}\t%0";
11717           else
11718             return "sal{b}\t%0";
11719         }
11720       else
11721         {
11722           if (get_attr_mode (insn) == MODE_SI)
11723             return "sal{l}\t{%2, %k0|%k0, %2}";
11724           else
11725             return "sal{b}\t{%2, %0|%0, %2}";
11726         }
11727     }
11729   [(set (attr "type")
11730      (cond [(eq_attr "alternative" "2")
11731               (const_string "lea")
11732             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11733                           (const_int 0))
11734                       (match_operand 0 "register_operand" ""))
11735                  (match_operand 2 "const1_operand" ""))
11736               (const_string "alu")
11737            ]
11738            (const_string "ishift")))
11739    (set_attr "mode" "QI,SI,SI")])
11741 (define_insn "*ashlqi3_1"
11742   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11743         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11744                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11745    (clobber (reg:CC FLAGS_REG))]
11746   "TARGET_PARTIAL_REG_STALL
11747    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11749   switch (get_attr_type (insn))
11750     {
11751     case TYPE_ALU:
11752       gcc_assert (operands[2] == const1_rtx);
11753       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11754         return "add{l}\t%k0, %k0";
11755       else
11756         return "add{b}\t%0, %0";
11758     default:
11759       if (REG_P (operands[2]))
11760         {
11761           if (get_attr_mode (insn) == MODE_SI)
11762             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11763           else
11764             return "sal{b}\t{%b2, %0|%0, %b2}";
11765         }
11766       else if (operands[2] == const1_rtx
11767                && (TARGET_SHIFT1 || optimize_size))
11768         {
11769           if (get_attr_mode (insn) == MODE_SI)
11770             return "sal{l}\t%0";
11771           else
11772             return "sal{b}\t%0";
11773         }
11774       else
11775         {
11776           if (get_attr_mode (insn) == MODE_SI)
11777             return "sal{l}\t{%2, %k0|%k0, %2}";
11778           else
11779             return "sal{b}\t{%2, %0|%0, %2}";
11780         }
11781     }
11783   [(set (attr "type")
11784      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11785                           (const_int 0))
11786                       (match_operand 0 "register_operand" ""))
11787                  (match_operand 2 "const1_operand" ""))
11788               (const_string "alu")
11789            ]
11790            (const_string "ishift")))
11791    (set_attr "mode" "QI,SI")])
11793 ;; This pattern can't accept a variable shift count, since shifts by
11794 ;; zero don't affect the flags.  We assume that shifts by constant
11795 ;; zero are optimized away.
11796 (define_insn "*ashlqi3_cmp"
11797   [(set (reg FLAGS_REG)
11798         (compare
11799           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11800                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11801           (const_int 0)))
11802    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11803         (ashift:QI (match_dup 1) (match_dup 2)))]
11804   "(optimize_size
11805     || !TARGET_PARTIAL_FLAG_REG_STALL
11806     || (operands[2] == const1_rtx
11807         && (TARGET_SHIFT1
11808             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11809    && ix86_match_ccmode (insn, CCGOCmode)
11810    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11812   switch (get_attr_type (insn))
11813     {
11814     case TYPE_ALU:
11815       gcc_assert (operands[2] == const1_rtx);
11816       return "add{b}\t%0, %0";
11818     default:
11819       if (REG_P (operands[2]))
11820         return "sal{b}\t{%b2, %0|%0, %b2}";
11821       else if (operands[2] == const1_rtx
11822                && (TARGET_SHIFT1 || optimize_size))
11823         return "sal{b}\t%0";
11824       else
11825         return "sal{b}\t{%2, %0|%0, %2}";
11826     }
11828   [(set (attr "type")
11829      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11830                           (const_int 0))
11831                       (match_operand 0 "register_operand" ""))
11832                  (match_operand 2 "const1_operand" ""))
11833               (const_string "alu")
11834            ]
11835            (const_string "ishift")))
11836    (set_attr "mode" "QI")])
11838 (define_insn "*ashlqi3_cconly"
11839   [(set (reg FLAGS_REG)
11840         (compare
11841           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11842                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11843           (const_int 0)))
11844    (clobber (match_scratch:QI 0 "=q"))]
11845   "(optimize_size
11846     || !TARGET_PARTIAL_FLAG_REG_STALL
11847     || (operands[2] == const1_rtx
11848         && (TARGET_SHIFT1
11849             || TARGET_DOUBLE_WITH_ADD)))
11850    && ix86_match_ccmode (insn, CCGOCmode)
11851    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11853   switch (get_attr_type (insn))
11854     {
11855     case TYPE_ALU:
11856       gcc_assert (operands[2] == const1_rtx);
11857       return "add{b}\t%0, %0";
11859     default:
11860       if (REG_P (operands[2]))
11861         return "sal{b}\t{%b2, %0|%0, %b2}";
11862       else if (operands[2] == const1_rtx
11863                && (TARGET_SHIFT1 || optimize_size))
11864         return "sal{b}\t%0";
11865       else
11866         return "sal{b}\t{%2, %0|%0, %2}";
11867     }
11869   [(set (attr "type")
11870      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11871                           (const_int 0))
11872                       (match_operand 0 "register_operand" ""))
11873                  (match_operand 2 "const1_operand" ""))
11874               (const_string "alu")
11875            ]
11876            (const_string "ishift")))
11877    (set_attr "mode" "QI")])
11879 ;; See comment above `ashldi3' about how this works.
11881 (define_expand "ashrti3"
11882   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11883                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11884                                 (match_operand:QI 2 "nonmemory_operand" "")))
11885               (clobber (reg:CC FLAGS_REG))])]
11886   "TARGET_64BIT"
11888   if (! immediate_operand (operands[2], QImode))
11889     {
11890       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11891       DONE;
11892     }
11893   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11894   DONE;
11897 (define_insn "ashrti3_1"
11898   [(set (match_operand:TI 0 "register_operand" "=r")
11899         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11900                      (match_operand:QI 2 "register_operand" "c")))
11901    (clobber (match_scratch:DI 3 "=&r"))
11902    (clobber (reg:CC FLAGS_REG))]
11903   "TARGET_64BIT"
11904   "#"
11905   [(set_attr "type" "multi")])
11907 (define_insn "*ashrti3_2"
11908   [(set (match_operand:TI 0 "register_operand" "=r")
11909         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11910                      (match_operand:QI 2 "immediate_operand" "O")))
11911    (clobber (reg:CC FLAGS_REG))]
11912   "TARGET_64BIT"
11913   "#"
11914   [(set_attr "type" "multi")])
11916 (define_split
11917   [(set (match_operand:TI 0 "register_operand" "")
11918         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11919                      (match_operand:QI 2 "register_operand" "")))
11920    (clobber (match_scratch:DI 3 ""))
11921    (clobber (reg:CC FLAGS_REG))]
11922   "TARGET_64BIT && reload_completed"
11923   [(const_int 0)]
11924   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11926 (define_split
11927   [(set (match_operand:TI 0 "register_operand" "")
11928         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11929                      (match_operand:QI 2 "immediate_operand" "")))
11930    (clobber (reg:CC FLAGS_REG))]
11931   "TARGET_64BIT && reload_completed"
11932   [(const_int 0)]
11933   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11935 (define_insn "x86_64_shrd"
11936   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11937         (ior:DI (ashiftrt:DI (match_dup 0)
11938                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11939                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11940                   (minus:QI (const_int 64) (match_dup 2)))))
11941    (clobber (reg:CC FLAGS_REG))]
11942   "TARGET_64BIT"
11943   "@
11944    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11945    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11946   [(set_attr "type" "ishift")
11947    (set_attr "prefix_0f" "1")
11948    (set_attr "mode" "DI")
11949    (set_attr "athlon_decode" "vector")
11950    (set_attr "amdfam10_decode" "vector")])
11952 (define_expand "ashrdi3"
11953   [(set (match_operand:DI 0 "shiftdi_operand" "")
11954         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11955                      (match_operand:QI 2 "nonmemory_operand" "")))]
11956   ""
11957   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11959 (define_insn "*ashrdi3_63_rex64"
11960   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11961         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11962                      (match_operand:DI 2 "const_int_operand" "i,i")))
11963    (clobber (reg:CC FLAGS_REG))]
11964   "TARGET_64BIT && INTVAL (operands[2]) == 63
11965    && (TARGET_USE_CLTD || optimize_size)
11966    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11967   "@
11968    {cqto|cqo}
11969    sar{q}\t{%2, %0|%0, %2}"
11970   [(set_attr "type" "imovx,ishift")
11971    (set_attr "prefix_0f" "0,*")
11972    (set_attr "length_immediate" "0,*")
11973    (set_attr "modrm" "0,1")
11974    (set_attr "mode" "DI")])
11976 (define_insn "*ashrdi3_1_one_bit_rex64"
11977   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11978         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11979                      (match_operand:QI 2 "const1_operand" "")))
11980    (clobber (reg:CC FLAGS_REG))]
11981   "TARGET_64BIT
11982    && (TARGET_SHIFT1 || optimize_size)
11983    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11984   "sar{q}\t%0"
11985   [(set_attr "type" "ishift")
11986    (set (attr "length")
11987      (if_then_else (match_operand:DI 0 "register_operand" "")
11988         (const_string "2")
11989         (const_string "*")))])
11991 (define_insn "*ashrdi3_1_rex64"
11992   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11993         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11994                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11995    (clobber (reg:CC FLAGS_REG))]
11996   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11997   "@
11998    sar{q}\t{%2, %0|%0, %2}
11999    sar{q}\t{%b2, %0|%0, %b2}"
12000   [(set_attr "type" "ishift")
12001    (set_attr "mode" "DI")])
12003 ;; This pattern can't accept a variable shift count, since shifts by
12004 ;; zero don't affect the flags.  We assume that shifts by constant
12005 ;; zero are optimized away.
12006 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12007   [(set (reg FLAGS_REG)
12008         (compare
12009           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12010                        (match_operand:QI 2 "const1_operand" ""))
12011           (const_int 0)))
12012    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12013         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12014   "TARGET_64BIT
12015    && (TARGET_SHIFT1 || optimize_size)
12016    && ix86_match_ccmode (insn, CCGOCmode)
12017    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12018   "sar{q}\t%0"
12019   [(set_attr "type" "ishift")
12020    (set (attr "length")
12021      (if_then_else (match_operand:DI 0 "register_operand" "")
12022         (const_string "2")
12023         (const_string "*")))])
12025 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12026   [(set (reg FLAGS_REG)
12027         (compare
12028           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12029                        (match_operand:QI 2 "const1_operand" ""))
12030           (const_int 0)))
12031    (clobber (match_scratch:DI 0 "=r"))]
12032   "TARGET_64BIT
12033    && (TARGET_SHIFT1 || optimize_size)
12034    && ix86_match_ccmode (insn, CCGOCmode)
12035    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12036   "sar{q}\t%0"
12037   [(set_attr "type" "ishift")
12038    (set_attr "length" "2")])
12040 ;; This pattern can't accept a variable shift count, since shifts by
12041 ;; zero don't affect the flags.  We assume that shifts by constant
12042 ;; zero are optimized away.
12043 (define_insn "*ashrdi3_cmp_rex64"
12044   [(set (reg FLAGS_REG)
12045         (compare
12046           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12047                        (match_operand:QI 2 "const_int_operand" "n"))
12048           (const_int 0)))
12049    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12050         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12051   "TARGET_64BIT
12052    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12053    && ix86_match_ccmode (insn, CCGOCmode)
12054    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12055   "sar{q}\t{%2, %0|%0, %2}"
12056   [(set_attr "type" "ishift")
12057    (set_attr "mode" "DI")])
12059 (define_insn "*ashrdi3_cconly_rex64"
12060   [(set (reg FLAGS_REG)
12061         (compare
12062           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12063                        (match_operand:QI 2 "const_int_operand" "n"))
12064           (const_int 0)))
12065    (clobber (match_scratch:DI 0 "=r"))]
12066   "TARGET_64BIT
12067    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12068    && ix86_match_ccmode (insn, CCGOCmode)
12069    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12070   "sar{q}\t{%2, %0|%0, %2}"
12071   [(set_attr "type" "ishift")
12072    (set_attr "mode" "DI")])
12074 (define_insn "*ashrdi3_1"
12075   [(set (match_operand:DI 0 "register_operand" "=r")
12076         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12077                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12078    (clobber (reg:CC FLAGS_REG))]
12079   "!TARGET_64BIT"
12080   "#"
12081   [(set_attr "type" "multi")])
12083 ;; By default we don't ask for a scratch register, because when DImode
12084 ;; values are manipulated, registers are already at a premium.  But if
12085 ;; we have one handy, we won't turn it away.
12086 (define_peephole2
12087   [(match_scratch:SI 3 "r")
12088    (parallel [(set (match_operand:DI 0 "register_operand" "")
12089                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12090                                 (match_operand:QI 2 "nonmemory_operand" "")))
12091               (clobber (reg:CC FLAGS_REG))])
12092    (match_dup 3)]
12093   "!TARGET_64BIT && TARGET_CMOVE"
12094   [(const_int 0)]
12095   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12097 (define_split
12098   [(set (match_operand:DI 0 "register_operand" "")
12099         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12100                      (match_operand:QI 2 "nonmemory_operand" "")))
12101    (clobber (reg:CC FLAGS_REG))]
12102   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12103                      ? epilogue_completed : reload_completed)"
12104   [(const_int 0)]
12105   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12107 (define_insn "x86_shrd_1"
12108   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12109         (ior:SI (ashiftrt:SI (match_dup 0)
12110                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
12111                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12112                   (minus:QI (const_int 32) (match_dup 2)))))
12113    (clobber (reg:CC FLAGS_REG))]
12114   ""
12115   "@
12116    shrd{l}\t{%2, %1, %0|%0, %1, %2}
12117    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12118   [(set_attr "type" "ishift")
12119    (set_attr "prefix_0f" "1")
12120    (set_attr "pent_pair" "np")
12121    (set_attr "mode" "SI")])
12123 (define_expand "x86_shift_adj_3"
12124   [(use (match_operand:SI 0 "register_operand" ""))
12125    (use (match_operand:SI 1 "register_operand" ""))
12126    (use (match_operand:QI 2 "register_operand" ""))]
12127   ""
12129   rtx label = gen_label_rtx ();
12130   rtx tmp;
12132   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12134   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12135   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12136   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12137                               gen_rtx_LABEL_REF (VOIDmode, label),
12138                               pc_rtx);
12139   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12140   JUMP_LABEL (tmp) = label;
12142   emit_move_insn (operands[0], operands[1]);
12143   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12145   emit_label (label);
12146   LABEL_NUSES (label) = 1;
12148   DONE;
12151 (define_insn "ashrsi3_31"
12152   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12153         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12154                      (match_operand:SI 2 "const_int_operand" "i,i")))
12155    (clobber (reg:CC FLAGS_REG))]
12156   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12157    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12158   "@
12159    {cltd|cdq}
12160    sar{l}\t{%2, %0|%0, %2}"
12161   [(set_attr "type" "imovx,ishift")
12162    (set_attr "prefix_0f" "0,*")
12163    (set_attr "length_immediate" "0,*")
12164    (set_attr "modrm" "0,1")
12165    (set_attr "mode" "SI")])
12167 (define_insn "*ashrsi3_31_zext"
12168   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12169         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12170                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12171    (clobber (reg:CC FLAGS_REG))]
12172   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12173    && INTVAL (operands[2]) == 31
12174    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12175   "@
12176    {cltd|cdq}
12177    sar{l}\t{%2, %k0|%k0, %2}"
12178   [(set_attr "type" "imovx,ishift")
12179    (set_attr "prefix_0f" "0,*")
12180    (set_attr "length_immediate" "0,*")
12181    (set_attr "modrm" "0,1")
12182    (set_attr "mode" "SI")])
12184 (define_expand "ashrsi3"
12185   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12186         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12187                      (match_operand:QI 2 "nonmemory_operand" "")))
12188    (clobber (reg:CC FLAGS_REG))]
12189   ""
12190   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12192 (define_insn "*ashrsi3_1_one_bit"
12193   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12194         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12195                      (match_operand:QI 2 "const1_operand" "")))
12196    (clobber (reg:CC FLAGS_REG))]
12197   "(TARGET_SHIFT1 || optimize_size)
12198    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12199   "sar{l}\t%0"
12200   [(set_attr "type" "ishift")
12201    (set (attr "length")
12202      (if_then_else (match_operand:SI 0 "register_operand" "")
12203         (const_string "2")
12204         (const_string "*")))])
12206 (define_insn "*ashrsi3_1_one_bit_zext"
12207   [(set (match_operand:DI 0 "register_operand" "=r")
12208         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12209                                      (match_operand:QI 2 "const1_operand" ""))))
12210    (clobber (reg:CC FLAGS_REG))]
12211   "TARGET_64BIT
12212    && (TARGET_SHIFT1 || optimize_size)
12213    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12214   "sar{l}\t%k0"
12215   [(set_attr "type" "ishift")
12216    (set_attr "length" "2")])
12218 (define_insn "*ashrsi3_1"
12219   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12220         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12221                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12222    (clobber (reg:CC FLAGS_REG))]
12223   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12224   "@
12225    sar{l}\t{%2, %0|%0, %2}
12226    sar{l}\t{%b2, %0|%0, %b2}"
12227   [(set_attr "type" "ishift")
12228    (set_attr "mode" "SI")])
12230 (define_insn "*ashrsi3_1_zext"
12231   [(set (match_operand:DI 0 "register_operand" "=r,r")
12232         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12233                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12234    (clobber (reg:CC FLAGS_REG))]
12235   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12236   "@
12237    sar{l}\t{%2, %k0|%k0, %2}
12238    sar{l}\t{%b2, %k0|%k0, %b2}"
12239   [(set_attr "type" "ishift")
12240    (set_attr "mode" "SI")])
12242 ;; This pattern can't accept a variable shift count, since shifts by
12243 ;; zero don't affect the flags.  We assume that shifts by constant
12244 ;; zero are optimized away.
12245 (define_insn "*ashrsi3_one_bit_cmp"
12246   [(set (reg FLAGS_REG)
12247         (compare
12248           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12249                        (match_operand:QI 2 "const1_operand" ""))
12250           (const_int 0)))
12251    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12252         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12253   "(TARGET_SHIFT1 || optimize_size)
12254    && ix86_match_ccmode (insn, CCGOCmode)
12255    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12256   "sar{l}\t%0"
12257   [(set_attr "type" "ishift")
12258    (set (attr "length")
12259      (if_then_else (match_operand:SI 0 "register_operand" "")
12260         (const_string "2")
12261         (const_string "*")))])
12263 (define_insn "*ashrsi3_one_bit_cconly"
12264   [(set (reg FLAGS_REG)
12265         (compare
12266           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12267                        (match_operand:QI 2 "const1_operand" ""))
12268           (const_int 0)))
12269    (clobber (match_scratch:SI 0 "=r"))]
12270   "(TARGET_SHIFT1 || optimize_size)
12271    && ix86_match_ccmode (insn, CCGOCmode)
12272    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12273   "sar{l}\t%0"
12274   [(set_attr "type" "ishift")
12275    (set_attr "length" "2")])
12277 (define_insn "*ashrsi3_one_bit_cmp_zext"
12278   [(set (reg FLAGS_REG)
12279         (compare
12280           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12281                        (match_operand:QI 2 "const1_operand" ""))
12282           (const_int 0)))
12283    (set (match_operand:DI 0 "register_operand" "=r")
12284         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12285   "TARGET_64BIT
12286    && (TARGET_SHIFT1 || optimize_size)
12287    && ix86_match_ccmode (insn, CCmode)
12288    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12289   "sar{l}\t%k0"
12290   [(set_attr "type" "ishift")
12291    (set_attr "length" "2")])
12293 ;; This pattern can't accept a variable shift count, since shifts by
12294 ;; zero don't affect the flags.  We assume that shifts by constant
12295 ;; zero are optimized away.
12296 (define_insn "*ashrsi3_cmp"
12297   [(set (reg FLAGS_REG)
12298         (compare
12299           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12300                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12301           (const_int 0)))
12302    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12303         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12304   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12305    && ix86_match_ccmode (insn, CCGOCmode)
12306    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12307   "sar{l}\t{%2, %0|%0, %2}"
12308   [(set_attr "type" "ishift")
12309    (set_attr "mode" "SI")])
12311 (define_insn "*ashrsi3_cconly"
12312   [(set (reg FLAGS_REG)
12313         (compare
12314           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12315                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12316           (const_int 0)))
12317    (clobber (match_scratch:SI 0 "=r"))]
12318   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12319    && ix86_match_ccmode (insn, CCGOCmode)
12320    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12321   "sar{l}\t{%2, %0|%0, %2}"
12322   [(set_attr "type" "ishift")
12323    (set_attr "mode" "SI")])
12325 (define_insn "*ashrsi3_cmp_zext"
12326   [(set (reg FLAGS_REG)
12327         (compare
12328           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12329                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12330           (const_int 0)))
12331    (set (match_operand:DI 0 "register_operand" "=r")
12332         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12333   "TARGET_64BIT
12334    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12335    && ix86_match_ccmode (insn, CCGOCmode)
12336    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12337   "sar{l}\t{%2, %k0|%k0, %2}"
12338   [(set_attr "type" "ishift")
12339    (set_attr "mode" "SI")])
12341 (define_expand "ashrhi3"
12342   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12343         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12344                      (match_operand:QI 2 "nonmemory_operand" "")))
12345    (clobber (reg:CC FLAGS_REG))]
12346   "TARGET_HIMODE_MATH"
12347   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12349 (define_insn "*ashrhi3_1_one_bit"
12350   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12351         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12352                      (match_operand:QI 2 "const1_operand" "")))
12353    (clobber (reg:CC FLAGS_REG))]
12354   "(TARGET_SHIFT1 || optimize_size)
12355    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12356   "sar{w}\t%0"
12357   [(set_attr "type" "ishift")
12358    (set (attr "length")
12359      (if_then_else (match_operand 0 "register_operand" "")
12360         (const_string "2")
12361         (const_string "*")))])
12363 (define_insn "*ashrhi3_1"
12364   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12365         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12366                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12367    (clobber (reg:CC FLAGS_REG))]
12368   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12369   "@
12370    sar{w}\t{%2, %0|%0, %2}
12371    sar{w}\t{%b2, %0|%0, %b2}"
12372   [(set_attr "type" "ishift")
12373    (set_attr "mode" "HI")])
12375 ;; This pattern can't accept a variable shift count, since shifts by
12376 ;; zero don't affect the flags.  We assume that shifts by constant
12377 ;; zero are optimized away.
12378 (define_insn "*ashrhi3_one_bit_cmp"
12379   [(set (reg FLAGS_REG)
12380         (compare
12381           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12382                        (match_operand:QI 2 "const1_operand" ""))
12383           (const_int 0)))
12384    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12385         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12386   "(TARGET_SHIFT1 || optimize_size)
12387    && ix86_match_ccmode (insn, CCGOCmode)
12388    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12389   "sar{w}\t%0"
12390   [(set_attr "type" "ishift")
12391    (set (attr "length")
12392      (if_then_else (match_operand 0 "register_operand" "")
12393         (const_string "2")
12394         (const_string "*")))])
12396 (define_insn "*ashrhi3_one_bit_cconly"
12397   [(set (reg FLAGS_REG)
12398         (compare
12399           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12400                        (match_operand:QI 2 "const1_operand" ""))
12401           (const_int 0)))
12402    (clobber (match_scratch:HI 0 "=r"))]
12403   "(TARGET_SHIFT1 || optimize_size)
12404    && ix86_match_ccmode (insn, CCGOCmode)
12405    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12406   "sar{w}\t%0"
12407   [(set_attr "type" "ishift")
12408    (set_attr "length" "2")])
12410 ;; This pattern can't accept a variable shift count, since shifts by
12411 ;; zero don't affect the flags.  We assume that shifts by constant
12412 ;; zero are optimized away.
12413 (define_insn "*ashrhi3_cmp"
12414   [(set (reg FLAGS_REG)
12415         (compare
12416           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12417                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12418           (const_int 0)))
12419    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12420         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12421   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12422    && ix86_match_ccmode (insn, CCGOCmode)
12423    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12424   "sar{w}\t{%2, %0|%0, %2}"
12425   [(set_attr "type" "ishift")
12426    (set_attr "mode" "HI")])
12428 (define_insn "*ashrhi3_cconly"
12429   [(set (reg FLAGS_REG)
12430         (compare
12431           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12432                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12433           (const_int 0)))
12434    (clobber (match_scratch:HI 0 "=r"))]
12435   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12436    && ix86_match_ccmode (insn, CCGOCmode)
12437    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12438   "sar{w}\t{%2, %0|%0, %2}"
12439   [(set_attr "type" "ishift")
12440    (set_attr "mode" "HI")])
12442 (define_expand "ashrqi3"
12443   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12444         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12445                      (match_operand:QI 2 "nonmemory_operand" "")))
12446    (clobber (reg:CC FLAGS_REG))]
12447   "TARGET_QIMODE_MATH"
12448   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12450 (define_insn "*ashrqi3_1_one_bit"
12451   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12452         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12453                      (match_operand:QI 2 "const1_operand" "")))
12454    (clobber (reg:CC FLAGS_REG))]
12455   "(TARGET_SHIFT1 || optimize_size)
12456    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12457   "sar{b}\t%0"
12458   [(set_attr "type" "ishift")
12459    (set (attr "length")
12460      (if_then_else (match_operand 0 "register_operand" "")
12461         (const_string "2")
12462         (const_string "*")))])
12464 (define_insn "*ashrqi3_1_one_bit_slp"
12465   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12466         (ashiftrt:QI (match_dup 0)
12467                      (match_operand:QI 1 "const1_operand" "")))
12468    (clobber (reg:CC FLAGS_REG))]
12469   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12470    && (TARGET_SHIFT1 || optimize_size)
12471    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12472   "sar{b}\t%0"
12473   [(set_attr "type" "ishift1")
12474    (set (attr "length")
12475      (if_then_else (match_operand 0 "register_operand" "")
12476         (const_string "2")
12477         (const_string "*")))])
12479 (define_insn "*ashrqi3_1"
12480   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12481         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12482                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12483    (clobber (reg:CC FLAGS_REG))]
12484   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12485   "@
12486    sar{b}\t{%2, %0|%0, %2}
12487    sar{b}\t{%b2, %0|%0, %b2}"
12488   [(set_attr "type" "ishift")
12489    (set_attr "mode" "QI")])
12491 (define_insn "*ashrqi3_1_slp"
12492   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12493         (ashiftrt:QI (match_dup 0)
12494                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12495    (clobber (reg:CC FLAGS_REG))]
12496   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12497    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12498   "@
12499    sar{b}\t{%1, %0|%0, %1}
12500    sar{b}\t{%b1, %0|%0, %b1}"
12501   [(set_attr "type" "ishift1")
12502    (set_attr "mode" "QI")])
12504 ;; This pattern can't accept a variable shift count, since shifts by
12505 ;; zero don't affect the flags.  We assume that shifts by constant
12506 ;; zero are optimized away.
12507 (define_insn "*ashrqi3_one_bit_cmp"
12508   [(set (reg FLAGS_REG)
12509         (compare
12510           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12511                        (match_operand:QI 2 "const1_operand" "I"))
12512           (const_int 0)))
12513    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12514         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12515   "(TARGET_SHIFT1 || optimize_size)
12516    && ix86_match_ccmode (insn, CCGOCmode)
12517    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12518   "sar{b}\t%0"
12519   [(set_attr "type" "ishift")
12520    (set (attr "length")
12521      (if_then_else (match_operand 0 "register_operand" "")
12522         (const_string "2")
12523         (const_string "*")))])
12525 (define_insn "*ashrqi3_one_bit_cconly"
12526   [(set (reg FLAGS_REG)
12527         (compare
12528           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12529                        (match_operand:QI 2 "const1_operand" "I"))
12530           (const_int 0)))
12531    (clobber (match_scratch:QI 0 "=q"))]
12532   "(TARGET_SHIFT1 || optimize_size)
12533    && ix86_match_ccmode (insn, CCGOCmode)
12534    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12535   "sar{b}\t%0"
12536   [(set_attr "type" "ishift")
12537    (set_attr "length" "2")])
12539 ;; This pattern can't accept a variable shift count, since shifts by
12540 ;; zero don't affect the flags.  We assume that shifts by constant
12541 ;; zero are optimized away.
12542 (define_insn "*ashrqi3_cmp"
12543   [(set (reg FLAGS_REG)
12544         (compare
12545           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12546                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12547           (const_int 0)))
12548    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12549         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12550   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12551    && ix86_match_ccmode (insn, CCGOCmode)
12552    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12553   "sar{b}\t{%2, %0|%0, %2}"
12554   [(set_attr "type" "ishift")
12555    (set_attr "mode" "QI")])
12557 (define_insn "*ashrqi3_cconly"
12558   [(set (reg FLAGS_REG)
12559         (compare
12560           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12561                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12562           (const_int 0)))
12563    (clobber (match_scratch:QI 0 "=q"))]
12564   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12565    && ix86_match_ccmode (insn, CCGOCmode)
12566    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12567   "sar{b}\t{%2, %0|%0, %2}"
12568   [(set_attr "type" "ishift")
12569    (set_attr "mode" "QI")])
12572 ;; Logical shift instructions
12574 ;; See comment above `ashldi3' about how this works.
12576 (define_expand "lshrti3"
12577   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12578                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12579                                 (match_operand:QI 2 "nonmemory_operand" "")))
12580               (clobber (reg:CC FLAGS_REG))])]
12581   "TARGET_64BIT"
12583   if (! immediate_operand (operands[2], QImode))
12584     {
12585       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12586       DONE;
12587     }
12588   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12589   DONE;
12592 (define_insn "lshrti3_1"
12593   [(set (match_operand:TI 0 "register_operand" "=r")
12594         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12595                      (match_operand:QI 2 "register_operand" "c")))
12596    (clobber (match_scratch:DI 3 "=&r"))
12597    (clobber (reg:CC FLAGS_REG))]
12598   "TARGET_64BIT"
12599   "#"
12600   [(set_attr "type" "multi")])
12602 ;; This pattern must be defined before *lshrti3_2 to prevent
12603 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12605 (define_insn "sse2_lshrti3"
12606   [(set (match_operand:TI 0 "register_operand" "=x")
12607         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12608                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12609   "TARGET_SSE2"
12611   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12612   return "psrldq\t{%2, %0|%0, %2}";
12614   [(set_attr "type" "sseishft")
12615    (set_attr "prefix_data16" "1")
12616    (set_attr "mode" "TI")])
12618 (define_insn "*lshrti3_2"
12619   [(set (match_operand:TI 0 "register_operand" "=r")
12620         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12621                      (match_operand:QI 2 "immediate_operand" "O")))
12622    (clobber (reg:CC FLAGS_REG))]
12623   "TARGET_64BIT"
12624   "#"
12625   [(set_attr "type" "multi")])
12627 (define_split
12628   [(set (match_operand:TI 0 "register_operand" "")
12629         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12630                      (match_operand:QI 2 "register_operand" "")))
12631    (clobber (match_scratch:DI 3 ""))
12632    (clobber (reg:CC FLAGS_REG))]
12633   "TARGET_64BIT && reload_completed"
12634   [(const_int 0)]
12635   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12637 (define_split
12638   [(set (match_operand:TI 0 "register_operand" "")
12639         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12640                      (match_operand:QI 2 "immediate_operand" "")))
12641    (clobber (reg:CC FLAGS_REG))]
12642   "TARGET_64BIT && reload_completed"
12643   [(const_int 0)]
12644   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12646 (define_expand "lshrdi3"
12647   [(set (match_operand:DI 0 "shiftdi_operand" "")
12648         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12649                      (match_operand:QI 2 "nonmemory_operand" "")))]
12650   ""
12651   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12653 (define_insn "*lshrdi3_1_one_bit_rex64"
12654   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12655         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12656                      (match_operand:QI 2 "const1_operand" "")))
12657    (clobber (reg:CC FLAGS_REG))]
12658   "TARGET_64BIT
12659    && (TARGET_SHIFT1 || optimize_size)
12660    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12661   "shr{q}\t%0"
12662   [(set_attr "type" "ishift")
12663    (set (attr "length")
12664      (if_then_else (match_operand:DI 0 "register_operand" "")
12665         (const_string "2")
12666         (const_string "*")))])
12668 (define_insn "*lshrdi3_1_rex64"
12669   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12670         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12671                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12672    (clobber (reg:CC FLAGS_REG))]
12673   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12674   "@
12675    shr{q}\t{%2, %0|%0, %2}
12676    shr{q}\t{%b2, %0|%0, %b2}"
12677   [(set_attr "type" "ishift")
12678    (set_attr "mode" "DI")])
12680 ;; This pattern can't accept a variable shift count, since shifts by
12681 ;; zero don't affect the flags.  We assume that shifts by constant
12682 ;; zero are optimized away.
12683 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12684   [(set (reg FLAGS_REG)
12685         (compare
12686           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12687                        (match_operand:QI 2 "const1_operand" ""))
12688           (const_int 0)))
12689    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12690         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12691   "TARGET_64BIT
12692    && (TARGET_SHIFT1 || optimize_size)
12693    && ix86_match_ccmode (insn, CCGOCmode)
12694    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12695   "shr{q}\t%0"
12696   [(set_attr "type" "ishift")
12697    (set (attr "length")
12698      (if_then_else (match_operand:DI 0 "register_operand" "")
12699         (const_string "2")
12700         (const_string "*")))])
12702 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12703   [(set (reg FLAGS_REG)
12704         (compare
12705           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12706                        (match_operand:QI 2 "const1_operand" ""))
12707           (const_int 0)))
12708    (clobber (match_scratch:DI 0 "=r"))]
12709   "TARGET_64BIT
12710    && (TARGET_SHIFT1 || optimize_size)
12711    && ix86_match_ccmode (insn, CCGOCmode)
12712    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12713   "shr{q}\t%0"
12714   [(set_attr "type" "ishift")
12715    (set_attr "length" "2")])
12717 ;; This pattern can't accept a variable shift count, since shifts by
12718 ;; zero don't affect the flags.  We assume that shifts by constant
12719 ;; zero are optimized away.
12720 (define_insn "*lshrdi3_cmp_rex64"
12721   [(set (reg FLAGS_REG)
12722         (compare
12723           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12724                        (match_operand:QI 2 "const_int_operand" "e"))
12725           (const_int 0)))
12726    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12727         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12728   "TARGET_64BIT
12729    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12730    && ix86_match_ccmode (insn, CCGOCmode)
12731    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12732   "shr{q}\t{%2, %0|%0, %2}"
12733   [(set_attr "type" "ishift")
12734    (set_attr "mode" "DI")])
12736 (define_insn "*lshrdi3_cconly_rex64"
12737   [(set (reg FLAGS_REG)
12738         (compare
12739           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12740                        (match_operand:QI 2 "const_int_operand" "e"))
12741           (const_int 0)))
12742    (clobber (match_scratch:DI 0 "=r"))]
12743   "TARGET_64BIT
12744    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12745    && ix86_match_ccmode (insn, CCGOCmode)
12746    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12747   "shr{q}\t{%2, %0|%0, %2}"
12748   [(set_attr "type" "ishift")
12749    (set_attr "mode" "DI")])
12751 (define_insn "*lshrdi3_1"
12752   [(set (match_operand:DI 0 "register_operand" "=r")
12753         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12754                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12755    (clobber (reg:CC FLAGS_REG))]
12756   "!TARGET_64BIT"
12757   "#"
12758   [(set_attr "type" "multi")])
12760 ;; By default we don't ask for a scratch register, because when DImode
12761 ;; values are manipulated, registers are already at a premium.  But if
12762 ;; we have one handy, we won't turn it away.
12763 (define_peephole2
12764   [(match_scratch:SI 3 "r")
12765    (parallel [(set (match_operand:DI 0 "register_operand" "")
12766                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12767                                 (match_operand:QI 2 "nonmemory_operand" "")))
12768               (clobber (reg:CC FLAGS_REG))])
12769    (match_dup 3)]
12770   "!TARGET_64BIT && TARGET_CMOVE"
12771   [(const_int 0)]
12772   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12774 (define_split
12775   [(set (match_operand:DI 0 "register_operand" "")
12776         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12777                      (match_operand:QI 2 "nonmemory_operand" "")))
12778    (clobber (reg:CC FLAGS_REG))]
12779   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12780                      ? epilogue_completed : reload_completed)"
12781   [(const_int 0)]
12782   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12784 (define_expand "lshrsi3"
12785   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12786         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12787                      (match_operand:QI 2 "nonmemory_operand" "")))
12788    (clobber (reg:CC FLAGS_REG))]
12789   ""
12790   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12792 (define_insn "*lshrsi3_1_one_bit"
12793   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12794         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12795                      (match_operand:QI 2 "const1_operand" "")))
12796    (clobber (reg:CC FLAGS_REG))]
12797   "(TARGET_SHIFT1 || optimize_size)
12798    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12799   "shr{l}\t%0"
12800   [(set_attr "type" "ishift")
12801    (set (attr "length")
12802      (if_then_else (match_operand:SI 0 "register_operand" "")
12803         (const_string "2")
12804         (const_string "*")))])
12806 (define_insn "*lshrsi3_1_one_bit_zext"
12807   [(set (match_operand:DI 0 "register_operand" "=r")
12808         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12809                      (match_operand:QI 2 "const1_operand" "")))
12810    (clobber (reg:CC FLAGS_REG))]
12811   "TARGET_64BIT
12812    && (TARGET_SHIFT1 || optimize_size)
12813    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12814   "shr{l}\t%k0"
12815   [(set_attr "type" "ishift")
12816    (set_attr "length" "2")])
12818 (define_insn "*lshrsi3_1"
12819   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12820         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12821                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12822    (clobber (reg:CC FLAGS_REG))]
12823   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12824   "@
12825    shr{l}\t{%2, %0|%0, %2}
12826    shr{l}\t{%b2, %0|%0, %b2}"
12827   [(set_attr "type" "ishift")
12828    (set_attr "mode" "SI")])
12830 (define_insn "*lshrsi3_1_zext"
12831   [(set (match_operand:DI 0 "register_operand" "=r,r")
12832         (zero_extend:DI
12833           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12834                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12835    (clobber (reg:CC FLAGS_REG))]
12836   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12837   "@
12838    shr{l}\t{%2, %k0|%k0, %2}
12839    shr{l}\t{%b2, %k0|%k0, %b2}"
12840   [(set_attr "type" "ishift")
12841    (set_attr "mode" "SI")])
12843 ;; This pattern can't accept a variable shift count, since shifts by
12844 ;; zero don't affect the flags.  We assume that shifts by constant
12845 ;; zero are optimized away.
12846 (define_insn "*lshrsi3_one_bit_cmp"
12847   [(set (reg FLAGS_REG)
12848         (compare
12849           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12850                        (match_operand:QI 2 "const1_operand" ""))
12851           (const_int 0)))
12852    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12853         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12854   "(TARGET_SHIFT1 || optimize_size)
12855    && ix86_match_ccmode (insn, CCGOCmode)
12856    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12857   "shr{l}\t%0"
12858   [(set_attr "type" "ishift")
12859    (set (attr "length")
12860      (if_then_else (match_operand:SI 0 "register_operand" "")
12861         (const_string "2")
12862         (const_string "*")))])
12864 (define_insn "*lshrsi3_one_bit_cconly"
12865   [(set (reg FLAGS_REG)
12866         (compare
12867           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12868                        (match_operand:QI 2 "const1_operand" ""))
12869           (const_int 0)))
12870    (clobber (match_scratch:SI 0 "=r"))]
12871   "(TARGET_SHIFT1 || optimize_size)
12872    && ix86_match_ccmode (insn, CCGOCmode)
12873    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12874   "shr{l}\t%0"
12875   [(set_attr "type" "ishift")
12876    (set_attr "length" "2")])
12878 (define_insn "*lshrsi3_cmp_one_bit_zext"
12879   [(set (reg FLAGS_REG)
12880         (compare
12881           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12882                        (match_operand:QI 2 "const1_operand" ""))
12883           (const_int 0)))
12884    (set (match_operand:DI 0 "register_operand" "=r")
12885         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12886   "TARGET_64BIT
12887    && (TARGET_SHIFT1 || optimize_size)
12888    && ix86_match_ccmode (insn, CCGOCmode)
12889    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12890   "shr{l}\t%k0"
12891   [(set_attr "type" "ishift")
12892    (set_attr "length" "2")])
12894 ;; This pattern can't accept a variable shift count, since shifts by
12895 ;; zero don't affect the flags.  We assume that shifts by constant
12896 ;; zero are optimized away.
12897 (define_insn "*lshrsi3_cmp"
12898   [(set (reg FLAGS_REG)
12899         (compare
12900           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12901                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12902           (const_int 0)))
12903    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12904         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12905   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12906    && ix86_match_ccmode (insn, CCGOCmode)
12907    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12908   "shr{l}\t{%2, %0|%0, %2}"
12909   [(set_attr "type" "ishift")
12910    (set_attr "mode" "SI")])
12912 (define_insn "*lshrsi3_cconly"
12913   [(set (reg FLAGS_REG)
12914       (compare
12915         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12916                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12917         (const_int 0)))
12918    (clobber (match_scratch:SI 0 "=r"))]
12919   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12920    && ix86_match_ccmode (insn, CCGOCmode)
12921    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12922   "shr{l}\t{%2, %0|%0, %2}"
12923   [(set_attr "type" "ishift")
12924    (set_attr "mode" "SI")])
12926 (define_insn "*lshrsi3_cmp_zext"
12927   [(set (reg FLAGS_REG)
12928         (compare
12929           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12930                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12931           (const_int 0)))
12932    (set (match_operand:DI 0 "register_operand" "=r")
12933         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12934   "TARGET_64BIT
12935    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12936    && ix86_match_ccmode (insn, CCGOCmode)
12937    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12938   "shr{l}\t{%2, %k0|%k0, %2}"
12939   [(set_attr "type" "ishift")
12940    (set_attr "mode" "SI")])
12942 (define_expand "lshrhi3"
12943   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12944         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12945                      (match_operand:QI 2 "nonmemory_operand" "")))
12946    (clobber (reg:CC FLAGS_REG))]
12947   "TARGET_HIMODE_MATH"
12948   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12950 (define_insn "*lshrhi3_1_one_bit"
12951   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12952         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12953                      (match_operand:QI 2 "const1_operand" "")))
12954    (clobber (reg:CC FLAGS_REG))]
12955   "(TARGET_SHIFT1 || optimize_size)
12956    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12957   "shr{w}\t%0"
12958   [(set_attr "type" "ishift")
12959    (set (attr "length")
12960      (if_then_else (match_operand 0 "register_operand" "")
12961         (const_string "2")
12962         (const_string "*")))])
12964 (define_insn "*lshrhi3_1"
12965   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12966         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12967                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12968    (clobber (reg:CC FLAGS_REG))]
12969   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12970   "@
12971    shr{w}\t{%2, %0|%0, %2}
12972    shr{w}\t{%b2, %0|%0, %b2}"
12973   [(set_attr "type" "ishift")
12974    (set_attr "mode" "HI")])
12976 ;; This pattern can't accept a variable shift count, since shifts by
12977 ;; zero don't affect the flags.  We assume that shifts by constant
12978 ;; zero are optimized away.
12979 (define_insn "*lshrhi3_one_bit_cmp"
12980   [(set (reg FLAGS_REG)
12981         (compare
12982           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12983                        (match_operand:QI 2 "const1_operand" ""))
12984           (const_int 0)))
12985    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12986         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12987   "(TARGET_SHIFT1 || optimize_size)
12988    && ix86_match_ccmode (insn, CCGOCmode)
12989    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12990   "shr{w}\t%0"
12991   [(set_attr "type" "ishift")
12992    (set (attr "length")
12993      (if_then_else (match_operand:SI 0 "register_operand" "")
12994         (const_string "2")
12995         (const_string "*")))])
12997 (define_insn "*lshrhi3_one_bit_cconly"
12998   [(set (reg FLAGS_REG)
12999         (compare
13000           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13001                        (match_operand:QI 2 "const1_operand" ""))
13002           (const_int 0)))
13003    (clobber (match_scratch:HI 0 "=r"))]
13004   "(TARGET_SHIFT1 || optimize_size)
13005    && ix86_match_ccmode (insn, CCGOCmode)
13006    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13007   "shr{w}\t%0"
13008   [(set_attr "type" "ishift")
13009    (set_attr "length" "2")])
13011 ;; This pattern can't accept a variable shift count, since shifts by
13012 ;; zero don't affect the flags.  We assume that shifts by constant
13013 ;; zero are optimized away.
13014 (define_insn "*lshrhi3_cmp"
13015   [(set (reg FLAGS_REG)
13016         (compare
13017           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13018                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13019           (const_int 0)))
13020    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13021         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13022   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13023    && ix86_match_ccmode (insn, CCGOCmode)
13024    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13025   "shr{w}\t{%2, %0|%0, %2}"
13026   [(set_attr "type" "ishift")
13027    (set_attr "mode" "HI")])
13029 (define_insn "*lshrhi3_cconly"
13030   [(set (reg FLAGS_REG)
13031         (compare
13032           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13033                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13034           (const_int 0)))
13035    (clobber (match_scratch:HI 0 "=r"))]
13036   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13037    && ix86_match_ccmode (insn, CCGOCmode)
13038    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13039   "shr{w}\t{%2, %0|%0, %2}"
13040   [(set_attr "type" "ishift")
13041    (set_attr "mode" "HI")])
13043 (define_expand "lshrqi3"
13044   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13045         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13046                      (match_operand:QI 2 "nonmemory_operand" "")))
13047    (clobber (reg:CC FLAGS_REG))]
13048   "TARGET_QIMODE_MATH"
13049   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13051 (define_insn "*lshrqi3_1_one_bit"
13052   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13053         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13054                      (match_operand:QI 2 "const1_operand" "")))
13055    (clobber (reg:CC FLAGS_REG))]
13056   "(TARGET_SHIFT1 || optimize_size)
13057    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13058   "shr{b}\t%0"
13059   [(set_attr "type" "ishift")
13060    (set (attr "length")
13061      (if_then_else (match_operand 0 "register_operand" "")
13062         (const_string "2")
13063         (const_string "*")))])
13065 (define_insn "*lshrqi3_1_one_bit_slp"
13066   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13067         (lshiftrt:QI (match_dup 0)
13068                      (match_operand:QI 1 "const1_operand" "")))
13069    (clobber (reg:CC FLAGS_REG))]
13070   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13071    && (TARGET_SHIFT1 || optimize_size)"
13072   "shr{b}\t%0"
13073   [(set_attr "type" "ishift1")
13074    (set (attr "length")
13075      (if_then_else (match_operand 0 "register_operand" "")
13076         (const_string "2")
13077         (const_string "*")))])
13079 (define_insn "*lshrqi3_1"
13080   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13081         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13082                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13083    (clobber (reg:CC FLAGS_REG))]
13084   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13085   "@
13086    shr{b}\t{%2, %0|%0, %2}
13087    shr{b}\t{%b2, %0|%0, %b2}"
13088   [(set_attr "type" "ishift")
13089    (set_attr "mode" "QI")])
13091 (define_insn "*lshrqi3_1_slp"
13092   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13093         (lshiftrt:QI (match_dup 0)
13094                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13095    (clobber (reg:CC FLAGS_REG))]
13096   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13097    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13098   "@
13099    shr{b}\t{%1, %0|%0, %1}
13100    shr{b}\t{%b1, %0|%0, %b1}"
13101   [(set_attr "type" "ishift1")
13102    (set_attr "mode" "QI")])
13104 ;; This pattern can't accept a variable shift count, since shifts by
13105 ;; zero don't affect the flags.  We assume that shifts by constant
13106 ;; zero are optimized away.
13107 (define_insn "*lshrqi2_one_bit_cmp"
13108   [(set (reg FLAGS_REG)
13109         (compare
13110           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13111                        (match_operand:QI 2 "const1_operand" ""))
13112           (const_int 0)))
13113    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13114         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13115   "(TARGET_SHIFT1 || optimize_size)
13116    && ix86_match_ccmode (insn, CCGOCmode)
13117    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13118   "shr{b}\t%0"
13119   [(set_attr "type" "ishift")
13120    (set (attr "length")
13121      (if_then_else (match_operand:SI 0 "register_operand" "")
13122         (const_string "2")
13123         (const_string "*")))])
13125 (define_insn "*lshrqi2_one_bit_cconly"
13126   [(set (reg FLAGS_REG)
13127         (compare
13128           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13129                        (match_operand:QI 2 "const1_operand" ""))
13130           (const_int 0)))
13131    (clobber (match_scratch:QI 0 "=q"))]
13132   "(TARGET_SHIFT1 || optimize_size)
13133    && ix86_match_ccmode (insn, CCGOCmode)
13134    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13135   "shr{b}\t%0"
13136   [(set_attr "type" "ishift")
13137    (set_attr "length" "2")])
13139 ;; This pattern can't accept a variable shift count, since shifts by
13140 ;; zero don't affect the flags.  We assume that shifts by constant
13141 ;; zero are optimized away.
13142 (define_insn "*lshrqi2_cmp"
13143   [(set (reg FLAGS_REG)
13144         (compare
13145           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13146                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13147           (const_int 0)))
13148    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13149         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13150   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13151    && ix86_match_ccmode (insn, CCGOCmode)
13152    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13153   "shr{b}\t{%2, %0|%0, %2}"
13154   [(set_attr "type" "ishift")
13155    (set_attr "mode" "QI")])
13157 (define_insn "*lshrqi2_cconly"
13158   [(set (reg FLAGS_REG)
13159         (compare
13160           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13161                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13162           (const_int 0)))
13163    (clobber (match_scratch:QI 0 "=q"))]
13164   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13165    && ix86_match_ccmode (insn, CCGOCmode)
13166    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13167   "shr{b}\t{%2, %0|%0, %2}"
13168   [(set_attr "type" "ishift")
13169    (set_attr "mode" "QI")])
13171 ;; Rotate instructions
13173 (define_expand "rotldi3"
13174   [(set (match_operand:DI 0 "shiftdi_operand" "")
13175         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13176                    (match_operand:QI 2 "nonmemory_operand" "")))
13177    (clobber (reg:CC FLAGS_REG))]
13178  ""
13180   if (TARGET_64BIT)
13181     {
13182       ix86_expand_binary_operator (ROTATE, DImode, operands);
13183       DONE;
13184     }
13185   if (!const_1_to_31_operand (operands[2], VOIDmode))
13186     FAIL;
13187   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13188   DONE;
13191 ;; Implement rotation using two double-precision shift instructions
13192 ;; and a scratch register.
13193 (define_insn_and_split "ix86_rotldi3"
13194  [(set (match_operand:DI 0 "register_operand" "=r")
13195        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13196                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13197   (clobber (reg:CC FLAGS_REG))
13198   (clobber (match_scratch:SI 3 "=&r"))]
13199  "!TARGET_64BIT"
13200  ""
13201  "&& reload_completed"
13202  [(set (match_dup 3) (match_dup 4))
13203   (parallel
13204    [(set (match_dup 4)
13205          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13206                  (lshiftrt:SI (match_dup 5)
13207                               (minus:QI (const_int 32) (match_dup 2)))))
13208     (clobber (reg:CC FLAGS_REG))])
13209   (parallel
13210    [(set (match_dup 5)
13211          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13212                  (lshiftrt:SI (match_dup 3)
13213                               (minus:QI (const_int 32) (match_dup 2)))))
13214     (clobber (reg:CC FLAGS_REG))])]
13215  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13217 (define_insn "*rotlsi3_1_one_bit_rex64"
13218   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13219         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13220                    (match_operand:QI 2 "const1_operand" "")))
13221    (clobber (reg:CC FLAGS_REG))]
13222   "TARGET_64BIT
13223    && (TARGET_SHIFT1 || optimize_size)
13224    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13225   "rol{q}\t%0"
13226   [(set_attr "type" "rotate")
13227    (set (attr "length")
13228      (if_then_else (match_operand:DI 0 "register_operand" "")
13229         (const_string "2")
13230         (const_string "*")))])
13232 (define_insn "*rotldi3_1_rex64"
13233   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13234         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13235                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13236    (clobber (reg:CC FLAGS_REG))]
13237   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13238   "@
13239    rol{q}\t{%2, %0|%0, %2}
13240    rol{q}\t{%b2, %0|%0, %b2}"
13241   [(set_attr "type" "rotate")
13242    (set_attr "mode" "DI")])
13244 (define_expand "rotlsi3"
13245   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13246         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13247                    (match_operand:QI 2 "nonmemory_operand" "")))
13248    (clobber (reg:CC FLAGS_REG))]
13249   ""
13250   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13252 (define_insn "*rotlsi3_1_one_bit"
13253   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13254         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13255                    (match_operand:QI 2 "const1_operand" "")))
13256    (clobber (reg:CC FLAGS_REG))]
13257   "(TARGET_SHIFT1 || optimize_size)
13258    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13259   "rol{l}\t%0"
13260   [(set_attr "type" "rotate")
13261    (set (attr "length")
13262      (if_then_else (match_operand:SI 0 "register_operand" "")
13263         (const_string "2")
13264         (const_string "*")))])
13266 (define_insn "*rotlsi3_1_one_bit_zext"
13267   [(set (match_operand:DI 0 "register_operand" "=r")
13268         (zero_extend:DI
13269           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13270                      (match_operand:QI 2 "const1_operand" ""))))
13271    (clobber (reg:CC FLAGS_REG))]
13272   "TARGET_64BIT
13273    && (TARGET_SHIFT1 || optimize_size)
13274    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13275   "rol{l}\t%k0"
13276   [(set_attr "type" "rotate")
13277    (set_attr "length" "2")])
13279 (define_insn "*rotlsi3_1"
13280   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13281         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13282                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13283    (clobber (reg:CC FLAGS_REG))]
13284   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13285   "@
13286    rol{l}\t{%2, %0|%0, %2}
13287    rol{l}\t{%b2, %0|%0, %b2}"
13288   [(set_attr "type" "rotate")
13289    (set_attr "mode" "SI")])
13291 (define_insn "*rotlsi3_1_zext"
13292   [(set (match_operand:DI 0 "register_operand" "=r,r")
13293         (zero_extend:DI
13294           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13295                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13296    (clobber (reg:CC FLAGS_REG))]
13297   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13298   "@
13299    rol{l}\t{%2, %k0|%k0, %2}
13300    rol{l}\t{%b2, %k0|%k0, %b2}"
13301   [(set_attr "type" "rotate")
13302    (set_attr "mode" "SI")])
13304 (define_expand "rotlhi3"
13305   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13306         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13307                    (match_operand:QI 2 "nonmemory_operand" "")))
13308    (clobber (reg:CC FLAGS_REG))]
13309   "TARGET_HIMODE_MATH"
13310   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13312 (define_insn "*rotlhi3_1_one_bit"
13313   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13314         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13315                    (match_operand:QI 2 "const1_operand" "")))
13316    (clobber (reg:CC FLAGS_REG))]
13317   "(TARGET_SHIFT1 || optimize_size)
13318    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13319   "rol{w}\t%0"
13320   [(set_attr "type" "rotate")
13321    (set (attr "length")
13322      (if_then_else (match_operand 0 "register_operand" "")
13323         (const_string "2")
13324         (const_string "*")))])
13326 (define_insn "*rotlhi3_1"
13327   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13328         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13329                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13330    (clobber (reg:CC FLAGS_REG))]
13331   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13332   "@
13333    rol{w}\t{%2, %0|%0, %2}
13334    rol{w}\t{%b2, %0|%0, %b2}"
13335   [(set_attr "type" "rotate")
13336    (set_attr "mode" "HI")])
13338 (define_split
13339  [(set (match_operand:HI 0 "register_operand" "")
13340        (rotate:HI (match_dup 0) (const_int 8)))
13341   (clobber (reg:CC FLAGS_REG))]
13342  "reload_completed"
13343  [(parallel [(set (strict_low_part (match_dup 0))
13344                   (bswap:HI (match_dup 0)))
13345              (clobber (reg:CC FLAGS_REG))])]
13346  "")
13348 (define_expand "rotlqi3"
13349   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13350         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13351                    (match_operand:QI 2 "nonmemory_operand" "")))
13352    (clobber (reg:CC FLAGS_REG))]
13353   "TARGET_QIMODE_MATH"
13354   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13356 (define_insn "*rotlqi3_1_one_bit_slp"
13357   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13358         (rotate:QI (match_dup 0)
13359                    (match_operand:QI 1 "const1_operand" "")))
13360    (clobber (reg:CC FLAGS_REG))]
13361   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13362    && (TARGET_SHIFT1 || optimize_size)"
13363   "rol{b}\t%0"
13364   [(set_attr "type" "rotate1")
13365    (set (attr "length")
13366      (if_then_else (match_operand 0 "register_operand" "")
13367         (const_string "2")
13368         (const_string "*")))])
13370 (define_insn "*rotlqi3_1_one_bit"
13371   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13372         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13373                    (match_operand:QI 2 "const1_operand" "")))
13374    (clobber (reg:CC FLAGS_REG))]
13375   "(TARGET_SHIFT1 || optimize_size)
13376    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13377   "rol{b}\t%0"
13378   [(set_attr "type" "rotate")
13379    (set (attr "length")
13380      (if_then_else (match_operand 0 "register_operand" "")
13381         (const_string "2")
13382         (const_string "*")))])
13384 (define_insn "*rotlqi3_1_slp"
13385   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13386         (rotate:QI (match_dup 0)
13387                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13388    (clobber (reg:CC FLAGS_REG))]
13389   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13390    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13391   "@
13392    rol{b}\t{%1, %0|%0, %1}
13393    rol{b}\t{%b1, %0|%0, %b1}"
13394   [(set_attr "type" "rotate1")
13395    (set_attr "mode" "QI")])
13397 (define_insn "*rotlqi3_1"
13398   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13399         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13400                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13401    (clobber (reg:CC FLAGS_REG))]
13402   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13403   "@
13404    rol{b}\t{%2, %0|%0, %2}
13405    rol{b}\t{%b2, %0|%0, %b2}"
13406   [(set_attr "type" "rotate")
13407    (set_attr "mode" "QI")])
13409 (define_expand "rotrdi3"
13410   [(set (match_operand:DI 0 "shiftdi_operand" "")
13411         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13412                    (match_operand:QI 2 "nonmemory_operand" "")))
13413    (clobber (reg:CC FLAGS_REG))]
13414  ""
13416   if (TARGET_64BIT)
13417     {
13418       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13419       DONE;
13420     }
13421   if (!const_1_to_31_operand (operands[2], VOIDmode))
13422     FAIL;
13423   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13424   DONE;
13427 ;; Implement rotation using two double-precision shift instructions
13428 ;; and a scratch register.
13429 (define_insn_and_split "ix86_rotrdi3"
13430  [(set (match_operand:DI 0 "register_operand" "=r")
13431        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13432                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13433   (clobber (reg:CC FLAGS_REG))
13434   (clobber (match_scratch:SI 3 "=&r"))]
13435  "!TARGET_64BIT"
13436  ""
13437  "&& reload_completed"
13438  [(set (match_dup 3) (match_dup 4))
13439   (parallel
13440    [(set (match_dup 4)
13441          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13442                  (ashift:SI (match_dup 5)
13443                             (minus:QI (const_int 32) (match_dup 2)))))
13444     (clobber (reg:CC FLAGS_REG))])
13445   (parallel
13446    [(set (match_dup 5)
13447          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13448                  (ashift:SI (match_dup 3)
13449                             (minus:QI (const_int 32) (match_dup 2)))))
13450     (clobber (reg:CC FLAGS_REG))])]
13451  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13453 (define_insn "*rotrdi3_1_one_bit_rex64"
13454   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13455         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13456                      (match_operand:QI 2 "const1_operand" "")))
13457    (clobber (reg:CC FLAGS_REG))]
13458   "TARGET_64BIT
13459    && (TARGET_SHIFT1 || optimize_size)
13460    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13461   "ror{q}\t%0"
13462   [(set_attr "type" "rotate")
13463    (set (attr "length")
13464      (if_then_else (match_operand:DI 0 "register_operand" "")
13465         (const_string "2")
13466         (const_string "*")))])
13468 (define_insn "*rotrdi3_1_rex64"
13469   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13470         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13471                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13472    (clobber (reg:CC FLAGS_REG))]
13473   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13474   "@
13475    ror{q}\t{%2, %0|%0, %2}
13476    ror{q}\t{%b2, %0|%0, %b2}"
13477   [(set_attr "type" "rotate")
13478    (set_attr "mode" "DI")])
13480 (define_expand "rotrsi3"
13481   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13482         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13483                      (match_operand:QI 2 "nonmemory_operand" "")))
13484    (clobber (reg:CC FLAGS_REG))]
13485   ""
13486   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13488 (define_insn "*rotrsi3_1_one_bit"
13489   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13490         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13491                      (match_operand:QI 2 "const1_operand" "")))
13492    (clobber (reg:CC FLAGS_REG))]
13493   "(TARGET_SHIFT1 || optimize_size)
13494    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13495   "ror{l}\t%0"
13496   [(set_attr "type" "rotate")
13497    (set (attr "length")
13498      (if_then_else (match_operand:SI 0 "register_operand" "")
13499         (const_string "2")
13500         (const_string "*")))])
13502 (define_insn "*rotrsi3_1_one_bit_zext"
13503   [(set (match_operand:DI 0 "register_operand" "=r")
13504         (zero_extend:DI
13505           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13506                        (match_operand:QI 2 "const1_operand" ""))))
13507    (clobber (reg:CC FLAGS_REG))]
13508   "TARGET_64BIT
13509    && (TARGET_SHIFT1 || optimize_size)
13510    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13511   "ror{l}\t%k0"
13512   [(set_attr "type" "rotate")
13513    (set (attr "length")
13514      (if_then_else (match_operand:SI 0 "register_operand" "")
13515         (const_string "2")
13516         (const_string "*")))])
13518 (define_insn "*rotrsi3_1"
13519   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13520         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13521                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13522    (clobber (reg:CC FLAGS_REG))]
13523   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13524   "@
13525    ror{l}\t{%2, %0|%0, %2}
13526    ror{l}\t{%b2, %0|%0, %b2}"
13527   [(set_attr "type" "rotate")
13528    (set_attr "mode" "SI")])
13530 (define_insn "*rotrsi3_1_zext"
13531   [(set (match_operand:DI 0 "register_operand" "=r,r")
13532         (zero_extend:DI
13533           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13534                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13535    (clobber (reg:CC FLAGS_REG))]
13536   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13537   "@
13538    ror{l}\t{%2, %k0|%k0, %2}
13539    ror{l}\t{%b2, %k0|%k0, %b2}"
13540   [(set_attr "type" "rotate")
13541    (set_attr "mode" "SI")])
13543 (define_expand "rotrhi3"
13544   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13545         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13546                      (match_operand:QI 2 "nonmemory_operand" "")))
13547    (clobber (reg:CC FLAGS_REG))]
13548   "TARGET_HIMODE_MATH"
13549   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13551 (define_insn "*rotrhi3_one_bit"
13552   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13553         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13554                      (match_operand:QI 2 "const1_operand" "")))
13555    (clobber (reg:CC FLAGS_REG))]
13556   "(TARGET_SHIFT1 || optimize_size)
13557    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13558   "ror{w}\t%0"
13559   [(set_attr "type" "rotate")
13560    (set (attr "length")
13561      (if_then_else (match_operand 0 "register_operand" "")
13562         (const_string "2")
13563         (const_string "*")))])
13565 (define_insn "*rotrhi3_1"
13566   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13567         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13568                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13569    (clobber (reg:CC FLAGS_REG))]
13570   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13571   "@
13572    ror{w}\t{%2, %0|%0, %2}
13573    ror{w}\t{%b2, %0|%0, %b2}"
13574   [(set_attr "type" "rotate")
13575    (set_attr "mode" "HI")])
13577 (define_split
13578  [(set (match_operand:HI 0 "register_operand" "")
13579        (rotatert:HI (match_dup 0) (const_int 8)))
13580   (clobber (reg:CC FLAGS_REG))]
13581  "reload_completed"
13582  [(parallel [(set (strict_low_part (match_dup 0))
13583                   (bswap:HI (match_dup 0)))
13584              (clobber (reg:CC FLAGS_REG))])]
13585  "")
13587 (define_expand "rotrqi3"
13588   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13589         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13590                      (match_operand:QI 2 "nonmemory_operand" "")))
13591    (clobber (reg:CC FLAGS_REG))]
13592   "TARGET_QIMODE_MATH"
13593   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13595 (define_insn "*rotrqi3_1_one_bit"
13596   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13597         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13598                      (match_operand:QI 2 "const1_operand" "")))
13599    (clobber (reg:CC FLAGS_REG))]
13600   "(TARGET_SHIFT1 || optimize_size)
13601    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13602   "ror{b}\t%0"
13603   [(set_attr "type" "rotate")
13604    (set (attr "length")
13605      (if_then_else (match_operand 0 "register_operand" "")
13606         (const_string "2")
13607         (const_string "*")))])
13609 (define_insn "*rotrqi3_1_one_bit_slp"
13610   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13611         (rotatert:QI (match_dup 0)
13612                      (match_operand:QI 1 "const1_operand" "")))
13613    (clobber (reg:CC FLAGS_REG))]
13614   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13615    && (TARGET_SHIFT1 || optimize_size)"
13616   "ror{b}\t%0"
13617   [(set_attr "type" "rotate1")
13618    (set (attr "length")
13619      (if_then_else (match_operand 0 "register_operand" "")
13620         (const_string "2")
13621         (const_string "*")))])
13623 (define_insn "*rotrqi3_1"
13624   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13625         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13626                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13627    (clobber (reg:CC FLAGS_REG))]
13628   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13629   "@
13630    ror{b}\t{%2, %0|%0, %2}
13631    ror{b}\t{%b2, %0|%0, %b2}"
13632   [(set_attr "type" "rotate")
13633    (set_attr "mode" "QI")])
13635 (define_insn "*rotrqi3_1_slp"
13636   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13637         (rotatert:QI (match_dup 0)
13638                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13639    (clobber (reg:CC FLAGS_REG))]
13640   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13641    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13642   "@
13643    ror{b}\t{%1, %0|%0, %1}
13644    ror{b}\t{%b1, %0|%0, %b1}"
13645   [(set_attr "type" "rotate1")
13646    (set_attr "mode" "QI")])
13648 ;; Bit set / bit test instructions
13650 (define_expand "extv"
13651   [(set (match_operand:SI 0 "register_operand" "")
13652         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13653                          (match_operand:SI 2 "const8_operand" "")
13654                          (match_operand:SI 3 "const8_operand" "")))]
13655   ""
13657   /* Handle extractions from %ah et al.  */
13658   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13659     FAIL;
13661   /* From mips.md: extract_bit_field doesn't verify that our source
13662      matches the predicate, so check it again here.  */
13663   if (! ext_register_operand (operands[1], VOIDmode))
13664     FAIL;
13667 (define_expand "extzv"
13668   [(set (match_operand:SI 0 "register_operand" "")
13669         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13670                          (match_operand:SI 2 "const8_operand" "")
13671                          (match_operand:SI 3 "const8_operand" "")))]
13672   ""
13674   /* Handle extractions from %ah et al.  */
13675   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13676     FAIL;
13678   /* From mips.md: extract_bit_field doesn't verify that our source
13679      matches the predicate, so check it again here.  */
13680   if (! ext_register_operand (operands[1], VOIDmode))
13681     FAIL;
13684 (define_expand "insv"
13685   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13686                       (match_operand 1 "const8_operand" "")
13687                       (match_operand 2 "const8_operand" ""))
13688         (match_operand 3 "register_operand" ""))]
13689   ""
13691   /* Handle insertions to %ah et al.  */
13692   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13693     FAIL;
13695   /* From mips.md: insert_bit_field doesn't verify that our source
13696      matches the predicate, so check it again here.  */
13697   if (! ext_register_operand (operands[0], VOIDmode))
13698     FAIL;
13700   if (TARGET_64BIT)
13701     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13702   else
13703     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13705   DONE;
13708 ;; %%% bts, btr, btc, bt.
13709 ;; In general these instructions are *slow* when applied to memory,
13710 ;; since they enforce atomic operation.  When applied to registers,
13711 ;; it depends on the cpu implementation.  They're never faster than
13712 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13713 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13714 ;; within the instruction itself, so operating on bits in the high
13715 ;; 32-bits of a register becomes easier.
13717 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13718 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13719 ;; negdf respectively, so they can never be disabled entirely.
13721 (define_insn "*btsq"
13722   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13723                          (const_int 1)
13724                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13725         (const_int 1))
13726    (clobber (reg:CC FLAGS_REG))]
13727   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13728   "bts{q} %1,%0"
13729   [(set_attr "type" "alu1")])
13731 (define_insn "*btrq"
13732   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13733                          (const_int 1)
13734                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13735         (const_int 0))
13736    (clobber (reg:CC FLAGS_REG))]
13737   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13738   "btr{q} %1,%0"
13739   [(set_attr "type" "alu1")])
13741 (define_insn "*btcq"
13742   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13743                          (const_int 1)
13744                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13745         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13746    (clobber (reg:CC FLAGS_REG))]
13747   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13748   "btc{q} %1,%0"
13749   [(set_attr "type" "alu1")])
13751 ;; Allow Nocona to avoid these instructions if a register is available.
13753 (define_peephole2
13754   [(match_scratch:DI 2 "r")
13755    (parallel [(set (zero_extract:DI
13756                      (match_operand:DI 0 "register_operand" "")
13757                      (const_int 1)
13758                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13759                    (const_int 1))
13760               (clobber (reg:CC FLAGS_REG))])]
13761   "TARGET_64BIT && !TARGET_USE_BT"
13762   [(const_int 0)]
13764   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13765   rtx op1;
13767   if (HOST_BITS_PER_WIDE_INT >= 64)
13768     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13769   else if (i < HOST_BITS_PER_WIDE_INT)
13770     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13771   else
13772     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13774   op1 = immed_double_const (lo, hi, DImode);
13775   if (i >= 31)
13776     {
13777       emit_move_insn (operands[2], op1);
13778       op1 = operands[2];
13779     }
13781   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13782   DONE;
13785 (define_peephole2
13786   [(match_scratch:DI 2 "r")
13787    (parallel [(set (zero_extract:DI
13788                      (match_operand:DI 0 "register_operand" "")
13789                      (const_int 1)
13790                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13791                    (const_int 0))
13792               (clobber (reg:CC FLAGS_REG))])]
13793   "TARGET_64BIT && !TARGET_USE_BT"
13794   [(const_int 0)]
13796   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13797   rtx op1;
13799   if (HOST_BITS_PER_WIDE_INT >= 64)
13800     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13801   else if (i < HOST_BITS_PER_WIDE_INT)
13802     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13803   else
13804     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13806   op1 = immed_double_const (~lo, ~hi, DImode);
13807   if (i >= 32)
13808     {
13809       emit_move_insn (operands[2], op1);
13810       op1 = operands[2];
13811     }
13813   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13814   DONE;
13817 (define_peephole2
13818   [(match_scratch:DI 2 "r")
13819    (parallel [(set (zero_extract:DI
13820                      (match_operand:DI 0 "register_operand" "")
13821                      (const_int 1)
13822                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13823               (not:DI (zero_extract:DI
13824                         (match_dup 0) (const_int 1) (match_dup 1))))
13825               (clobber (reg:CC FLAGS_REG))])]
13826   "TARGET_64BIT && !TARGET_USE_BT"
13827   [(const_int 0)]
13829   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13830   rtx op1;
13832   if (HOST_BITS_PER_WIDE_INT >= 64)
13833     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13834   else if (i < HOST_BITS_PER_WIDE_INT)
13835     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13836   else
13837     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13839   op1 = immed_double_const (lo, hi, DImode);
13840   if (i >= 31)
13841     {
13842       emit_move_insn (operands[2], op1);
13843       op1 = operands[2];
13844     }
13846   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13847   DONE;
13850 ;; Store-flag instructions.
13852 ;; For all sCOND expanders, also expand the compare or test insn that
13853 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13855 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13856 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13857 ;; way, which can later delete the movzx if only QImode is needed.
13859 (define_expand "s<code>"
13860   [(set (match_operand:QI 0 "register_operand" "")
13861         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13862   ""
13863   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13865 (define_expand "s<code>"
13866   [(set (match_operand:QI 0 "register_operand" "")
13867         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13868   "TARGET_80387 || TARGET_SSE"
13869   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13871 (define_insn "*setcc_1"
13872   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13873         (match_operator:QI 1 "ix86_comparison_operator"
13874           [(reg FLAGS_REG) (const_int 0)]))]
13875   ""
13876   "set%C1\t%0"
13877   [(set_attr "type" "setcc")
13878    (set_attr "mode" "QI")])
13880 (define_insn "*setcc_2"
13881   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13882         (match_operator:QI 1 "ix86_comparison_operator"
13883           [(reg FLAGS_REG) (const_int 0)]))]
13884   ""
13885   "set%C1\t%0"
13886   [(set_attr "type" "setcc")
13887    (set_attr "mode" "QI")])
13889 ;; In general it is not safe to assume too much about CCmode registers,
13890 ;; so simplify-rtx stops when it sees a second one.  Under certain
13891 ;; conditions this is safe on x86, so help combine not create
13893 ;;      seta    %al
13894 ;;      testb   %al, %al
13895 ;;      sete    %al
13897 (define_split
13898   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13899         (ne:QI (match_operator 1 "ix86_comparison_operator"
13900                  [(reg FLAGS_REG) (const_int 0)])
13901             (const_int 0)))]
13902   ""
13903   [(set (match_dup 0) (match_dup 1))]
13905   PUT_MODE (operands[1], QImode);
13908 (define_split
13909   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13910         (ne:QI (match_operator 1 "ix86_comparison_operator"
13911                  [(reg FLAGS_REG) (const_int 0)])
13912             (const_int 0)))]
13913   ""
13914   [(set (match_dup 0) (match_dup 1))]
13916   PUT_MODE (operands[1], QImode);
13919 (define_split
13920   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13921         (eq:QI (match_operator 1 "ix86_comparison_operator"
13922                  [(reg FLAGS_REG) (const_int 0)])
13923             (const_int 0)))]
13924   ""
13925   [(set (match_dup 0) (match_dup 1))]
13927   rtx new_op1 = copy_rtx (operands[1]);
13928   operands[1] = new_op1;
13929   PUT_MODE (new_op1, QImode);
13930   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13931                                              GET_MODE (XEXP (new_op1, 0))));
13933   /* Make sure that (a) the CCmode we have for the flags is strong
13934      enough for the reversed compare or (b) we have a valid FP compare.  */
13935   if (! ix86_comparison_operator (new_op1, VOIDmode))
13936     FAIL;
13939 (define_split
13940   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13941         (eq:QI (match_operator 1 "ix86_comparison_operator"
13942                  [(reg FLAGS_REG) (const_int 0)])
13943             (const_int 0)))]
13944   ""
13945   [(set (match_dup 0) (match_dup 1))]
13947   rtx new_op1 = copy_rtx (operands[1]);
13948   operands[1] = new_op1;
13949   PUT_MODE (new_op1, QImode);
13950   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13951                                              GET_MODE (XEXP (new_op1, 0))));
13953   /* Make sure that (a) the CCmode we have for the flags is strong
13954      enough for the reversed compare or (b) we have a valid FP compare.  */
13955   if (! ix86_comparison_operator (new_op1, VOIDmode))
13956     FAIL;
13959 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13960 ;; subsequent logical operations are used to imitate conditional moves.
13961 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13962 ;; it directly.
13964 (define_insn "*sse_setcc<mode>"
13965   [(set (match_operand:MODEF 0 "register_operand" "=x")
13966         (match_operator:MODEF 1 "sse_comparison_operator"
13967           [(match_operand:MODEF 2 "register_operand" "0")
13968            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13969   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13970   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13971   [(set_attr "type" "ssecmp")
13972    (set_attr "mode" "<MODE>")])
13974 (define_insn "*sse5_setcc<mode>"
13975   [(set (match_operand:MODEF 0 "register_operand" "=x")
13976         (match_operator:MODEF 1 "sse5_comparison_float_operator"
13977           [(match_operand:MODEF 2 "register_operand" "x")
13978            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13979   "TARGET_SSE5"
13980   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13981   [(set_attr "type" "sse4arg")
13982    (set_attr "mode" "<MODE>")])
13985 ;; Basic conditional jump instructions.
13986 ;; We ignore the overflow flag for signed branch instructions.
13988 ;; For all bCOND expanders, also expand the compare or test insn that
13989 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13991 (define_expand "b<code>"
13992   [(set (pc)
13993         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13994                                    (const_int 0))
13995                       (label_ref (match_operand 0 ""))
13996                       (pc)))]
13997   ""
13998   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14000 (define_expand "b<code>"
14001   [(set (pc)
14002         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
14003                                   (const_int 0))
14004                       (label_ref (match_operand 0 ""))
14005                       (pc)))]
14006   "TARGET_80387 || TARGET_SSE_MATH"
14007   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
14009 (define_insn "*jcc_1"
14010   [(set (pc)
14011         (if_then_else (match_operator 1 "ix86_comparison_operator"
14012                                       [(reg FLAGS_REG) (const_int 0)])
14013                       (label_ref (match_operand 0 "" ""))
14014                       (pc)))]
14015   ""
14016   "%+j%C1\t%l0"
14017   [(set_attr "type" "ibr")
14018    (set_attr "modrm" "0")
14019    (set (attr "length")
14020            (if_then_else (and (ge (minus (match_dup 0) (pc))
14021                                   (const_int -126))
14022                               (lt (minus (match_dup 0) (pc))
14023                                   (const_int 128)))
14024              (const_int 2)
14025              (const_int 6)))])
14027 (define_insn "*jcc_2"
14028   [(set (pc)
14029         (if_then_else (match_operator 1 "ix86_comparison_operator"
14030                                       [(reg FLAGS_REG) (const_int 0)])
14031                       (pc)
14032                       (label_ref (match_operand 0 "" ""))))]
14033   ""
14034   "%+j%c1\t%l0"
14035   [(set_attr "type" "ibr")
14036    (set_attr "modrm" "0")
14037    (set (attr "length")
14038            (if_then_else (and (ge (minus (match_dup 0) (pc))
14039                                   (const_int -126))
14040                               (lt (minus (match_dup 0) (pc))
14041                                   (const_int 128)))
14042              (const_int 2)
14043              (const_int 6)))])
14045 ;; In general it is not safe to assume too much about CCmode registers,
14046 ;; so simplify-rtx stops when it sees a second one.  Under certain
14047 ;; conditions this is safe on x86, so help combine not create
14049 ;;      seta    %al
14050 ;;      testb   %al, %al
14051 ;;      je      Lfoo
14053 (define_split
14054   [(set (pc)
14055         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14056                                       [(reg FLAGS_REG) (const_int 0)])
14057                           (const_int 0))
14058                       (label_ref (match_operand 1 "" ""))
14059                       (pc)))]
14060   ""
14061   [(set (pc)
14062         (if_then_else (match_dup 0)
14063                       (label_ref (match_dup 1))
14064                       (pc)))]
14066   PUT_MODE (operands[0], VOIDmode);
14069 (define_split
14070   [(set (pc)
14071         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14072                                       [(reg FLAGS_REG) (const_int 0)])
14073                           (const_int 0))
14074                       (label_ref (match_operand 1 "" ""))
14075                       (pc)))]
14076   ""
14077   [(set (pc)
14078         (if_then_else (match_dup 0)
14079                       (label_ref (match_dup 1))
14080                       (pc)))]
14082   rtx new_op0 = copy_rtx (operands[0]);
14083   operands[0] = new_op0;
14084   PUT_MODE (new_op0, VOIDmode);
14085   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14086                                              GET_MODE (XEXP (new_op0, 0))));
14088   /* Make sure that (a) the CCmode we have for the flags is strong
14089      enough for the reversed compare or (b) we have a valid FP compare.  */
14090   if (! ix86_comparison_operator (new_op0, VOIDmode))
14091     FAIL;
14094 ;; Define combination compare-and-branch fp compare instructions to use
14095 ;; during early optimization.  Splitting the operation apart early makes
14096 ;; for bad code when we want to reverse the operation.
14098 (define_insn "*fp_jcc_1_mixed"
14099   [(set (pc)
14100         (if_then_else (match_operator 0 "comparison_operator"
14101                         [(match_operand 1 "register_operand" "f,x")
14102                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14103           (label_ref (match_operand 3 "" ""))
14104           (pc)))
14105    (clobber (reg:CCFP FPSR_REG))
14106    (clobber (reg:CCFP FLAGS_REG))]
14107   "TARGET_MIX_SSE_I387
14108    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14109    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14110    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14111   "#")
14113 (define_insn "*fp_jcc_1_sse"
14114   [(set (pc)
14115         (if_then_else (match_operator 0 "comparison_operator"
14116                         [(match_operand 1 "register_operand" "x")
14117                          (match_operand 2 "nonimmediate_operand" "xm")])
14118           (label_ref (match_operand 3 "" ""))
14119           (pc)))
14120    (clobber (reg:CCFP FPSR_REG))
14121    (clobber (reg:CCFP FLAGS_REG))]
14122   "TARGET_SSE_MATH
14123    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14124    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14125    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14126   "#")
14128 (define_insn "*fp_jcc_1_387"
14129   [(set (pc)
14130         (if_then_else (match_operator 0 "comparison_operator"
14131                         [(match_operand 1 "register_operand" "f")
14132                          (match_operand 2 "register_operand" "f")])
14133           (label_ref (match_operand 3 "" ""))
14134           (pc)))
14135    (clobber (reg:CCFP FPSR_REG))
14136    (clobber (reg:CCFP FLAGS_REG))]
14137   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14138    && TARGET_CMOVE
14139    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14140    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14141   "#")
14143 (define_insn "*fp_jcc_2_mixed"
14144   [(set (pc)
14145         (if_then_else (match_operator 0 "comparison_operator"
14146                         [(match_operand 1 "register_operand" "f,x")
14147                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14148           (pc)
14149           (label_ref (match_operand 3 "" ""))))
14150    (clobber (reg:CCFP FPSR_REG))
14151    (clobber (reg:CCFP FLAGS_REG))]
14152   "TARGET_MIX_SSE_I387
14153    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14154    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14155    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14156   "#")
14158 (define_insn "*fp_jcc_2_sse"
14159   [(set (pc)
14160         (if_then_else (match_operator 0 "comparison_operator"
14161                         [(match_operand 1 "register_operand" "x")
14162                          (match_operand 2 "nonimmediate_operand" "xm")])
14163           (pc)
14164           (label_ref (match_operand 3 "" ""))))
14165    (clobber (reg:CCFP FPSR_REG))
14166    (clobber (reg:CCFP FLAGS_REG))]
14167   "TARGET_SSE_MATH
14168    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14169    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14170    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14171   "#")
14173 (define_insn "*fp_jcc_2_387"
14174   [(set (pc)
14175         (if_then_else (match_operator 0 "comparison_operator"
14176                         [(match_operand 1 "register_operand" "f")
14177                          (match_operand 2 "register_operand" "f")])
14178           (pc)
14179           (label_ref (match_operand 3 "" ""))))
14180    (clobber (reg:CCFP FPSR_REG))
14181    (clobber (reg:CCFP FLAGS_REG))]
14182   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14183    && TARGET_CMOVE
14184    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14185    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14186   "#")
14188 (define_insn "*fp_jcc_3_387"
14189   [(set (pc)
14190         (if_then_else (match_operator 0 "comparison_operator"
14191                         [(match_operand 1 "register_operand" "f")
14192                          (match_operand 2 "nonimmediate_operand" "fm")])
14193           (label_ref (match_operand 3 "" ""))
14194           (pc)))
14195    (clobber (reg:CCFP FPSR_REG))
14196    (clobber (reg:CCFP FLAGS_REG))
14197    (clobber (match_scratch:HI 4 "=a"))]
14198   "TARGET_80387
14199    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14200    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14201    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14202    && SELECT_CC_MODE (GET_CODE (operands[0]),
14203                       operands[1], operands[2]) == CCFPmode
14204    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14205   "#")
14207 (define_insn "*fp_jcc_4_387"
14208   [(set (pc)
14209         (if_then_else (match_operator 0 "comparison_operator"
14210                         [(match_operand 1 "register_operand" "f")
14211                          (match_operand 2 "nonimmediate_operand" "fm")])
14212           (pc)
14213           (label_ref (match_operand 3 "" ""))))
14214    (clobber (reg:CCFP FPSR_REG))
14215    (clobber (reg:CCFP FLAGS_REG))
14216    (clobber (match_scratch:HI 4 "=a"))]
14217   "TARGET_80387
14218    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14219    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14220    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14221    && SELECT_CC_MODE (GET_CODE (operands[0]),
14222                       operands[1], operands[2]) == CCFPmode
14223    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14224   "#")
14226 (define_insn "*fp_jcc_5_387"
14227   [(set (pc)
14228         (if_then_else (match_operator 0 "comparison_operator"
14229                         [(match_operand 1 "register_operand" "f")
14230                          (match_operand 2 "register_operand" "f")])
14231           (label_ref (match_operand 3 "" ""))
14232           (pc)))
14233    (clobber (reg:CCFP FPSR_REG))
14234    (clobber (reg:CCFP FLAGS_REG))
14235    (clobber (match_scratch:HI 4 "=a"))]
14236   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14237    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14238    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14239   "#")
14241 (define_insn "*fp_jcc_6_387"
14242   [(set (pc)
14243         (if_then_else (match_operator 0 "comparison_operator"
14244                         [(match_operand 1 "register_operand" "f")
14245                          (match_operand 2 "register_operand" "f")])
14246           (pc)
14247           (label_ref (match_operand 3 "" ""))))
14248    (clobber (reg:CCFP FPSR_REG))
14249    (clobber (reg:CCFP FLAGS_REG))
14250    (clobber (match_scratch:HI 4 "=a"))]
14251   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14252    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14253    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14254   "#")
14256 (define_insn "*fp_jcc_7_387"
14257   [(set (pc)
14258         (if_then_else (match_operator 0 "comparison_operator"
14259                         [(match_operand 1 "register_operand" "f")
14260                          (match_operand 2 "const0_operand" "X")])
14261           (label_ref (match_operand 3 "" ""))
14262           (pc)))
14263    (clobber (reg:CCFP FPSR_REG))
14264    (clobber (reg:CCFP FLAGS_REG))
14265    (clobber (match_scratch:HI 4 "=a"))]
14266   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14267    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14268    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14269    && SELECT_CC_MODE (GET_CODE (operands[0]),
14270                       operands[1], operands[2]) == CCFPmode
14271    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14272   "#")
14274 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14275 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14276 ;; with a precedence over other operators and is always put in the first
14277 ;; place. Swap condition and operands to match ficom instruction.
14279 (define_insn "*fp_jcc_8<mode>_387"
14280   [(set (pc)
14281         (if_then_else (match_operator 0 "comparison_operator"
14282                         [(match_operator 1 "float_operator"
14283                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14284                            (match_operand 3 "register_operand" "f,f")])
14285           (label_ref (match_operand 4 "" ""))
14286           (pc)))
14287    (clobber (reg:CCFP FPSR_REG))
14288    (clobber (reg:CCFP FLAGS_REG))
14289    (clobber (match_scratch:HI 5 "=a,a"))]
14290   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14291    && TARGET_USE_<MODE>MODE_FIOP
14292    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14293    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14294    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14295    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14296   "#")
14298 (define_split
14299   [(set (pc)
14300         (if_then_else (match_operator 0 "comparison_operator"
14301                         [(match_operand 1 "register_operand" "")
14302                          (match_operand 2 "nonimmediate_operand" "")])
14303           (match_operand 3 "" "")
14304           (match_operand 4 "" "")))
14305    (clobber (reg:CCFP FPSR_REG))
14306    (clobber (reg:CCFP FLAGS_REG))]
14307   "reload_completed"
14308   [(const_int 0)]
14310   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14311                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14312   DONE;
14315 (define_split
14316   [(set (pc)
14317         (if_then_else (match_operator 0 "comparison_operator"
14318                         [(match_operand 1 "register_operand" "")
14319                          (match_operand 2 "general_operand" "")])
14320           (match_operand 3 "" "")
14321           (match_operand 4 "" "")))
14322    (clobber (reg:CCFP FPSR_REG))
14323    (clobber (reg:CCFP FLAGS_REG))
14324    (clobber (match_scratch:HI 5 "=a"))]
14325   "reload_completed"
14326   [(const_int 0)]
14328   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14329                         operands[3], operands[4], operands[5], NULL_RTX);
14330   DONE;
14333 (define_split
14334   [(set (pc)
14335         (if_then_else (match_operator 0 "comparison_operator"
14336                         [(match_operator 1 "float_operator"
14337                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14338                            (match_operand 3 "register_operand" "")])
14339           (match_operand 4 "" "")
14340           (match_operand 5 "" "")))
14341    (clobber (reg:CCFP FPSR_REG))
14342    (clobber (reg:CCFP FLAGS_REG))
14343    (clobber (match_scratch:HI 6 "=a"))]
14344   "reload_completed"
14345   [(const_int 0)]
14347   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14348   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14349                         operands[3], operands[7],
14350                         operands[4], operands[5], operands[6], NULL_RTX);
14351   DONE;
14354 ;; %%% Kill this when reload knows how to do it.
14355 (define_split
14356   [(set (pc)
14357         (if_then_else (match_operator 0 "comparison_operator"
14358                         [(match_operator 1 "float_operator"
14359                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14360                            (match_operand 3 "register_operand" "")])
14361           (match_operand 4 "" "")
14362           (match_operand 5 "" "")))
14363    (clobber (reg:CCFP FPSR_REG))
14364    (clobber (reg:CCFP FLAGS_REG))
14365    (clobber (match_scratch:HI 6 "=a"))]
14366   "reload_completed"
14367   [(const_int 0)]
14369   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14370   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14371   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14372                         operands[3], operands[7],
14373                         operands[4], operands[5], operands[6], operands[2]);
14374   DONE;
14377 ;; Unconditional and other jump instructions
14379 (define_insn "jump"
14380   [(set (pc)
14381         (label_ref (match_operand 0 "" "")))]
14382   ""
14383   "jmp\t%l0"
14384   [(set_attr "type" "ibr")
14385    (set (attr "length")
14386            (if_then_else (and (ge (minus (match_dup 0) (pc))
14387                                   (const_int -126))
14388                               (lt (minus (match_dup 0) (pc))
14389                                   (const_int 128)))
14390              (const_int 2)
14391              (const_int 5)))
14392    (set_attr "modrm" "0")])
14394 (define_expand "indirect_jump"
14395   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14396   ""
14397   "")
14399 (define_insn "*indirect_jump"
14400   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))]
14401   "!TARGET_64BIT"
14402   "jmp\t%A0"
14403   [(set_attr "type" "ibr")
14404    (set_attr "length_immediate" "0")])
14406 (define_insn "*indirect_jump_rtx64"
14407   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))]
14408   "TARGET_64BIT"
14409   "jmp\t%A0"
14410   [(set_attr "type" "ibr")
14411    (set_attr "length_immediate" "0")])
14413 (define_expand "tablejump"
14414   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14415               (use (label_ref (match_operand 1 "" "")))])]
14416   ""
14418   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14419      relative.  Convert the relative address to an absolute address.  */
14420   if (flag_pic)
14421     {
14422       rtx op0, op1;
14423       enum rtx_code code;
14425       /* We can't use @GOTOFF for text labels on VxWorks;
14426          see gotoff_operand.  */
14427       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14428         {
14429           code = PLUS;
14430           op0 = operands[0];
14431           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14432         }
14433       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14434         {
14435           code = PLUS;
14436           op0 = operands[0];
14437           op1 = pic_offset_table_rtx;
14438         }
14439       else
14440         {
14441           code = MINUS;
14442           op0 = pic_offset_table_rtx;
14443           op1 = operands[0];
14444         }
14446       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14447                                          OPTAB_DIRECT);
14448     }
14451 (define_insn "*tablejump_1"
14452   [(set (pc) (match_operand:SI 0 "nonimmediate_operand" "rm"))
14453    (use (label_ref (match_operand 1 "" "")))]
14454   "!TARGET_64BIT"
14455   "jmp\t%A0"
14456   [(set_attr "type" "ibr")
14457    (set_attr "length_immediate" "0")])
14459 (define_insn "*tablejump_1_rtx64"
14460   [(set (pc) (match_operand:DI 0 "nonimmediate_operand" "rm"))
14461    (use (label_ref (match_operand 1 "" "")))]
14462   "TARGET_64BIT"
14463   "jmp\t%A0"
14464   [(set_attr "type" "ibr")
14465    (set_attr "length_immediate" "0")])
14467 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14469 (define_peephole2
14470   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14471    (set (match_operand:QI 1 "register_operand" "")
14472         (match_operator:QI 2 "ix86_comparison_operator"
14473           [(reg FLAGS_REG) (const_int 0)]))
14474    (set (match_operand 3 "q_regs_operand" "")
14475         (zero_extend (match_dup 1)))]
14476   "(peep2_reg_dead_p (3, operands[1])
14477     || operands_match_p (operands[1], operands[3]))
14478    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14479   [(set (match_dup 4) (match_dup 0))
14480    (set (strict_low_part (match_dup 5))
14481         (match_dup 2))]
14483   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14484   operands[5] = gen_lowpart (QImode, operands[3]);
14485   ix86_expand_clear (operands[3]);
14488 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14490 (define_peephole2
14491   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14492    (set (match_operand:QI 1 "register_operand" "")
14493         (match_operator:QI 2 "ix86_comparison_operator"
14494           [(reg FLAGS_REG) (const_int 0)]))
14495    (parallel [(set (match_operand 3 "q_regs_operand" "")
14496                    (zero_extend (match_dup 1)))
14497               (clobber (reg:CC FLAGS_REG))])]
14498   "(peep2_reg_dead_p (3, operands[1])
14499     || operands_match_p (operands[1], operands[3]))
14500    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14501   [(set (match_dup 4) (match_dup 0))
14502    (set (strict_low_part (match_dup 5))
14503         (match_dup 2))]
14505   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14506   operands[5] = gen_lowpart (QImode, operands[3]);
14507   ix86_expand_clear (operands[3]);
14510 ;; Call instructions.
14512 ;; The predicates normally associated with named expanders are not properly
14513 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14514 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14516 ;; Call subroutine returning no value.
14518 (define_expand "call_pop"
14519   [(parallel [(call (match_operand:QI 0 "" "")
14520                     (match_operand:SI 1 "" ""))
14521               (set (reg:SI SP_REG)
14522                    (plus:SI (reg:SI SP_REG)
14523                             (match_operand:SI 3 "" "")))])]
14524   "!TARGET_64BIT"
14526   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14527   DONE;
14530 (define_insn "*call_pop_0"
14531   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14532          (match_operand:SI 1 "" ""))
14533    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14534                             (match_operand:SI 2 "immediate_operand" "")))]
14535   "!TARGET_64BIT"
14537   if (SIBLING_CALL_P (insn))
14538     return "jmp\t%P0";
14539   else
14540     return "call\t%P0";
14542   [(set_attr "type" "call")])
14544 (define_insn "*call_pop_1"
14545   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14546          (match_operand:SI 1 "" ""))
14547    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14548                             (match_operand:SI 2 "immediate_operand" "i")))]
14549   "!TARGET_64BIT"
14551   if (constant_call_address_operand (operands[0], Pmode))
14552     {
14553       if (SIBLING_CALL_P (insn))
14554         return "jmp\t%P0";
14555       else
14556         return "call\t%P0";
14557     }
14558   if (SIBLING_CALL_P (insn))
14559     return "jmp\t%A0";
14560   else
14561     return "call\t%A0";
14563   [(set_attr "type" "call")])
14565 (define_expand "call"
14566   [(call (match_operand:QI 0 "" "")
14567          (match_operand 1 "" ""))
14568    (use (match_operand 2 "" ""))]
14569   ""
14571   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14572   DONE;
14575 (define_expand "sibcall"
14576   [(call (match_operand:QI 0 "" "")
14577          (match_operand 1 "" ""))
14578    (use (match_operand 2 "" ""))]
14579   ""
14581   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14582   DONE;
14585 (define_insn "*call_0"
14586   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14587          (match_operand 1 "" ""))]
14588   ""
14590   if (SIBLING_CALL_P (insn))
14591     return "jmp\t%P0";
14592   else
14593     return "call\t%P0";
14595   [(set_attr "type" "call")])
14597 (define_insn "*call_1"
14598   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14599          (match_operand 1 "" ""))]
14600   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14602   if (constant_call_address_operand (operands[0], Pmode))
14603     return "call\t%P0";
14604   return "call\t%A0";
14606   [(set_attr "type" "call")])
14608 (define_insn "*sibcall_1"
14609   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14610          (match_operand 1 "" ""))]
14611   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14613   if (constant_call_address_operand (operands[0], Pmode))
14614     return "jmp\t%P0";
14615   return "jmp\t%A0";
14617   [(set_attr "type" "call")])
14619 (define_insn "*call_1_rex64"
14620   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14621          (match_operand 1 "" ""))]
14622   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14623    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14625   if (constant_call_address_operand (operands[0], Pmode))
14626     return "call\t%P0";
14627   return "call\t%A0";
14629   [(set_attr "type" "call")])
14631 (define_insn "*call_1_rex64_large"
14632   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14633          (match_operand 1 "" ""))]
14634   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14635   "call\t%A0"
14636   [(set_attr "type" "call")])
14638 (define_insn "*sibcall_1_rex64"
14639   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14640          (match_operand 1 "" ""))]
14641   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14642   "jmp\t%P0"
14643   [(set_attr "type" "call")])
14645 (define_insn "*sibcall_1_rex64_v"
14646   [(call (mem:QI (reg:DI R11_REG))
14647          (match_operand 0 "" ""))]
14648   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14649   "jmp\t{*%%}r11"
14650   [(set_attr "type" "call")])
14653 ;; Call subroutine, returning value in operand 0
14655 (define_expand "call_value_pop"
14656   [(parallel [(set (match_operand 0 "" "")
14657                    (call (match_operand:QI 1 "" "")
14658                          (match_operand:SI 2 "" "")))
14659               (set (reg:SI SP_REG)
14660                    (plus:SI (reg:SI SP_REG)
14661                             (match_operand:SI 4 "" "")))])]
14662   "!TARGET_64BIT"
14664   ix86_expand_call (operands[0], operands[1], operands[2],
14665                     operands[3], operands[4], 0);
14666   DONE;
14669 (define_expand "call_value"
14670   [(set (match_operand 0 "" "")
14671         (call (match_operand:QI 1 "" "")
14672               (match_operand:SI 2 "" "")))
14673    (use (match_operand:SI 3 "" ""))]
14674   ;; Operand 2 not used on the i386.
14675   ""
14677   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14678   DONE;
14681 (define_expand "sibcall_value"
14682   [(set (match_operand 0 "" "")
14683         (call (match_operand:QI 1 "" "")
14684               (match_operand:SI 2 "" "")))
14685    (use (match_operand:SI 3 "" ""))]
14686   ;; Operand 2 not used on the i386.
14687   ""
14689   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14690   DONE;
14693 ;; Call subroutine returning any type.
14695 (define_expand "untyped_call"
14696   [(parallel [(call (match_operand 0 "" "")
14697                     (const_int 0))
14698               (match_operand 1 "" "")
14699               (match_operand 2 "" "")])]
14700   ""
14702   int i;
14704   /* In order to give reg-stack an easier job in validating two
14705      coprocessor registers as containing a possible return value,
14706      simply pretend the untyped call returns a complex long double
14707      value.  */
14709   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14710                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14711                     operands[0], const0_rtx, GEN_INT (SSE_REGPARM_MAX - 1),
14712                     NULL, 0);
14714   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14715     {
14716       rtx set = XVECEXP (operands[2], 0, i);
14717       emit_move_insn (SET_DEST (set), SET_SRC (set));
14718     }
14720   /* The optimizer does not know that the call sets the function value
14721      registers we stored in the result block.  We avoid problems by
14722      claiming that all hard registers are used and clobbered at this
14723      point.  */
14724   emit_insn (gen_blockage ());
14726   DONE;
14729 ;; Prologue and epilogue instructions
14731 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14732 ;; all of memory.  This blocks insns from being moved across this point.
14734 (define_insn "blockage"
14735   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14736   ""
14737   ""
14738   [(set_attr "length" "0")])
14740 ;; As USE insns aren't meaningful after reload, this is used instead
14741 ;; to prevent deleting instructions setting registers for PIC code
14742 (define_insn "prologue_use"
14743   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14744   ""
14745   ""
14746   [(set_attr "length" "0")])
14748 ;; Insn emitted into the body of a function to return from a function.
14749 ;; This is only done if the function's epilogue is known to be simple.
14750 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14752 (define_expand "return"
14753   [(return)]
14754   "ix86_can_use_return_insn_p ()"
14756   if (crtl->args.pops_args)
14757     {
14758       rtx popc = GEN_INT (crtl->args.pops_args);
14759       emit_jump_insn (gen_return_pop_internal (popc));
14760       DONE;
14761     }
14764 (define_insn "return_internal"
14765   [(return)]
14766   "reload_completed"
14767   "ret"
14768   [(set_attr "length" "1")
14769    (set_attr "length_immediate" "0")
14770    (set_attr "modrm" "0")])
14772 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14773 ;; instruction Athlon and K8 have.
14775 (define_insn "return_internal_long"
14776   [(return)
14777    (unspec [(const_int 0)] UNSPEC_REP)]
14778   "reload_completed"
14779   "rep\;ret"
14780   [(set_attr "length" "1")
14781    (set_attr "length_immediate" "0")
14782    (set_attr "prefix_rep" "1")
14783    (set_attr "modrm" "0")])
14785 (define_insn "return_pop_internal"
14786   [(return)
14787    (use (match_operand:SI 0 "const_int_operand" ""))]
14788   "reload_completed"
14789   "ret\t%0"
14790   [(set_attr "length" "3")
14791    (set_attr "length_immediate" "2")
14792    (set_attr "modrm" "0")])
14794 (define_insn "return_indirect_internal"
14795   [(return)
14796    (use (match_operand:SI 0 "register_operand" "r"))]
14797   "reload_completed"
14798   "jmp\t%A0"
14799   [(set_attr "type" "ibr")
14800    (set_attr "length_immediate" "0")])
14802 (define_insn "nop"
14803   [(const_int 0)]
14804   ""
14805   "nop"
14806   [(set_attr "length" "1")
14807    (set_attr "length_immediate" "0")
14808    (set_attr "modrm" "0")])
14810 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14811 ;; branch prediction penalty for the third jump in a 16-byte
14812 ;; block on K8.
14814 (define_insn "align"
14815   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14816   ""
14818 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14819   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14820 #else
14821   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14822      The align insn is used to avoid 3 jump instructions in the row to improve
14823      branch prediction and the benefits hardly outweigh the cost of extra 8
14824      nops on the average inserted by full alignment pseudo operation.  */
14825 #endif
14826   return "";
14828   [(set_attr "length" "16")])
14830 (define_expand "prologue"
14831   [(const_int 0)]
14832   ""
14833   "ix86_expand_prologue (); DONE;")
14835 (define_insn "set_got"
14836   [(set (match_operand:SI 0 "register_operand" "=r")
14837         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14838    (clobber (reg:CC FLAGS_REG))]
14839   "!TARGET_64BIT"
14840   { return output_set_got (operands[0], NULL_RTX); }
14841   [(set_attr "type" "multi")
14842    (set_attr "length" "12")])
14844 (define_insn "set_got_labelled"
14845   [(set (match_operand:SI 0 "register_operand" "=r")
14846         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14847          UNSPEC_SET_GOT))
14848    (clobber (reg:CC FLAGS_REG))]
14849   "!TARGET_64BIT"
14850   { return output_set_got (operands[0], operands[1]); }
14851   [(set_attr "type" "multi")
14852    (set_attr "length" "12")])
14854 (define_insn "set_got_rex64"
14855   [(set (match_operand:DI 0 "register_operand" "=r")
14856         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14857   "TARGET_64BIT"
14858   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14859   [(set_attr "type" "lea")
14860    (set_attr "length" "6")])
14862 (define_insn "set_rip_rex64"
14863   [(set (match_operand:DI 0 "register_operand" "=r")
14864         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
14865   "TARGET_64BIT"
14866   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14867   [(set_attr "type" "lea")
14868    (set_attr "length" "6")])
14870 (define_insn "set_got_offset_rex64"
14871   [(set (match_operand:DI 0 "register_operand" "=r")
14872         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
14873   "TARGET_64BIT"
14874   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14875   [(set_attr "type" "imov")
14876    (set_attr "length" "11")])
14878 (define_expand "epilogue"
14879   [(const_int 0)]
14880   ""
14881   "ix86_expand_epilogue (1); DONE;")
14883 (define_expand "sibcall_epilogue"
14884   [(const_int 0)]
14885   ""
14886   "ix86_expand_epilogue (0); DONE;")
14888 (define_expand "eh_return"
14889   [(use (match_operand 0 "register_operand" ""))]
14890   ""
14892   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14894   /* Tricky bit: we write the address of the handler to which we will
14895      be returning into someone else's stack frame, one word below the
14896      stack address we wish to restore.  */
14897   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14898   tmp = plus_constant (tmp, -UNITS_PER_WORD);
14899   tmp = gen_rtx_MEM (Pmode, tmp);
14900   emit_move_insn (tmp, ra);
14902   if (Pmode == SImode)
14903     emit_jump_insn (gen_eh_return_si (sa));
14904   else
14905     emit_jump_insn (gen_eh_return_di (sa));
14906   emit_barrier ();
14907   DONE;
14910 (define_insn_and_split "eh_return_si"
14911   [(set (pc)
14912         (unspec [(match_operand:SI 0 "register_operand" "c")]
14913                  UNSPEC_EH_RETURN))]
14914   "!TARGET_64BIT"
14915   "#"
14916   "reload_completed"
14917   [(const_int 0)]
14918   "ix86_expand_epilogue (2); DONE;")
14920 (define_insn_and_split "eh_return_di"
14921   [(set (pc)
14922         (unspec [(match_operand:DI 0 "register_operand" "c")]
14923                  UNSPEC_EH_RETURN))]
14924   "TARGET_64BIT"
14925   "#"
14926   "reload_completed"
14927   [(const_int 0)]
14928   "ix86_expand_epilogue (2); DONE;")
14930 (define_insn "leave"
14931   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14932    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14933    (clobber (mem:BLK (scratch)))]
14934   "!TARGET_64BIT"
14935   "leave"
14936   [(set_attr "type" "leave")])
14938 (define_insn "leave_rex64"
14939   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14940    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14941    (clobber (mem:BLK (scratch)))]
14942   "TARGET_64BIT"
14943   "leave"
14944   [(set_attr "type" "leave")])
14946 (define_expand "ffssi2"
14947   [(parallel
14948      [(set (match_operand:SI 0 "register_operand" "")
14949            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14950       (clobber (match_scratch:SI 2 ""))
14951       (clobber (reg:CC FLAGS_REG))])]
14952   ""
14954   if (TARGET_CMOVE)
14955     {
14956       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14957       DONE;
14958     }
14961 (define_expand "ffs_cmove"
14962   [(set (match_dup 2) (const_int -1))
14963    (parallel [(set (reg:CCZ FLAGS_REG)
14964                    (compare:CCZ (match_operand:SI 1 "register_operand" "")
14965                                 (const_int 0)))
14966               (set (match_operand:SI 0 "nonimmediate_operand" "")
14967                    (ctz:SI (match_dup 1)))])
14968    (set (match_dup 0) (if_then_else:SI
14969                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
14970                         (match_dup 2)
14971                         (match_dup 0)))
14972    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14973               (clobber (reg:CC FLAGS_REG))])]
14974   "TARGET_CMOVE"
14975   "operands[2] = gen_reg_rtx (SImode);")
14977 (define_insn_and_split "*ffs_no_cmove"
14978   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
14979         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14980    (clobber (match_scratch:SI 2 "=&q"))
14981    (clobber (reg:CC FLAGS_REG))]
14982   "!TARGET_CMOVE"
14983   "#"
14984   "&& reload_completed"
14985   [(parallel [(set (reg:CCZ FLAGS_REG)
14986                    (compare:CCZ (match_dup 1) (const_int 0)))
14987               (set (match_dup 0) (ctz:SI (match_dup 1)))])
14988    (set (strict_low_part (match_dup 3))
14989         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14990    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14991               (clobber (reg:CC FLAGS_REG))])
14992    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14993               (clobber (reg:CC FLAGS_REG))])
14994    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14995               (clobber (reg:CC FLAGS_REG))])]
14997   operands[3] = gen_lowpart (QImode, operands[2]);
14998   ix86_expand_clear (operands[2]);
15001 (define_insn "*ffssi_1"
15002   [(set (reg:CCZ FLAGS_REG)
15003         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15004                      (const_int 0)))
15005    (set (match_operand:SI 0 "register_operand" "=r")
15006         (ctz:SI (match_dup 1)))]
15007   ""
15008   "bsf{l}\t{%1, %0|%0, %1}"
15009   [(set_attr "prefix_0f" "1")])
15011 (define_expand "ffsdi2"
15012   [(set (match_dup 2) (const_int -1))
15013    (parallel [(set (reg:CCZ FLAGS_REG)
15014                    (compare:CCZ (match_operand:DI 1 "register_operand" "")
15015                                 (const_int 0)))
15016               (set (match_operand:DI 0 "nonimmediate_operand" "")
15017                    (ctz:DI (match_dup 1)))])
15018    (set (match_dup 0) (if_then_else:DI
15019                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15020                         (match_dup 2)
15021                         (match_dup 0)))
15022    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15023               (clobber (reg:CC FLAGS_REG))])]
15024   "TARGET_64BIT"
15025   "operands[2] = gen_reg_rtx (DImode);")
15027 (define_insn "*ffsdi_1"
15028   [(set (reg:CCZ FLAGS_REG)
15029         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15030                      (const_int 0)))
15031    (set (match_operand:DI 0 "register_operand" "=r")
15032         (ctz:DI (match_dup 1)))]
15033   "TARGET_64BIT"
15034   "bsf{q}\t{%1, %0|%0, %1}"
15035   [(set_attr "prefix_0f" "1")])
15037 (define_insn "ctzsi2"
15038   [(set (match_operand:SI 0 "register_operand" "=r")
15039         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15040    (clobber (reg:CC FLAGS_REG))]
15041   ""
15042   "bsf{l}\t{%1, %0|%0, %1}"
15043   [(set_attr "prefix_0f" "1")])
15045 (define_insn "ctzdi2"
15046   [(set (match_operand:DI 0 "register_operand" "=r")
15047         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15048    (clobber (reg:CC FLAGS_REG))]
15049   "TARGET_64BIT"
15050   "bsf{q}\t{%1, %0|%0, %1}"
15051   [(set_attr "prefix_0f" "1")])
15053 (define_expand "clzsi2"
15054   [(parallel
15055      [(set (match_operand:SI 0 "register_operand" "")
15056            (minus:SI (const_int 31)
15057                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15058       (clobber (reg:CC FLAGS_REG))])
15059    (parallel
15060      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15061       (clobber (reg:CC FLAGS_REG))])]
15062   ""
15064   if (TARGET_ABM)
15065     {
15066       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15067       DONE;
15068     }
15071 (define_insn "clzsi2_abm"
15072   [(set (match_operand:SI 0 "register_operand" "=r")
15073         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15074    (clobber (reg:CC FLAGS_REG))]
15075   "TARGET_ABM"
15076   "lzcnt{l}\t{%1, %0|%0, %1}"
15077   [(set_attr "prefix_rep" "1")
15078    (set_attr "type" "bitmanip")
15079    (set_attr "mode" "SI")])
15081 (define_insn "*bsr"
15082   [(set (match_operand:SI 0 "register_operand" "=r")
15083         (minus:SI (const_int 31)
15084                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15085    (clobber (reg:CC FLAGS_REG))]
15086   ""
15087   "bsr{l}\t{%1, %0|%0, %1}"
15088   [(set_attr "prefix_0f" "1")
15089    (set_attr "mode" "SI")])
15091 (define_insn "popcountsi2"
15092   [(set (match_operand:SI 0 "register_operand" "=r")
15093         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15094    (clobber (reg:CC FLAGS_REG))]
15095   "TARGET_POPCNT"
15096   "popcnt{l}\t{%1, %0|%0, %1}"
15097   [(set_attr "prefix_rep" "1")
15098    (set_attr "type" "bitmanip")
15099    (set_attr "mode" "SI")])
15101 (define_insn "*popcountsi2_cmp"
15102   [(set (reg FLAGS_REG)
15103         (compare
15104           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15105           (const_int 0)))
15106    (set (match_operand:SI 0 "register_operand" "=r")
15107         (popcount:SI (match_dup 1)))]
15108   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15109   "popcnt{l}\t{%1, %0|%0, %1}"
15110   [(set_attr "prefix_rep" "1")
15111    (set_attr "type" "bitmanip")
15112    (set_attr "mode" "SI")])
15114 (define_insn "*popcountsi2_cmp_zext"
15115   [(set (reg FLAGS_REG)
15116         (compare
15117           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15118           (const_int 0)))
15119    (set (match_operand:DI 0 "register_operand" "=r")
15120         (zero_extend:DI(popcount:SI (match_dup 1))))]
15121   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15122   "popcnt{l}\t{%1, %0|%0, %1}"
15123   [(set_attr "prefix_rep" "1")
15124    (set_attr "type" "bitmanip")
15125    (set_attr "mode" "SI")])
15127 (define_expand "bswapsi2"
15128   [(set (match_operand:SI 0 "register_operand" "")
15129         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15130   ""
15132   if (!TARGET_BSWAP)
15133     {
15134       rtx x = operands[0];
15136       emit_move_insn (x, operands[1]);
15137       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15138       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15139       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15140       DONE;
15141     }
15144 (define_insn "*bswapsi_1"
15145   [(set (match_operand:SI 0 "register_operand" "=r")
15146         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15147   "TARGET_BSWAP"
15148   "bswap\t%0"
15149   [(set_attr "prefix_0f" "1")
15150    (set_attr "length" "2")])
15152 (define_insn "*bswaphi_lowpart_1"
15153   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15154         (bswap:HI (match_dup 0)))
15155    (clobber (reg:CC FLAGS_REG))]
15156   "TARGET_USE_XCHGB || optimize_size"
15157   "@
15158     xchg{b}\t{%h0, %b0|%b0, %h0}
15159     rol{w}\t{$8, %0|%0, 8}"
15160   [(set_attr "length" "2,4")
15161    (set_attr "mode" "QI,HI")])
15163 (define_insn "bswaphi_lowpart"
15164   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15165         (bswap:HI (match_dup 0)))
15166    (clobber (reg:CC FLAGS_REG))]
15167   ""
15168   "rol{w}\t{$8, %0|%0, 8}"
15169   [(set_attr "length" "4")
15170    (set_attr "mode" "HI")])
15172 (define_insn "bswapdi2"
15173   [(set (match_operand:DI 0 "register_operand" "=r")
15174         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15175   "TARGET_64BIT"
15176   "bswap\t%0"
15177   [(set_attr "prefix_0f" "1")
15178    (set_attr "length" "3")])
15180 (define_expand "clzdi2"
15181   [(parallel
15182      [(set (match_operand:DI 0 "register_operand" "")
15183            (minus:DI (const_int 63)
15184                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15185       (clobber (reg:CC FLAGS_REG))])
15186    (parallel
15187      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15188       (clobber (reg:CC FLAGS_REG))])]
15189   "TARGET_64BIT"
15191   if (TARGET_ABM)
15192     {
15193       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15194       DONE;
15195     }
15198 (define_insn "clzdi2_abm"
15199   [(set (match_operand:DI 0 "register_operand" "=r")
15200         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15201    (clobber (reg:CC FLAGS_REG))]
15202   "TARGET_64BIT && TARGET_ABM"
15203   "lzcnt{q}\t{%1, %0|%0, %1}"
15204   [(set_attr "prefix_rep" "1")
15205    (set_attr "type" "bitmanip")
15206    (set_attr "mode" "DI")])
15208 (define_insn "*bsr_rex64"
15209   [(set (match_operand:DI 0 "register_operand" "=r")
15210         (minus:DI (const_int 63)
15211                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15212    (clobber (reg:CC FLAGS_REG))]
15213   "TARGET_64BIT"
15214   "bsr{q}\t{%1, %0|%0, %1}"
15215   [(set_attr "prefix_0f" "1")
15216    (set_attr "mode" "DI")])
15218 (define_insn "popcountdi2"
15219   [(set (match_operand:DI 0 "register_operand" "=r")
15220         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15221    (clobber (reg:CC FLAGS_REG))]
15222   "TARGET_64BIT && TARGET_POPCNT"
15223   "popcnt{q}\t{%1, %0|%0, %1}"
15224   [(set_attr "prefix_rep" "1")
15225    (set_attr "type" "bitmanip")
15226    (set_attr "mode" "DI")])
15228 (define_insn "*popcountdi2_cmp"
15229   [(set (reg FLAGS_REG)
15230         (compare
15231           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15232           (const_int 0)))
15233    (set (match_operand:DI 0 "register_operand" "=r")
15234         (popcount:DI (match_dup 1)))]
15235   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15236   "popcnt{q}\t{%1, %0|%0, %1}"
15237   [(set_attr "prefix_rep" "1")
15238    (set_attr "type" "bitmanip")
15239    (set_attr "mode" "DI")])
15241 (define_expand "clzhi2"
15242   [(parallel
15243      [(set (match_operand:HI 0 "register_operand" "")
15244            (minus:HI (const_int 15)
15245                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15246       (clobber (reg:CC FLAGS_REG))])
15247    (parallel
15248      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15249       (clobber (reg:CC FLAGS_REG))])]
15250   ""
15252   if (TARGET_ABM)
15253     {
15254       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15255       DONE;
15256     }
15259 (define_insn "clzhi2_abm"
15260   [(set (match_operand:HI 0 "register_operand" "=r")
15261         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15262    (clobber (reg:CC FLAGS_REG))]
15263   "TARGET_ABM"
15264   "lzcnt{w}\t{%1, %0|%0, %1}"
15265   [(set_attr "prefix_rep" "1")
15266    (set_attr "type" "bitmanip")
15267    (set_attr "mode" "HI")])
15269 (define_insn "*bsrhi"
15270   [(set (match_operand:HI 0 "register_operand" "=r")
15271         (minus:HI (const_int 15)
15272                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15273    (clobber (reg:CC FLAGS_REG))]
15274   ""
15275   "bsr{w}\t{%1, %0|%0, %1}"
15276   [(set_attr "prefix_0f" "1")
15277    (set_attr "mode" "HI")])
15279 (define_insn "popcounthi2"
15280   [(set (match_operand:HI 0 "register_operand" "=r")
15281         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15282    (clobber (reg:CC FLAGS_REG))]
15283   "TARGET_POPCNT"
15284   "popcnt{w}\t{%1, %0|%0, %1}"
15285   [(set_attr "prefix_rep" "1")
15286    (set_attr "type" "bitmanip")
15287    (set_attr "mode" "HI")])
15289 (define_insn "*popcounthi2_cmp"
15290   [(set (reg FLAGS_REG)
15291         (compare
15292           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15293           (const_int 0)))
15294    (set (match_operand:HI 0 "register_operand" "=r")
15295         (popcount:HI (match_dup 1)))]
15296   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15297   "popcnt{w}\t{%1, %0|%0, %1}"
15298   [(set_attr "prefix_rep" "1")
15299    (set_attr "type" "bitmanip")
15300    (set_attr "mode" "HI")])
15302 (define_expand "paritydi2"
15303   [(set (match_operand:DI 0 "register_operand" "")
15304         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15305   "! TARGET_POPCNT"
15307   rtx scratch = gen_reg_rtx (QImode);
15308   rtx cond;
15310   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15311                                 NULL_RTX, operands[1]));
15313   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15314                          gen_rtx_REG (CCmode, FLAGS_REG),
15315                          const0_rtx);
15316   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15318   if (TARGET_64BIT)
15319     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15320   else
15321     {
15322       rtx tmp = gen_reg_rtx (SImode);
15324       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15325       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15326     }
15327   DONE;
15330 (define_insn_and_split "paritydi2_cmp"
15331   [(set (reg:CC FLAGS_REG)
15332         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15333    (clobber (match_scratch:DI 0 "=r"))
15334    (clobber (match_scratch:SI 1 "=&r"))
15335    (clobber (match_scratch:HI 2 "=Q"))]
15336   "! TARGET_POPCNT"
15337   "#"
15338   "&& reload_completed"
15339   [(parallel
15340      [(set (match_dup 1)
15341            (xor:SI (match_dup 1) (match_dup 4)))
15342       (clobber (reg:CC FLAGS_REG))])
15343    (parallel
15344      [(set (reg:CC FLAGS_REG)
15345            (parity:CC (match_dup 1)))
15346       (clobber (match_dup 1))
15347       (clobber (match_dup 2))])]
15349   operands[4] = gen_lowpart (SImode, operands[3]);
15351   if (TARGET_64BIT)
15352     {
15353       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15354       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15355     }
15356   else
15357     operands[1] = gen_highpart (SImode, operands[3]);
15360 (define_expand "paritysi2"
15361   [(set (match_operand:SI 0 "register_operand" "")
15362         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15363   "! TARGET_POPCNT"
15365   rtx scratch = gen_reg_rtx (QImode);
15366   rtx cond;
15368   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15370   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15371                          gen_rtx_REG (CCmode, FLAGS_REG),
15372                          const0_rtx);
15373   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15375   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15376   DONE;
15379 (define_insn_and_split "paritysi2_cmp"
15380   [(set (reg:CC FLAGS_REG)
15381         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15382    (clobber (match_scratch:SI 0 "=r"))
15383    (clobber (match_scratch:HI 1 "=&Q"))]
15384   "! TARGET_POPCNT"
15385   "#"
15386   "&& reload_completed"
15387   [(parallel
15388      [(set (match_dup 1)
15389            (xor:HI (match_dup 1) (match_dup 3)))
15390       (clobber (reg:CC FLAGS_REG))])
15391    (parallel
15392      [(set (reg:CC FLAGS_REG)
15393            (parity:CC (match_dup 1)))
15394       (clobber (match_dup 1))])]
15396   operands[3] = gen_lowpart (HImode, operands[2]);
15398   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15399   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15402 (define_insn "*parityhi2_cmp"
15403   [(set (reg:CC FLAGS_REG)
15404         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15405    (clobber (match_scratch:HI 0 "=Q"))]
15406   "! TARGET_POPCNT"
15407   "xor{b}\t{%h0, %b0|%b0, %h0}"
15408   [(set_attr "length" "2")
15409    (set_attr "mode" "HI")])
15411 (define_insn "*parityqi2_cmp"
15412   [(set (reg:CC FLAGS_REG)
15413         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15414   "! TARGET_POPCNT"
15415   "test{b}\t%0, %0"
15416   [(set_attr "length" "2")
15417    (set_attr "mode" "QI")])
15419 ;; Thread-local storage patterns for ELF.
15421 ;; Note that these code sequences must appear exactly as shown
15422 ;; in order to allow linker relaxation.
15424 (define_insn "*tls_global_dynamic_32_gnu"
15425   [(set (match_operand:SI 0 "register_operand" "=a")
15426         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15427                     (match_operand:SI 2 "tls_symbolic_operand" "")
15428                     (match_operand:SI 3 "call_insn_operand" "")]
15429                     UNSPEC_TLS_GD))
15430    (clobber (match_scratch:SI 4 "=d"))
15431    (clobber (match_scratch:SI 5 "=c"))
15432    (clobber (reg:CC FLAGS_REG))]
15433   "!TARGET_64BIT && TARGET_GNU_TLS"
15434   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15435   [(set_attr "type" "multi")
15436    (set_attr "length" "12")])
15438 (define_insn "*tls_global_dynamic_32_sun"
15439   [(set (match_operand:SI 0 "register_operand" "=a")
15440         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15441                     (match_operand:SI 2 "tls_symbolic_operand" "")
15442                     (match_operand:SI 3 "call_insn_operand" "")]
15443                     UNSPEC_TLS_GD))
15444    (clobber (match_scratch:SI 4 "=d"))
15445    (clobber (match_scratch:SI 5 "=c"))
15446    (clobber (reg:CC FLAGS_REG))]
15447   "!TARGET_64BIT && TARGET_SUN_TLS"
15448   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15449         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15450   [(set_attr "type" "multi")
15451    (set_attr "length" "14")])
15453 (define_expand "tls_global_dynamic_32"
15454   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15455                    (unspec:SI
15456                     [(match_dup 2)
15457                      (match_operand:SI 1 "tls_symbolic_operand" "")
15458                      (match_dup 3)]
15459                     UNSPEC_TLS_GD))
15460               (clobber (match_scratch:SI 4 ""))
15461               (clobber (match_scratch:SI 5 ""))
15462               (clobber (reg:CC FLAGS_REG))])]
15463   ""
15465   if (flag_pic)
15466     operands[2] = pic_offset_table_rtx;
15467   else
15468     {
15469       operands[2] = gen_reg_rtx (Pmode);
15470       emit_insn (gen_set_got (operands[2]));
15471     }
15472   if (TARGET_GNU2_TLS)
15473     {
15474        emit_insn (gen_tls_dynamic_gnu2_32
15475                   (operands[0], operands[1], operands[2]));
15476        DONE;
15477     }
15478   operands[3] = ix86_tls_get_addr ();
15481 (define_insn "*tls_global_dynamic_64"
15482   [(set (match_operand:DI 0 "register_operand" "=a")
15483         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15484                  (match_operand:DI 3 "" "")))
15485    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15486               UNSPEC_TLS_GD)]
15487   "TARGET_64BIT"
15488   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15489   [(set_attr "type" "multi")
15490    (set_attr "length" "16")])
15492 (define_expand "tls_global_dynamic_64"
15493   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15494                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15495               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15496                          UNSPEC_TLS_GD)])]
15497   ""
15499   if (TARGET_GNU2_TLS)
15500     {
15501        emit_insn (gen_tls_dynamic_gnu2_64
15502                   (operands[0], operands[1]));
15503        DONE;
15504     }
15505   operands[2] = ix86_tls_get_addr ();
15508 (define_insn "*tls_local_dynamic_base_32_gnu"
15509   [(set (match_operand:SI 0 "register_operand" "=a")
15510         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15511                     (match_operand:SI 2 "call_insn_operand" "")]
15512                    UNSPEC_TLS_LD_BASE))
15513    (clobber (match_scratch:SI 3 "=d"))
15514    (clobber (match_scratch:SI 4 "=c"))
15515    (clobber (reg:CC FLAGS_REG))]
15516   "!TARGET_64BIT && TARGET_GNU_TLS"
15517   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15518   [(set_attr "type" "multi")
15519    (set_attr "length" "11")])
15521 (define_insn "*tls_local_dynamic_base_32_sun"
15522   [(set (match_operand:SI 0 "register_operand" "=a")
15523         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15524                     (match_operand:SI 2 "call_insn_operand" "")]
15525                    UNSPEC_TLS_LD_BASE))
15526    (clobber (match_scratch:SI 3 "=d"))
15527    (clobber (match_scratch:SI 4 "=c"))
15528    (clobber (reg:CC FLAGS_REG))]
15529   "!TARGET_64BIT && TARGET_SUN_TLS"
15530   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15531         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15532   [(set_attr "type" "multi")
15533    (set_attr "length" "13")])
15535 (define_expand "tls_local_dynamic_base_32"
15536   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15537                    (unspec:SI [(match_dup 1) (match_dup 2)]
15538                               UNSPEC_TLS_LD_BASE))
15539               (clobber (match_scratch:SI 3 ""))
15540               (clobber (match_scratch:SI 4 ""))
15541               (clobber (reg:CC FLAGS_REG))])]
15542   ""
15544   if (flag_pic)
15545     operands[1] = pic_offset_table_rtx;
15546   else
15547     {
15548       operands[1] = gen_reg_rtx (Pmode);
15549       emit_insn (gen_set_got (operands[1]));
15550     }
15551   if (TARGET_GNU2_TLS)
15552     {
15553        emit_insn (gen_tls_dynamic_gnu2_32
15554                   (operands[0], ix86_tls_module_base (), operands[1]));
15555        DONE;
15556     }
15557   operands[2] = ix86_tls_get_addr ();
15560 (define_insn "*tls_local_dynamic_base_64"
15561   [(set (match_operand:DI 0 "register_operand" "=a")
15562         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15563                  (match_operand:DI 2 "" "")))
15564    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15565   "TARGET_64BIT"
15566   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15567   [(set_attr "type" "multi")
15568    (set_attr "length" "12")])
15570 (define_expand "tls_local_dynamic_base_64"
15571   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15572                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15573               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15574   ""
15576   if (TARGET_GNU2_TLS)
15577     {
15578        emit_insn (gen_tls_dynamic_gnu2_64
15579                   (operands[0], ix86_tls_module_base ()));
15580        DONE;
15581     }
15582   operands[1] = ix86_tls_get_addr ();
15585 ;; Local dynamic of a single variable is a lose.  Show combine how
15586 ;; to convert that back to global dynamic.
15588 (define_insn_and_split "*tls_local_dynamic_32_once"
15589   [(set (match_operand:SI 0 "register_operand" "=a")
15590         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15591                              (match_operand:SI 2 "call_insn_operand" "")]
15592                             UNSPEC_TLS_LD_BASE)
15593                  (const:SI (unspec:SI
15594                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15595                             UNSPEC_DTPOFF))))
15596    (clobber (match_scratch:SI 4 "=d"))
15597    (clobber (match_scratch:SI 5 "=c"))
15598    (clobber (reg:CC FLAGS_REG))]
15599   ""
15600   "#"
15601   ""
15602   [(parallel [(set (match_dup 0)
15603                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15604                               UNSPEC_TLS_GD))
15605               (clobber (match_dup 4))
15606               (clobber (match_dup 5))
15607               (clobber (reg:CC FLAGS_REG))])]
15608   "")
15610 ;; Load and add the thread base pointer from %gs:0.
15612 (define_insn "*load_tp_si"
15613   [(set (match_operand:SI 0 "register_operand" "=r")
15614         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15615   "!TARGET_64BIT"
15616   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15617   [(set_attr "type" "imov")
15618    (set_attr "modrm" "0")
15619    (set_attr "length" "7")
15620    (set_attr "memory" "load")
15621    (set_attr "imm_disp" "false")])
15623 (define_insn "*add_tp_si"
15624   [(set (match_operand:SI 0 "register_operand" "=r")
15625         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15626                  (match_operand:SI 1 "register_operand" "0")))
15627    (clobber (reg:CC FLAGS_REG))]
15628   "!TARGET_64BIT"
15629   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15630   [(set_attr "type" "alu")
15631    (set_attr "modrm" "0")
15632    (set_attr "length" "7")
15633    (set_attr "memory" "load")
15634    (set_attr "imm_disp" "false")])
15636 (define_insn "*load_tp_di"
15637   [(set (match_operand:DI 0 "register_operand" "=r")
15638         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15639   "TARGET_64BIT"
15640   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15641   [(set_attr "type" "imov")
15642    (set_attr "modrm" "0")
15643    (set_attr "length" "7")
15644    (set_attr "memory" "load")
15645    (set_attr "imm_disp" "false")])
15647 (define_insn "*add_tp_di"
15648   [(set (match_operand:DI 0 "register_operand" "=r")
15649         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15650                  (match_operand:DI 1 "register_operand" "0")))
15651    (clobber (reg:CC FLAGS_REG))]
15652   "TARGET_64BIT"
15653   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15654   [(set_attr "type" "alu")
15655    (set_attr "modrm" "0")
15656    (set_attr "length" "7")
15657    (set_attr "memory" "load")
15658    (set_attr "imm_disp" "false")])
15660 ;; GNU2 TLS patterns can be split.
15662 (define_expand "tls_dynamic_gnu2_32"
15663   [(set (match_dup 3)
15664         (plus:SI (match_operand:SI 2 "register_operand" "")
15665                  (const:SI
15666                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15667                              UNSPEC_TLSDESC))))
15668    (parallel
15669     [(set (match_operand:SI 0 "register_operand" "")
15670           (unspec:SI [(match_dup 1) (match_dup 3)
15671                       (match_dup 2) (reg:SI SP_REG)]
15672                       UNSPEC_TLSDESC))
15673      (clobber (reg:CC FLAGS_REG))])]
15674   "!TARGET_64BIT && TARGET_GNU2_TLS"
15676   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15677   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15680 (define_insn "*tls_dynamic_lea_32"
15681   [(set (match_operand:SI 0 "register_operand" "=r")
15682         (plus:SI (match_operand:SI 1 "register_operand" "b")
15683                  (const:SI
15684                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15685                               UNSPEC_TLSDESC))))]
15686   "!TARGET_64BIT && TARGET_GNU2_TLS"
15687   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15688   [(set_attr "type" "lea")
15689    (set_attr "mode" "SI")
15690    (set_attr "length" "6")
15691    (set_attr "length_address" "4")])
15693 (define_insn "*tls_dynamic_call_32"
15694   [(set (match_operand:SI 0 "register_operand" "=a")
15695         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15696                     (match_operand:SI 2 "register_operand" "0")
15697                     ;; we have to make sure %ebx still points to the GOT
15698                     (match_operand:SI 3 "register_operand" "b")
15699                     (reg:SI SP_REG)]
15700                    UNSPEC_TLSDESC))
15701    (clobber (reg:CC FLAGS_REG))]
15702   "!TARGET_64BIT && TARGET_GNU2_TLS"
15703   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15704   [(set_attr "type" "call")
15705    (set_attr "length" "2")
15706    (set_attr "length_address" "0")])
15708 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15709   [(set (match_operand:SI 0 "register_operand" "=&a")
15710         (plus:SI
15711          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15712                      (match_operand:SI 4 "" "")
15713                      (match_operand:SI 2 "register_operand" "b")
15714                      (reg:SI SP_REG)]
15715                     UNSPEC_TLSDESC)
15716          (const:SI (unspec:SI
15717                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15718                     UNSPEC_DTPOFF))))
15719    (clobber (reg:CC FLAGS_REG))]
15720   "!TARGET_64BIT && TARGET_GNU2_TLS"
15721   "#"
15722   ""
15723   [(set (match_dup 0) (match_dup 5))]
15725   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15726   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15729 (define_expand "tls_dynamic_gnu2_64"
15730   [(set (match_dup 2)
15731         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15732                    UNSPEC_TLSDESC))
15733    (parallel
15734     [(set (match_operand:DI 0 "register_operand" "")
15735           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15736                      UNSPEC_TLSDESC))
15737      (clobber (reg:CC FLAGS_REG))])]
15738   "TARGET_64BIT && TARGET_GNU2_TLS"
15740   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15741   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15744 (define_insn "*tls_dynamic_lea_64"
15745   [(set (match_operand:DI 0 "register_operand" "=r")
15746         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15747                    UNSPEC_TLSDESC))]
15748   "TARGET_64BIT && TARGET_GNU2_TLS"
15749   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15750   [(set_attr "type" "lea")
15751    (set_attr "mode" "DI")
15752    (set_attr "length" "7")
15753    (set_attr "length_address" "4")])
15755 (define_insn "*tls_dynamic_call_64"
15756   [(set (match_operand:DI 0 "register_operand" "=a")
15757         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15758                     (match_operand:DI 2 "register_operand" "0")
15759                     (reg:DI SP_REG)]
15760                    UNSPEC_TLSDESC))
15761    (clobber (reg:CC FLAGS_REG))]
15762   "TARGET_64BIT && TARGET_GNU2_TLS"
15763   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15764   [(set_attr "type" "call")
15765    (set_attr "length" "2")
15766    (set_attr "length_address" "0")])
15768 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15769   [(set (match_operand:DI 0 "register_operand" "=&a")
15770         (plus:DI
15771          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15772                      (match_operand:DI 3 "" "")
15773                      (reg:DI SP_REG)]
15774                     UNSPEC_TLSDESC)
15775          (const:DI (unspec:DI
15776                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15777                     UNSPEC_DTPOFF))))
15778    (clobber (reg:CC FLAGS_REG))]
15779   "TARGET_64BIT && TARGET_GNU2_TLS"
15780   "#"
15781   ""
15782   [(set (match_dup 0) (match_dup 4))]
15784   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15785   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15790 ;; These patterns match the binary 387 instructions for addM3, subM3,
15791 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15792 ;; SFmode.  The first is the normal insn, the second the same insn but
15793 ;; with one operand a conversion, and the third the same insn but with
15794 ;; the other operand a conversion.  The conversion may be SFmode or
15795 ;; SImode if the target mode DFmode, but only SImode if the target mode
15796 ;; is SFmode.
15798 ;; Gcc is slightly more smart about handling normal two address instructions
15799 ;; so use special patterns for add and mull.
15801 (define_insn "*fop_sf_comm_mixed"
15802   [(set (match_operand:SF 0 "register_operand" "=f,x")
15803         (match_operator:SF 3 "binary_fp_operator"
15804                         [(match_operand:SF 1 "nonimmediate_operand" "%0,0")
15805                          (match_operand:SF 2 "nonimmediate_operand" "fm,xm")]))]
15806   "TARGET_MIX_SSE_I387
15807    && COMMUTATIVE_ARITH_P (operands[3])
15808    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15809   "* return output_387_binary_op (insn, operands);"
15810   [(set (attr "type")
15811         (if_then_else (eq_attr "alternative" "1")
15812            (if_then_else (match_operand:SF 3 "mult_operator" "")
15813               (const_string "ssemul")
15814               (const_string "sseadd"))
15815            (if_then_else (match_operand:SF 3 "mult_operator" "")
15816               (const_string "fmul")
15817               (const_string "fop"))))
15818    (set_attr "mode" "SF")])
15820 (define_insn "*fop_sf_comm_sse"
15821   [(set (match_operand:SF 0 "register_operand" "=x")
15822         (match_operator:SF 3 "binary_fp_operator"
15823                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15824                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15825   "TARGET_SSE_MATH
15826    && COMMUTATIVE_ARITH_P (operands[3])
15827    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15828   "* return output_387_binary_op (insn, operands);"
15829   [(set (attr "type")
15830         (if_then_else (match_operand:SF 3 "mult_operator" "")
15831            (const_string "ssemul")
15832            (const_string "sseadd")))
15833    (set_attr "mode" "SF")])
15835 (define_insn "*fop_sf_comm_i387"
15836   [(set (match_operand:SF 0 "register_operand" "=f")
15837         (match_operator:SF 3 "binary_fp_operator"
15838                         [(match_operand:SF 1 "nonimmediate_operand" "%0")
15839                          (match_operand:SF 2 "nonimmediate_operand" "fm")]))]
15840   "TARGET_80387
15841    && COMMUTATIVE_ARITH_P (operands[3])
15842    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15843   "* return output_387_binary_op (insn, operands);"
15844   [(set (attr "type")
15845         (if_then_else (match_operand:SF 3 "mult_operator" "")
15846            (const_string "fmul")
15847            (const_string "fop")))
15848    (set_attr "mode" "SF")])
15850 (define_insn "*fop_sf_1_mixed"
15851   [(set (match_operand:SF 0 "register_operand" "=f,f,x")
15852         (match_operator:SF 3 "binary_fp_operator"
15853                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm,0")
15854                          (match_operand:SF 2 "nonimmediate_operand" "fm,0,xm")]))]
15855   "TARGET_MIX_SSE_I387
15856    && !COMMUTATIVE_ARITH_P (operands[3])
15857    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15858   "* return output_387_binary_op (insn, operands);"
15859   [(set (attr "type")
15860         (cond [(and (eq_attr "alternative" "2")
15861                     (match_operand:SF 3 "mult_operator" ""))
15862                  (const_string "ssemul")
15863                (and (eq_attr "alternative" "2")
15864                     (match_operand:SF 3 "div_operator" ""))
15865                  (const_string "ssediv")
15866                (eq_attr "alternative" "2")
15867                  (const_string "sseadd")
15868                (match_operand:SF 3 "mult_operator" "")
15869                  (const_string "fmul")
15870                (match_operand:SF 3 "div_operator" "")
15871                  (const_string "fdiv")
15872               ]
15873               (const_string "fop")))
15874    (set_attr "mode" "SF")])
15876 (define_insn "*rcpsf2_sse"
15877   [(set (match_operand:SF 0 "register_operand" "=x")
15878         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15879                    UNSPEC_RCP))]
15880   "TARGET_SSE_MATH"
15881   "rcpss\t{%1, %0|%0, %1}"
15882   [(set_attr "type" "sse")
15883    (set_attr "mode" "SF")])
15885 (define_insn "*fop_sf_1_sse"
15886   [(set (match_operand:SF 0 "register_operand" "=x")
15887         (match_operator:SF 3 "binary_fp_operator"
15888                         [(match_operand:SF 1 "register_operand" "0")
15889                          (match_operand:SF 2 "nonimmediate_operand" "xm")]))]
15890   "TARGET_SSE_MATH
15891    && !COMMUTATIVE_ARITH_P (operands[3])"
15892   "* return output_387_binary_op (insn, operands);"
15893   [(set (attr "type")
15894         (cond [(match_operand:SF 3 "mult_operator" "")
15895                  (const_string "ssemul")
15896                (match_operand:SF 3 "div_operator" "")
15897                  (const_string "ssediv")
15898               ]
15899               (const_string "sseadd")))
15900    (set_attr "mode" "SF")])
15902 ;; This pattern is not fully shadowed by the pattern above.
15903 (define_insn "*fop_sf_1_i387"
15904   [(set (match_operand:SF 0 "register_operand" "=f,f")
15905         (match_operator:SF 3 "binary_fp_operator"
15906                         [(match_operand:SF 1 "nonimmediate_operand" "0,fm")
15907                          (match_operand:SF 2 "nonimmediate_operand" "fm,0")]))]
15908   "TARGET_80387 && !TARGET_SSE_MATH
15909    && !COMMUTATIVE_ARITH_P (operands[3])
15910    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15911   "* return output_387_binary_op (insn, operands);"
15912   [(set (attr "type")
15913         (cond [(match_operand:SF 3 "mult_operator" "")
15914                  (const_string "fmul")
15915                (match_operand:SF 3 "div_operator" "")
15916                  (const_string "fdiv")
15917               ]
15918               (const_string "fop")))
15919    (set_attr "mode" "SF")])
15921 ;; ??? Add SSE splitters for these!
15922 (define_insn "*fop_sf_2<mode>_i387"
15923   [(set (match_operand:SF 0 "register_operand" "=f,f")
15924         (match_operator:SF 3 "binary_fp_operator"
15925           [(float:SF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15926            (match_operand:SF 2 "register_operand" "0,0")]))]
15927   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15928   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15929   [(set (attr "type")
15930         (cond [(match_operand:SF 3 "mult_operator" "")
15931                  (const_string "fmul")
15932                (match_operand:SF 3 "div_operator" "")
15933                  (const_string "fdiv")
15934               ]
15935               (const_string "fop")))
15936    (set_attr "fp_int_src" "true")
15937    (set_attr "mode" "<MODE>")])
15939 (define_insn "*fop_sf_3<mode>_i387"
15940   [(set (match_operand:SF 0 "register_operand" "=f,f")
15941         (match_operator:SF 3 "binary_fp_operator"
15942           [(match_operand:SF 1 "register_operand" "0,0")
15943            (float:SF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15944   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP && !TARGET_SSE_MATH"
15945   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15946   [(set (attr "type")
15947         (cond [(match_operand:SF 3 "mult_operator" "")
15948                  (const_string "fmul")
15949                (match_operand:SF 3 "div_operator" "")
15950                  (const_string "fdiv")
15951               ]
15952               (const_string "fop")))
15953    (set_attr "fp_int_src" "true")
15954    (set_attr "mode" "<MODE>")])
15956 (define_insn "*fop_df_comm_mixed"
15957   [(set (match_operand:DF 0 "register_operand" "=f,x")
15958         (match_operator:DF 3 "binary_fp_operator"
15959           [(match_operand:DF 1 "nonimmediate_operand" "%0,0")
15960            (match_operand:DF 2 "nonimmediate_operand" "fm,xm")]))]
15961   "TARGET_SSE2 && TARGET_MIX_SSE_I387
15962    && COMMUTATIVE_ARITH_P (operands[3])
15963    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15964   "* return output_387_binary_op (insn, operands);"
15965   [(set (attr "type")
15966         (if_then_else (eq_attr "alternative" "1")
15967            (if_then_else (match_operand:DF 3 "mult_operator" "")
15968               (const_string "ssemul")
15969               (const_string "sseadd"))
15970            (if_then_else (match_operand:DF 3 "mult_operator" "")
15971               (const_string "fmul")
15972               (const_string "fop"))))
15973    (set_attr "mode" "DF")])
15975 (define_insn "*fop_df_comm_sse"
15976   [(set (match_operand:DF 0 "register_operand" "=x")
15977         (match_operator:DF 3 "binary_fp_operator"
15978           [(match_operand:DF 1 "nonimmediate_operand" "%0")
15979            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
15980   "TARGET_SSE2 && TARGET_SSE_MATH
15981    && COMMUTATIVE_ARITH_P (operands[3])
15982    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15983   "* return output_387_binary_op (insn, operands);"
15984   [(set (attr "type")
15985         (if_then_else (match_operand:DF 3 "mult_operator" "")
15986            (const_string "ssemul")
15987            (const_string "sseadd")))
15988    (set_attr "mode" "DF")])
15990 (define_insn "*fop_df_comm_i387"
15991   [(set (match_operand:DF 0 "register_operand" "=f")
15992         (match_operator:DF 3 "binary_fp_operator"
15993                         [(match_operand:DF 1 "nonimmediate_operand" "%0")
15994                          (match_operand:DF 2 "nonimmediate_operand" "fm")]))]
15995   "TARGET_80387
15996    && COMMUTATIVE_ARITH_P (operands[3])
15997    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15998   "* return output_387_binary_op (insn, operands);"
15999   [(set (attr "type")
16000         (if_then_else (match_operand:DF 3 "mult_operator" "")
16001            (const_string "fmul")
16002            (const_string "fop")))
16003    (set_attr "mode" "DF")])
16005 (define_insn "*fop_df_1_mixed"
16006   [(set (match_operand:DF 0 "register_operand" "=f,f,x")
16007         (match_operator:DF 3 "binary_fp_operator"
16008           [(match_operand:DF 1 "nonimmediate_operand" "0,fm,0")
16009            (match_operand:DF 2 "nonimmediate_operand" "fm,0,xm")]))]
16010   "TARGET_SSE2 && TARGET_SSE_MATH && TARGET_MIX_SSE_I387
16011    && !COMMUTATIVE_ARITH_P (operands[3])
16012    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16013   "* return output_387_binary_op (insn, operands);"
16014   [(set (attr "type")
16015         (cond [(and (eq_attr "alternative" "2")
16016                     (match_operand:DF 3 "mult_operator" ""))
16017                  (const_string "ssemul")
16018                (and (eq_attr "alternative" "2")
16019                     (match_operand:DF 3 "div_operator" ""))
16020                  (const_string "ssediv")
16021                (eq_attr "alternative" "2")
16022                  (const_string "sseadd")
16023                (match_operand:DF 3 "mult_operator" "")
16024                  (const_string "fmul")
16025                (match_operand:DF 3 "div_operator" "")
16026                  (const_string "fdiv")
16027               ]
16028               (const_string "fop")))
16029    (set_attr "mode" "DF")])
16031 (define_insn "*fop_df_1_sse"
16032   [(set (match_operand:DF 0 "register_operand" "=x")
16033         (match_operator:DF 3 "binary_fp_operator"
16034           [(match_operand:DF 1 "register_operand" "0")
16035            (match_operand:DF 2 "nonimmediate_operand" "xm")]))]
16036   "TARGET_SSE2 && TARGET_SSE_MATH
16037    && !COMMUTATIVE_ARITH_P (operands[3])"
16038   "* return output_387_binary_op (insn, operands);"
16039   [(set_attr "mode" "DF")
16040    (set (attr "type")
16041         (cond [(match_operand:DF 3 "mult_operator" "")
16042                  (const_string "ssemul")
16043                (match_operand:DF 3 "div_operator" "")
16044                  (const_string "ssediv")
16045               ]
16046               (const_string "sseadd")))])
16048 ;; This pattern is not fully shadowed by the pattern above.
16049 (define_insn "*fop_df_1_i387"
16050   [(set (match_operand:DF 0 "register_operand" "=f,f")
16051         (match_operator:DF 3 "binary_fp_operator"
16052                         [(match_operand:DF 1 "nonimmediate_operand" "0,fm")
16053                          (match_operand:DF 2 "nonimmediate_operand" "fm,0")]))]
16054   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16055    && !COMMUTATIVE_ARITH_P (operands[3])
16056    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16057   "* return output_387_binary_op (insn, operands);"
16058   [(set (attr "type")
16059         (cond [(match_operand:DF 3 "mult_operator" "")
16060                  (const_string "fmul")
16061                (match_operand:DF 3 "div_operator" "")
16062                  (const_string "fdiv")
16063               ]
16064               (const_string "fop")))
16065    (set_attr "mode" "DF")])
16067 ;; ??? Add SSE splitters for these!
16068 (define_insn "*fop_df_2<mode>_i387"
16069   [(set (match_operand:DF 0 "register_operand" "=f,f")
16070         (match_operator:DF 3 "binary_fp_operator"
16071            [(float:DF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16072             (match_operand:DF 2 "register_operand" "0,0")]))]
16073   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16074    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16075   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16076   [(set (attr "type")
16077         (cond [(match_operand:DF 3 "mult_operator" "")
16078                  (const_string "fmul")
16079                (match_operand:DF 3 "div_operator" "")
16080                  (const_string "fdiv")
16081               ]
16082               (const_string "fop")))
16083    (set_attr "fp_int_src" "true")
16084    (set_attr "mode" "<MODE>")])
16086 (define_insn "*fop_df_3<mode>_i387"
16087   [(set (match_operand:DF 0 "register_operand" "=f,f")
16088         (match_operator:DF 3 "binary_fp_operator"
16089            [(match_operand:DF 1 "register_operand" "0,0")
16090             (float:DF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16091   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP
16092    && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16093   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16094   [(set (attr "type")
16095         (cond [(match_operand:DF 3 "mult_operator" "")
16096                  (const_string "fmul")
16097                (match_operand:DF 3 "div_operator" "")
16098                  (const_string "fdiv")
16099               ]
16100               (const_string "fop")))
16101    (set_attr "fp_int_src" "true")
16102    (set_attr "mode" "<MODE>")])
16104 (define_insn "*fop_df_4_i387"
16105   [(set (match_operand:DF 0 "register_operand" "=f,f")
16106         (match_operator:DF 3 "binary_fp_operator"
16107            [(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16108             (match_operand:DF 2 "register_operand" "0,f")]))]
16109   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16110    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16111   "* return output_387_binary_op (insn, operands);"
16112   [(set (attr "type")
16113         (cond [(match_operand:DF 3 "mult_operator" "")
16114                  (const_string "fmul")
16115                (match_operand:DF 3 "div_operator" "")
16116                  (const_string "fdiv")
16117               ]
16118               (const_string "fop")))
16119    (set_attr "mode" "SF")])
16121 (define_insn "*fop_df_5_i387"
16122   [(set (match_operand:DF 0 "register_operand" "=f,f")
16123         (match_operator:DF 3 "binary_fp_operator"
16124           [(match_operand:DF 1 "register_operand" "0,f")
16125            (float_extend:DF
16126             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16127   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16128   "* return output_387_binary_op (insn, operands);"
16129   [(set (attr "type")
16130         (cond [(match_operand:DF 3 "mult_operator" "")
16131                  (const_string "fmul")
16132                (match_operand:DF 3 "div_operator" "")
16133                  (const_string "fdiv")
16134               ]
16135               (const_string "fop")))
16136    (set_attr "mode" "SF")])
16138 (define_insn "*fop_df_6_i387"
16139   [(set (match_operand:DF 0 "register_operand" "=f,f")
16140         (match_operator:DF 3 "binary_fp_operator"
16141           [(float_extend:DF
16142             (match_operand:SF 1 "register_operand" "0,f"))
16143            (float_extend:DF
16144             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16145   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16146   "* return output_387_binary_op (insn, operands);"
16147   [(set (attr "type")
16148         (cond [(match_operand:DF 3 "mult_operator" "")
16149                  (const_string "fmul")
16150                (match_operand:DF 3 "div_operator" "")
16151                  (const_string "fdiv")
16152               ]
16153               (const_string "fop")))
16154    (set_attr "mode" "SF")])
16156 (define_insn "*fop_xf_comm_i387"
16157   [(set (match_operand:XF 0 "register_operand" "=f")
16158         (match_operator:XF 3 "binary_fp_operator"
16159                         [(match_operand:XF 1 "register_operand" "%0")
16160                          (match_operand:XF 2 "register_operand" "f")]))]
16161   "TARGET_80387
16162    && COMMUTATIVE_ARITH_P (operands[3])"
16163   "* return output_387_binary_op (insn, operands);"
16164   [(set (attr "type")
16165         (if_then_else (match_operand:XF 3 "mult_operator" "")
16166            (const_string "fmul")
16167            (const_string "fop")))
16168    (set_attr "mode" "XF")])
16170 (define_insn "*fop_xf_1_i387"
16171   [(set (match_operand:XF 0 "register_operand" "=f,f")
16172         (match_operator:XF 3 "binary_fp_operator"
16173                         [(match_operand:XF 1 "register_operand" "0,f")
16174                          (match_operand:XF 2 "register_operand" "f,0")]))]
16175   "TARGET_80387
16176    && !COMMUTATIVE_ARITH_P (operands[3])"
16177   "* return output_387_binary_op (insn, operands);"
16178   [(set (attr "type")
16179         (cond [(match_operand:XF 3 "mult_operator" "")
16180                  (const_string "fmul")
16181                (match_operand:XF 3 "div_operator" "")
16182                  (const_string "fdiv")
16183               ]
16184               (const_string "fop")))
16185    (set_attr "mode" "XF")])
16187 (define_insn "*fop_xf_2<mode>_i387"
16188   [(set (match_operand:XF 0 "register_operand" "=f,f")
16189         (match_operator:XF 3 "binary_fp_operator"
16190            [(float:XF (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16191             (match_operand:XF 2 "register_operand" "0,0")]))]
16192   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16193   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16194   [(set (attr "type")
16195         (cond [(match_operand:XF 3 "mult_operator" "")
16196                  (const_string "fmul")
16197                (match_operand:XF 3 "div_operator" "")
16198                  (const_string "fdiv")
16199               ]
16200               (const_string "fop")))
16201    (set_attr "fp_int_src" "true")
16202    (set_attr "mode" "<MODE>")])
16204 (define_insn "*fop_xf_3<mode>_i387"
16205   [(set (match_operand:XF 0 "register_operand" "=f,f")
16206         (match_operator:XF 3 "binary_fp_operator"
16207           [(match_operand:XF 1 "register_operand" "0,0")
16208            (float:XF (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16209   "TARGET_80387 && TARGET_USE_<MODE>MODE_FIOP"
16210   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16211   [(set (attr "type")
16212         (cond [(match_operand:XF 3 "mult_operator" "")
16213                  (const_string "fmul")
16214                (match_operand:XF 3 "div_operator" "")
16215                  (const_string "fdiv")
16216               ]
16217               (const_string "fop")))
16218    (set_attr "fp_int_src" "true")
16219    (set_attr "mode" "<MODE>")])
16221 (define_insn "*fop_xf_4_i387"
16222   [(set (match_operand:XF 0 "register_operand" "=f,f")
16223         (match_operator:XF 3 "binary_fp_operator"
16224            [(float_extend:XF
16225               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16226             (match_operand:XF 2 "register_operand" "0,f")]))]
16227   "TARGET_80387"
16228   "* return output_387_binary_op (insn, operands);"
16229   [(set (attr "type")
16230         (cond [(match_operand:XF 3 "mult_operator" "")
16231                  (const_string "fmul")
16232                (match_operand:XF 3 "div_operator" "")
16233                  (const_string "fdiv")
16234               ]
16235               (const_string "fop")))
16236    (set_attr "mode" "SF")])
16238 (define_insn "*fop_xf_5_i387"
16239   [(set (match_operand:XF 0 "register_operand" "=f,f")
16240         (match_operator:XF 3 "binary_fp_operator"
16241           [(match_operand:XF 1 "register_operand" "0,f")
16242            (float_extend:XF
16243              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16244   "TARGET_80387"
16245   "* return output_387_binary_op (insn, operands);"
16246   [(set (attr "type")
16247         (cond [(match_operand:XF 3 "mult_operator" "")
16248                  (const_string "fmul")
16249                (match_operand:XF 3 "div_operator" "")
16250                  (const_string "fdiv")
16251               ]
16252               (const_string "fop")))
16253    (set_attr "mode" "SF")])
16255 (define_insn "*fop_xf_6_i387"
16256   [(set (match_operand:XF 0 "register_operand" "=f,f")
16257         (match_operator:XF 3 "binary_fp_operator"
16258           [(float_extend:XF
16259              (match_operand:MODEF 1 "register_operand" "0,f"))
16260            (float_extend:XF
16261              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16262   "TARGET_80387"
16263   "* return output_387_binary_op (insn, operands);"
16264   [(set (attr "type")
16265         (cond [(match_operand:XF 3 "mult_operator" "")
16266                  (const_string "fmul")
16267                (match_operand:XF 3 "div_operator" "")
16268                  (const_string "fdiv")
16269               ]
16270               (const_string "fop")))
16271    (set_attr "mode" "SF")])
16273 (define_split
16274   [(set (match_operand 0 "register_operand" "")
16275         (match_operator 3 "binary_fp_operator"
16276            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16277             (match_operand 2 "register_operand" "")]))]
16278   "reload_completed
16279    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16280   [(const_int 0)]
16282   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16283   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16284   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16285                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16286                                           GET_MODE (operands[3]),
16287                                           operands[4],
16288                                           operands[2])));
16289   ix86_free_from_memory (GET_MODE (operands[1]));
16290   DONE;
16293 (define_split
16294   [(set (match_operand 0 "register_operand" "")
16295         (match_operator 3 "binary_fp_operator"
16296            [(match_operand 1 "register_operand" "")
16297             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16298   "reload_completed
16299    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16300   [(const_int 0)]
16302   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16303   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16304   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16305                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16306                                           GET_MODE (operands[3]),
16307                                           operands[1],
16308                                           operands[4])));
16309   ix86_free_from_memory (GET_MODE (operands[2]));
16310   DONE;
16313 ;; FPU special functions.
16315 ;; This pattern implements a no-op XFmode truncation for
16316 ;; all fancy i386 XFmode math functions.
16318 (define_insn "truncxf<mode>2_i387_noop_unspec"
16319   [(set (match_operand:MODEF 0 "register_operand" "=f")
16320         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16321         UNSPEC_TRUNC_NOOP))]
16322   "TARGET_USE_FANCY_MATH_387"
16323   "* return output_387_reg_move (insn, operands);"
16324   [(set_attr "type" "fmov")
16325    (set_attr "mode" "<MODE>")])
16327 (define_insn "sqrtxf2"
16328   [(set (match_operand:XF 0 "register_operand" "=f")
16329         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16330   "TARGET_USE_FANCY_MATH_387"
16331   "fsqrt"
16332   [(set_attr "type" "fpspc")
16333    (set_attr "mode" "XF")
16334    (set_attr "athlon_decode" "direct")
16335    (set_attr "amdfam10_decode" "direct")])
16337 (define_insn "sqrt_extend<mode>xf2_i387"
16338   [(set (match_operand:XF 0 "register_operand" "=f")
16339         (sqrt:XF
16340           (float_extend:XF
16341             (match_operand:MODEF 1 "register_operand" "0"))))]
16342   "TARGET_USE_FANCY_MATH_387"
16343   "fsqrt"
16344   [(set_attr "type" "fpspc")
16345    (set_attr "mode" "XF")
16346    (set_attr "athlon_decode" "direct")
16347    (set_attr "amdfam10_decode" "direct")])
16349 (define_insn "*rsqrtsf2_sse"
16350   [(set (match_operand:SF 0 "register_operand" "=x")
16351         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16352                    UNSPEC_RSQRT))]
16353   "TARGET_SSE_MATH"
16354   "rsqrtss\t{%1, %0|%0, %1}"
16355   [(set_attr "type" "sse")
16356    (set_attr "mode" "SF")])
16358 (define_expand "rsqrtsf2"
16359   [(set (match_operand:SF 0 "register_operand" "")
16360         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16361                    UNSPEC_RSQRT))]
16362   "TARGET_SSE_MATH"
16364   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16365   DONE;
16368 (define_insn "*sqrt<mode>2_sse"
16369   [(set (match_operand:MODEF 0 "register_operand" "=x")
16370         (sqrt:MODEF
16371           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16372   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16373   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16374   [(set_attr "type" "sse")
16375    (set_attr "mode" "<MODE>")
16376    (set_attr "athlon_decode" "*")
16377    (set_attr "amdfam10_decode" "*")])
16379 (define_expand "sqrt<mode>2"
16380   [(set (match_operand:MODEF 0 "register_operand" "")
16381         (sqrt:MODEF
16382           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16383   "TARGET_USE_FANCY_MATH_387
16384    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16386   if (<MODE>mode == SFmode
16387       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16388       && flag_finite_math_only && !flag_trapping_math
16389       && flag_unsafe_math_optimizations)
16390     {
16391       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16392       DONE;
16393     }
16395   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16396     {
16397       rtx op0 = gen_reg_rtx (XFmode);
16398       rtx op1 = force_reg (<MODE>mode, operands[1]);
16400       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16401       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16402       DONE;
16403    }
16406 (define_insn "fpremxf4_i387"
16407   [(set (match_operand:XF 0 "register_operand" "=f")
16408         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16409                     (match_operand:XF 3 "register_operand" "1")]
16410                    UNSPEC_FPREM_F))
16411    (set (match_operand:XF 1 "register_operand" "=u")
16412         (unspec:XF [(match_dup 2) (match_dup 3)]
16413                    UNSPEC_FPREM_U))
16414    (set (reg:CCFP FPSR_REG)
16415         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16416                      UNSPEC_C2_FLAG))]
16417   "TARGET_USE_FANCY_MATH_387"
16418   "fprem"
16419   [(set_attr "type" "fpspc")
16420    (set_attr "mode" "XF")])
16422 (define_expand "fmodxf3"
16423   [(use (match_operand:XF 0 "register_operand" ""))
16424    (use (match_operand:XF 1 "general_operand" ""))
16425    (use (match_operand:XF 2 "general_operand" ""))]
16426   "TARGET_USE_FANCY_MATH_387"
16428   rtx label = gen_label_rtx ();
16430   rtx op1 = gen_reg_rtx (XFmode);
16431   rtx op2 = gen_reg_rtx (XFmode);
16433   emit_move_insn (op1, operands[1]);
16434   emit_move_insn (op2, operands[2]);
16436   emit_label (label);
16437   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16438   ix86_emit_fp_unordered_jump (label);
16439   LABEL_NUSES (label) = 1;
16441   emit_move_insn (operands[0], op1);
16442   DONE;
16445 (define_expand "fmod<mode>3"
16446   [(use (match_operand:MODEF 0 "register_operand" ""))
16447    (use (match_operand:MODEF 1 "general_operand" ""))
16448    (use (match_operand:MODEF 2 "general_operand" ""))]
16449   "TARGET_USE_FANCY_MATH_387"
16451   rtx label = gen_label_rtx ();
16453   rtx op1 = gen_reg_rtx (XFmode);
16454   rtx op2 = gen_reg_rtx (XFmode);
16456   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16457   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16459   emit_label (label);
16460   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16461   ix86_emit_fp_unordered_jump (label);
16462   LABEL_NUSES (label) = 1;
16464   /* Truncate the result properly for strict SSE math.  */
16465   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16466       && !TARGET_MIX_SSE_I387)
16467     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16468   else
16469     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16471   DONE;
16474 (define_insn "fprem1xf4_i387"
16475   [(set (match_operand:XF 0 "register_operand" "=f")
16476         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16477                     (match_operand:XF 3 "register_operand" "1")]
16478                    UNSPEC_FPREM1_F))
16479    (set (match_operand:XF 1 "register_operand" "=u")
16480         (unspec:XF [(match_dup 2) (match_dup 3)]
16481                    UNSPEC_FPREM1_U))
16482    (set (reg:CCFP FPSR_REG)
16483         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16484                      UNSPEC_C2_FLAG))]
16485   "TARGET_USE_FANCY_MATH_387"
16486   "fprem1"
16487   [(set_attr "type" "fpspc")
16488    (set_attr "mode" "XF")])
16490 (define_expand "remainderxf3"
16491   [(use (match_operand:XF 0 "register_operand" ""))
16492    (use (match_operand:XF 1 "general_operand" ""))
16493    (use (match_operand:XF 2 "general_operand" ""))]
16494   "TARGET_USE_FANCY_MATH_387"
16496   rtx label = gen_label_rtx ();
16498   rtx op1 = gen_reg_rtx (XFmode);
16499   rtx op2 = gen_reg_rtx (XFmode);
16501   emit_move_insn (op1, operands[1]);
16502   emit_move_insn (op2, operands[2]);
16504   emit_label (label);
16505   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16506   ix86_emit_fp_unordered_jump (label);
16507   LABEL_NUSES (label) = 1;
16509   emit_move_insn (operands[0], op1);
16510   DONE;
16513 (define_expand "remainder<mode>3"
16514   [(use (match_operand:MODEF 0 "register_operand" ""))
16515    (use (match_operand:MODEF 1 "general_operand" ""))
16516    (use (match_operand:MODEF 2 "general_operand" ""))]
16517   "TARGET_USE_FANCY_MATH_387"
16519   rtx label = gen_label_rtx ();
16521   rtx op1 = gen_reg_rtx (XFmode);
16522   rtx op2 = gen_reg_rtx (XFmode);
16524   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16525   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16527   emit_label (label);
16529   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16530   ix86_emit_fp_unordered_jump (label);
16531   LABEL_NUSES (label) = 1;
16533   /* Truncate the result properly for strict SSE math.  */
16534   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16535       && !TARGET_MIX_SSE_I387)
16536     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16537   else
16538     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16540   DONE;
16543 (define_insn "*sinxf2_i387"
16544   [(set (match_operand:XF 0 "register_operand" "=f")
16545         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16546   "TARGET_USE_FANCY_MATH_387
16547    && flag_unsafe_math_optimizations"
16548   "fsin"
16549   [(set_attr "type" "fpspc")
16550    (set_attr "mode" "XF")])
16552 (define_insn "*sin_extend<mode>xf2_i387"
16553   [(set (match_operand:XF 0 "register_operand" "=f")
16554         (unspec:XF [(float_extend:XF
16555                       (match_operand:MODEF 1 "register_operand" "0"))]
16556                    UNSPEC_SIN))]
16557   "TARGET_USE_FANCY_MATH_387
16558    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16559        || TARGET_MIX_SSE_I387)
16560    && flag_unsafe_math_optimizations"
16561   "fsin"
16562   [(set_attr "type" "fpspc")
16563    (set_attr "mode" "XF")])
16565 (define_insn "*cosxf2_i387"
16566   [(set (match_operand:XF 0 "register_operand" "=f")
16567         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16568   "TARGET_USE_FANCY_MATH_387
16569    && flag_unsafe_math_optimizations"
16570   "fcos"
16571   [(set_attr "type" "fpspc")
16572    (set_attr "mode" "XF")])
16574 (define_insn "*cos_extend<mode>xf2_i387"
16575   [(set (match_operand:XF 0 "register_operand" "=f")
16576         (unspec:XF [(float_extend:XF
16577                       (match_operand:MODEF 1 "register_operand" "0"))]
16578                    UNSPEC_COS))]
16579   "TARGET_USE_FANCY_MATH_387
16580    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16581        || TARGET_MIX_SSE_I387)
16582    && flag_unsafe_math_optimizations"
16583   "fcos"
16584   [(set_attr "type" "fpspc")
16585    (set_attr "mode" "XF")])
16587 ;; When sincos pattern is defined, sin and cos builtin functions will be
16588 ;; expanded to sincos pattern with one of its outputs left unused.
16589 ;; CSE pass will figure out if two sincos patterns can be combined,
16590 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16591 ;; depending on the unused output.
16593 (define_insn "sincosxf3"
16594   [(set (match_operand:XF 0 "register_operand" "=f")
16595         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16596                    UNSPEC_SINCOS_COS))
16597    (set (match_operand:XF 1 "register_operand" "=u")
16598         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16599   "TARGET_USE_FANCY_MATH_387
16600    && flag_unsafe_math_optimizations"
16601   "fsincos"
16602   [(set_attr "type" "fpspc")
16603    (set_attr "mode" "XF")])
16605 (define_split
16606   [(set (match_operand:XF 0 "register_operand" "")
16607         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16608                    UNSPEC_SINCOS_COS))
16609    (set (match_operand:XF 1 "register_operand" "")
16610         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16611   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16612    && !(reload_completed || reload_in_progress)"
16613   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16614   "")
16616 (define_split
16617   [(set (match_operand:XF 0 "register_operand" "")
16618         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16619                    UNSPEC_SINCOS_COS))
16620    (set (match_operand:XF 1 "register_operand" "")
16621         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16622   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16623    && !(reload_completed || reload_in_progress)"
16624   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16625   "")
16627 (define_insn "sincos_extend<mode>xf3_i387"
16628   [(set (match_operand:XF 0 "register_operand" "=f")
16629         (unspec:XF [(float_extend:XF
16630                       (match_operand:MODEF 2 "register_operand" "0"))]
16631                    UNSPEC_SINCOS_COS))
16632    (set (match_operand:XF 1 "register_operand" "=u")
16633         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16634   "TARGET_USE_FANCY_MATH_387
16635    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16636        || TARGET_MIX_SSE_I387)
16637    && flag_unsafe_math_optimizations"
16638   "fsincos"
16639   [(set_attr "type" "fpspc")
16640    (set_attr "mode" "XF")])
16642 (define_split
16643   [(set (match_operand:XF 0 "register_operand" "")
16644         (unspec:XF [(float_extend:XF
16645                       (match_operand:MODEF 2 "register_operand" ""))]
16646                    UNSPEC_SINCOS_COS))
16647    (set (match_operand:XF 1 "register_operand" "")
16648         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16649   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16650    && !(reload_completed || reload_in_progress)"
16651   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16652   "")
16654 (define_split
16655   [(set (match_operand:XF 0 "register_operand" "")
16656         (unspec:XF [(float_extend:XF
16657                       (match_operand:MODEF 2 "register_operand" ""))]
16658                    UNSPEC_SINCOS_COS))
16659    (set (match_operand:XF 1 "register_operand" "")
16660         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16661   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16662    && !(reload_completed || reload_in_progress)"
16663   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16664   "")
16666 (define_expand "sincos<mode>3"
16667   [(use (match_operand:MODEF 0 "register_operand" ""))
16668    (use (match_operand:MODEF 1 "register_operand" ""))
16669    (use (match_operand:MODEF 2 "register_operand" ""))]
16670   "TARGET_USE_FANCY_MATH_387
16671    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16672        || TARGET_MIX_SSE_I387)
16673    && flag_unsafe_math_optimizations"
16675   rtx op0 = gen_reg_rtx (XFmode);
16676   rtx op1 = gen_reg_rtx (XFmode);
16678   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16679   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16680   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16681   DONE;
16684 (define_insn "fptanxf4_i387"
16685   [(set (match_operand:XF 0 "register_operand" "=f")
16686         (match_operand:XF 3 "const_double_operand" "F"))
16687    (set (match_operand:XF 1 "register_operand" "=u")
16688         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16689                    UNSPEC_TAN))]
16690   "TARGET_USE_FANCY_MATH_387
16691    && flag_unsafe_math_optimizations
16692    && standard_80387_constant_p (operands[3]) == 2"
16693   "fptan"
16694   [(set_attr "type" "fpspc")
16695    (set_attr "mode" "XF")])
16697 (define_insn "fptan_extend<mode>xf4_i387"
16698   [(set (match_operand:MODEF 0 "register_operand" "=f")
16699         (match_operand:MODEF 3 "const_double_operand" "F"))
16700    (set (match_operand:XF 1 "register_operand" "=u")
16701         (unspec:XF [(float_extend:XF
16702                       (match_operand:MODEF 2 "register_operand" "0"))]
16703                    UNSPEC_TAN))]
16704   "TARGET_USE_FANCY_MATH_387
16705    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16706        || TARGET_MIX_SSE_I387)
16707    && flag_unsafe_math_optimizations
16708    && standard_80387_constant_p (operands[3]) == 2"
16709   "fptan"
16710   [(set_attr "type" "fpspc")
16711    (set_attr "mode" "XF")])
16713 (define_expand "tanxf2"
16714   [(use (match_operand:XF 0 "register_operand" ""))
16715    (use (match_operand:XF 1 "register_operand" ""))]
16716   "TARGET_USE_FANCY_MATH_387
16717    && flag_unsafe_math_optimizations"
16719   rtx one = gen_reg_rtx (XFmode);
16720   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16722   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16723   DONE;
16726 (define_expand "tan<mode>2"
16727   [(use (match_operand:MODEF 0 "register_operand" ""))
16728    (use (match_operand:MODEF 1 "register_operand" ""))]
16729   "TARGET_USE_FANCY_MATH_387
16730    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16731        || TARGET_MIX_SSE_I387)
16732    && flag_unsafe_math_optimizations"
16734   rtx op0 = gen_reg_rtx (XFmode);
16736   rtx one = gen_reg_rtx (<MODE>mode);
16737   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16739   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16740                                              operands[1], op2));
16741   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16742   DONE;
16745 (define_insn "*fpatanxf3_i387"
16746   [(set (match_operand:XF 0 "register_operand" "=f")
16747         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16748                     (match_operand:XF 2 "register_operand" "u")]
16749                    UNSPEC_FPATAN))
16750    (clobber (match_scratch:XF 3 "=2"))]
16751   "TARGET_USE_FANCY_MATH_387
16752    && flag_unsafe_math_optimizations"
16753   "fpatan"
16754   [(set_attr "type" "fpspc")
16755    (set_attr "mode" "XF")])
16757 (define_insn "fpatan_extend<mode>xf3_i387"
16758   [(set (match_operand:XF 0 "register_operand" "=f")
16759         (unspec:XF [(float_extend:XF
16760                       (match_operand:MODEF 1 "register_operand" "0"))
16761                     (float_extend:XF
16762                       (match_operand:MODEF 2 "register_operand" "u"))]
16763                    UNSPEC_FPATAN))
16764    (clobber (match_scratch:XF 3 "=2"))]
16765   "TARGET_USE_FANCY_MATH_387
16766    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16767        || TARGET_MIX_SSE_I387)
16768    && flag_unsafe_math_optimizations"
16769   "fpatan"
16770   [(set_attr "type" "fpspc")
16771    (set_attr "mode" "XF")])
16773 (define_expand "atan2xf3"
16774   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16775                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16776                                (match_operand:XF 1 "register_operand" "")]
16777                               UNSPEC_FPATAN))
16778               (clobber (match_scratch:XF 3 ""))])]
16779   "TARGET_USE_FANCY_MATH_387
16780    && flag_unsafe_math_optimizations"
16781   "")
16783 (define_expand "atan2<mode>3"
16784   [(use (match_operand:MODEF 0 "register_operand" ""))
16785    (use (match_operand:MODEF 1 "register_operand" ""))
16786    (use (match_operand:MODEF 2 "register_operand" ""))]
16787   "TARGET_USE_FANCY_MATH_387
16788    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16789        || TARGET_MIX_SSE_I387)
16790    && flag_unsafe_math_optimizations"
16792   rtx op0 = gen_reg_rtx (XFmode);
16794   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16795   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16796   DONE;
16799 (define_expand "atanxf2"
16800   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16801                    (unspec:XF [(match_dup 2)
16802                                (match_operand:XF 1 "register_operand" "")]
16803                               UNSPEC_FPATAN))
16804               (clobber (match_scratch:XF 3 ""))])]
16805   "TARGET_USE_FANCY_MATH_387
16806    && flag_unsafe_math_optimizations"
16808   operands[2] = gen_reg_rtx (XFmode);
16809   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16812 (define_expand "atan<mode>2"
16813   [(use (match_operand:MODEF 0 "register_operand" ""))
16814    (use (match_operand:MODEF 1 "register_operand" ""))]
16815   "TARGET_USE_FANCY_MATH_387
16816    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16817        || TARGET_MIX_SSE_I387)
16818    && flag_unsafe_math_optimizations"
16820   rtx op0 = gen_reg_rtx (XFmode);
16822   rtx op2 = gen_reg_rtx (<MODE>mode);
16823   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16825   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16826   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16827   DONE;
16830 (define_expand "asinxf2"
16831   [(set (match_dup 2)
16832         (mult:XF (match_operand:XF 1 "register_operand" "")
16833                  (match_dup 1)))
16834    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16835    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16836    (parallel [(set (match_operand:XF 0 "register_operand" "")
16837                    (unspec:XF [(match_dup 5) (match_dup 1)]
16838                               UNSPEC_FPATAN))
16839               (clobber (match_scratch:XF 6 ""))])]
16840   "TARGET_USE_FANCY_MATH_387
16841    && flag_unsafe_math_optimizations && !optimize_size"
16843   int i;
16845   for (i = 2; i < 6; i++)
16846     operands[i] = gen_reg_rtx (XFmode);
16848   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16851 (define_expand "asin<mode>2"
16852   [(use (match_operand:MODEF 0 "register_operand" ""))
16853    (use (match_operand:MODEF 1 "general_operand" ""))]
16854  "TARGET_USE_FANCY_MATH_387
16855    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16856        || TARGET_MIX_SSE_I387)
16857    && flag_unsafe_math_optimizations && !optimize_size"
16859   rtx op0 = gen_reg_rtx (XFmode);
16860   rtx op1 = gen_reg_rtx (XFmode);
16862   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16863   emit_insn (gen_asinxf2 (op0, op1));
16864   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16865   DONE;
16868 (define_expand "acosxf2"
16869   [(set (match_dup 2)
16870         (mult:XF (match_operand:XF 1 "register_operand" "")
16871                  (match_dup 1)))
16872    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16873    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16874    (parallel [(set (match_operand:XF 0 "register_operand" "")
16875                    (unspec:XF [(match_dup 1) (match_dup 5)]
16876                               UNSPEC_FPATAN))
16877               (clobber (match_scratch:XF 6 ""))])]
16878   "TARGET_USE_FANCY_MATH_387
16879    && flag_unsafe_math_optimizations && !optimize_size"
16881   int i;
16883   for (i = 2; i < 6; i++)
16884     operands[i] = gen_reg_rtx (XFmode);
16886   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16889 (define_expand "acos<mode>2"
16890   [(use (match_operand:MODEF 0 "register_operand" ""))
16891    (use (match_operand:MODEF 1 "general_operand" ""))]
16892  "TARGET_USE_FANCY_MATH_387
16893    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16894        || TARGET_MIX_SSE_I387)
16895    && flag_unsafe_math_optimizations && !optimize_size"
16897   rtx op0 = gen_reg_rtx (XFmode);
16898   rtx op1 = gen_reg_rtx (XFmode);
16900   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16901   emit_insn (gen_acosxf2 (op0, op1));
16902   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16903   DONE;
16906 (define_insn "fyl2xxf3_i387"
16907   [(set (match_operand:XF 0 "register_operand" "=f")
16908         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16909                     (match_operand:XF 2 "register_operand" "u")]
16910                    UNSPEC_FYL2X))
16911    (clobber (match_scratch:XF 3 "=2"))]
16912   "TARGET_USE_FANCY_MATH_387
16913    && flag_unsafe_math_optimizations"
16914   "fyl2x"
16915   [(set_attr "type" "fpspc")
16916    (set_attr "mode" "XF")])
16918 (define_insn "fyl2x_extend<mode>xf3_i387"
16919   [(set (match_operand:XF 0 "register_operand" "=f")
16920         (unspec:XF [(float_extend:XF
16921                       (match_operand:MODEF 1 "register_operand" "0"))
16922                     (match_operand:XF 2 "register_operand" "u")]
16923                    UNSPEC_FYL2X))
16924    (clobber (match_scratch:XF 3 "=2"))]
16925   "TARGET_USE_FANCY_MATH_387
16926    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16927        || TARGET_MIX_SSE_I387)
16928    && flag_unsafe_math_optimizations"
16929   "fyl2x"
16930   [(set_attr "type" "fpspc")
16931    (set_attr "mode" "XF")])
16933 (define_expand "logxf2"
16934   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16935                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16936                                (match_dup 2)] UNSPEC_FYL2X))
16937               (clobber (match_scratch:XF 3 ""))])]
16938   "TARGET_USE_FANCY_MATH_387
16939    && flag_unsafe_math_optimizations"
16941   operands[2] = gen_reg_rtx (XFmode);
16942   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16945 (define_expand "log<mode>2"
16946   [(use (match_operand:MODEF 0 "register_operand" ""))
16947    (use (match_operand:MODEF 1 "register_operand" ""))]
16948   "TARGET_USE_FANCY_MATH_387
16949    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16950        || TARGET_MIX_SSE_I387)
16951    && flag_unsafe_math_optimizations"
16953   rtx op0 = gen_reg_rtx (XFmode);
16955   rtx op2 = gen_reg_rtx (XFmode);
16956   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16958   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16959   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16960   DONE;
16963 (define_expand "log10xf2"
16964   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16965                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16966                                (match_dup 2)] UNSPEC_FYL2X))
16967               (clobber (match_scratch:XF 3 ""))])]
16968   "TARGET_USE_FANCY_MATH_387
16969    && flag_unsafe_math_optimizations"
16971   operands[2] = gen_reg_rtx (XFmode);
16972   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16975 (define_expand "log10<mode>2"
16976   [(use (match_operand:MODEF 0 "register_operand" ""))
16977    (use (match_operand:MODEF 1 "register_operand" ""))]
16978   "TARGET_USE_FANCY_MATH_387
16979    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16980        || TARGET_MIX_SSE_I387)
16981    && flag_unsafe_math_optimizations"
16983   rtx op0 = gen_reg_rtx (XFmode);
16985   rtx op2 = gen_reg_rtx (XFmode);
16986   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16988   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16989   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16990   DONE;
16993 (define_expand "log2xf2"
16994   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16995                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16996                                (match_dup 2)] UNSPEC_FYL2X))
16997               (clobber (match_scratch:XF 3 ""))])]
16998   "TARGET_USE_FANCY_MATH_387
16999    && flag_unsafe_math_optimizations"
17001   operands[2] = gen_reg_rtx (XFmode);
17002   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17005 (define_expand "log2<mode>2"
17006   [(use (match_operand:MODEF 0 "register_operand" ""))
17007    (use (match_operand:MODEF 1 "register_operand" ""))]
17008   "TARGET_USE_FANCY_MATH_387
17009    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17010        || TARGET_MIX_SSE_I387)
17011    && flag_unsafe_math_optimizations"
17013   rtx op0 = gen_reg_rtx (XFmode);
17015   rtx op2 = gen_reg_rtx (XFmode);
17016   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17018   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17019   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17020   DONE;
17023 (define_insn "fyl2xp1xf3_i387"
17024   [(set (match_operand:XF 0 "register_operand" "=f")
17025         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17026                     (match_operand:XF 2 "register_operand" "u")]
17027                    UNSPEC_FYL2XP1))
17028    (clobber (match_scratch:XF 3 "=2"))]
17029   "TARGET_USE_FANCY_MATH_387
17030    && flag_unsafe_math_optimizations"
17031   "fyl2xp1"
17032   [(set_attr "type" "fpspc")
17033    (set_attr "mode" "XF")])
17035 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17036   [(set (match_operand:XF 0 "register_operand" "=f")
17037         (unspec:XF [(float_extend:XF
17038                       (match_operand:MODEF 1 "register_operand" "0"))
17039                     (match_operand:XF 2 "register_operand" "u")]
17040                    UNSPEC_FYL2XP1))
17041    (clobber (match_scratch:XF 3 "=2"))]
17042   "TARGET_USE_FANCY_MATH_387
17043    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17044        || TARGET_MIX_SSE_I387)
17045    && flag_unsafe_math_optimizations"
17046   "fyl2xp1"
17047   [(set_attr "type" "fpspc")
17048    (set_attr "mode" "XF")])
17050 (define_expand "log1pxf2"
17051   [(use (match_operand:XF 0 "register_operand" ""))
17052    (use (match_operand:XF 1 "register_operand" ""))]
17053   "TARGET_USE_FANCY_MATH_387
17054    && flag_unsafe_math_optimizations && !optimize_size"
17056   ix86_emit_i387_log1p (operands[0], operands[1]);
17057   DONE;
17060 (define_expand "log1p<mode>2"
17061   [(use (match_operand:MODEF 0 "register_operand" ""))
17062    (use (match_operand:MODEF 1 "register_operand" ""))]
17063   "TARGET_USE_FANCY_MATH_387
17064    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17065        || TARGET_MIX_SSE_I387)
17066    && flag_unsafe_math_optimizations && !optimize_size"
17068   rtx op0 = gen_reg_rtx (XFmode);
17070   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17072   ix86_emit_i387_log1p (op0, operands[1]);
17073   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17074   DONE;
17077 (define_insn "fxtractxf3_i387"
17078   [(set (match_operand:XF 0 "register_operand" "=f")
17079         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17080                    UNSPEC_XTRACT_FRACT))
17081    (set (match_operand:XF 1 "register_operand" "=u")
17082         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17083   "TARGET_USE_FANCY_MATH_387
17084    && flag_unsafe_math_optimizations"
17085   "fxtract"
17086   [(set_attr "type" "fpspc")
17087    (set_attr "mode" "XF")])
17089 (define_insn "fxtract_extend<mode>xf3_i387"
17090   [(set (match_operand:XF 0 "register_operand" "=f")
17091         (unspec:XF [(float_extend:XF
17092                       (match_operand:MODEF 2 "register_operand" "0"))]
17093                    UNSPEC_XTRACT_FRACT))
17094    (set (match_operand:XF 1 "register_operand" "=u")
17095         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17096   "TARGET_USE_FANCY_MATH_387
17097    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17098        || TARGET_MIX_SSE_I387)
17099    && flag_unsafe_math_optimizations"
17100   "fxtract"
17101   [(set_attr "type" "fpspc")
17102    (set_attr "mode" "XF")])
17104 (define_expand "logbxf2"
17105   [(parallel [(set (match_dup 2)
17106                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17107                               UNSPEC_XTRACT_FRACT))
17108               (set (match_operand:XF 0 "register_operand" "")
17109                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17110   "TARGET_USE_FANCY_MATH_387
17111    && flag_unsafe_math_optimizations"
17113   operands[2] = gen_reg_rtx (XFmode);
17116 (define_expand "logb<mode>2"
17117   [(use (match_operand:MODEF 0 "register_operand" ""))
17118    (use (match_operand:MODEF 1 "register_operand" ""))]
17119   "TARGET_USE_FANCY_MATH_387
17120    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17121        || TARGET_MIX_SSE_I387)
17122    && flag_unsafe_math_optimizations"
17124   rtx op0 = gen_reg_rtx (XFmode);
17125   rtx op1 = gen_reg_rtx (XFmode);
17127   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17128   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17129   DONE;
17132 (define_expand "ilogbxf2"
17133   [(use (match_operand:SI 0 "register_operand" ""))
17134    (use (match_operand:XF 1 "register_operand" ""))]
17135   "TARGET_USE_FANCY_MATH_387
17136    && flag_unsafe_math_optimizations && !optimize_size"
17138   rtx op0 = gen_reg_rtx (XFmode);
17139   rtx op1 = gen_reg_rtx (XFmode);
17141   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17142   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17143   DONE;
17146 (define_expand "ilogb<mode>2"
17147   [(use (match_operand:SI 0 "register_operand" ""))
17148    (use (match_operand:MODEF 1 "register_operand" ""))]
17149   "TARGET_USE_FANCY_MATH_387
17150    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17151        || TARGET_MIX_SSE_I387)
17152    && flag_unsafe_math_optimizations && !optimize_size"
17154   rtx op0 = gen_reg_rtx (XFmode);
17155   rtx op1 = gen_reg_rtx (XFmode);
17157   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17158   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17159   DONE;
17162 (define_insn "*f2xm1xf2_i387"
17163   [(set (match_operand:XF 0 "register_operand" "=f")
17164         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17165                    UNSPEC_F2XM1))]
17166   "TARGET_USE_FANCY_MATH_387
17167    && flag_unsafe_math_optimizations"
17168   "f2xm1"
17169   [(set_attr "type" "fpspc")
17170    (set_attr "mode" "XF")])
17172 (define_insn "*fscalexf4_i387"
17173   [(set (match_operand:XF 0 "register_operand" "=f")
17174         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17175                     (match_operand:XF 3 "register_operand" "1")]
17176                    UNSPEC_FSCALE_FRACT))
17177    (set (match_operand:XF 1 "register_operand" "=u")
17178         (unspec:XF [(match_dup 2) (match_dup 3)]
17179                    UNSPEC_FSCALE_EXP))]
17180   "TARGET_USE_FANCY_MATH_387
17181    && flag_unsafe_math_optimizations"
17182   "fscale"
17183   [(set_attr "type" "fpspc")
17184    (set_attr "mode" "XF")])
17186 (define_expand "expNcorexf3"
17187   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17188                                (match_operand:XF 2 "register_operand" "")))
17189    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17190    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17191    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17192    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17193    (parallel [(set (match_operand:XF 0 "register_operand" "")
17194                    (unspec:XF [(match_dup 8) (match_dup 4)]
17195                               UNSPEC_FSCALE_FRACT))
17196               (set (match_dup 9)
17197                    (unspec:XF [(match_dup 8) (match_dup 4)]
17198                               UNSPEC_FSCALE_EXP))])]
17199   "TARGET_USE_FANCY_MATH_387
17200    && flag_unsafe_math_optimizations && !optimize_size"
17202   int i;
17204   for (i = 3; i < 10; i++)
17205     operands[i] = gen_reg_rtx (XFmode);
17207   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17210 (define_expand "expxf2"
17211   [(use (match_operand:XF 0 "register_operand" ""))
17212    (use (match_operand:XF 1 "register_operand" ""))]
17213   "TARGET_USE_FANCY_MATH_387
17214    && flag_unsafe_math_optimizations && !optimize_size"
17216   rtx op2 = gen_reg_rtx (XFmode);
17217   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17219   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17220   DONE;
17223 (define_expand "exp<mode>2"
17224   [(use (match_operand:MODEF 0 "register_operand" ""))
17225    (use (match_operand:MODEF 1 "general_operand" ""))]
17226  "TARGET_USE_FANCY_MATH_387
17227    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17228        || TARGET_MIX_SSE_I387)
17229    && flag_unsafe_math_optimizations && !optimize_size"
17231   rtx op0 = gen_reg_rtx (XFmode);
17232   rtx op1 = gen_reg_rtx (XFmode);
17234   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17235   emit_insn (gen_expxf2 (op0, op1));
17236   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17237   DONE;
17240 (define_expand "exp10xf2"
17241   [(use (match_operand:XF 0 "register_operand" ""))
17242    (use (match_operand:XF 1 "register_operand" ""))]
17243   "TARGET_USE_FANCY_MATH_387
17244    && flag_unsafe_math_optimizations && !optimize_size"
17246   rtx op2 = gen_reg_rtx (XFmode);
17247   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17249   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17250   DONE;
17253 (define_expand "exp10<mode>2"
17254   [(use (match_operand:MODEF 0 "register_operand" ""))
17255    (use (match_operand:MODEF 1 "general_operand" ""))]
17256  "TARGET_USE_FANCY_MATH_387
17257    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17258        || TARGET_MIX_SSE_I387)
17259    && flag_unsafe_math_optimizations && !optimize_size"
17261   rtx op0 = gen_reg_rtx (XFmode);
17262   rtx op1 = gen_reg_rtx (XFmode);
17264   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17265   emit_insn (gen_exp10xf2 (op0, op1));
17266   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17267   DONE;
17270 (define_expand "exp2xf2"
17271   [(use (match_operand:XF 0 "register_operand" ""))
17272    (use (match_operand:XF 1 "register_operand" ""))]
17273   "TARGET_USE_FANCY_MATH_387
17274    && flag_unsafe_math_optimizations && !optimize_size"
17276   rtx op2 = gen_reg_rtx (XFmode);
17277   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17279   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17280   DONE;
17283 (define_expand "exp2<mode>2"
17284   [(use (match_operand:MODEF 0 "register_operand" ""))
17285    (use (match_operand:MODEF 1 "general_operand" ""))]
17286  "TARGET_USE_FANCY_MATH_387
17287    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17288        || TARGET_MIX_SSE_I387)
17289    && flag_unsafe_math_optimizations && !optimize_size"
17291   rtx op0 = gen_reg_rtx (XFmode);
17292   rtx op1 = gen_reg_rtx (XFmode);
17294   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17295   emit_insn (gen_exp2xf2 (op0, op1));
17296   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17297   DONE;
17300 (define_expand "expm1xf2"
17301   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17302                                (match_dup 2)))
17303    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17304    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17305    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17306    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17307    (parallel [(set (match_dup 7)
17308                    (unspec:XF [(match_dup 6) (match_dup 4)]
17309                               UNSPEC_FSCALE_FRACT))
17310               (set (match_dup 8)
17311                    (unspec:XF [(match_dup 6) (match_dup 4)]
17312                               UNSPEC_FSCALE_EXP))])
17313    (parallel [(set (match_dup 10)
17314                    (unspec:XF [(match_dup 9) (match_dup 8)]
17315                               UNSPEC_FSCALE_FRACT))
17316               (set (match_dup 11)
17317                    (unspec:XF [(match_dup 9) (match_dup 8)]
17318                               UNSPEC_FSCALE_EXP))])
17319    (set (match_dup 12) (minus:XF (match_dup 10)
17320                                  (float_extend:XF (match_dup 13))))
17321    (set (match_operand:XF 0 "register_operand" "")
17322         (plus:XF (match_dup 12) (match_dup 7)))]
17323   "TARGET_USE_FANCY_MATH_387
17324    && flag_unsafe_math_optimizations && !optimize_size"
17326   int i;
17328   for (i = 2; i < 13; i++)
17329     operands[i] = gen_reg_rtx (XFmode);
17331   operands[13]
17332     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17334   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17337 (define_expand "expm1<mode>2"
17338   [(use (match_operand:MODEF 0 "register_operand" ""))
17339    (use (match_operand:MODEF 1 "general_operand" ""))]
17340  "TARGET_USE_FANCY_MATH_387
17341    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17342        || TARGET_MIX_SSE_I387)
17343    && flag_unsafe_math_optimizations && !optimize_size"
17345   rtx op0 = gen_reg_rtx (XFmode);
17346   rtx op1 = gen_reg_rtx (XFmode);
17348   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17349   emit_insn (gen_expm1xf2 (op0, op1));
17350   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17351   DONE;
17354 (define_expand "ldexpxf3"
17355   [(set (match_dup 3)
17356         (float:XF (match_operand:SI 2 "register_operand" "")))
17357    (parallel [(set (match_operand:XF 0 " register_operand" "")
17358                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17359                                (match_dup 3)]
17360                               UNSPEC_FSCALE_FRACT))
17361               (set (match_dup 4)
17362                    (unspec:XF [(match_dup 1) (match_dup 3)]
17363                               UNSPEC_FSCALE_EXP))])]
17364   "TARGET_USE_FANCY_MATH_387
17365    && flag_unsafe_math_optimizations && !optimize_size"
17367   operands[3] = gen_reg_rtx (XFmode);
17368   operands[4] = gen_reg_rtx (XFmode);
17371 (define_expand "ldexp<mode>3"
17372   [(use (match_operand:MODEF 0 "register_operand" ""))
17373    (use (match_operand:MODEF 1 "general_operand" ""))
17374    (use (match_operand:SI 2 "register_operand" ""))]
17375  "TARGET_USE_FANCY_MATH_387
17376    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17377        || TARGET_MIX_SSE_I387)
17378    && flag_unsafe_math_optimizations && !optimize_size"
17380   rtx op0 = gen_reg_rtx (XFmode);
17381   rtx op1 = gen_reg_rtx (XFmode);
17383   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17384   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17385   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17386   DONE;
17389 (define_expand "scalbxf3"
17390   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17391                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17392                                (match_operand:XF 2 "register_operand" "")]
17393                               UNSPEC_FSCALE_FRACT))
17394               (set (match_dup 3)
17395                    (unspec:XF [(match_dup 1) (match_dup 2)]
17396                               UNSPEC_FSCALE_EXP))])]
17397   "TARGET_USE_FANCY_MATH_387
17398    && flag_unsafe_math_optimizations && !optimize_size"
17400   operands[3] = gen_reg_rtx (XFmode);
17403 (define_expand "scalb<mode>3"
17404   [(use (match_operand:MODEF 0 "register_operand" ""))
17405    (use (match_operand:MODEF 1 "general_operand" ""))
17406    (use (match_operand:MODEF 2 "register_operand" ""))]
17407  "TARGET_USE_FANCY_MATH_387
17408    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17409        || TARGET_MIX_SSE_I387)
17410    && flag_unsafe_math_optimizations && !optimize_size"
17412   rtx op0 = gen_reg_rtx (XFmode);
17413   rtx op1 = gen_reg_rtx (XFmode);
17414   rtx op2 = gen_reg_rtx (XFmode);
17416   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17417   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17418   emit_insn (gen_scalbxf3 (op0, op1, op2));
17419   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17420   DONE;
17424 (define_insn "sse4_1_round<mode>2"
17425   [(set (match_operand:MODEF 0 "register_operand" "=x")
17426         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17427                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17428                       UNSPEC_ROUND))]
17429   "TARGET_ROUND"
17430   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17431   [(set_attr "type" "ssecvt")
17432    (set_attr "prefix_extra" "1")
17433    (set_attr "mode" "<MODE>")])
17435 (define_insn "rintxf2"
17436   [(set (match_operand:XF 0 "register_operand" "=f")
17437         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17438                    UNSPEC_FRNDINT))]
17439   "TARGET_USE_FANCY_MATH_387
17440    && flag_unsafe_math_optimizations"
17441   "frndint"
17442   [(set_attr "type" "fpspc")
17443    (set_attr "mode" "XF")])
17445 (define_expand "rint<mode>2"
17446   [(use (match_operand:MODEF 0 "register_operand" ""))
17447    (use (match_operand:MODEF 1 "register_operand" ""))]
17448   "(TARGET_USE_FANCY_MATH_387
17449     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17450         || TARGET_MIX_SSE_I387)
17451     && flag_unsafe_math_optimizations)
17452    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17453        && !flag_trapping_math
17454        && (TARGET_ROUND || !optimize_size))"
17456   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17457       && !flag_trapping_math
17458       && (TARGET_ROUND || !optimize_size))
17459     {
17460       if (TARGET_ROUND)
17461         emit_insn (gen_sse4_1_round<mode>2
17462                    (operands[0], operands[1], GEN_INT (0x04)));
17463       else
17464         ix86_expand_rint (operand0, operand1);
17465     }
17466   else
17467     {
17468       rtx op0 = gen_reg_rtx (XFmode);
17469       rtx op1 = gen_reg_rtx (XFmode);
17471       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17472       emit_insn (gen_rintxf2 (op0, op1));
17474       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17475     }
17476   DONE;
17479 (define_expand "round<mode>2"
17480   [(match_operand:MODEF 0 "register_operand" "")
17481    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17482   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17483    && !flag_trapping_math && !flag_rounding_math
17484    && !optimize_size"
17486   if (TARGET_64BIT || (<MODE>mode != DFmode))
17487     ix86_expand_round (operand0, operand1);
17488   else
17489     ix86_expand_rounddf_32 (operand0, operand1);
17490   DONE;
17493 (define_insn_and_split "*fistdi2_1"
17494   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17495         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17496                    UNSPEC_FIST))]
17497   "TARGET_USE_FANCY_MATH_387
17498    && !(reload_completed || reload_in_progress)"
17499   "#"
17500   "&& 1"
17501   [(const_int 0)]
17503   if (memory_operand (operands[0], VOIDmode))
17504     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17505   else
17506     {
17507       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17508       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17509                                          operands[2]));
17510     }
17511   DONE;
17513   [(set_attr "type" "fpspc")
17514    (set_attr "mode" "DI")])
17516 (define_insn "fistdi2"
17517   [(set (match_operand:DI 0 "memory_operand" "=m")
17518         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17519                    UNSPEC_FIST))
17520    (clobber (match_scratch:XF 2 "=&1f"))]
17521   "TARGET_USE_FANCY_MATH_387"
17522   "* return output_fix_trunc (insn, operands, 0);"
17523   [(set_attr "type" "fpspc")
17524    (set_attr "mode" "DI")])
17526 (define_insn "fistdi2_with_temp"
17527   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17528         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17529                    UNSPEC_FIST))
17530    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17531    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17532   "TARGET_USE_FANCY_MATH_387"
17533   "#"
17534   [(set_attr "type" "fpspc")
17535    (set_attr "mode" "DI")])
17537 (define_split
17538   [(set (match_operand:DI 0 "register_operand" "")
17539         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17540                    UNSPEC_FIST))
17541    (clobber (match_operand:DI 2 "memory_operand" ""))
17542    (clobber (match_scratch 3 ""))]
17543   "reload_completed"
17544   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17545               (clobber (match_dup 3))])
17546    (set (match_dup 0) (match_dup 2))]
17547   "")
17549 (define_split
17550   [(set (match_operand:DI 0 "memory_operand" "")
17551         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17552                    UNSPEC_FIST))
17553    (clobber (match_operand:DI 2 "memory_operand" ""))
17554    (clobber (match_scratch 3 ""))]
17555   "reload_completed"
17556   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17557               (clobber (match_dup 3))])]
17558   "")
17560 (define_insn_and_split "*fist<mode>2_1"
17561   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17562         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17563                            UNSPEC_FIST))]
17564   "TARGET_USE_FANCY_MATH_387
17565    && !(reload_completed || reload_in_progress)"
17566   "#"
17567   "&& 1"
17568   [(const_int 0)]
17570   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17571   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17572                                         operands[2]));
17573   DONE;
17575   [(set_attr "type" "fpspc")
17576    (set_attr "mode" "<MODE>")])
17578 (define_insn "fist<mode>2"
17579   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17580         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17581                            UNSPEC_FIST))]
17582   "TARGET_USE_FANCY_MATH_387"
17583   "* return output_fix_trunc (insn, operands, 0);"
17584   [(set_attr "type" "fpspc")
17585    (set_attr "mode" "<MODE>")])
17587 (define_insn "fist<mode>2_with_temp"
17588   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17589         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17590                            UNSPEC_FIST))
17591    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17592   "TARGET_USE_FANCY_MATH_387"
17593   "#"
17594   [(set_attr "type" "fpspc")
17595    (set_attr "mode" "<MODE>")])
17597 (define_split
17598   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17599         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17600                            UNSPEC_FIST))
17601    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17602   "reload_completed"
17603   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17604    (set (match_dup 0) (match_dup 2))]
17605   "")
17607 (define_split
17608   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17609         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17610                            UNSPEC_FIST))
17611    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17612   "reload_completed"
17613   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17614   "")
17616 (define_expand "lrintxf<mode>2"
17617   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17618      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17619                       UNSPEC_FIST))]
17620   "TARGET_USE_FANCY_MATH_387"
17621   "")
17623 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17624   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17625      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17626                         UNSPEC_FIX_NOTRUNC))]
17627   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17628    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17629   "")
17631 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17632   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17633    (match_operand:MODEF 1 "register_operand" "")]
17634   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17635    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17636    && !flag_trapping_math && !flag_rounding_math
17637    && !optimize_size"
17639   ix86_expand_lround (operand0, operand1);
17640   DONE;
17643 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17644 (define_insn_and_split "frndintxf2_floor"
17645   [(set (match_operand:XF 0 "register_operand" "")
17646         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17647          UNSPEC_FRNDINT_FLOOR))
17648    (clobber (reg:CC FLAGS_REG))]
17649   "TARGET_USE_FANCY_MATH_387
17650    && flag_unsafe_math_optimizations
17651    && !(reload_completed || reload_in_progress)"
17652   "#"
17653   "&& 1"
17654   [(const_int 0)]
17656   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17658   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17659   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17661   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17662                                         operands[2], operands[3]));
17663   DONE;
17665   [(set_attr "type" "frndint")
17666    (set_attr "i387_cw" "floor")
17667    (set_attr "mode" "XF")])
17669 (define_insn "frndintxf2_floor_i387"
17670   [(set (match_operand:XF 0 "register_operand" "=f")
17671         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17672          UNSPEC_FRNDINT_FLOOR))
17673    (use (match_operand:HI 2 "memory_operand" "m"))
17674    (use (match_operand:HI 3 "memory_operand" "m"))]
17675   "TARGET_USE_FANCY_MATH_387
17676    && flag_unsafe_math_optimizations"
17677   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17678   [(set_attr "type" "frndint")
17679    (set_attr "i387_cw" "floor")
17680    (set_attr "mode" "XF")])
17682 (define_expand "floorxf2"
17683   [(use (match_operand:XF 0 "register_operand" ""))
17684    (use (match_operand:XF 1 "register_operand" ""))]
17685   "TARGET_USE_FANCY_MATH_387
17686    && flag_unsafe_math_optimizations && !optimize_size"
17688   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17689   DONE;
17692 (define_expand "floor<mode>2"
17693   [(use (match_operand:MODEF 0 "register_operand" ""))
17694    (use (match_operand:MODEF 1 "register_operand" ""))]
17695   "(TARGET_USE_FANCY_MATH_387
17696     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17697         || TARGET_MIX_SSE_I387)
17698     && flag_unsafe_math_optimizations && !optimize_size)
17699    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17700        && !flag_trapping_math
17701        && (TARGET_ROUND || !optimize_size))"
17703   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17704       && !flag_trapping_math
17705       && (TARGET_ROUND || !optimize_size))
17706     {
17707       if (TARGET_ROUND)
17708         emit_insn (gen_sse4_1_round<mode>2
17709                    (operands[0], operands[1], GEN_INT (0x01)));
17710       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17711         ix86_expand_floorceil (operand0, operand1, true);
17712       else
17713         ix86_expand_floorceildf_32 (operand0, operand1, true);
17714     }
17715   else
17716     {
17717       rtx op0 = gen_reg_rtx (XFmode);
17718       rtx op1 = gen_reg_rtx (XFmode);
17720       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17721       emit_insn (gen_frndintxf2_floor (op0, op1));
17723       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17724     }
17725   DONE;
17728 (define_insn_and_split "*fist<mode>2_floor_1"
17729   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17730         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17731          UNSPEC_FIST_FLOOR))
17732    (clobber (reg:CC FLAGS_REG))]
17733   "TARGET_USE_FANCY_MATH_387
17734    && flag_unsafe_math_optimizations
17735    && !(reload_completed || reload_in_progress)"
17736   "#"
17737   "&& 1"
17738   [(const_int 0)]
17740   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17742   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17743   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17744   if (memory_operand (operands[0], VOIDmode))
17745     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17746                                       operands[2], operands[3]));
17747   else
17748     {
17749       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17750       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17751                                                   operands[2], operands[3],
17752                                                   operands[4]));
17753     }
17754   DONE;
17756   [(set_attr "type" "fistp")
17757    (set_attr "i387_cw" "floor")
17758    (set_attr "mode" "<MODE>")])
17760 (define_insn "fistdi2_floor"
17761   [(set (match_operand:DI 0 "memory_operand" "=m")
17762         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17763          UNSPEC_FIST_FLOOR))
17764    (use (match_operand:HI 2 "memory_operand" "m"))
17765    (use (match_operand:HI 3 "memory_operand" "m"))
17766    (clobber (match_scratch:XF 4 "=&1f"))]
17767   "TARGET_USE_FANCY_MATH_387
17768    && flag_unsafe_math_optimizations"
17769   "* return output_fix_trunc (insn, operands, 0);"
17770   [(set_attr "type" "fistp")
17771    (set_attr "i387_cw" "floor")
17772    (set_attr "mode" "DI")])
17774 (define_insn "fistdi2_floor_with_temp"
17775   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17776         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17777          UNSPEC_FIST_FLOOR))
17778    (use (match_operand:HI 2 "memory_operand" "m,m"))
17779    (use (match_operand:HI 3 "memory_operand" "m,m"))
17780    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17781    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17782   "TARGET_USE_FANCY_MATH_387
17783    && flag_unsafe_math_optimizations"
17784   "#"
17785   [(set_attr "type" "fistp")
17786    (set_attr "i387_cw" "floor")
17787    (set_attr "mode" "DI")])
17789 (define_split
17790   [(set (match_operand:DI 0 "register_operand" "")
17791         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17792          UNSPEC_FIST_FLOOR))
17793    (use (match_operand:HI 2 "memory_operand" ""))
17794    (use (match_operand:HI 3 "memory_operand" ""))
17795    (clobber (match_operand:DI 4 "memory_operand" ""))
17796    (clobber (match_scratch 5 ""))]
17797   "reload_completed"
17798   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17799               (use (match_dup 2))
17800               (use (match_dup 3))
17801               (clobber (match_dup 5))])
17802    (set (match_dup 0) (match_dup 4))]
17803   "")
17805 (define_split
17806   [(set (match_operand:DI 0 "memory_operand" "")
17807         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17808          UNSPEC_FIST_FLOOR))
17809    (use (match_operand:HI 2 "memory_operand" ""))
17810    (use (match_operand:HI 3 "memory_operand" ""))
17811    (clobber (match_operand:DI 4 "memory_operand" ""))
17812    (clobber (match_scratch 5 ""))]
17813   "reload_completed"
17814   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17815               (use (match_dup 2))
17816               (use (match_dup 3))
17817               (clobber (match_dup 5))])]
17818   "")
17820 (define_insn "fist<mode>2_floor"
17821   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17822         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17823          UNSPEC_FIST_FLOOR))
17824    (use (match_operand:HI 2 "memory_operand" "m"))
17825    (use (match_operand:HI 3 "memory_operand" "m"))]
17826   "TARGET_USE_FANCY_MATH_387
17827    && flag_unsafe_math_optimizations"
17828   "* return output_fix_trunc (insn, operands, 0);"
17829   [(set_attr "type" "fistp")
17830    (set_attr "i387_cw" "floor")
17831    (set_attr "mode" "<MODE>")])
17833 (define_insn "fist<mode>2_floor_with_temp"
17834   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17835         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17836          UNSPEC_FIST_FLOOR))
17837    (use (match_operand:HI 2 "memory_operand" "m,m"))
17838    (use (match_operand:HI 3 "memory_operand" "m,m"))
17839    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17840   "TARGET_USE_FANCY_MATH_387
17841    && flag_unsafe_math_optimizations"
17842   "#"
17843   [(set_attr "type" "fistp")
17844    (set_attr "i387_cw" "floor")
17845    (set_attr "mode" "<MODE>")])
17847 (define_split
17848   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17849         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17850          UNSPEC_FIST_FLOOR))
17851    (use (match_operand:HI 2 "memory_operand" ""))
17852    (use (match_operand:HI 3 "memory_operand" ""))
17853    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17854   "reload_completed"
17855   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17856                                   UNSPEC_FIST_FLOOR))
17857               (use (match_dup 2))
17858               (use (match_dup 3))])
17859    (set (match_dup 0) (match_dup 4))]
17860   "")
17862 (define_split
17863   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17864         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17865          UNSPEC_FIST_FLOOR))
17866    (use (match_operand:HI 2 "memory_operand" ""))
17867    (use (match_operand:HI 3 "memory_operand" ""))
17868    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17869   "reload_completed"
17870   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17871                                   UNSPEC_FIST_FLOOR))
17872               (use (match_dup 2))
17873               (use (match_dup 3))])]
17874   "")
17876 (define_expand "lfloorxf<mode>2"
17877   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17878                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17879                     UNSPEC_FIST_FLOOR))
17880               (clobber (reg:CC FLAGS_REG))])]
17881   "TARGET_USE_FANCY_MATH_387
17882    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17883    && flag_unsafe_math_optimizations"
17884   "")
17886 (define_expand "lfloor<mode>di2"
17887   [(match_operand:DI 0 "nonimmediate_operand" "")
17888    (match_operand:MODEF 1 "register_operand" "")]
17889   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17890    && !flag_trapping_math
17891    && !optimize_size"
17893   ix86_expand_lfloorceil (operand0, operand1, true);
17894   DONE;
17897 (define_expand "lfloor<mode>si2"
17898   [(match_operand:SI 0 "nonimmediate_operand" "")
17899    (match_operand:MODEF 1 "register_operand" "")]
17900   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17901    && !flag_trapping_math
17902    && (!optimize_size || !TARGET_64BIT)"
17904   ix86_expand_lfloorceil (operand0, operand1, true);
17905   DONE;
17908 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17909 (define_insn_and_split "frndintxf2_ceil"
17910   [(set (match_operand:XF 0 "register_operand" "")
17911         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17912          UNSPEC_FRNDINT_CEIL))
17913    (clobber (reg:CC FLAGS_REG))]
17914   "TARGET_USE_FANCY_MATH_387
17915    && flag_unsafe_math_optimizations
17916    && !(reload_completed || reload_in_progress)"
17917   "#"
17918   "&& 1"
17919   [(const_int 0)]
17921   ix86_optimize_mode_switching[I387_CEIL] = 1;
17923   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17924   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17926   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17927                                        operands[2], operands[3]));
17928   DONE;
17930   [(set_attr "type" "frndint")
17931    (set_attr "i387_cw" "ceil")
17932    (set_attr "mode" "XF")])
17934 (define_insn "frndintxf2_ceil_i387"
17935   [(set (match_operand:XF 0 "register_operand" "=f")
17936         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17937          UNSPEC_FRNDINT_CEIL))
17938    (use (match_operand:HI 2 "memory_operand" "m"))
17939    (use (match_operand:HI 3 "memory_operand" "m"))]
17940   "TARGET_USE_FANCY_MATH_387
17941    && flag_unsafe_math_optimizations"
17942   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17943   [(set_attr "type" "frndint")
17944    (set_attr "i387_cw" "ceil")
17945    (set_attr "mode" "XF")])
17947 (define_expand "ceilxf2"
17948   [(use (match_operand:XF 0 "register_operand" ""))
17949    (use (match_operand:XF 1 "register_operand" ""))]
17950   "TARGET_USE_FANCY_MATH_387
17951    && flag_unsafe_math_optimizations && !optimize_size"
17953   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17954   DONE;
17957 (define_expand "ceil<mode>2"
17958   [(use (match_operand:MODEF 0 "register_operand" ""))
17959    (use (match_operand:MODEF 1 "register_operand" ""))]
17960   "(TARGET_USE_FANCY_MATH_387
17961     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17962         || TARGET_MIX_SSE_I387)
17963     && flag_unsafe_math_optimizations && !optimize_size)
17964    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17965        && !flag_trapping_math
17966        && (TARGET_ROUND || !optimize_size))"
17968   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17969       && !flag_trapping_math
17970       && (TARGET_ROUND || !optimize_size))
17971     {
17972       if (TARGET_ROUND)
17973         emit_insn (gen_sse4_1_round<mode>2
17974                    (operands[0], operands[1], GEN_INT (0x02)));
17975       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17976         ix86_expand_floorceil (operand0, operand1, false);
17977       else
17978         ix86_expand_floorceildf_32 (operand0, operand1, false);
17979     }
17980   else
17981     {
17982       rtx op0 = gen_reg_rtx (XFmode);
17983       rtx op1 = gen_reg_rtx (XFmode);
17985       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17986       emit_insn (gen_frndintxf2_ceil (op0, op1));
17988       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17989     }
17990   DONE;
17993 (define_insn_and_split "*fist<mode>2_ceil_1"
17994   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17995         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17996          UNSPEC_FIST_CEIL))
17997    (clobber (reg:CC FLAGS_REG))]
17998   "TARGET_USE_FANCY_MATH_387
17999    && flag_unsafe_math_optimizations
18000    && !(reload_completed || reload_in_progress)"
18001   "#"
18002   "&& 1"
18003   [(const_int 0)]
18005   ix86_optimize_mode_switching[I387_CEIL] = 1;
18007   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18008   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18009   if (memory_operand (operands[0], VOIDmode))
18010     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18011                                      operands[2], operands[3]));
18012   else
18013     {
18014       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18015       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18016                                                  operands[2], operands[3],
18017                                                  operands[4]));
18018     }
18019   DONE;
18021   [(set_attr "type" "fistp")
18022    (set_attr "i387_cw" "ceil")
18023    (set_attr "mode" "<MODE>")])
18025 (define_insn "fistdi2_ceil"
18026   [(set (match_operand:DI 0 "memory_operand" "=m")
18027         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18028          UNSPEC_FIST_CEIL))
18029    (use (match_operand:HI 2 "memory_operand" "m"))
18030    (use (match_operand:HI 3 "memory_operand" "m"))
18031    (clobber (match_scratch:XF 4 "=&1f"))]
18032   "TARGET_USE_FANCY_MATH_387
18033    && flag_unsafe_math_optimizations"
18034   "* return output_fix_trunc (insn, operands, 0);"
18035   [(set_attr "type" "fistp")
18036    (set_attr "i387_cw" "ceil")
18037    (set_attr "mode" "DI")])
18039 (define_insn "fistdi2_ceil_with_temp"
18040   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18041         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18042          UNSPEC_FIST_CEIL))
18043    (use (match_operand:HI 2 "memory_operand" "m,m"))
18044    (use (match_operand:HI 3 "memory_operand" "m,m"))
18045    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18046    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18047   "TARGET_USE_FANCY_MATH_387
18048    && flag_unsafe_math_optimizations"
18049   "#"
18050   [(set_attr "type" "fistp")
18051    (set_attr "i387_cw" "ceil")
18052    (set_attr "mode" "DI")])
18054 (define_split
18055   [(set (match_operand:DI 0 "register_operand" "")
18056         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18057          UNSPEC_FIST_CEIL))
18058    (use (match_operand:HI 2 "memory_operand" ""))
18059    (use (match_operand:HI 3 "memory_operand" ""))
18060    (clobber (match_operand:DI 4 "memory_operand" ""))
18061    (clobber (match_scratch 5 ""))]
18062   "reload_completed"
18063   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18064               (use (match_dup 2))
18065               (use (match_dup 3))
18066               (clobber (match_dup 5))])
18067    (set (match_dup 0) (match_dup 4))]
18068   "")
18070 (define_split
18071   [(set (match_operand:DI 0 "memory_operand" "")
18072         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18073          UNSPEC_FIST_CEIL))
18074    (use (match_operand:HI 2 "memory_operand" ""))
18075    (use (match_operand:HI 3 "memory_operand" ""))
18076    (clobber (match_operand:DI 4 "memory_operand" ""))
18077    (clobber (match_scratch 5 ""))]
18078   "reload_completed"
18079   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18080               (use (match_dup 2))
18081               (use (match_dup 3))
18082               (clobber (match_dup 5))])]
18083   "")
18085 (define_insn "fist<mode>2_ceil"
18086   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18087         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18088          UNSPEC_FIST_CEIL))
18089    (use (match_operand:HI 2 "memory_operand" "m"))
18090    (use (match_operand:HI 3 "memory_operand" "m"))]
18091   "TARGET_USE_FANCY_MATH_387
18092    && flag_unsafe_math_optimizations"
18093   "* return output_fix_trunc (insn, operands, 0);"
18094   [(set_attr "type" "fistp")
18095    (set_attr "i387_cw" "ceil")
18096    (set_attr "mode" "<MODE>")])
18098 (define_insn "fist<mode>2_ceil_with_temp"
18099   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18100         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18101          UNSPEC_FIST_CEIL))
18102    (use (match_operand:HI 2 "memory_operand" "m,m"))
18103    (use (match_operand:HI 3 "memory_operand" "m,m"))
18104    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18105   "TARGET_USE_FANCY_MATH_387
18106    && flag_unsafe_math_optimizations"
18107   "#"
18108   [(set_attr "type" "fistp")
18109    (set_attr "i387_cw" "ceil")
18110    (set_attr "mode" "<MODE>")])
18112 (define_split
18113   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18114         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18115          UNSPEC_FIST_CEIL))
18116    (use (match_operand:HI 2 "memory_operand" ""))
18117    (use (match_operand:HI 3 "memory_operand" ""))
18118    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18119   "reload_completed"
18120   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18121                                   UNSPEC_FIST_CEIL))
18122               (use (match_dup 2))
18123               (use (match_dup 3))])
18124    (set (match_dup 0) (match_dup 4))]
18125   "")
18127 (define_split
18128   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18129         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18130          UNSPEC_FIST_CEIL))
18131    (use (match_operand:HI 2 "memory_operand" ""))
18132    (use (match_operand:HI 3 "memory_operand" ""))
18133    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18134   "reload_completed"
18135   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18136                                   UNSPEC_FIST_CEIL))
18137               (use (match_dup 2))
18138               (use (match_dup 3))])]
18139   "")
18141 (define_expand "lceilxf<mode>2"
18142   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18143                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18144                     UNSPEC_FIST_CEIL))
18145               (clobber (reg:CC FLAGS_REG))])]
18146   "TARGET_USE_FANCY_MATH_387
18147    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18148    && flag_unsafe_math_optimizations"
18149   "")
18151 (define_expand "lceil<mode>di2"
18152   [(match_operand:DI 0 "nonimmediate_operand" "")
18153    (match_operand:MODEF 1 "register_operand" "")]
18154   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18155    && !flag_trapping_math"
18157   ix86_expand_lfloorceil (operand0, operand1, false);
18158   DONE;
18161 (define_expand "lceil<mode>si2"
18162   [(match_operand:SI 0 "nonimmediate_operand" "")
18163    (match_operand:MODEF 1 "register_operand" "")]
18164   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18165    && !flag_trapping_math"
18167   ix86_expand_lfloorceil (operand0, operand1, false);
18168   DONE;
18171 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18172 (define_insn_and_split "frndintxf2_trunc"
18173   [(set (match_operand:XF 0 "register_operand" "")
18174         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18175          UNSPEC_FRNDINT_TRUNC))
18176    (clobber (reg:CC FLAGS_REG))]
18177   "TARGET_USE_FANCY_MATH_387
18178    && flag_unsafe_math_optimizations
18179    && !(reload_completed || reload_in_progress)"
18180   "#"
18181   "&& 1"
18182   [(const_int 0)]
18184   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18186   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18187   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18189   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18190                                         operands[2], operands[3]));
18191   DONE;
18193   [(set_attr "type" "frndint")
18194    (set_attr "i387_cw" "trunc")
18195    (set_attr "mode" "XF")])
18197 (define_insn "frndintxf2_trunc_i387"
18198   [(set (match_operand:XF 0 "register_operand" "=f")
18199         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18200          UNSPEC_FRNDINT_TRUNC))
18201    (use (match_operand:HI 2 "memory_operand" "m"))
18202    (use (match_operand:HI 3 "memory_operand" "m"))]
18203   "TARGET_USE_FANCY_MATH_387
18204    && flag_unsafe_math_optimizations"
18205   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18206   [(set_attr "type" "frndint")
18207    (set_attr "i387_cw" "trunc")
18208    (set_attr "mode" "XF")])
18210 (define_expand "btruncxf2"
18211   [(use (match_operand:XF 0 "register_operand" ""))
18212    (use (match_operand:XF 1 "register_operand" ""))]
18213   "TARGET_USE_FANCY_MATH_387
18214    && flag_unsafe_math_optimizations && !optimize_size"
18216   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18217   DONE;
18220 (define_expand "btrunc<mode>2"
18221   [(use (match_operand:MODEF 0 "register_operand" ""))
18222    (use (match_operand:MODEF 1 "register_operand" ""))]
18223   "(TARGET_USE_FANCY_MATH_387
18224     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18225         || TARGET_MIX_SSE_I387)
18226     && flag_unsafe_math_optimizations && !optimize_size)
18227    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18228        && !flag_trapping_math
18229        && (TARGET_ROUND || !optimize_size))"
18231   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18232       && !flag_trapping_math
18233       && (TARGET_ROUND || !optimize_size))
18234     {
18235       if (TARGET_ROUND)
18236         emit_insn (gen_sse4_1_round<mode>2
18237                    (operands[0], operands[1], GEN_INT (0x03)));
18238       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18239         ix86_expand_trunc (operand0, operand1);
18240       else
18241         ix86_expand_truncdf_32 (operand0, operand1);
18242     }
18243   else
18244     {
18245       rtx op0 = gen_reg_rtx (XFmode);
18246       rtx op1 = gen_reg_rtx (XFmode);
18248       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18249       emit_insn (gen_frndintxf2_trunc (op0, op1));
18251       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18252     }
18253   DONE;
18256 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18257 (define_insn_and_split "frndintxf2_mask_pm"
18258   [(set (match_operand:XF 0 "register_operand" "")
18259         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18260          UNSPEC_FRNDINT_MASK_PM))
18261    (clobber (reg:CC FLAGS_REG))]
18262   "TARGET_USE_FANCY_MATH_387
18263    && flag_unsafe_math_optimizations
18264    && !(reload_completed || reload_in_progress)"
18265   "#"
18266   "&& 1"
18267   [(const_int 0)]
18269   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18271   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18272   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18274   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18275                                           operands[2], operands[3]));
18276   DONE;
18278   [(set_attr "type" "frndint")
18279    (set_attr "i387_cw" "mask_pm")
18280    (set_attr "mode" "XF")])
18282 (define_insn "frndintxf2_mask_pm_i387"
18283   [(set (match_operand:XF 0 "register_operand" "=f")
18284         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18285          UNSPEC_FRNDINT_MASK_PM))
18286    (use (match_operand:HI 2 "memory_operand" "m"))
18287    (use (match_operand:HI 3 "memory_operand" "m"))]
18288   "TARGET_USE_FANCY_MATH_387
18289    && flag_unsafe_math_optimizations"
18290   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18291   [(set_attr "type" "frndint")
18292    (set_attr "i387_cw" "mask_pm")
18293    (set_attr "mode" "XF")])
18295 (define_expand "nearbyintxf2"
18296   [(use (match_operand:XF 0 "register_operand" ""))
18297    (use (match_operand:XF 1 "register_operand" ""))]
18298   "TARGET_USE_FANCY_MATH_387
18299    && flag_unsafe_math_optimizations"
18301   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18303   DONE;
18306 (define_expand "nearbyint<mode>2"
18307   [(use (match_operand:MODEF 0 "register_operand" ""))
18308    (use (match_operand:MODEF 1 "register_operand" ""))]
18309   "TARGET_USE_FANCY_MATH_387
18310    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18311        || TARGET_MIX_SSE_I387)
18312    && flag_unsafe_math_optimizations"
18314   rtx op0 = gen_reg_rtx (XFmode);
18315   rtx op1 = gen_reg_rtx (XFmode);
18317   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18318   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18320   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18321   DONE;
18324 (define_insn "fxam<mode>2_i387"
18325   [(set (match_operand:HI 0 "register_operand" "=a")
18326         (unspec:HI
18327           [(match_operand:X87MODEF 1 "register_operand" "f")]
18328           UNSPEC_FXAM))]
18329   "TARGET_USE_FANCY_MATH_387"
18330   "fxam\n\tfnstsw\t%0"
18331   [(set_attr "type" "multi")
18332    (set_attr "unit" "i387")
18333    (set_attr "mode" "<MODE>")])
18335 (define_expand "isinf<mode>2"
18336   [(use (match_operand:SI 0 "register_operand" ""))
18337    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18338   "TARGET_USE_FANCY_MATH_387
18339    && TARGET_C99_FUNCTIONS
18340    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18342   rtx mask = GEN_INT (0x45);
18343   rtx val = GEN_INT (0x05);
18345   rtx cond;
18347   rtx scratch = gen_reg_rtx (HImode);
18348   rtx res = gen_reg_rtx (QImode);
18350   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18351   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18352   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18353   cond = gen_rtx_fmt_ee (EQ, QImode,
18354                          gen_rtx_REG (CCmode, FLAGS_REG),
18355                          const0_rtx);
18356   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18357   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18358   DONE;
18361 (define_expand "signbit<mode>2"
18362   [(use (match_operand:SI 0 "register_operand" ""))
18363    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18364   "TARGET_USE_FANCY_MATH_387
18365    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18367   rtx mask = GEN_INT (0x0200);
18369   rtx scratch = gen_reg_rtx (HImode);
18371   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18372   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18373   DONE;
18376 ;; Block operation instructions
18378 (define_insn "cld"
18379   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18380   ""
18381   "cld"
18382   [(set_attr "length" "1")
18383    (set_attr "length_immediate" "0")
18384    (set_attr "modrm" "0")])
18386 (define_expand "movmemsi"
18387   [(use (match_operand:BLK 0 "memory_operand" ""))
18388    (use (match_operand:BLK 1 "memory_operand" ""))
18389    (use (match_operand:SI 2 "nonmemory_operand" ""))
18390    (use (match_operand:SI 3 "const_int_operand" ""))
18391    (use (match_operand:SI 4 "const_int_operand" ""))
18392    (use (match_operand:SI 5 "const_int_operand" ""))]
18393   ""
18395  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18396                          operands[4], operands[5]))
18397    DONE;
18398  else
18399    FAIL;
18402 (define_expand "movmemdi"
18403   [(use (match_operand:BLK 0 "memory_operand" ""))
18404    (use (match_operand:BLK 1 "memory_operand" ""))
18405    (use (match_operand:DI 2 "nonmemory_operand" ""))
18406    (use (match_operand:DI 3 "const_int_operand" ""))
18407    (use (match_operand:SI 4 "const_int_operand" ""))
18408    (use (match_operand:SI 5 "const_int_operand" ""))]
18409   "TARGET_64BIT"
18411  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18412                          operands[4], operands[5]))
18413    DONE;
18414  else
18415    FAIL;
18418 ;; Most CPUs don't like single string operations
18419 ;; Handle this case here to simplify previous expander.
18421 (define_expand "strmov"
18422   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18423    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18424    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18425               (clobber (reg:CC FLAGS_REG))])
18426    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18427               (clobber (reg:CC FLAGS_REG))])]
18428   ""
18430   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18432   /* If .md ever supports :P for Pmode, these can be directly
18433      in the pattern above.  */
18434   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18435   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18437   /* Can't use this if the user has appropriated esi or edi.  */
18438   if ((TARGET_SINGLE_STRINGOP || optimize_size)
18439       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18440     {
18441       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18442                                       operands[2], operands[3],
18443                                       operands[5], operands[6]));
18444       DONE;
18445     }
18447   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18450 (define_expand "strmov_singleop"
18451   [(parallel [(set (match_operand 1 "memory_operand" "")
18452                    (match_operand 3 "memory_operand" ""))
18453               (set (match_operand 0 "register_operand" "")
18454                    (match_operand 4 "" ""))
18455               (set (match_operand 2 "register_operand" "")
18456                    (match_operand 5 "" ""))])]
18457   "TARGET_SINGLE_STRINGOP || optimize_size"
18458   "ix86_current_function_needs_cld = 1;")
18460 (define_insn "*strmovdi_rex_1"
18461   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18462         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18463    (set (match_operand:DI 0 "register_operand" "=D")
18464         (plus:DI (match_dup 2)
18465                  (const_int 8)))
18466    (set (match_operand:DI 1 "register_operand" "=S")
18467         (plus:DI (match_dup 3)
18468                  (const_int 8)))]
18469   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18470   "movsq"
18471   [(set_attr "type" "str")
18472    (set_attr "mode" "DI")
18473    (set_attr "memory" "both")])
18475 (define_insn "*strmovsi_1"
18476   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18477         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18478    (set (match_operand:SI 0 "register_operand" "=D")
18479         (plus:SI (match_dup 2)
18480                  (const_int 4)))
18481    (set (match_operand:SI 1 "register_operand" "=S")
18482         (plus:SI (match_dup 3)
18483                  (const_int 4)))]
18484   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18485   "movs{l|d}"
18486   [(set_attr "type" "str")
18487    (set_attr "mode" "SI")
18488    (set_attr "memory" "both")])
18490 (define_insn "*strmovsi_rex_1"
18491   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18492         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18493    (set (match_operand:DI 0 "register_operand" "=D")
18494         (plus:DI (match_dup 2)
18495                  (const_int 4)))
18496    (set (match_operand:DI 1 "register_operand" "=S")
18497         (plus:DI (match_dup 3)
18498                  (const_int 4)))]
18499   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18500   "movs{l|d}"
18501   [(set_attr "type" "str")
18502    (set_attr "mode" "SI")
18503    (set_attr "memory" "both")])
18505 (define_insn "*strmovhi_1"
18506   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18507         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18508    (set (match_operand:SI 0 "register_operand" "=D")
18509         (plus:SI (match_dup 2)
18510                  (const_int 2)))
18511    (set (match_operand:SI 1 "register_operand" "=S")
18512         (plus:SI (match_dup 3)
18513                  (const_int 2)))]
18514   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18515   "movsw"
18516   [(set_attr "type" "str")
18517    (set_attr "memory" "both")
18518    (set_attr "mode" "HI")])
18520 (define_insn "*strmovhi_rex_1"
18521   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18522         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18523    (set (match_operand:DI 0 "register_operand" "=D")
18524         (plus:DI (match_dup 2)
18525                  (const_int 2)))
18526    (set (match_operand:DI 1 "register_operand" "=S")
18527         (plus:DI (match_dup 3)
18528                  (const_int 2)))]
18529   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18530   "movsw"
18531   [(set_attr "type" "str")
18532    (set_attr "memory" "both")
18533    (set_attr "mode" "HI")])
18535 (define_insn "*strmovqi_1"
18536   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18537         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18538    (set (match_operand:SI 0 "register_operand" "=D")
18539         (plus:SI (match_dup 2)
18540                  (const_int 1)))
18541    (set (match_operand:SI 1 "register_operand" "=S")
18542         (plus:SI (match_dup 3)
18543                  (const_int 1)))]
18544   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18545   "movsb"
18546   [(set_attr "type" "str")
18547    (set_attr "memory" "both")
18548    (set_attr "mode" "QI")])
18550 (define_insn "*strmovqi_rex_1"
18551   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18552         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18553    (set (match_operand:DI 0 "register_operand" "=D")
18554         (plus:DI (match_dup 2)
18555                  (const_int 1)))
18556    (set (match_operand:DI 1 "register_operand" "=S")
18557         (plus:DI (match_dup 3)
18558                  (const_int 1)))]
18559   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18560   "movsb"
18561   [(set_attr "type" "str")
18562    (set_attr "memory" "both")
18563    (set_attr "mode" "QI")])
18565 (define_expand "rep_mov"
18566   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18567               (set (match_operand 0 "register_operand" "")
18568                    (match_operand 5 "" ""))
18569               (set (match_operand 2 "register_operand" "")
18570                    (match_operand 6 "" ""))
18571               (set (match_operand 1 "memory_operand" "")
18572                    (match_operand 3 "memory_operand" ""))
18573               (use (match_dup 4))])]
18574   ""
18575   "ix86_current_function_needs_cld = 1;")
18577 (define_insn "*rep_movdi_rex64"
18578   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18579    (set (match_operand:DI 0 "register_operand" "=D")
18580         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18581                             (const_int 3))
18582                  (match_operand:DI 3 "register_operand" "0")))
18583    (set (match_operand:DI 1 "register_operand" "=S")
18584         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18585                  (match_operand:DI 4 "register_operand" "1")))
18586    (set (mem:BLK (match_dup 3))
18587         (mem:BLK (match_dup 4)))
18588    (use (match_dup 5))]
18589   "TARGET_64BIT"
18590   "rep movsq"
18591   [(set_attr "type" "str")
18592    (set_attr "prefix_rep" "1")
18593    (set_attr "memory" "both")
18594    (set_attr "mode" "DI")])
18596 (define_insn "*rep_movsi"
18597   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18598    (set (match_operand:SI 0 "register_operand" "=D")
18599         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18600                             (const_int 2))
18601                  (match_operand:SI 3 "register_operand" "0")))
18602    (set (match_operand:SI 1 "register_operand" "=S")
18603         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18604                  (match_operand:SI 4 "register_operand" "1")))
18605    (set (mem:BLK (match_dup 3))
18606         (mem:BLK (match_dup 4)))
18607    (use (match_dup 5))]
18608   "!TARGET_64BIT"
18609   "rep movs{l|d}"
18610   [(set_attr "type" "str")
18611    (set_attr "prefix_rep" "1")
18612    (set_attr "memory" "both")
18613    (set_attr "mode" "SI")])
18615 (define_insn "*rep_movsi_rex64"
18616   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18617    (set (match_operand:DI 0 "register_operand" "=D")
18618         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18619                             (const_int 2))
18620                  (match_operand:DI 3 "register_operand" "0")))
18621    (set (match_operand:DI 1 "register_operand" "=S")
18622         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18623                  (match_operand:DI 4 "register_operand" "1")))
18624    (set (mem:BLK (match_dup 3))
18625         (mem:BLK (match_dup 4)))
18626    (use (match_dup 5))]
18627   "TARGET_64BIT"
18628   "rep movs{l|d}"
18629   [(set_attr "type" "str")
18630    (set_attr "prefix_rep" "1")
18631    (set_attr "memory" "both")
18632    (set_attr "mode" "SI")])
18634 (define_insn "*rep_movqi"
18635   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18636    (set (match_operand:SI 0 "register_operand" "=D")
18637         (plus:SI (match_operand:SI 3 "register_operand" "0")
18638                  (match_operand:SI 5 "register_operand" "2")))
18639    (set (match_operand:SI 1 "register_operand" "=S")
18640         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18641    (set (mem:BLK (match_dup 3))
18642         (mem:BLK (match_dup 4)))
18643    (use (match_dup 5))]
18644   "!TARGET_64BIT"
18645   "rep movsb"
18646   [(set_attr "type" "str")
18647    (set_attr "prefix_rep" "1")
18648    (set_attr "memory" "both")
18649    (set_attr "mode" "SI")])
18651 (define_insn "*rep_movqi_rex64"
18652   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18653    (set (match_operand:DI 0 "register_operand" "=D")
18654         (plus:DI (match_operand:DI 3 "register_operand" "0")
18655                  (match_operand:DI 5 "register_operand" "2")))
18656    (set (match_operand:DI 1 "register_operand" "=S")
18657         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18658    (set (mem:BLK (match_dup 3))
18659         (mem:BLK (match_dup 4)))
18660    (use (match_dup 5))]
18661   "TARGET_64BIT"
18662   "rep movsb"
18663   [(set_attr "type" "str")
18664    (set_attr "prefix_rep" "1")
18665    (set_attr "memory" "both")
18666    (set_attr "mode" "SI")])
18668 (define_expand "setmemsi"
18669    [(use (match_operand:BLK 0 "memory_operand" ""))
18670     (use (match_operand:SI 1 "nonmemory_operand" ""))
18671     (use (match_operand 2 "const_int_operand" ""))
18672     (use (match_operand 3 "const_int_operand" ""))
18673     (use (match_operand:SI 4 "const_int_operand" ""))
18674     (use (match_operand:SI 5 "const_int_operand" ""))]
18675   ""
18677  if (ix86_expand_setmem (operands[0], operands[1],
18678                          operands[2], operands[3],
18679                          operands[4], operands[5]))
18680    DONE;
18681  else
18682    FAIL;
18685 (define_expand "setmemdi"
18686    [(use (match_operand:BLK 0 "memory_operand" ""))
18687     (use (match_operand:DI 1 "nonmemory_operand" ""))
18688     (use (match_operand 2 "const_int_operand" ""))
18689     (use (match_operand 3 "const_int_operand" ""))
18690     (use (match_operand 4 "const_int_operand" ""))
18691     (use (match_operand 5 "const_int_operand" ""))]
18692   "TARGET_64BIT"
18694  if (ix86_expand_setmem (operands[0], operands[1],
18695                          operands[2], operands[3],
18696                          operands[4], operands[5]))
18697    DONE;
18698  else
18699    FAIL;
18702 ;; Most CPUs don't like single string operations
18703 ;; Handle this case here to simplify previous expander.
18705 (define_expand "strset"
18706   [(set (match_operand 1 "memory_operand" "")
18707         (match_operand 2 "register_operand" ""))
18708    (parallel [(set (match_operand 0 "register_operand" "")
18709                    (match_dup 3))
18710               (clobber (reg:CC FLAGS_REG))])]
18711   ""
18713   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18714     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18716   /* If .md ever supports :P for Pmode, this can be directly
18717      in the pattern above.  */
18718   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18719                               GEN_INT (GET_MODE_SIZE (GET_MODE
18720                                                       (operands[2]))));
18721   if (TARGET_SINGLE_STRINGOP || optimize_size)
18722     {
18723       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18724                                       operands[3]));
18725       DONE;
18726     }
18729 (define_expand "strset_singleop"
18730   [(parallel [(set (match_operand 1 "memory_operand" "")
18731                    (match_operand 2 "register_operand" ""))
18732               (set (match_operand 0 "register_operand" "")
18733                    (match_operand 3 "" ""))])]
18734   "TARGET_SINGLE_STRINGOP || optimize_size"
18735   "ix86_current_function_needs_cld = 1;")
18737 (define_insn "*strsetdi_rex_1"
18738   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18739         (match_operand:DI 2 "register_operand" "a"))
18740    (set (match_operand:DI 0 "register_operand" "=D")
18741         (plus:DI (match_dup 1)
18742                  (const_int 8)))]
18743   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18744   "stosq"
18745   [(set_attr "type" "str")
18746    (set_attr "memory" "store")
18747    (set_attr "mode" "DI")])
18749 (define_insn "*strsetsi_1"
18750   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18751         (match_operand:SI 2 "register_operand" "a"))
18752    (set (match_operand:SI 0 "register_operand" "=D")
18753         (plus:SI (match_dup 1)
18754                  (const_int 4)))]
18755   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18756   "stos{l|d}"
18757   [(set_attr "type" "str")
18758    (set_attr "memory" "store")
18759    (set_attr "mode" "SI")])
18761 (define_insn "*strsetsi_rex_1"
18762   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18763         (match_operand:SI 2 "register_operand" "a"))
18764    (set (match_operand:DI 0 "register_operand" "=D")
18765         (plus:DI (match_dup 1)
18766                  (const_int 4)))]
18767   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18768   "stos{l|d}"
18769   [(set_attr "type" "str")
18770    (set_attr "memory" "store")
18771    (set_attr "mode" "SI")])
18773 (define_insn "*strsethi_1"
18774   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18775         (match_operand:HI 2 "register_operand" "a"))
18776    (set (match_operand:SI 0 "register_operand" "=D")
18777         (plus:SI (match_dup 1)
18778                  (const_int 2)))]
18779   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18780   "stosw"
18781   [(set_attr "type" "str")
18782    (set_attr "memory" "store")
18783    (set_attr "mode" "HI")])
18785 (define_insn "*strsethi_rex_1"
18786   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18787         (match_operand:HI 2 "register_operand" "a"))
18788    (set (match_operand:DI 0 "register_operand" "=D")
18789         (plus:DI (match_dup 1)
18790                  (const_int 2)))]
18791   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18792   "stosw"
18793   [(set_attr "type" "str")
18794    (set_attr "memory" "store")
18795    (set_attr "mode" "HI")])
18797 (define_insn "*strsetqi_1"
18798   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18799         (match_operand:QI 2 "register_operand" "a"))
18800    (set (match_operand:SI 0 "register_operand" "=D")
18801         (plus:SI (match_dup 1)
18802                  (const_int 1)))]
18803   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18804   "stosb"
18805   [(set_attr "type" "str")
18806    (set_attr "memory" "store")
18807    (set_attr "mode" "QI")])
18809 (define_insn "*strsetqi_rex_1"
18810   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18811         (match_operand:QI 2 "register_operand" "a"))
18812    (set (match_operand:DI 0 "register_operand" "=D")
18813         (plus:DI (match_dup 1)
18814                  (const_int 1)))]
18815   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18816   "stosb"
18817   [(set_attr "type" "str")
18818    (set_attr "memory" "store")
18819    (set_attr "mode" "QI")])
18821 (define_expand "rep_stos"
18822   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18823               (set (match_operand 0 "register_operand" "")
18824                    (match_operand 4 "" ""))
18825               (set (match_operand 2 "memory_operand" "") (const_int 0))
18826               (use (match_operand 3 "register_operand" ""))
18827               (use (match_dup 1))])]
18828   ""
18829   "ix86_current_function_needs_cld = 1;")
18831 (define_insn "*rep_stosdi_rex64"
18832   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18833    (set (match_operand:DI 0 "register_operand" "=D")
18834         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18835                             (const_int 3))
18836                  (match_operand:DI 3 "register_operand" "0")))
18837    (set (mem:BLK (match_dup 3))
18838         (const_int 0))
18839    (use (match_operand:DI 2 "register_operand" "a"))
18840    (use (match_dup 4))]
18841   "TARGET_64BIT"
18842   "rep stosq"
18843   [(set_attr "type" "str")
18844    (set_attr "prefix_rep" "1")
18845    (set_attr "memory" "store")
18846    (set_attr "mode" "DI")])
18848 (define_insn "*rep_stossi"
18849   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18850    (set (match_operand:SI 0 "register_operand" "=D")
18851         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18852                             (const_int 2))
18853                  (match_operand:SI 3 "register_operand" "0")))
18854    (set (mem:BLK (match_dup 3))
18855         (const_int 0))
18856    (use (match_operand:SI 2 "register_operand" "a"))
18857    (use (match_dup 4))]
18858   "!TARGET_64BIT"
18859   "rep stos{l|d}"
18860   [(set_attr "type" "str")
18861    (set_attr "prefix_rep" "1")
18862    (set_attr "memory" "store")
18863    (set_attr "mode" "SI")])
18865 (define_insn "*rep_stossi_rex64"
18866   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18867    (set (match_operand:DI 0 "register_operand" "=D")
18868         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18869                             (const_int 2))
18870                  (match_operand:DI 3 "register_operand" "0")))
18871    (set (mem:BLK (match_dup 3))
18872         (const_int 0))
18873    (use (match_operand:SI 2 "register_operand" "a"))
18874    (use (match_dup 4))]
18875   "TARGET_64BIT"
18876   "rep stos{l|d}"
18877   [(set_attr "type" "str")
18878    (set_attr "prefix_rep" "1")
18879    (set_attr "memory" "store")
18880    (set_attr "mode" "SI")])
18882 (define_insn "*rep_stosqi"
18883   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18884    (set (match_operand:SI 0 "register_operand" "=D")
18885         (plus:SI (match_operand:SI 3 "register_operand" "0")
18886                  (match_operand:SI 4 "register_operand" "1")))
18887    (set (mem:BLK (match_dup 3))
18888         (const_int 0))
18889    (use (match_operand:QI 2 "register_operand" "a"))
18890    (use (match_dup 4))]
18891   "!TARGET_64BIT"
18892   "rep stosb"
18893   [(set_attr "type" "str")
18894    (set_attr "prefix_rep" "1")
18895    (set_attr "memory" "store")
18896    (set_attr "mode" "QI")])
18898 (define_insn "*rep_stosqi_rex64"
18899   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18900    (set (match_operand:DI 0 "register_operand" "=D")
18901         (plus:DI (match_operand:DI 3 "register_operand" "0")
18902                  (match_operand:DI 4 "register_operand" "1")))
18903    (set (mem:BLK (match_dup 3))
18904         (const_int 0))
18905    (use (match_operand:QI 2 "register_operand" "a"))
18906    (use (match_dup 4))]
18907   "TARGET_64BIT"
18908   "rep stosb"
18909   [(set_attr "type" "str")
18910    (set_attr "prefix_rep" "1")
18911    (set_attr "memory" "store")
18912    (set_attr "mode" "QI")])
18914 (define_expand "cmpstrnsi"
18915   [(set (match_operand:SI 0 "register_operand" "")
18916         (compare:SI (match_operand:BLK 1 "general_operand" "")
18917                     (match_operand:BLK 2 "general_operand" "")))
18918    (use (match_operand 3 "general_operand" ""))
18919    (use (match_operand 4 "immediate_operand" ""))]
18920   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18922   rtx addr1, addr2, out, outlow, count, countreg, align;
18924   /* Can't use this if the user has appropriated esi or edi.  */
18925   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18926     FAIL;
18928   out = operands[0];
18929   if (!REG_P (out))
18930     out = gen_reg_rtx (SImode);
18932   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18933   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18934   if (addr1 != XEXP (operands[1], 0))
18935     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18936   if (addr2 != XEXP (operands[2], 0))
18937     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18939   count = operands[3];
18940   countreg = ix86_zero_extend_to_Pmode (count);
18942   /* %%% Iff we are testing strict equality, we can use known alignment
18943      to good advantage.  This may be possible with combine, particularly
18944      once cc0 is dead.  */
18945   align = operands[4];
18947   if (CONST_INT_P (count))
18948     {
18949       if (INTVAL (count) == 0)
18950         {
18951           emit_move_insn (operands[0], const0_rtx);
18952           DONE;
18953         }
18954       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18955                                      operands[1], operands[2]));
18956     }
18957   else
18958     {
18959       if (TARGET_64BIT)
18960         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18961       else
18962         emit_insn (gen_cmpsi_1 (countreg, countreg));
18963       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18964                                   operands[1], operands[2]));
18965     }
18967   outlow = gen_lowpart (QImode, out);
18968   emit_insn (gen_cmpintqi (outlow));
18969   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18971   if (operands[0] != out)
18972     emit_move_insn (operands[0], out);
18974   DONE;
18977 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18979 (define_expand "cmpintqi"
18980   [(set (match_dup 1)
18981         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18982    (set (match_dup 2)
18983         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18984    (parallel [(set (match_operand:QI 0 "register_operand" "")
18985                    (minus:QI (match_dup 1)
18986                              (match_dup 2)))
18987               (clobber (reg:CC FLAGS_REG))])]
18988   ""
18989   "operands[1] = gen_reg_rtx (QImode);
18990    operands[2] = gen_reg_rtx (QImode);")
18992 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18993 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18995 (define_expand "cmpstrnqi_nz_1"
18996   [(parallel [(set (reg:CC FLAGS_REG)
18997                    (compare:CC (match_operand 4 "memory_operand" "")
18998                                (match_operand 5 "memory_operand" "")))
18999               (use (match_operand 2 "register_operand" ""))
19000               (use (match_operand:SI 3 "immediate_operand" ""))
19001               (clobber (match_operand 0 "register_operand" ""))
19002               (clobber (match_operand 1 "register_operand" ""))
19003               (clobber (match_dup 2))])]
19004   ""
19005   "ix86_current_function_needs_cld = 1;")
19007 (define_insn "*cmpstrnqi_nz_1"
19008   [(set (reg:CC FLAGS_REG)
19009         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19010                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19011    (use (match_operand:SI 6 "register_operand" "2"))
19012    (use (match_operand:SI 3 "immediate_operand" "i"))
19013    (clobber (match_operand:SI 0 "register_operand" "=S"))
19014    (clobber (match_operand:SI 1 "register_operand" "=D"))
19015    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19016   "!TARGET_64BIT"
19017   "repz cmpsb"
19018   [(set_attr "type" "str")
19019    (set_attr "mode" "QI")
19020    (set_attr "prefix_rep" "1")])
19022 (define_insn "*cmpstrnqi_nz_rex_1"
19023   [(set (reg:CC FLAGS_REG)
19024         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19025                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19026    (use (match_operand:DI 6 "register_operand" "2"))
19027    (use (match_operand:SI 3 "immediate_operand" "i"))
19028    (clobber (match_operand:DI 0 "register_operand" "=S"))
19029    (clobber (match_operand:DI 1 "register_operand" "=D"))
19030    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19031   "TARGET_64BIT"
19032   "repz cmpsb"
19033   [(set_attr "type" "str")
19034    (set_attr "mode" "QI")
19035    (set_attr "prefix_rep" "1")])
19037 ;; The same, but the count is not known to not be zero.
19039 (define_expand "cmpstrnqi_1"
19040   [(parallel [(set (reg:CC FLAGS_REG)
19041                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19042                                      (const_int 0))
19043                   (compare:CC (match_operand 4 "memory_operand" "")
19044                               (match_operand 5 "memory_operand" ""))
19045                   (const_int 0)))
19046               (use (match_operand:SI 3 "immediate_operand" ""))
19047               (use (reg:CC FLAGS_REG))
19048               (clobber (match_operand 0 "register_operand" ""))
19049               (clobber (match_operand 1 "register_operand" ""))
19050               (clobber (match_dup 2))])]
19051   ""
19052   "ix86_current_function_needs_cld = 1;")
19054 (define_insn "*cmpstrnqi_1"
19055   [(set (reg:CC FLAGS_REG)
19056         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19057                              (const_int 0))
19058           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19059                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19060           (const_int 0)))
19061    (use (match_operand:SI 3 "immediate_operand" "i"))
19062    (use (reg:CC FLAGS_REG))
19063    (clobber (match_operand:SI 0 "register_operand" "=S"))
19064    (clobber (match_operand:SI 1 "register_operand" "=D"))
19065    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19066   "!TARGET_64BIT"
19067   "repz cmpsb"
19068   [(set_attr "type" "str")
19069    (set_attr "mode" "QI")
19070    (set_attr "prefix_rep" "1")])
19072 (define_insn "*cmpstrnqi_rex_1"
19073   [(set (reg:CC FLAGS_REG)
19074         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19075                              (const_int 0))
19076           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19077                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19078           (const_int 0)))
19079    (use (match_operand:SI 3 "immediate_operand" "i"))
19080    (use (reg:CC FLAGS_REG))
19081    (clobber (match_operand:DI 0 "register_operand" "=S"))
19082    (clobber (match_operand:DI 1 "register_operand" "=D"))
19083    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19084   "TARGET_64BIT"
19085   "repz cmpsb"
19086   [(set_attr "type" "str")
19087    (set_attr "mode" "QI")
19088    (set_attr "prefix_rep" "1")])
19090 (define_expand "strlensi"
19091   [(set (match_operand:SI 0 "register_operand" "")
19092         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19093                     (match_operand:QI 2 "immediate_operand" "")
19094                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19095   ""
19097  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19098    DONE;
19099  else
19100    FAIL;
19103 (define_expand "strlendi"
19104   [(set (match_operand:DI 0 "register_operand" "")
19105         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19106                     (match_operand:QI 2 "immediate_operand" "")
19107                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19108   ""
19110  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19111    DONE;
19112  else
19113    FAIL;
19116 (define_expand "strlenqi_1"
19117   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19118               (clobber (match_operand 1 "register_operand" ""))
19119               (clobber (reg:CC FLAGS_REG))])]
19120   ""
19121   "ix86_current_function_needs_cld = 1;")
19123 (define_insn "*strlenqi_1"
19124   [(set (match_operand:SI 0 "register_operand" "=&c")
19125         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19126                     (match_operand:QI 2 "register_operand" "a")
19127                     (match_operand:SI 3 "immediate_operand" "i")
19128                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19129    (clobber (match_operand:SI 1 "register_operand" "=D"))
19130    (clobber (reg:CC FLAGS_REG))]
19131   "!TARGET_64BIT"
19132   "repnz scasb"
19133   [(set_attr "type" "str")
19134    (set_attr "mode" "QI")
19135    (set_attr "prefix_rep" "1")])
19137 (define_insn "*strlenqi_rex_1"
19138   [(set (match_operand:DI 0 "register_operand" "=&c")
19139         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19140                     (match_operand:QI 2 "register_operand" "a")
19141                     (match_operand:DI 3 "immediate_operand" "i")
19142                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19143    (clobber (match_operand:DI 1 "register_operand" "=D"))
19144    (clobber (reg:CC FLAGS_REG))]
19145   "TARGET_64BIT"
19146   "repnz scasb"
19147   [(set_attr "type" "str")
19148    (set_attr "mode" "QI")
19149    (set_attr "prefix_rep" "1")])
19151 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19152 ;; handled in combine, but it is not currently up to the task.
19153 ;; When used for their truth value, the cmpstrn* expanders generate
19154 ;; code like this:
19156 ;;   repz cmpsb
19157 ;;   seta       %al
19158 ;;   setb       %dl
19159 ;;   cmpb       %al, %dl
19160 ;;   jcc        label
19162 ;; The intermediate three instructions are unnecessary.
19164 ;; This one handles cmpstrn*_nz_1...
19165 (define_peephole2
19166   [(parallel[
19167      (set (reg:CC FLAGS_REG)
19168           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19169                       (mem:BLK (match_operand 5 "register_operand" ""))))
19170      (use (match_operand 6 "register_operand" ""))
19171      (use (match_operand:SI 3 "immediate_operand" ""))
19172      (clobber (match_operand 0 "register_operand" ""))
19173      (clobber (match_operand 1 "register_operand" ""))
19174      (clobber (match_operand 2 "register_operand" ""))])
19175    (set (match_operand:QI 7 "register_operand" "")
19176         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19177    (set (match_operand:QI 8 "register_operand" "")
19178         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19179    (set (reg FLAGS_REG)
19180         (compare (match_dup 7) (match_dup 8)))
19181   ]
19182   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19183   [(parallel[
19184      (set (reg:CC FLAGS_REG)
19185           (compare:CC (mem:BLK (match_dup 4))
19186                       (mem:BLK (match_dup 5))))
19187      (use (match_dup 6))
19188      (use (match_dup 3))
19189      (clobber (match_dup 0))
19190      (clobber (match_dup 1))
19191      (clobber (match_dup 2))])]
19192   "")
19194 ;; ...and this one handles cmpstrn*_1.
19195 (define_peephole2
19196   [(parallel[
19197      (set (reg:CC FLAGS_REG)
19198           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19199                                (const_int 0))
19200             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19201                         (mem:BLK (match_operand 5 "register_operand" "")))
19202             (const_int 0)))
19203      (use (match_operand:SI 3 "immediate_operand" ""))
19204      (use (reg:CC FLAGS_REG))
19205      (clobber (match_operand 0 "register_operand" ""))
19206      (clobber (match_operand 1 "register_operand" ""))
19207      (clobber (match_operand 2 "register_operand" ""))])
19208    (set (match_operand:QI 7 "register_operand" "")
19209         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19210    (set (match_operand:QI 8 "register_operand" "")
19211         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19212    (set (reg FLAGS_REG)
19213         (compare (match_dup 7) (match_dup 8)))
19214   ]
19215   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19216   [(parallel[
19217      (set (reg:CC FLAGS_REG)
19218           (if_then_else:CC (ne (match_dup 6)
19219                                (const_int 0))
19220             (compare:CC (mem:BLK (match_dup 4))
19221                         (mem:BLK (match_dup 5)))
19222             (const_int 0)))
19223      (use (match_dup 3))
19224      (use (reg:CC FLAGS_REG))
19225      (clobber (match_dup 0))
19226      (clobber (match_dup 1))
19227      (clobber (match_dup 2))])]
19228   "")
19232 ;; Conditional move instructions.
19234 (define_expand "movdicc"
19235   [(set (match_operand:DI 0 "register_operand" "")
19236         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19237                          (match_operand:DI 2 "general_operand" "")
19238                          (match_operand:DI 3 "general_operand" "")))]
19239   "TARGET_64BIT"
19240   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19242 (define_insn "x86_movdicc_0_m1_rex64"
19243   [(set (match_operand:DI 0 "register_operand" "=r")
19244         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19245           (const_int -1)
19246           (const_int 0)))
19247    (clobber (reg:CC FLAGS_REG))]
19248   "TARGET_64BIT"
19249   "sbb{q}\t%0, %0"
19250   ; Since we don't have the proper number of operands for an alu insn,
19251   ; fill in all the blanks.
19252   [(set_attr "type" "alu")
19253    (set_attr "pent_pair" "pu")
19254    (set_attr "memory" "none")
19255    (set_attr "imm_disp" "false")
19256    (set_attr "mode" "DI")
19257    (set_attr "length_immediate" "0")])
19259 (define_insn "*x86_movdicc_0_m1_se"
19260   [(set (match_operand:DI 0 "register_operand" "=r")
19261         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19262                          (const_int 1)
19263                          (const_int 0)))
19264    (clobber (reg:CC FLAGS_REG))]
19265   ""
19266   "sbb{q}\t%0, %0"
19267   [(set_attr "type" "alu")
19268    (set_attr "pent_pair" "pu")
19269    (set_attr "memory" "none")
19270    (set_attr "imm_disp" "false")
19271    (set_attr "mode" "DI")
19272    (set_attr "length_immediate" "0")])
19274 (define_insn "*movdicc_c_rex64"
19275   [(set (match_operand:DI 0 "register_operand" "=r,r")
19276         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19277                                 [(reg FLAGS_REG) (const_int 0)])
19278                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19279                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19280   "TARGET_64BIT && TARGET_CMOVE
19281    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19282   "@
19283    cmov%O2%C1\t{%2, %0|%0, %2}
19284    cmov%O2%c1\t{%3, %0|%0, %3}"
19285   [(set_attr "type" "icmov")
19286    (set_attr "mode" "DI")])
19288 (define_expand "movsicc"
19289   [(set (match_operand:SI 0 "register_operand" "")
19290         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19291                          (match_operand:SI 2 "general_operand" "")
19292                          (match_operand:SI 3 "general_operand" "")))]
19293   ""
19294   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19296 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19297 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19298 ;; So just document what we're doing explicitly.
19300 (define_insn "x86_movsicc_0_m1"
19301   [(set (match_operand:SI 0 "register_operand" "=r")
19302         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19303           (const_int -1)
19304           (const_int 0)))
19305    (clobber (reg:CC FLAGS_REG))]
19306   ""
19307   "sbb{l}\t%0, %0"
19308   ; Since we don't have the proper number of operands for an alu insn,
19309   ; fill in all the blanks.
19310   [(set_attr "type" "alu")
19311    (set_attr "pent_pair" "pu")
19312    (set_attr "memory" "none")
19313    (set_attr "imm_disp" "false")
19314    (set_attr "mode" "SI")
19315    (set_attr "length_immediate" "0")])
19317 (define_insn "*x86_movsicc_0_m1_se"
19318   [(set (match_operand:SI 0 "register_operand" "=r")
19319         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19320                          (const_int 1)
19321                          (const_int 0)))
19322    (clobber (reg:CC FLAGS_REG))]
19323   ""
19324   "sbb{l}\t%0, %0"
19325   [(set_attr "type" "alu")
19326    (set_attr "pent_pair" "pu")
19327    (set_attr "memory" "none")
19328    (set_attr "imm_disp" "false")
19329    (set_attr "mode" "SI")
19330    (set_attr "length_immediate" "0")])
19332 (define_insn "*movsicc_noc"
19333   [(set (match_operand:SI 0 "register_operand" "=r,r")
19334         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19335                                 [(reg FLAGS_REG) (const_int 0)])
19336                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19337                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19338   "TARGET_CMOVE
19339    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19340   "@
19341    cmov%O2%C1\t{%2, %0|%0, %2}
19342    cmov%O2%c1\t{%3, %0|%0, %3}"
19343   [(set_attr "type" "icmov")
19344    (set_attr "mode" "SI")])
19346 (define_expand "movhicc"
19347   [(set (match_operand:HI 0 "register_operand" "")
19348         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19349                          (match_operand:HI 2 "general_operand" "")
19350                          (match_operand:HI 3 "general_operand" "")))]
19351   "TARGET_HIMODE_MATH"
19352   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19354 (define_insn "*movhicc_noc"
19355   [(set (match_operand:HI 0 "register_operand" "=r,r")
19356         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19357                                 [(reg FLAGS_REG) (const_int 0)])
19358                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19359                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19360   "TARGET_CMOVE
19361    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19362   "@
19363    cmov%O2%C1\t{%2, %0|%0, %2}
19364    cmov%O2%c1\t{%3, %0|%0, %3}"
19365   [(set_attr "type" "icmov")
19366    (set_attr "mode" "HI")])
19368 (define_expand "movqicc"
19369   [(set (match_operand:QI 0 "register_operand" "")
19370         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19371                          (match_operand:QI 2 "general_operand" "")
19372                          (match_operand:QI 3 "general_operand" "")))]
19373   "TARGET_QIMODE_MATH"
19374   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19376 (define_insn_and_split "*movqicc_noc"
19377   [(set (match_operand:QI 0 "register_operand" "=r,r")
19378         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19379                                 [(match_operand 4 "flags_reg_operand" "")
19380                                  (const_int 0)])
19381                       (match_operand:QI 2 "register_operand" "r,0")
19382                       (match_operand:QI 3 "register_operand" "0,r")))]
19383   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19384   "#"
19385   "&& reload_completed"
19386   [(set (match_dup 0)
19387         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19388                       (match_dup 2)
19389                       (match_dup 3)))]
19390   "operands[0] = gen_lowpart (SImode, operands[0]);
19391    operands[2] = gen_lowpart (SImode, operands[2]);
19392    operands[3] = gen_lowpart (SImode, operands[3]);"
19393   [(set_attr "type" "icmov")
19394    (set_attr "mode" "SI")])
19396 (define_expand "mov<mode>cc"
19397   [(set (match_operand:X87MODEF 0 "register_operand" "")
19398         (if_then_else:X87MODEF
19399           (match_operand 1 "comparison_operator" "")
19400           (match_operand:X87MODEF 2 "register_operand" "")
19401           (match_operand:X87MODEF 3 "register_operand" "")))]
19402   "(TARGET_80387 && TARGET_CMOVE)
19403    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19404   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19406 (define_insn "*movsfcc_1_387"
19407   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19408         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19409                                 [(reg FLAGS_REG) (const_int 0)])
19410                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19411                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19412   "TARGET_80387 && TARGET_CMOVE
19413    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19414   "@
19415    fcmov%F1\t{%2, %0|%0, %2}
19416    fcmov%f1\t{%3, %0|%0, %3}
19417    cmov%O2%C1\t{%2, %0|%0, %2}
19418    cmov%O2%c1\t{%3, %0|%0, %3}"
19419   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19420    (set_attr "mode" "SF,SF,SI,SI")])
19422 (define_insn "*movdfcc_1"
19423   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19424         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19425                                 [(reg FLAGS_REG) (const_int 0)])
19426                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19427                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19428   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19429    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19430   "@
19431    fcmov%F1\t{%2, %0|%0, %2}
19432    fcmov%f1\t{%3, %0|%0, %3}
19433    #
19434    #"
19435   [(set_attr "type" "fcmov,fcmov,multi,multi")
19436    (set_attr "mode" "DF")])
19438 (define_insn "*movdfcc_1_rex64"
19439   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19440         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19441                                 [(reg FLAGS_REG) (const_int 0)])
19442                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19443                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19444   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19445    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19446   "@
19447    fcmov%F1\t{%2, %0|%0, %2}
19448    fcmov%f1\t{%3, %0|%0, %3}
19449    cmov%O2%C1\t{%2, %0|%0, %2}
19450    cmov%O2%c1\t{%3, %0|%0, %3}"
19451   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19452    (set_attr "mode" "DF")])
19454 (define_split
19455   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19456         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19457                                 [(match_operand 4 "flags_reg_operand" "")
19458                                  (const_int 0)])
19459                       (match_operand:DF 2 "nonimmediate_operand" "")
19460                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19461   "!TARGET_64BIT && reload_completed"
19462   [(set (match_dup 2)
19463         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19464                       (match_dup 5)
19465                       (match_dup 6)))
19466    (set (match_dup 3)
19467         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19468                       (match_dup 7)
19469                       (match_dup 8)))]
19470   "split_di (&operands[2], 2, &operands[5], &operands[7]);
19471    split_di (&operands[0], 1, &operands[2], &operands[3]);")
19473 (define_insn "*movxfcc_1"
19474   [(set (match_operand:XF 0 "register_operand" "=f,f")
19475         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19476                                 [(reg FLAGS_REG) (const_int 0)])
19477                       (match_operand:XF 2 "register_operand" "f,0")
19478                       (match_operand:XF 3 "register_operand" "0,f")))]
19479   "TARGET_80387 && TARGET_CMOVE"
19480   "@
19481    fcmov%F1\t{%2, %0|%0, %2}
19482    fcmov%f1\t{%3, %0|%0, %3}"
19483   [(set_attr "type" "fcmov")
19484    (set_attr "mode" "XF")])
19486 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19487 ;; the scalar versions to have only XMM registers as operands.
19489 ;; SSE5 conditional move
19490 (define_insn "*sse5_pcmov_<mode>"
19491   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19492         (if_then_else:MODEF
19493           (match_operand:MODEF 1 "register_operand" "x,0")
19494           (match_operand:MODEF 2 "register_operand" "0,x")
19495           (match_operand:MODEF 3 "register_operand" "x,x")))]
19496   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19497   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19498   [(set_attr "type" "sse4arg")])
19500 ;; These versions of the min/max patterns are intentionally ignorant of
19501 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19502 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19503 ;; are undefined in this condition, we're certain this is correct.
19505 (define_insn "<code><mode>3"
19506   [(set (match_operand:MODEF 0 "register_operand" "=x")
19507         (smaxmin:MODEF
19508           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19509           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19510   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19511   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19512   [(set_attr "type" "sseadd")
19513    (set_attr "mode" "<MODE>")])
19515 ;; These versions of the min/max patterns implement exactly the operations
19516 ;;   min = (op1 < op2 ? op1 : op2)
19517 ;;   max = (!(op1 < op2) ? op1 : op2)
19518 ;; Their operands are not commutative, and thus they may be used in the
19519 ;; presence of -0.0 and NaN.
19521 (define_insn "*ieee_smin<mode>3"
19522   [(set (match_operand:MODEF 0 "register_operand" "=x")
19523         (unspec:MODEF
19524           [(match_operand:MODEF 1 "register_operand" "0")
19525            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19526          UNSPEC_IEEE_MIN))]
19527   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19528   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19529   [(set_attr "type" "sseadd")
19530    (set_attr "mode" "<MODE>")])
19532 (define_insn "*ieee_smax<mode>3"
19533   [(set (match_operand:MODEF 0 "register_operand" "=x")
19534         (unspec:MODEF
19535           [(match_operand:MODEF 1 "register_operand" "0")
19536            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19537          UNSPEC_IEEE_MAX))]
19538   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19539   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19540   [(set_attr "type" "sseadd")
19541    (set_attr "mode" "<MODE>")])
19543 ;; Make two stack loads independent:
19544 ;;   fld aa              fld aa
19545 ;;   fld %st(0)     ->   fld bb
19546 ;;   fmul bb             fmul %st(1), %st
19548 ;; Actually we only match the last two instructions for simplicity.
19549 (define_peephole2
19550   [(set (match_operand 0 "fp_register_operand" "")
19551         (match_operand 1 "fp_register_operand" ""))
19552    (set (match_dup 0)
19553         (match_operator 2 "binary_fp_operator"
19554            [(match_dup 0)
19555             (match_operand 3 "memory_operand" "")]))]
19556   "REGNO (operands[0]) != REGNO (operands[1])"
19557   [(set (match_dup 0) (match_dup 3))
19558    (set (match_dup 0) (match_dup 4))]
19560   ;; The % modifier is not operational anymore in peephole2's, so we have to
19561   ;; swap the operands manually in the case of addition and multiplication.
19562   "if (COMMUTATIVE_ARITH_P (operands[2]))
19563      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19564                                  operands[0], operands[1]);
19565    else
19566      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19567                                  operands[1], operands[0]);")
19569 ;; Conditional addition patterns
19570 (define_expand "add<mode>cc"
19571   [(match_operand:SWI 0 "register_operand" "")
19572    (match_operand 1 "comparison_operator" "")
19573    (match_operand:SWI 2 "register_operand" "")
19574    (match_operand:SWI 3 "const_int_operand" "")]
19575   ""
19576   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19579 ;; Misc patterns (?)
19581 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19582 ;; Otherwise there will be nothing to keep
19584 ;; [(set (reg ebp) (reg esp))]
19585 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19586 ;;  (clobber (eflags)]
19587 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19589 ;; in proper program order.
19590 (define_insn "pro_epilogue_adjust_stack_1"
19591   [(set (match_operand:SI 0 "register_operand" "=r,r")
19592         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19593                  (match_operand:SI 2 "immediate_operand" "i,i")))
19594    (clobber (reg:CC FLAGS_REG))
19595    (clobber (mem:BLK (scratch)))]
19596   "!TARGET_64BIT"
19598   switch (get_attr_type (insn))
19599     {
19600     case TYPE_IMOV:
19601       return "mov{l}\t{%1, %0|%0, %1}";
19603     case TYPE_ALU:
19604       if (CONST_INT_P (operands[2])
19605           && (INTVAL (operands[2]) == 128
19606               || (INTVAL (operands[2]) < 0
19607                   && INTVAL (operands[2]) != -128)))
19608         {
19609           operands[2] = GEN_INT (-INTVAL (operands[2]));
19610           return "sub{l}\t{%2, %0|%0, %2}";
19611         }
19612       return "add{l}\t{%2, %0|%0, %2}";
19614     case TYPE_LEA:
19615       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19616       return "lea{l}\t{%a2, %0|%0, %a2}";
19618     default:
19619       gcc_unreachable ();
19620     }
19622   [(set (attr "type")
19623         (cond [(eq_attr "alternative" "0")
19624                  (const_string "alu")
19625                (match_operand:SI 2 "const0_operand" "")
19626                  (const_string "imov")
19627               ]
19628               (const_string "lea")))
19629    (set_attr "mode" "SI")])
19631 (define_insn "pro_epilogue_adjust_stack_rex64"
19632   [(set (match_operand:DI 0 "register_operand" "=r,r")
19633         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19634                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19635    (clobber (reg:CC FLAGS_REG))
19636    (clobber (mem:BLK (scratch)))]
19637   "TARGET_64BIT"
19639   switch (get_attr_type (insn))
19640     {
19641     case TYPE_IMOV:
19642       return "mov{q}\t{%1, %0|%0, %1}";
19644     case TYPE_ALU:
19645       if (CONST_INT_P (operands[2])
19646           /* Avoid overflows.  */
19647           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19648           && (INTVAL (operands[2]) == 128
19649               || (INTVAL (operands[2]) < 0
19650                   && INTVAL (operands[2]) != -128)))
19651         {
19652           operands[2] = GEN_INT (-INTVAL (operands[2]));
19653           return "sub{q}\t{%2, %0|%0, %2}";
19654         }
19655       return "add{q}\t{%2, %0|%0, %2}";
19657     case TYPE_LEA:
19658       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19659       return "lea{q}\t{%a2, %0|%0, %a2}";
19661     default:
19662       gcc_unreachable ();
19663     }
19665   [(set (attr "type")
19666         (cond [(eq_attr "alternative" "0")
19667                  (const_string "alu")
19668                (match_operand:DI 2 "const0_operand" "")
19669                  (const_string "imov")
19670               ]
19671               (const_string "lea")))
19672    (set_attr "mode" "DI")])
19674 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19675   [(set (match_operand:DI 0 "register_operand" "=r,r")
19676         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19677                  (match_operand:DI 3 "immediate_operand" "i,i")))
19678    (use (match_operand:DI 2 "register_operand" "r,r"))
19679    (clobber (reg:CC FLAGS_REG))
19680    (clobber (mem:BLK (scratch)))]
19681   "TARGET_64BIT"
19683   switch (get_attr_type (insn))
19684     {
19685     case TYPE_ALU:
19686       return "add{q}\t{%2, %0|%0, %2}";
19688     case TYPE_LEA:
19689       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19690       return "lea{q}\t{%a2, %0|%0, %a2}";
19692     default:
19693       gcc_unreachable ();
19694     }
19696   [(set_attr "type" "alu,lea")
19697    (set_attr "mode" "DI")])
19699 (define_insn "allocate_stack_worker_32"
19700   [(set (match_operand:SI 0 "register_operand" "+a")
19701         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19702    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19703    (clobber (reg:CC FLAGS_REG))]
19704   "!TARGET_64BIT && TARGET_STACK_PROBE"
19705   "call\t___chkstk"
19706   [(set_attr "type" "multi")
19707    (set_attr "length" "5")])
19709 (define_insn "allocate_stack_worker_64"
19710   [(set (match_operand:DI 0 "register_operand" "+a")
19711         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19712    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19713    (clobber (reg:DI R10_REG))
19714    (clobber (reg:DI R11_REG))
19715    (clobber (reg:CC FLAGS_REG))]
19716   "TARGET_64BIT && TARGET_STACK_PROBE"
19717   "call\t___chkstk"
19718   [(set_attr "type" "multi")
19719    (set_attr "length" "5")])
19721 (define_expand "allocate_stack"
19722   [(match_operand 0 "register_operand" "")
19723    (match_operand 1 "general_operand" "")]
19724   "TARGET_STACK_PROBE"
19726   rtx x;
19728 #ifndef CHECK_STACK_LIMIT
19729 #define CHECK_STACK_LIMIT 0
19730 #endif
19732   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19733       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19734     {
19735       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19736                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19737       if (x != stack_pointer_rtx)
19738         emit_move_insn (stack_pointer_rtx, x);
19739     }
19740   else
19741     {
19742       x = copy_to_mode_reg (Pmode, operands[1]);
19743       if (TARGET_64BIT)
19744         x = gen_allocate_stack_worker_64 (x);
19745       else
19746         x = gen_allocate_stack_worker_32 (x);
19747       emit_insn (x);
19748     }
19750   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19751   DONE;
19754 (define_expand "builtin_setjmp_receiver"
19755   [(label_ref (match_operand 0 "" ""))]
19756   "!TARGET_64BIT && flag_pic"
19758   if (TARGET_MACHO)
19759     {
19760       rtx xops[3];
19761       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19762       rtx label_rtx = gen_label_rtx ();
19763       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19764       xops[0] = xops[1] = picreg;
19765       xops[2] = gen_rtx_CONST (SImode,
19766                   gen_rtx_MINUS (SImode,
19767                     gen_rtx_LABEL_REF (SImode, label_rtx),
19768                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19769       ix86_expand_binary_operator (MINUS, SImode, xops);
19770     }
19771   else
19772     emit_insn (gen_set_got (pic_offset_table_rtx));
19773   DONE;
19776 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19778 (define_split
19779   [(set (match_operand 0 "register_operand" "")
19780         (match_operator 3 "promotable_binary_operator"
19781            [(match_operand 1 "register_operand" "")
19782             (match_operand 2 "aligned_operand" "")]))
19783    (clobber (reg:CC FLAGS_REG))]
19784   "! TARGET_PARTIAL_REG_STALL && reload_completed
19785    && ((GET_MODE (operands[0]) == HImode
19786         && ((!optimize_size && !TARGET_FAST_PREFIX)
19787             /* ??? next two lines just !satisfies_constraint_K (...) */
19788             || !CONST_INT_P (operands[2])
19789             || satisfies_constraint_K (operands[2])))
19790        || (GET_MODE (operands[0]) == QImode
19791            && (TARGET_PROMOTE_QImode || optimize_size)))"
19792   [(parallel [(set (match_dup 0)
19793                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19794               (clobber (reg:CC FLAGS_REG))])]
19795   "operands[0] = gen_lowpart (SImode, operands[0]);
19796    operands[1] = gen_lowpart (SImode, operands[1]);
19797    if (GET_CODE (operands[3]) != ASHIFT)
19798      operands[2] = gen_lowpart (SImode, operands[2]);
19799    PUT_MODE (operands[3], SImode);")
19801 ; Promote the QImode tests, as i386 has encoding of the AND
19802 ; instruction with 32-bit sign-extended immediate and thus the
19803 ; instruction size is unchanged, except in the %eax case for
19804 ; which it is increased by one byte, hence the ! optimize_size.
19805 (define_split
19806   [(set (match_operand 0 "flags_reg_operand" "")
19807         (match_operator 2 "compare_operator"
19808           [(and (match_operand 3 "aligned_operand" "")
19809                 (match_operand 4 "const_int_operand" ""))
19810            (const_int 0)]))
19811    (set (match_operand 1 "register_operand" "")
19812         (and (match_dup 3) (match_dup 4)))]
19813   "! TARGET_PARTIAL_REG_STALL && reload_completed
19814    && ! optimize_size
19815    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19816        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19817    /* Ensure that the operand will remain sign-extended immediate.  */
19818    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19819   [(parallel [(set (match_dup 0)
19820                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19821                                     (const_int 0)]))
19822               (set (match_dup 1)
19823                    (and:SI (match_dup 3) (match_dup 4)))])]
19825   operands[4]
19826     = gen_int_mode (INTVAL (operands[4])
19827                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19828   operands[1] = gen_lowpart (SImode, operands[1]);
19829   operands[3] = gen_lowpart (SImode, operands[3]);
19832 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19833 ; the TEST instruction with 32-bit sign-extended immediate and thus
19834 ; the instruction size would at least double, which is not what we
19835 ; want even with ! optimize_size.
19836 (define_split
19837   [(set (match_operand 0 "flags_reg_operand" "")
19838         (match_operator 1 "compare_operator"
19839           [(and (match_operand:HI 2 "aligned_operand" "")
19840                 (match_operand:HI 3 "const_int_operand" ""))
19841            (const_int 0)]))]
19842   "! TARGET_PARTIAL_REG_STALL && reload_completed
19843    && ! TARGET_FAST_PREFIX
19844    && ! optimize_size
19845    /* Ensure that the operand will remain sign-extended immediate.  */
19846    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19847   [(set (match_dup 0)
19848         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19849                          (const_int 0)]))]
19851   operands[3]
19852     = gen_int_mode (INTVAL (operands[3])
19853                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19854   operands[2] = gen_lowpart (SImode, operands[2]);
19857 (define_split
19858   [(set (match_operand 0 "register_operand" "")
19859         (neg (match_operand 1 "register_operand" "")))
19860    (clobber (reg:CC FLAGS_REG))]
19861   "! TARGET_PARTIAL_REG_STALL && reload_completed
19862    && (GET_MODE (operands[0]) == HImode
19863        || (GET_MODE (operands[0]) == QImode
19864            && (TARGET_PROMOTE_QImode || optimize_size)))"
19865   [(parallel [(set (match_dup 0)
19866                    (neg:SI (match_dup 1)))
19867               (clobber (reg:CC FLAGS_REG))])]
19868   "operands[0] = gen_lowpart (SImode, operands[0]);
19869    operands[1] = gen_lowpart (SImode, operands[1]);")
19871 (define_split
19872   [(set (match_operand 0 "register_operand" "")
19873         (not (match_operand 1 "register_operand" "")))]
19874   "! TARGET_PARTIAL_REG_STALL && reload_completed
19875    && (GET_MODE (operands[0]) == HImode
19876        || (GET_MODE (operands[0]) == QImode
19877            && (TARGET_PROMOTE_QImode || optimize_size)))"
19878   [(set (match_dup 0)
19879         (not:SI (match_dup 1)))]
19880   "operands[0] = gen_lowpart (SImode, operands[0]);
19881    operands[1] = gen_lowpart (SImode, operands[1]);")
19883 (define_split
19884   [(set (match_operand 0 "register_operand" "")
19885         (if_then_else (match_operator 1 "comparison_operator"
19886                                 [(reg FLAGS_REG) (const_int 0)])
19887                       (match_operand 2 "register_operand" "")
19888                       (match_operand 3 "register_operand" "")))]
19889   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19890    && (GET_MODE (operands[0]) == HImode
19891        || (GET_MODE (operands[0]) == QImode
19892            && (TARGET_PROMOTE_QImode || optimize_size)))"
19893   [(set (match_dup 0)
19894         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19895   "operands[0] = gen_lowpart (SImode, operands[0]);
19896    operands[2] = gen_lowpart (SImode, operands[2]);
19897    operands[3] = gen_lowpart (SImode, operands[3]);")
19900 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19901 ;; transform a complex memory operation into two memory to register operations.
19903 ;; Don't push memory operands
19904 (define_peephole2
19905   [(set (match_operand:SI 0 "push_operand" "")
19906         (match_operand:SI 1 "memory_operand" ""))
19907    (match_scratch:SI 2 "r")]
19908   "!optimize_size && !TARGET_PUSH_MEMORY
19909    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19910   [(set (match_dup 2) (match_dup 1))
19911    (set (match_dup 0) (match_dup 2))]
19912   "")
19914 (define_peephole2
19915   [(set (match_operand:DI 0 "push_operand" "")
19916         (match_operand:DI 1 "memory_operand" ""))
19917    (match_scratch:DI 2 "r")]
19918   "!optimize_size && !TARGET_PUSH_MEMORY
19919    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19920   [(set (match_dup 2) (match_dup 1))
19921    (set (match_dup 0) (match_dup 2))]
19922   "")
19924 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19925 ;; SImode pushes.
19926 (define_peephole2
19927   [(set (match_operand:SF 0 "push_operand" "")
19928         (match_operand:SF 1 "memory_operand" ""))
19929    (match_scratch:SF 2 "r")]
19930   "!optimize_size && !TARGET_PUSH_MEMORY
19931    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19932   [(set (match_dup 2) (match_dup 1))
19933    (set (match_dup 0) (match_dup 2))]
19934   "")
19936 (define_peephole2
19937   [(set (match_operand:HI 0 "push_operand" "")
19938         (match_operand:HI 1 "memory_operand" ""))
19939    (match_scratch:HI 2 "r")]
19940   "!optimize_size && !TARGET_PUSH_MEMORY
19941    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19942   [(set (match_dup 2) (match_dup 1))
19943    (set (match_dup 0) (match_dup 2))]
19944   "")
19946 (define_peephole2
19947   [(set (match_operand:QI 0 "push_operand" "")
19948         (match_operand:QI 1 "memory_operand" ""))
19949    (match_scratch:QI 2 "q")]
19950   "!optimize_size && !TARGET_PUSH_MEMORY
19951    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19952   [(set (match_dup 2) (match_dup 1))
19953    (set (match_dup 0) (match_dup 2))]
19954   "")
19956 ;; Don't move an immediate directly to memory when the instruction
19957 ;; gets too big.
19958 (define_peephole2
19959   [(match_scratch:SI 1 "r")
19960    (set (match_operand:SI 0 "memory_operand" "")
19961         (const_int 0))]
19962   "! optimize_size
19963    && ! TARGET_USE_MOV0
19964    && TARGET_SPLIT_LONG_MOVES
19965    && get_attr_length (insn) >= ix86_cost->large_insn
19966    && peep2_regno_dead_p (0, FLAGS_REG)"
19967   [(parallel [(set (match_dup 1) (const_int 0))
19968               (clobber (reg:CC FLAGS_REG))])
19969    (set (match_dup 0) (match_dup 1))]
19970   "")
19972 (define_peephole2
19973   [(match_scratch:HI 1 "r")
19974    (set (match_operand:HI 0 "memory_operand" "")
19975         (const_int 0))]
19976   "! optimize_size
19977    && ! TARGET_USE_MOV0
19978    && TARGET_SPLIT_LONG_MOVES
19979    && get_attr_length (insn) >= ix86_cost->large_insn
19980    && peep2_regno_dead_p (0, FLAGS_REG)"
19981   [(parallel [(set (match_dup 2) (const_int 0))
19982               (clobber (reg:CC FLAGS_REG))])
19983    (set (match_dup 0) (match_dup 1))]
19984   "operands[2] = gen_lowpart (SImode, operands[1]);")
19986 (define_peephole2
19987   [(match_scratch:QI 1 "q")
19988    (set (match_operand:QI 0 "memory_operand" "")
19989         (const_int 0))]
19990   "! optimize_size
19991    && ! TARGET_USE_MOV0
19992    && TARGET_SPLIT_LONG_MOVES
19993    && get_attr_length (insn) >= ix86_cost->large_insn
19994    && peep2_regno_dead_p (0, FLAGS_REG)"
19995   [(parallel [(set (match_dup 2) (const_int 0))
19996               (clobber (reg:CC FLAGS_REG))])
19997    (set (match_dup 0) (match_dup 1))]
19998   "operands[2] = gen_lowpart (SImode, operands[1]);")
20000 (define_peephole2
20001   [(match_scratch:SI 2 "r")
20002    (set (match_operand:SI 0 "memory_operand" "")
20003         (match_operand:SI 1 "immediate_operand" ""))]
20004   "! optimize_size
20005    && TARGET_SPLIT_LONG_MOVES
20006    && get_attr_length (insn) >= ix86_cost->large_insn"
20007   [(set (match_dup 2) (match_dup 1))
20008    (set (match_dup 0) (match_dup 2))]
20009   "")
20011 (define_peephole2
20012   [(match_scratch:HI 2 "r")
20013    (set (match_operand:HI 0 "memory_operand" "")
20014         (match_operand:HI 1 "immediate_operand" ""))]
20015   "! optimize_size
20016    && TARGET_SPLIT_LONG_MOVES
20017    && get_attr_length (insn) >= ix86_cost->large_insn"
20018   [(set (match_dup 2) (match_dup 1))
20019    (set (match_dup 0) (match_dup 2))]
20020   "")
20022 (define_peephole2
20023   [(match_scratch:QI 2 "q")
20024    (set (match_operand:QI 0 "memory_operand" "")
20025         (match_operand:QI 1 "immediate_operand" ""))]
20026   "! optimize_size
20027    && TARGET_SPLIT_LONG_MOVES
20028    && get_attr_length (insn) >= ix86_cost->large_insn"
20029   [(set (match_dup 2) (match_dup 1))
20030    (set (match_dup 0) (match_dup 2))]
20031   "")
20033 ;; Don't compare memory with zero, load and use a test instead.
20034 (define_peephole2
20035   [(set (match_operand 0 "flags_reg_operand" "")
20036         (match_operator 1 "compare_operator"
20037           [(match_operand:SI 2 "memory_operand" "")
20038            (const_int 0)]))
20039    (match_scratch:SI 3 "r")]
20040   " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20041   [(set (match_dup 3) (match_dup 2))
20042    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20043   "")
20045 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20046 ;; Don't split NOTs with a displacement operand, because resulting XOR
20047 ;; will not be pairable anyway.
20049 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20050 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20051 ;; so this split helps here as well.
20053 ;; Note: Can't do this as a regular split because we can't get proper
20054 ;; lifetime information then.
20056 (define_peephole2
20057   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20058         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20059   "!optimize_size
20060    && ((TARGET_NOT_UNPAIRABLE
20061         && (!MEM_P (operands[0])
20062             || !memory_displacement_operand (operands[0], SImode)))
20063        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20064    && peep2_regno_dead_p (0, FLAGS_REG)"
20065   [(parallel [(set (match_dup 0)
20066                    (xor:SI (match_dup 1) (const_int -1)))
20067               (clobber (reg:CC FLAGS_REG))])]
20068   "")
20070 (define_peephole2
20071   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20072         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20073   "!optimize_size
20074    && ((TARGET_NOT_UNPAIRABLE
20075         && (!MEM_P (operands[0])
20076             || !memory_displacement_operand (operands[0], HImode)))
20077        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20078    && peep2_regno_dead_p (0, FLAGS_REG)"
20079   [(parallel [(set (match_dup 0)
20080                    (xor:HI (match_dup 1) (const_int -1)))
20081               (clobber (reg:CC FLAGS_REG))])]
20082   "")
20084 (define_peephole2
20085   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20086         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20087   "!optimize_size
20088    && ((TARGET_NOT_UNPAIRABLE
20089         && (!MEM_P (operands[0])
20090             || !memory_displacement_operand (operands[0], QImode)))
20091        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20092    && peep2_regno_dead_p (0, FLAGS_REG)"
20093   [(parallel [(set (match_dup 0)
20094                    (xor:QI (match_dup 1) (const_int -1)))
20095               (clobber (reg:CC FLAGS_REG))])]
20096   "")
20098 ;; Non pairable "test imm, reg" instructions can be translated to
20099 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20100 ;; byte opcode instead of two, have a short form for byte operands),
20101 ;; so do it for other CPUs as well.  Given that the value was dead,
20102 ;; this should not create any new dependencies.  Pass on the sub-word
20103 ;; versions if we're concerned about partial register stalls.
20105 (define_peephole2
20106   [(set (match_operand 0 "flags_reg_operand" "")
20107         (match_operator 1 "compare_operator"
20108           [(and:SI (match_operand:SI 2 "register_operand" "")
20109                    (match_operand:SI 3 "immediate_operand" ""))
20110            (const_int 0)]))]
20111   "ix86_match_ccmode (insn, CCNOmode)
20112    && (true_regnum (operands[2]) != AX_REG
20113        || satisfies_constraint_K (operands[3]))
20114    && peep2_reg_dead_p (1, operands[2])"
20115   [(parallel
20116      [(set (match_dup 0)
20117            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20118                             (const_int 0)]))
20119       (set (match_dup 2)
20120            (and:SI (match_dup 2) (match_dup 3)))])]
20121   "")
20123 ;; We don't need to handle HImode case, because it will be promoted to SImode
20124 ;; on ! TARGET_PARTIAL_REG_STALL
20126 (define_peephole2
20127   [(set (match_operand 0 "flags_reg_operand" "")
20128         (match_operator 1 "compare_operator"
20129           [(and:QI (match_operand:QI 2 "register_operand" "")
20130                    (match_operand:QI 3 "immediate_operand" ""))
20131            (const_int 0)]))]
20132   "! TARGET_PARTIAL_REG_STALL
20133    && ix86_match_ccmode (insn, CCNOmode)
20134    && true_regnum (operands[2]) != AX_REG
20135    && peep2_reg_dead_p (1, operands[2])"
20136   [(parallel
20137      [(set (match_dup 0)
20138            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20139                             (const_int 0)]))
20140       (set (match_dup 2)
20141            (and:QI (match_dup 2) (match_dup 3)))])]
20142   "")
20144 (define_peephole2
20145   [(set (match_operand 0 "flags_reg_operand" "")
20146         (match_operator 1 "compare_operator"
20147           [(and:SI
20148              (zero_extract:SI
20149                (match_operand 2 "ext_register_operand" "")
20150                (const_int 8)
20151                (const_int 8))
20152              (match_operand 3 "const_int_operand" ""))
20153            (const_int 0)]))]
20154   "! TARGET_PARTIAL_REG_STALL
20155    && ix86_match_ccmode (insn, CCNOmode)
20156    && true_regnum (operands[2]) != AX_REG
20157    && peep2_reg_dead_p (1, operands[2])"
20158   [(parallel [(set (match_dup 0)
20159                    (match_op_dup 1
20160                      [(and:SI
20161                         (zero_extract:SI
20162                           (match_dup 2)
20163                           (const_int 8)
20164                           (const_int 8))
20165                         (match_dup 3))
20166                       (const_int 0)]))
20167               (set (zero_extract:SI (match_dup 2)
20168                                     (const_int 8)
20169                                     (const_int 8))
20170                    (and:SI
20171                      (zero_extract:SI
20172                        (match_dup 2)
20173                        (const_int 8)
20174                        (const_int 8))
20175                      (match_dup 3)))])]
20176   "")
20178 ;; Don't do logical operations with memory inputs.
20179 (define_peephole2
20180   [(match_scratch:SI 2 "r")
20181    (parallel [(set (match_operand:SI 0 "register_operand" "")
20182                    (match_operator:SI 3 "arith_or_logical_operator"
20183                      [(match_dup 0)
20184                       (match_operand:SI 1 "memory_operand" "")]))
20185               (clobber (reg:CC FLAGS_REG))])]
20186   "! optimize_size && ! TARGET_READ_MODIFY"
20187   [(set (match_dup 2) (match_dup 1))
20188    (parallel [(set (match_dup 0)
20189                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20190               (clobber (reg:CC FLAGS_REG))])]
20191   "")
20193 (define_peephole2
20194   [(match_scratch:SI 2 "r")
20195    (parallel [(set (match_operand:SI 0 "register_operand" "")
20196                    (match_operator:SI 3 "arith_or_logical_operator"
20197                      [(match_operand:SI 1 "memory_operand" "")
20198                       (match_dup 0)]))
20199               (clobber (reg:CC FLAGS_REG))])]
20200   "! optimize_size && ! TARGET_READ_MODIFY"
20201   [(set (match_dup 2) (match_dup 1))
20202    (parallel [(set (match_dup 0)
20203                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20204               (clobber (reg:CC FLAGS_REG))])]
20205   "")
20207 ; Don't do logical operations with memory outputs
20209 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20210 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20211 ; the same decoder scheduling characteristics as the original.
20213 (define_peephole2
20214   [(match_scratch:SI 2 "r")
20215    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20216                    (match_operator:SI 3 "arith_or_logical_operator"
20217                      [(match_dup 0)
20218                       (match_operand:SI 1 "nonmemory_operand" "")]))
20219               (clobber (reg:CC FLAGS_REG))])]
20220   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20221   [(set (match_dup 2) (match_dup 0))
20222    (parallel [(set (match_dup 2)
20223                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20224               (clobber (reg:CC FLAGS_REG))])
20225    (set (match_dup 0) (match_dup 2))]
20226   "")
20228 (define_peephole2
20229   [(match_scratch:SI 2 "r")
20230    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20231                    (match_operator:SI 3 "arith_or_logical_operator"
20232                      [(match_operand:SI 1 "nonmemory_operand" "")
20233                       (match_dup 0)]))
20234               (clobber (reg:CC FLAGS_REG))])]
20235   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20236   [(set (match_dup 2) (match_dup 0))
20237    (parallel [(set (match_dup 2)
20238                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20239               (clobber (reg:CC FLAGS_REG))])
20240    (set (match_dup 0) (match_dup 2))]
20241   "")
20243 ;; Attempt to always use XOR for zeroing registers.
20244 (define_peephole2
20245   [(set (match_operand 0 "register_operand" "")
20246         (match_operand 1 "const0_operand" ""))]
20247   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20248    && (! TARGET_USE_MOV0 || optimize_size)
20249    && GENERAL_REG_P (operands[0])
20250    && peep2_regno_dead_p (0, FLAGS_REG)"
20251   [(parallel [(set (match_dup 0) (const_int 0))
20252               (clobber (reg:CC FLAGS_REG))])]
20254   operands[0] = gen_lowpart (word_mode, operands[0]);
20257 (define_peephole2
20258   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20259         (const_int 0))]
20260   "(GET_MODE (operands[0]) == QImode
20261     || GET_MODE (operands[0]) == HImode)
20262    && (! TARGET_USE_MOV0 || optimize_size)
20263    && peep2_regno_dead_p (0, FLAGS_REG)"
20264   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20265               (clobber (reg:CC FLAGS_REG))])])
20267 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20268 (define_peephole2
20269   [(set (match_operand 0 "register_operand" "")
20270         (const_int -1))]
20271   "(GET_MODE (operands[0]) == HImode
20272     || GET_MODE (operands[0]) == SImode
20273     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20274    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20275    && peep2_regno_dead_p (0, FLAGS_REG)"
20276   [(parallel [(set (match_dup 0) (const_int -1))
20277               (clobber (reg:CC FLAGS_REG))])]
20278   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20279                               operands[0]);")
20281 ;; Attempt to convert simple leas to adds. These can be created by
20282 ;; move expanders.
20283 (define_peephole2
20284   [(set (match_operand:SI 0 "register_operand" "")
20285         (plus:SI (match_dup 0)
20286                  (match_operand:SI 1 "nonmemory_operand" "")))]
20287   "peep2_regno_dead_p (0, FLAGS_REG)"
20288   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20289               (clobber (reg:CC FLAGS_REG))])]
20290   "")
20292 (define_peephole2
20293   [(set (match_operand:SI 0 "register_operand" "")
20294         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20295                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20296   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20297   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20298               (clobber (reg:CC FLAGS_REG))])]
20299   "operands[2] = gen_lowpart (SImode, operands[2]);")
20301 (define_peephole2
20302   [(set (match_operand:DI 0 "register_operand" "")
20303         (plus:DI (match_dup 0)
20304                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20305   "peep2_regno_dead_p (0, FLAGS_REG)"
20306   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20307               (clobber (reg:CC FLAGS_REG))])]
20308   "")
20310 (define_peephole2
20311   [(set (match_operand:SI 0 "register_operand" "")
20312         (mult:SI (match_dup 0)
20313                  (match_operand:SI 1 "const_int_operand" "")))]
20314   "exact_log2 (INTVAL (operands[1])) >= 0
20315    && peep2_regno_dead_p (0, FLAGS_REG)"
20316   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20317               (clobber (reg:CC FLAGS_REG))])]
20318   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20320 (define_peephole2
20321   [(set (match_operand:DI 0 "register_operand" "")
20322         (mult:DI (match_dup 0)
20323                  (match_operand:DI 1 "const_int_operand" "")))]
20324   "exact_log2 (INTVAL (operands[1])) >= 0
20325    && peep2_regno_dead_p (0, FLAGS_REG)"
20326   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20327               (clobber (reg:CC FLAGS_REG))])]
20328   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20330 (define_peephole2
20331   [(set (match_operand:SI 0 "register_operand" "")
20332         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20333                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20334   "exact_log2 (INTVAL (operands[2])) >= 0
20335    && REGNO (operands[0]) == REGNO (operands[1])
20336    && peep2_regno_dead_p (0, FLAGS_REG)"
20337   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20338               (clobber (reg:CC FLAGS_REG))])]
20339   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20341 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20342 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20343 ;; many CPUs it is also faster, since special hardware to avoid esp
20344 ;; dependencies is present.
20346 ;; While some of these conversions may be done using splitters, we use peepholes
20347 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20349 ;; Convert prologue esp subtractions to push.
20350 ;; We need register to push.  In order to keep verify_flow_info happy we have
20351 ;; two choices
20352 ;; - use scratch and clobber it in order to avoid dependencies
20353 ;; - use already live register
20354 ;; We can't use the second way right now, since there is no reliable way how to
20355 ;; verify that given register is live.  First choice will also most likely in
20356 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20357 ;; call clobbered registers are dead.  We may want to use base pointer as an
20358 ;; alternative when no register is available later.
20360 (define_peephole2
20361   [(match_scratch:SI 0 "r")
20362    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20363               (clobber (reg:CC FLAGS_REG))
20364               (clobber (mem:BLK (scratch)))])]
20365   "optimize_size || !TARGET_SUB_ESP_4"
20366   [(clobber (match_dup 0))
20367    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20368               (clobber (mem:BLK (scratch)))])])
20370 (define_peephole2
20371   [(match_scratch:SI 0 "r")
20372    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20373               (clobber (reg:CC FLAGS_REG))
20374               (clobber (mem:BLK (scratch)))])]
20375   "optimize_size || !TARGET_SUB_ESP_8"
20376   [(clobber (match_dup 0))
20377    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20378    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20379               (clobber (mem:BLK (scratch)))])])
20381 ;; Convert esp subtractions to push.
20382 (define_peephole2
20383   [(match_scratch:SI 0 "r")
20384    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20385               (clobber (reg:CC FLAGS_REG))])]
20386   "optimize_size || !TARGET_SUB_ESP_4"
20387   [(clobber (match_dup 0))
20388    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20390 (define_peephole2
20391   [(match_scratch:SI 0 "r")
20392    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20393               (clobber (reg:CC FLAGS_REG))])]
20394   "optimize_size || !TARGET_SUB_ESP_8"
20395   [(clobber (match_dup 0))
20396    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20397    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20399 ;; Convert epilogue deallocator to pop.
20400 (define_peephole2
20401   [(match_scratch:SI 0 "r")
20402    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20403               (clobber (reg:CC FLAGS_REG))
20404               (clobber (mem:BLK (scratch)))])]
20405   "optimize_size || !TARGET_ADD_ESP_4"
20406   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20407               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20408               (clobber (mem:BLK (scratch)))])]
20409   "")
20411 ;; Two pops case is tricky, since pop causes dependency on destination register.
20412 ;; We use two registers if available.
20413 (define_peephole2
20414   [(match_scratch:SI 0 "r")
20415    (match_scratch:SI 1 "r")
20416    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20417               (clobber (reg:CC FLAGS_REG))
20418               (clobber (mem:BLK (scratch)))])]
20419   "optimize_size || !TARGET_ADD_ESP_8"
20420   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20421               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20422               (clobber (mem:BLK (scratch)))])
20423    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20424               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20425   "")
20427 (define_peephole2
20428   [(match_scratch:SI 0 "r")
20429    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20430               (clobber (reg:CC FLAGS_REG))
20431               (clobber (mem:BLK (scratch)))])]
20432   "optimize_size"
20433   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20434               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20435               (clobber (mem:BLK (scratch)))])
20436    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20437               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20438   "")
20440 ;; Convert esp additions to pop.
20441 (define_peephole2
20442   [(match_scratch:SI 0 "r")
20443    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20444               (clobber (reg:CC FLAGS_REG))])]
20445   ""
20446   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20447               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20448   "")
20450 ;; Two pops case is tricky, since pop causes dependency on destination register.
20451 ;; We use two registers if available.
20452 (define_peephole2
20453   [(match_scratch:SI 0 "r")
20454    (match_scratch:SI 1 "r")
20455    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20456               (clobber (reg:CC FLAGS_REG))])]
20457   ""
20458   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20459               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20460    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20461               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20462   "")
20464 (define_peephole2
20465   [(match_scratch:SI 0 "r")
20466    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20467               (clobber (reg:CC FLAGS_REG))])]
20468   "optimize_size"
20469   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20470               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20471    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20472               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20473   "")
20475 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20476 ;; required and register dies.  Similarly for 128 to plus -128.
20477 (define_peephole2
20478   [(set (match_operand 0 "flags_reg_operand" "")
20479         (match_operator 1 "compare_operator"
20480           [(match_operand 2 "register_operand" "")
20481            (match_operand 3 "const_int_operand" "")]))]
20482   "(INTVAL (operands[3]) == -1
20483     || INTVAL (operands[3]) == 1
20484     || INTVAL (operands[3]) == 128)
20485    && ix86_match_ccmode (insn, CCGCmode)
20486    && peep2_reg_dead_p (1, operands[2])"
20487   [(parallel [(set (match_dup 0)
20488                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20489               (clobber (match_dup 2))])]
20490   "")
20492 (define_peephole2
20493   [(match_scratch:DI 0 "r")
20494    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20495               (clobber (reg:CC FLAGS_REG))
20496               (clobber (mem:BLK (scratch)))])]
20497   "optimize_size || !TARGET_SUB_ESP_4"
20498   [(clobber (match_dup 0))
20499    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20500               (clobber (mem:BLK (scratch)))])])
20502 (define_peephole2
20503   [(match_scratch:DI 0 "r")
20504    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20505               (clobber (reg:CC FLAGS_REG))
20506               (clobber (mem:BLK (scratch)))])]
20507   "optimize_size || !TARGET_SUB_ESP_8"
20508   [(clobber (match_dup 0))
20509    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20510    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20511               (clobber (mem:BLK (scratch)))])])
20513 ;; Convert esp subtractions to push.
20514 (define_peephole2
20515   [(match_scratch:DI 0 "r")
20516    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20517               (clobber (reg:CC FLAGS_REG))])]
20518   "optimize_size || !TARGET_SUB_ESP_4"
20519   [(clobber (match_dup 0))
20520    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20522 (define_peephole2
20523   [(match_scratch:DI 0 "r")
20524    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20525               (clobber (reg:CC FLAGS_REG))])]
20526   "optimize_size || !TARGET_SUB_ESP_8"
20527   [(clobber (match_dup 0))
20528    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20529    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20531 ;; Convert epilogue deallocator to pop.
20532 (define_peephole2
20533   [(match_scratch:DI 0 "r")
20534    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20535               (clobber (reg:CC FLAGS_REG))
20536               (clobber (mem:BLK (scratch)))])]
20537   "optimize_size || !TARGET_ADD_ESP_4"
20538   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20539               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20540               (clobber (mem:BLK (scratch)))])]
20541   "")
20543 ;; Two pops case is tricky, since pop causes dependency on destination register.
20544 ;; We use two registers if available.
20545 (define_peephole2
20546   [(match_scratch:DI 0 "r")
20547    (match_scratch:DI 1 "r")
20548    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20549               (clobber (reg:CC FLAGS_REG))
20550               (clobber (mem:BLK (scratch)))])]
20551   "optimize_size || !TARGET_ADD_ESP_8"
20552   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20553               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20554               (clobber (mem:BLK (scratch)))])
20555    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20556               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20557   "")
20559 (define_peephole2
20560   [(match_scratch:DI 0 "r")
20561    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20562               (clobber (reg:CC FLAGS_REG))
20563               (clobber (mem:BLK (scratch)))])]
20564   "optimize_size"
20565   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20566               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20567               (clobber (mem:BLK (scratch)))])
20568    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20569               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20570   "")
20572 ;; Convert esp additions to pop.
20573 (define_peephole2
20574   [(match_scratch:DI 0 "r")
20575    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20576               (clobber (reg:CC FLAGS_REG))])]
20577   ""
20578   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20579               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20580   "")
20582 ;; Two pops case is tricky, since pop causes dependency on destination register.
20583 ;; We use two registers if available.
20584 (define_peephole2
20585   [(match_scratch:DI 0 "r")
20586    (match_scratch:DI 1 "r")
20587    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20588               (clobber (reg:CC FLAGS_REG))])]
20589   ""
20590   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20591               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20592    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20593               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20594   "")
20596 (define_peephole2
20597   [(match_scratch:DI 0 "r")
20598    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20599               (clobber (reg:CC FLAGS_REG))])]
20600   "optimize_size"
20601   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20602               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20603    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20604               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20605   "")
20607 ;; Convert imul by three, five and nine into lea
20608 (define_peephole2
20609   [(parallel
20610     [(set (match_operand:SI 0 "register_operand" "")
20611           (mult:SI (match_operand:SI 1 "register_operand" "")
20612                    (match_operand:SI 2 "const_int_operand" "")))
20613      (clobber (reg:CC FLAGS_REG))])]
20614   "INTVAL (operands[2]) == 3
20615    || INTVAL (operands[2]) == 5
20616    || INTVAL (operands[2]) == 9"
20617   [(set (match_dup 0)
20618         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20619                  (match_dup 1)))]
20620   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20622 (define_peephole2
20623   [(parallel
20624     [(set (match_operand:SI 0 "register_operand" "")
20625           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20626                    (match_operand:SI 2 "const_int_operand" "")))
20627      (clobber (reg:CC FLAGS_REG))])]
20628   "!optimize_size
20629    && (INTVAL (operands[2]) == 3
20630        || INTVAL (operands[2]) == 5
20631        || INTVAL (operands[2]) == 9)"
20632   [(set (match_dup 0) (match_dup 1))
20633    (set (match_dup 0)
20634         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20635                  (match_dup 0)))]
20636   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20638 (define_peephole2
20639   [(parallel
20640     [(set (match_operand:DI 0 "register_operand" "")
20641           (mult:DI (match_operand:DI 1 "register_operand" "")
20642                    (match_operand:DI 2 "const_int_operand" "")))
20643      (clobber (reg:CC FLAGS_REG))])]
20644   "TARGET_64BIT
20645    && (INTVAL (operands[2]) == 3
20646        || INTVAL (operands[2]) == 5
20647        || INTVAL (operands[2]) == 9)"
20648   [(set (match_dup 0)
20649         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20650                  (match_dup 1)))]
20651   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20653 (define_peephole2
20654   [(parallel
20655     [(set (match_operand:DI 0 "register_operand" "")
20656           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20657                    (match_operand:DI 2 "const_int_operand" "")))
20658      (clobber (reg:CC FLAGS_REG))])]
20659   "TARGET_64BIT
20660    && !optimize_size
20661    && (INTVAL (operands[2]) == 3
20662        || INTVAL (operands[2]) == 5
20663        || INTVAL (operands[2]) == 9)"
20664   [(set (match_dup 0) (match_dup 1))
20665    (set (match_dup 0)
20666         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20667                  (match_dup 0)))]
20668   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20670 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20671 ;; imul $32bit_imm, reg, reg is direct decoded.
20672 (define_peephole2
20673   [(match_scratch:DI 3 "r")
20674    (parallel [(set (match_operand:DI 0 "register_operand" "")
20675                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20676                             (match_operand:DI 2 "immediate_operand" "")))
20677               (clobber (reg:CC FLAGS_REG))])]
20678   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20679    && !satisfies_constraint_K (operands[2])"
20680   [(set (match_dup 3) (match_dup 1))
20681    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20682               (clobber (reg:CC FLAGS_REG))])]
20685 (define_peephole2
20686   [(match_scratch:SI 3 "r")
20687    (parallel [(set (match_operand:SI 0 "register_operand" "")
20688                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20689                             (match_operand:SI 2 "immediate_operand" "")))
20690               (clobber (reg:CC FLAGS_REG))])]
20691   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20692    && !satisfies_constraint_K (operands[2])"
20693   [(set (match_dup 3) (match_dup 1))
20694    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20695               (clobber (reg:CC FLAGS_REG))])]
20698 (define_peephole2
20699   [(match_scratch:SI 3 "r")
20700    (parallel [(set (match_operand:DI 0 "register_operand" "")
20701                    (zero_extend:DI
20702                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20703                               (match_operand:SI 2 "immediate_operand" ""))))
20704               (clobber (reg:CC FLAGS_REG))])]
20705   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20706    && !satisfies_constraint_K (operands[2])"
20707   [(set (match_dup 3) (match_dup 1))
20708    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20709               (clobber (reg:CC FLAGS_REG))])]
20712 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20713 ;; Convert it into imul reg, reg
20714 ;; It would be better to force assembler to encode instruction using long
20715 ;; immediate, but there is apparently no way to do so.
20716 (define_peephole2
20717   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20718                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20719                             (match_operand:DI 2 "const_int_operand" "")))
20720               (clobber (reg:CC FLAGS_REG))])
20721    (match_scratch:DI 3 "r")]
20722   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20723    && satisfies_constraint_K (operands[2])"
20724   [(set (match_dup 3) (match_dup 2))
20725    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20726               (clobber (reg:CC FLAGS_REG))])]
20728   if (!rtx_equal_p (operands[0], operands[1]))
20729     emit_move_insn (operands[0], operands[1]);
20732 (define_peephole2
20733   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20734                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20735                             (match_operand:SI 2 "const_int_operand" "")))
20736               (clobber (reg:CC FLAGS_REG))])
20737    (match_scratch:SI 3 "r")]
20738   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20739    && satisfies_constraint_K (operands[2])"
20740   [(set (match_dup 3) (match_dup 2))
20741    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20742               (clobber (reg:CC FLAGS_REG))])]
20744   if (!rtx_equal_p (operands[0], operands[1]))
20745     emit_move_insn (operands[0], operands[1]);
20748 (define_peephole2
20749   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20750                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20751                             (match_operand:HI 2 "immediate_operand" "")))
20752               (clobber (reg:CC FLAGS_REG))])
20753    (match_scratch:HI 3 "r")]
20754   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20755   [(set (match_dup 3) (match_dup 2))
20756    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20757               (clobber (reg:CC FLAGS_REG))])]
20759   if (!rtx_equal_p (operands[0], operands[1]))
20760     emit_move_insn (operands[0], operands[1]);
20763 ;; After splitting up read-modify operations, array accesses with memory
20764 ;; operands might end up in form:
20765 ;;  sall    $2, %eax
20766 ;;  movl    4(%esp), %edx
20767 ;;  addl    %edx, %eax
20768 ;; instead of pre-splitting:
20769 ;;  sall    $2, %eax
20770 ;;  addl    4(%esp), %eax
20771 ;; Turn it into:
20772 ;;  movl    4(%esp), %edx
20773 ;;  leal    (%edx,%eax,4), %eax
20775 (define_peephole2
20776   [(parallel [(set (match_operand 0 "register_operand" "")
20777                    (ashift (match_operand 1 "register_operand" "")
20778                            (match_operand 2 "const_int_operand" "")))
20779                (clobber (reg:CC FLAGS_REG))])
20780    (set (match_operand 3 "register_operand")
20781         (match_operand 4 "x86_64_general_operand" ""))
20782    (parallel [(set (match_operand 5 "register_operand" "")
20783                    (plus (match_operand 6 "register_operand" "")
20784                          (match_operand 7 "register_operand" "")))
20785                    (clobber (reg:CC FLAGS_REG))])]
20786   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20787    /* Validate MODE for lea.  */
20788    && ((!TARGET_PARTIAL_REG_STALL
20789         && (GET_MODE (operands[0]) == QImode
20790             || GET_MODE (operands[0]) == HImode))
20791        || GET_MODE (operands[0]) == SImode
20792        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20793    /* We reorder load and the shift.  */
20794    && !rtx_equal_p (operands[1], operands[3])
20795    && !reg_overlap_mentioned_p (operands[0], operands[4])
20796    /* Last PLUS must consist of operand 0 and 3.  */
20797    && !rtx_equal_p (operands[0], operands[3])
20798    && (rtx_equal_p (operands[3], operands[6])
20799        || rtx_equal_p (operands[3], operands[7]))
20800    && (rtx_equal_p (operands[0], operands[6])
20801        || rtx_equal_p (operands[0], operands[7]))
20802    /* The intermediate operand 0 must die or be same as output.  */
20803    && (rtx_equal_p (operands[0], operands[5])
20804        || peep2_reg_dead_p (3, operands[0]))"
20805   [(set (match_dup 3) (match_dup 4))
20806    (set (match_dup 0) (match_dup 1))]
20808   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20809   int scale = 1 << INTVAL (operands[2]);
20810   rtx index = gen_lowpart (Pmode, operands[1]);
20811   rtx base = gen_lowpart (Pmode, operands[3]);
20812   rtx dest = gen_lowpart (mode, operands[5]);
20814   operands[1] = gen_rtx_PLUS (Pmode, base,
20815                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20816   if (mode != Pmode)
20817     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20818   operands[0] = dest;
20821 ;; Call-value patterns last so that the wildcard operand does not
20822 ;; disrupt insn-recog's switch tables.
20824 (define_insn "*call_value_pop_0"
20825   [(set (match_operand 0 "" "")
20826         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20827               (match_operand:SI 2 "" "")))
20828    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20829                             (match_operand:SI 3 "immediate_operand" "")))]
20830   "!TARGET_64BIT"
20832   if (SIBLING_CALL_P (insn))
20833     return "jmp\t%P1";
20834   else
20835     return "call\t%P1";
20837   [(set_attr "type" "callv")])
20839 (define_insn "*call_value_pop_1"
20840   [(set (match_operand 0 "" "")
20841         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20842               (match_operand:SI 2 "" "")))
20843    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20844                             (match_operand:SI 3 "immediate_operand" "i")))]
20845   "!TARGET_64BIT"
20847   if (constant_call_address_operand (operands[1], Pmode))
20848     {
20849       if (SIBLING_CALL_P (insn))
20850         return "jmp\t%P1";
20851       else
20852         return "call\t%P1";
20853     }
20854   if (SIBLING_CALL_P (insn))
20855     return "jmp\t%A1";
20856   else
20857     return "call\t%A1";
20859   [(set_attr "type" "callv")])
20861 (define_insn "*call_value_0"
20862   [(set (match_operand 0 "" "")
20863         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20864               (match_operand:SI 2 "" "")))]
20865   "!TARGET_64BIT"
20867   if (SIBLING_CALL_P (insn))
20868     return "jmp\t%P1";
20869   else
20870     return "call\t%P1";
20872   [(set_attr "type" "callv")])
20874 (define_insn "*call_value_0_rex64"
20875   [(set (match_operand 0 "" "")
20876         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20877               (match_operand:DI 2 "const_int_operand" "")))]
20878   "TARGET_64BIT"
20880   if (SIBLING_CALL_P (insn))
20881     return "jmp\t%P1";
20882   else
20883     return "call\t%P1";
20885   [(set_attr "type" "callv")])
20887 (define_insn "*call_value_1"
20888   [(set (match_operand 0 "" "")
20889         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20890               (match_operand:SI 2 "" "")))]
20891   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20893   if (constant_call_address_operand (operands[1], Pmode))
20894     return "call\t%P1";
20895   return "call\t%A1";
20897   [(set_attr "type" "callv")])
20899 (define_insn "*sibcall_value_1"
20900   [(set (match_operand 0 "" "")
20901         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20902               (match_operand:SI 2 "" "")))]
20903   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20905   if (constant_call_address_operand (operands[1], Pmode))
20906     return "jmp\t%P1";
20907   return "jmp\t%A1";
20909   [(set_attr "type" "callv")])
20911 (define_insn "*call_value_1_rex64"
20912   [(set (match_operand 0 "" "")
20913         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20914               (match_operand:DI 2 "" "")))]
20915   "!SIBLING_CALL_P (insn) && TARGET_64BIT
20916    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20918   if (constant_call_address_operand (operands[1], Pmode))
20919     return "call\t%P1";
20920   return "call\t%A1";
20922   [(set_attr "type" "callv")])
20924 (define_insn "*call_value_1_rex64_large"
20925   [(set (match_operand 0 "" "")
20926         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20927               (match_operand:DI 2 "" "")))]
20928   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20929   "call\t%A1"
20930   [(set_attr "type" "callv")])
20932 (define_insn "*sibcall_value_1_rex64"
20933   [(set (match_operand 0 "" "")
20934         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20935               (match_operand:DI 2 "" "")))]
20936   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20937   "jmp\t%P1"
20938   [(set_attr "type" "callv")])
20940 (define_insn "*sibcall_value_1_rex64_v"
20941   [(set (match_operand 0 "" "")
20942         (call (mem:QI (reg:DI R11_REG))
20943               (match_operand:DI 1 "" "")))]
20944   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20945   "jmp\t{*%%}r11"
20946   [(set_attr "type" "callv")])
20948 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20949 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20950 ;; caught for use by garbage collectors and the like.  Using an insn that
20951 ;; maps to SIGILL makes it more likely the program will rightfully die.
20952 ;; Keeping with tradition, "6" is in honor of #UD.
20953 (define_insn "trap"
20954   [(trap_if (const_int 1) (const_int 6))]
20955   ""
20956   { return ASM_SHORT "0x0b0f"; }
20957   [(set_attr "length" "2")])
20959 (define_expand "sse_prologue_save"
20960   [(parallel [(set (match_operand:BLK 0 "" "")
20961                    (unspec:BLK [(reg:DI 21)
20962                                 (reg:DI 22)
20963                                 (reg:DI 23)
20964                                 (reg:DI 24)
20965                                 (reg:DI 25)
20966                                 (reg:DI 26)
20967                                 (reg:DI 27)
20968                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20969               (use (match_operand:DI 1 "register_operand" ""))
20970               (use (match_operand:DI 2 "immediate_operand" ""))
20971               (use (label_ref:DI (match_operand 3 "" "")))])]
20972   "TARGET_64BIT"
20973   "")
20975 (define_insn "*sse_prologue_save_insn"
20976   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20977                           (match_operand:DI 4 "const_int_operand" "n")))
20978         (unspec:BLK [(reg:DI 21)
20979                      (reg:DI 22)
20980                      (reg:DI 23)
20981                      (reg:DI 24)
20982                      (reg:DI 25)
20983                      (reg:DI 26)
20984                      (reg:DI 27)
20985                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20986    (use (match_operand:DI 1 "register_operand" "r"))
20987    (use (match_operand:DI 2 "const_int_operand" "i"))
20988    (use (label_ref:DI (match_operand 3 "" "X")))]
20989   "TARGET_64BIT
20990    && INTVAL (operands[4]) + SSE_REGPARM_MAX * 16 - 16 < 128
20991    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20993   int i;
20994   operands[0] = gen_rtx_MEM (Pmode,
20995                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20996   output_asm_insn ("jmp\t%A1", operands);
20997   for (i = SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20998     {
20999       operands[4] = adjust_address (operands[0], DImode, i*16);
21000       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21001       PUT_MODE (operands[4], TImode);
21002       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21003         output_asm_insn ("rex", operands);
21004       output_asm_insn ("movaps\t{%5, %4|%4, %5}", operands);
21005     }
21006   (*targetm.asm_out.internal_label) (asm_out_file, "L",
21007                                      CODE_LABEL_NUMBER (operands[3]));
21008   return "";
21010   [(set_attr "type" "other")
21011    (set_attr "length_immediate" "0")
21012    (set_attr "length_address" "0")
21013    (set_attr "length" "34")
21014    (set_attr "memory" "store")
21015    (set_attr "modrm" "0")
21016    (set_attr "mode" "DI")])
21018 (define_expand "prefetch"
21019   [(prefetch (match_operand 0 "address_operand" "")
21020              (match_operand:SI 1 "const_int_operand" "")
21021              (match_operand:SI 2 "const_int_operand" ""))]
21022   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21024   int rw = INTVAL (operands[1]);
21025   int locality = INTVAL (operands[2]);
21027   gcc_assert (rw == 0 || rw == 1);
21028   gcc_assert (locality >= 0 && locality <= 3);
21029   gcc_assert (GET_MODE (operands[0]) == Pmode
21030               || GET_MODE (operands[0]) == VOIDmode);
21032   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21033      supported by SSE counterpart or the SSE prefetch is not available
21034      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21035      of locality.  */
21036   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21037     operands[2] = GEN_INT (3);
21038   else
21039     operands[1] = const0_rtx;
21042 (define_insn "*prefetch_sse"
21043   [(prefetch (match_operand:SI 0 "address_operand" "p")
21044              (const_int 0)
21045              (match_operand:SI 1 "const_int_operand" ""))]
21046   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21048   static const char * const patterns[4] = {
21049    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21050   };
21052   int locality = INTVAL (operands[1]);
21053   gcc_assert (locality >= 0 && locality <= 3);
21055   return patterns[locality];
21057   [(set_attr "type" "sse")
21058    (set_attr "memory" "none")])
21060 (define_insn "*prefetch_sse_rex"
21061   [(prefetch (match_operand:DI 0 "address_operand" "p")
21062              (const_int 0)
21063              (match_operand:SI 1 "const_int_operand" ""))]
21064   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21066   static const char * const patterns[4] = {
21067    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21068   };
21070   int locality = INTVAL (operands[1]);
21071   gcc_assert (locality >= 0 && locality <= 3);
21073   return patterns[locality];
21075   [(set_attr "type" "sse")
21076    (set_attr "memory" "none")])
21078 (define_insn "*prefetch_3dnow"
21079   [(prefetch (match_operand:SI 0 "address_operand" "p")
21080              (match_operand:SI 1 "const_int_operand" "n")
21081              (const_int 3))]
21082   "TARGET_3DNOW && !TARGET_64BIT"
21084   if (INTVAL (operands[1]) == 0)
21085     return "prefetch\t%a0";
21086   else
21087     return "prefetchw\t%a0";
21089   [(set_attr "type" "mmx")
21090    (set_attr "memory" "none")])
21092 (define_insn "*prefetch_3dnow_rex"
21093   [(prefetch (match_operand:DI 0 "address_operand" "p")
21094              (match_operand:SI 1 "const_int_operand" "n")
21095              (const_int 3))]
21096   "TARGET_3DNOW && TARGET_64BIT"
21098   if (INTVAL (operands[1]) == 0)
21099     return "prefetch\t%a0";
21100   else
21101     return "prefetchw\t%a0";
21103   [(set_attr "type" "mmx")
21104    (set_attr "memory" "none")])
21106 (define_expand "stack_protect_set"
21107   [(match_operand 0 "memory_operand" "")
21108    (match_operand 1 "memory_operand" "")]
21109   ""
21111 #ifdef TARGET_THREAD_SSP_OFFSET
21112   if (TARGET_64BIT)
21113     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21114                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21115   else
21116     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21117                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21118 #else
21119   if (TARGET_64BIT)
21120     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21121   else
21122     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21123 #endif
21124   DONE;
21127 (define_insn "stack_protect_set_si"
21128   [(set (match_operand:SI 0 "memory_operand" "=m")
21129         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21130    (set (match_scratch:SI 2 "=&r") (const_int 0))
21131    (clobber (reg:CC FLAGS_REG))]
21132   ""
21133   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21134   [(set_attr "type" "multi")])
21136 (define_insn "stack_protect_set_di"
21137   [(set (match_operand:DI 0 "memory_operand" "=m")
21138         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21139    (set (match_scratch:DI 2 "=&r") (const_int 0))
21140    (clobber (reg:CC FLAGS_REG))]
21141   "TARGET_64BIT"
21142   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21143   [(set_attr "type" "multi")])
21145 (define_insn "stack_tls_protect_set_si"
21146   [(set (match_operand:SI 0 "memory_operand" "=m")
21147         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21148    (set (match_scratch:SI 2 "=&r") (const_int 0))
21149    (clobber (reg:CC FLAGS_REG))]
21150   ""
21151   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21152   [(set_attr "type" "multi")])
21154 (define_insn "stack_tls_protect_set_di"
21155   [(set (match_operand:DI 0 "memory_operand" "=m")
21156         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21157    (set (match_scratch:DI 2 "=&r") (const_int 0))
21158    (clobber (reg:CC FLAGS_REG))]
21159   "TARGET_64BIT"
21160   {
21161      /* The kernel uses a different segment register for performance reasons; a
21162         system call would not have to trash the userspace segment register,
21163         which would be expensive */
21164      if (ix86_cmodel != CM_KERNEL)
21165         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21166      else
21167         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21168   }
21169   [(set_attr "type" "multi")])
21171 (define_expand "stack_protect_test"
21172   [(match_operand 0 "memory_operand" "")
21173    (match_operand 1 "memory_operand" "")
21174    (match_operand 2 "" "")]
21175   ""
21177   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21178   ix86_compare_op0 = operands[0];
21179   ix86_compare_op1 = operands[1];
21180   ix86_compare_emitted = flags;
21182 #ifdef TARGET_THREAD_SSP_OFFSET
21183   if (TARGET_64BIT)
21184     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21185                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21186   else
21187     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21188                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21189 #else
21190   if (TARGET_64BIT)
21191     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21192   else
21193     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21194 #endif
21195   emit_jump_insn (gen_beq (operands[2]));
21196   DONE;
21199 (define_insn "stack_protect_test_si"
21200   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21201         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21202                      (match_operand:SI 2 "memory_operand" "m")]
21203                     UNSPEC_SP_TEST))
21204    (clobber (match_scratch:SI 3 "=&r"))]
21205   ""
21206   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21207   [(set_attr "type" "multi")])
21209 (define_insn "stack_protect_test_di"
21210   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21211         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21212                      (match_operand:DI 2 "memory_operand" "m")]
21213                     UNSPEC_SP_TEST))
21214    (clobber (match_scratch:DI 3 "=&r"))]
21215   "TARGET_64BIT"
21216   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21217   [(set_attr "type" "multi")])
21219 (define_insn "stack_tls_protect_test_si"
21220   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21221         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21222                      (match_operand:SI 2 "const_int_operand" "i")]
21223                     UNSPEC_SP_TLS_TEST))
21224    (clobber (match_scratch:SI 3 "=r"))]
21225   ""
21226   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21227   [(set_attr "type" "multi")])
21229 (define_insn "stack_tls_protect_test_di"
21230   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21231         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21232                      (match_operand:DI 2 "const_int_operand" "i")]
21233                     UNSPEC_SP_TLS_TEST))
21234    (clobber (match_scratch:DI 3 "=r"))]
21235   "TARGET_64BIT"
21236   {
21237      /* The kernel uses a different segment register for performance reasons; a
21238         system call would not have to trash the userspace segment register,
21239         which would be expensive */
21240      if (ix86_cmodel != CM_KERNEL)
21241         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21242      else
21243         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21244   }
21245   [(set_attr "type" "multi")])
21247 (define_mode_iterator CRC32MODE [QI HI SI])
21248 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21249 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21251 (define_insn "sse4_2_crc32<mode>"
21252   [(set (match_operand:SI 0 "register_operand" "=r")
21253         (unspec:SI
21254           [(match_operand:SI 1 "register_operand" "0")
21255            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21256           UNSPEC_CRC32))]
21257   "TARGET_SSE4_2"
21258   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21259   [(set_attr "type" "sselog1")
21260    (set_attr "prefix_rep" "1")
21261    (set_attr "prefix_extra" "1")
21262    (set_attr "mode" "SI")])
21264 (define_insn "sse4_2_crc32di"
21265   [(set (match_operand:DI 0 "register_operand" "=r")
21266         (unspec:DI
21267           [(match_operand:DI 1 "register_operand" "0")
21268            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21269           UNSPEC_CRC32))]
21270   "TARGET_SSE4_2 && TARGET_64BIT"
21271   "crc32q\t{%2, %0|%0, %2}"
21272   [(set_attr "type" "sselog1")
21273    (set_attr "prefix_rep" "1")
21274    (set_attr "prefix_extra" "1")
21275    (set_attr "mode" "DI")])
21277 (include "mmx.md")
21278 (include "sse.md")
21279 (include "sync.md")