2008-07-01 Jerry DeLisle <jvdelisle@gcc.gnu.org>
[official-gcc.git] / gcc / config / i386 / i386.md
blobc67cf467bc90ac522094a40e4e59e08cecd0f44d
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 "n") (HI "n") (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 ;; This mode iterator allows :P to be used for patterns that operate on
635 ;; pointer-sized quantities.  Exactly one of the two alternatives will match.
636 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
639 ;; Scheduling descriptions
641 (include "pentium.md")
642 (include "ppro.md")
643 (include "k6.md")
644 (include "athlon.md")
645 (include "geode.md")
648 ;; Operand and operator predicates and constraints
650 (include "predicates.md")
651 (include "constraints.md")
654 ;; Compare instructions.
656 ;; All compare insns have expanders that save the operands away without
657 ;; actually generating RTL.  The bCOND or sCOND (emitted immediately
658 ;; after the cmp) will actually emit the cmpM.
660 (define_expand "cmpti"
661   [(set (reg:CC FLAGS_REG)
662         (compare:CC (match_operand:TI 0 "nonimmediate_operand" "")
663                     (match_operand:TI 1 "x86_64_general_operand" "")))]
664   "TARGET_64BIT"
666   if (MEM_P (operands[0]) && MEM_P (operands[1]))
667     operands[0] = force_reg (TImode, operands[0]);
668   ix86_compare_op0 = operands[0];
669   ix86_compare_op1 = operands[1];
670   DONE;
673 (define_expand "cmpdi"
674   [(set (reg:CC FLAGS_REG)
675         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
676                     (match_operand:DI 1 "x86_64_general_operand" "")))]
677   ""
679   if (MEM_P (operands[0]) && MEM_P (operands[1]))
680     operands[0] = force_reg (DImode, operands[0]);
681   ix86_compare_op0 = operands[0];
682   ix86_compare_op1 = operands[1];
683   DONE;
686 (define_expand "cmpsi"
687   [(set (reg:CC FLAGS_REG)
688         (compare:CC (match_operand:SI 0 "cmpsi_operand" "")
689                     (match_operand:SI 1 "general_operand" "")))]
690   ""
692   if (MEM_P (operands[0]) && MEM_P (operands[1]))
693     operands[0] = force_reg (SImode, operands[0]);
694   ix86_compare_op0 = operands[0];
695   ix86_compare_op1 = operands[1];
696   DONE;
699 (define_expand "cmphi"
700   [(set (reg:CC FLAGS_REG)
701         (compare:CC (match_operand:HI 0 "nonimmediate_operand" "")
702                     (match_operand:HI 1 "general_operand" "")))]
703   ""
705   if (MEM_P (operands[0]) && MEM_P (operands[1]))
706     operands[0] = force_reg (HImode, operands[0]);
707   ix86_compare_op0 = operands[0];
708   ix86_compare_op1 = operands[1];
709   DONE;
712 (define_expand "cmpqi"
713   [(set (reg:CC FLAGS_REG)
714         (compare:CC (match_operand:QI 0 "nonimmediate_operand" "")
715                     (match_operand:QI 1 "general_operand" "")))]
716   "TARGET_QIMODE_MATH"
718   if (MEM_P (operands[0]) && MEM_P (operands[1]))
719     operands[0] = force_reg (QImode, operands[0]);
720   ix86_compare_op0 = operands[0];
721   ix86_compare_op1 = operands[1];
722   DONE;
725 (define_insn "cmpdi_ccno_1_rex64"
726   [(set (reg FLAGS_REG)
727         (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
728                  (match_operand:DI 1 "const0_operand" "")))]
729   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
730   "@
731    test{q}\t%0, %0
732    cmp{q}\t{%1, %0|%0, %1}"
733   [(set_attr "type" "test,icmp")
734    (set_attr "length_immediate" "0,1")
735    (set_attr "mode" "DI")])
737 (define_insn "*cmpdi_minus_1_rex64"
738   [(set (reg FLAGS_REG)
739         (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
740                            (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
741                  (const_int 0)))]
742   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
743   "cmp{q}\t{%1, %0|%0, %1}"
744   [(set_attr "type" "icmp")
745    (set_attr "mode" "DI")])
747 (define_expand "cmpdi_1_rex64"
748   [(set (reg:CC FLAGS_REG)
749         (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
750                     (match_operand:DI 1 "general_operand" "")))]
751   "TARGET_64BIT"
752   "")
754 (define_insn "cmpdi_1_insn_rex64"
755   [(set (reg FLAGS_REG)
756         (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
757                  (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
758   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
759   "cmp{q}\t{%1, %0|%0, %1}"
760   [(set_attr "type" "icmp")
761    (set_attr "mode" "DI")])
764 (define_insn "*cmpsi_ccno_1"
765   [(set (reg FLAGS_REG)
766         (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
767                  (match_operand:SI 1 "const0_operand" "")))]
768   "ix86_match_ccmode (insn, CCNOmode)"
769   "@
770    test{l}\t%0, %0
771    cmp{l}\t{%1, %0|%0, %1}"
772   [(set_attr "type" "test,icmp")
773    (set_attr "length_immediate" "0,1")
774    (set_attr "mode" "SI")])
776 (define_insn "*cmpsi_minus_1"
777   [(set (reg FLAGS_REG)
778         (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
779                            (match_operand:SI 1 "general_operand" "ri,mr"))
780                  (const_int 0)))]
781   "ix86_match_ccmode (insn, CCGOCmode)"
782   "cmp{l}\t{%1, %0|%0, %1}"
783   [(set_attr "type" "icmp")
784    (set_attr "mode" "SI")])
786 (define_expand "cmpsi_1"
787   [(set (reg:CC FLAGS_REG)
788         (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
789                     (match_operand:SI 1 "general_operand" "")))]
790   ""
791   "")
793 (define_insn "*cmpsi_1_insn"
794   [(set (reg FLAGS_REG)
795         (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
796                  (match_operand:SI 1 "general_operand" "ri,mr")))]
797   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
798     && ix86_match_ccmode (insn, CCmode)"
799   "cmp{l}\t{%1, %0|%0, %1}"
800   [(set_attr "type" "icmp")
801    (set_attr "mode" "SI")])
803 (define_insn "*cmphi_ccno_1"
804   [(set (reg FLAGS_REG)
805         (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
806                  (match_operand:HI 1 "const0_operand" "")))]
807   "ix86_match_ccmode (insn, CCNOmode)"
808   "@
809    test{w}\t%0, %0
810    cmp{w}\t{%1, %0|%0, %1}"
811   [(set_attr "type" "test,icmp")
812    (set_attr "length_immediate" "0,1")
813    (set_attr "mode" "HI")])
815 (define_insn "*cmphi_minus_1"
816   [(set (reg FLAGS_REG)
817         (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
818                            (match_operand:HI 1 "general_operand" "rn,mr"))
819                  (const_int 0)))]
820   "ix86_match_ccmode (insn, CCGOCmode)"
821   "cmp{w}\t{%1, %0|%0, %1}"
822   [(set_attr "type" "icmp")
823    (set_attr "mode" "HI")])
825 (define_insn "*cmphi_1"
826   [(set (reg FLAGS_REG)
827         (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
828                  (match_operand:HI 1 "general_operand" "rn,mr")))]
829   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
830    && ix86_match_ccmode (insn, CCmode)"
831   "cmp{w}\t{%1, %0|%0, %1}"
832   [(set_attr "type" "icmp")
833    (set_attr "mode" "HI")])
835 (define_insn "*cmpqi_ccno_1"
836   [(set (reg FLAGS_REG)
837         (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
838                  (match_operand:QI 1 "const0_operand" "")))]
839   "ix86_match_ccmode (insn, CCNOmode)"
840   "@
841    test{b}\t%0, %0
842    cmp{b}\t{$0, %0|%0, 0}"
843   [(set_attr "type" "test,icmp")
844    (set_attr "length_immediate" "0,1")
845    (set_attr "mode" "QI")])
847 (define_insn "*cmpqi_1"
848   [(set (reg FLAGS_REG)
849         (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
850                  (match_operand:QI 1 "general_operand" "qn,mq")))]
851   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
852     && ix86_match_ccmode (insn, CCmode)"
853   "cmp{b}\t{%1, %0|%0, %1}"
854   [(set_attr "type" "icmp")
855    (set_attr "mode" "QI")])
857 (define_insn "*cmpqi_minus_1"
858   [(set (reg FLAGS_REG)
859         (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
860                            (match_operand:QI 1 "general_operand" "qn,mq"))
861                  (const_int 0)))]
862   "ix86_match_ccmode (insn, CCGOCmode)"
863   "cmp{b}\t{%1, %0|%0, %1}"
864   [(set_attr "type" "icmp")
865    (set_attr "mode" "QI")])
867 (define_insn "*cmpqi_ext_1"
868   [(set (reg FLAGS_REG)
869         (compare
870           (match_operand:QI 0 "general_operand" "Qm")
871           (subreg:QI
872             (zero_extract:SI
873               (match_operand 1 "ext_register_operand" "Q")
874               (const_int 8)
875               (const_int 8)) 0)))]
876   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
877   "cmp{b}\t{%h1, %0|%0, %h1}"
878   [(set_attr "type" "icmp")
879    (set_attr "mode" "QI")])
881 (define_insn "*cmpqi_ext_1_rex64"
882   [(set (reg FLAGS_REG)
883         (compare
884           (match_operand:QI 0 "register_operand" "Q")
885           (subreg:QI
886             (zero_extract:SI
887               (match_operand 1 "ext_register_operand" "Q")
888               (const_int 8)
889               (const_int 8)) 0)))]
890   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
891   "cmp{b}\t{%h1, %0|%0, %h1}"
892   [(set_attr "type" "icmp")
893    (set_attr "mode" "QI")])
895 (define_insn "*cmpqi_ext_2"
896   [(set (reg FLAGS_REG)
897         (compare
898           (subreg:QI
899             (zero_extract:SI
900               (match_operand 0 "ext_register_operand" "Q")
901               (const_int 8)
902               (const_int 8)) 0)
903           (match_operand:QI 1 "const0_operand" "")))]
904   "ix86_match_ccmode (insn, CCNOmode)"
905   "test{b}\t%h0, %h0"
906   [(set_attr "type" "test")
907    (set_attr "length_immediate" "0")
908    (set_attr "mode" "QI")])
910 (define_expand "cmpqi_ext_3"
911   [(set (reg:CC FLAGS_REG)
912         (compare:CC
913           (subreg:QI
914             (zero_extract:SI
915               (match_operand 0 "ext_register_operand" "")
916               (const_int 8)
917               (const_int 8)) 0)
918           (match_operand:QI 1 "general_operand" "")))]
919   ""
920   "")
922 (define_insn "cmpqi_ext_3_insn"
923   [(set (reg FLAGS_REG)
924         (compare
925           (subreg:QI
926             (zero_extract:SI
927               (match_operand 0 "ext_register_operand" "Q")
928               (const_int 8)
929               (const_int 8)) 0)
930           (match_operand:QI 1 "general_operand" "Qmn")))]
931   "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
932   "cmp{b}\t{%1, %h0|%h0, %1}"
933   [(set_attr "type" "icmp")
934    (set_attr "mode" "QI")])
936 (define_insn "cmpqi_ext_3_insn_rex64"
937   [(set (reg FLAGS_REG)
938         (compare
939           (subreg:QI
940             (zero_extract:SI
941               (match_operand 0 "ext_register_operand" "Q")
942               (const_int 8)
943               (const_int 8)) 0)
944           (match_operand:QI 1 "nonmemory_operand" "Qn")))]
945   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
946   "cmp{b}\t{%1, %h0|%h0, %1}"
947   [(set_attr "type" "icmp")
948    (set_attr "mode" "QI")])
950 (define_insn "*cmpqi_ext_4"
951   [(set (reg FLAGS_REG)
952         (compare
953           (subreg:QI
954             (zero_extract:SI
955               (match_operand 0 "ext_register_operand" "Q")
956               (const_int 8)
957               (const_int 8)) 0)
958           (subreg:QI
959             (zero_extract:SI
960               (match_operand 1 "ext_register_operand" "Q")
961               (const_int 8)
962               (const_int 8)) 0)))]
963   "ix86_match_ccmode (insn, CCmode)"
964   "cmp{b}\t{%h1, %h0|%h0, %h1}"
965   [(set_attr "type" "icmp")
966    (set_attr "mode" "QI")])
968 ;; These implement float point compares.
969 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
970 ;; which would allow mix and match FP modes on the compares.  Which is what
971 ;; the old patterns did, but with many more of them.
973 (define_expand "cmpxf"
974   [(set (reg:CC FLAGS_REG)
975         (compare:CC (match_operand:XF 0 "nonmemory_operand" "")
976                     (match_operand:XF 1 "nonmemory_operand" "")))]
977   "TARGET_80387"
979   ix86_compare_op0 = operands[0];
980   ix86_compare_op1 = operands[1];
981   DONE;
984 (define_expand "cmp<mode>"
985   [(set (reg:CC FLAGS_REG)
986         (compare:CC (match_operand:MODEF 0 "cmp_fp_expander_operand" "")
987                     (match_operand:MODEF 1 "cmp_fp_expander_operand" "")))]
988   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
990   ix86_compare_op0 = operands[0];
991   ix86_compare_op1 = operands[1];
992   DONE;
995 ;; FP compares, step 1:
996 ;; Set the FP condition codes.
998 ;; CCFPmode     compare with exceptions
999 ;; CCFPUmode    compare with no exceptions
1001 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1002 ;; used to manage the reg stack popping would not be preserved.
1004 (define_insn "*cmpfp_0"
1005   [(set (match_operand:HI 0 "register_operand" "=a")
1006         (unspec:HI
1007           [(compare:CCFP
1008              (match_operand 1 "register_operand" "f")
1009              (match_operand 2 "const0_operand" ""))]
1010         UNSPEC_FNSTSW))]
1011   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1012    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1013   "* return output_fp_compare (insn, operands, 0, 0);"
1014   [(set_attr "type" "multi")
1015    (set_attr "unit" "i387")
1016    (set (attr "mode")
1017      (cond [(match_operand:SF 1 "" "")
1018               (const_string "SF")
1019             (match_operand:DF 1 "" "")
1020               (const_string "DF")
1021            ]
1022            (const_string "XF")))])
1024 (define_insn_and_split "*cmpfp_0_cc"
1025   [(set (reg:CCFP FLAGS_REG)
1026         (compare:CCFP
1027           (match_operand 1 "register_operand" "f")
1028           (match_operand 2 "const0_operand" "")))
1029    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1030   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1031    && TARGET_SAHF && !TARGET_CMOVE
1032    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1033   "#"
1034   "&& reload_completed"
1035   [(set (match_dup 0)
1036         (unspec:HI
1037           [(compare:CCFP (match_dup 1)(match_dup 2))]
1038         UNSPEC_FNSTSW))
1039    (set (reg:CC FLAGS_REG)
1040         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1041   ""
1042   [(set_attr "type" "multi")
1043    (set_attr "unit" "i387")
1044    (set (attr "mode")
1045      (cond [(match_operand:SF 1 "" "")
1046               (const_string "SF")
1047             (match_operand:DF 1 "" "")
1048               (const_string "DF")
1049            ]
1050            (const_string "XF")))])
1052 (define_insn "*cmpfp_xf"
1053   [(set (match_operand:HI 0 "register_operand" "=a")
1054         (unspec:HI
1055           [(compare:CCFP
1056              (match_operand:XF 1 "register_operand" "f")
1057              (match_operand:XF 2 "register_operand" "f"))]
1058           UNSPEC_FNSTSW))]
1059   "TARGET_80387"
1060   "* return output_fp_compare (insn, operands, 0, 0);"
1061   [(set_attr "type" "multi")
1062    (set_attr "unit" "i387")
1063    (set_attr "mode" "XF")])
1065 (define_insn_and_split "*cmpfp_xf_cc"
1066   [(set (reg:CCFP FLAGS_REG)
1067         (compare:CCFP
1068           (match_operand:XF 1 "register_operand" "f")
1069           (match_operand:XF 2 "register_operand" "f")))
1070    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1071   "TARGET_80387
1072    && TARGET_SAHF && !TARGET_CMOVE"
1073   "#"
1074   "&& reload_completed"
1075   [(set (match_dup 0)
1076         (unspec:HI
1077           [(compare:CCFP (match_dup 1)(match_dup 2))]
1078         UNSPEC_FNSTSW))
1079    (set (reg:CC FLAGS_REG)
1080         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1081   ""
1082   [(set_attr "type" "multi")
1083    (set_attr "unit" "i387")
1084    (set_attr "mode" "XF")])
1086 (define_insn "*cmpfp_<mode>"
1087   [(set (match_operand:HI 0 "register_operand" "=a")
1088         (unspec:HI
1089           [(compare:CCFP
1090              (match_operand:MODEF 1 "register_operand" "f")
1091              (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1092           UNSPEC_FNSTSW))]
1093   "TARGET_80387"
1094   "* return output_fp_compare (insn, operands, 0, 0);"
1095   [(set_attr "type" "multi")
1096    (set_attr "unit" "i387")
1097    (set_attr "mode" "<MODE>")])
1099 (define_insn_and_split "*cmpfp_<mode>_cc"
1100   [(set (reg:CCFP FLAGS_REG)
1101         (compare:CCFP
1102           (match_operand:MODEF 1 "register_operand" "f")
1103           (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1104    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1105   "TARGET_80387
1106    && TARGET_SAHF && !TARGET_CMOVE"
1107   "#"
1108   "&& reload_completed"
1109   [(set (match_dup 0)
1110         (unspec:HI
1111           [(compare:CCFP (match_dup 1)(match_dup 2))]
1112         UNSPEC_FNSTSW))
1113    (set (reg:CC FLAGS_REG)
1114         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1115   ""
1116   [(set_attr "type" "multi")
1117    (set_attr "unit" "i387")
1118    (set_attr "mode" "<MODE>")])
1120 (define_insn "*cmpfp_u"
1121   [(set (match_operand:HI 0 "register_operand" "=a")
1122         (unspec:HI
1123           [(compare:CCFPU
1124              (match_operand 1 "register_operand" "f")
1125              (match_operand 2 "register_operand" "f"))]
1126           UNSPEC_FNSTSW))]
1127   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1128    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1129   "* return output_fp_compare (insn, operands, 0, 1);"
1130   [(set_attr "type" "multi")
1131    (set_attr "unit" "i387")
1132    (set (attr "mode")
1133      (cond [(match_operand:SF 1 "" "")
1134               (const_string "SF")
1135             (match_operand:DF 1 "" "")
1136               (const_string "DF")
1137            ]
1138            (const_string "XF")))])
1140 (define_insn_and_split "*cmpfp_u_cc"
1141   [(set (reg:CCFPU FLAGS_REG)
1142         (compare:CCFPU
1143           (match_operand 1 "register_operand" "f")
1144           (match_operand 2 "register_operand" "f")))
1145    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1146   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1147    && TARGET_SAHF && !TARGET_CMOVE
1148    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1149   "#"
1150   "&& reload_completed"
1151   [(set (match_dup 0)
1152         (unspec:HI
1153           [(compare:CCFPU (match_dup 1)(match_dup 2))]
1154         UNSPEC_FNSTSW))
1155    (set (reg:CC FLAGS_REG)
1156         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1157   ""
1158   [(set_attr "type" "multi")
1159    (set_attr "unit" "i387")
1160    (set (attr "mode")
1161      (cond [(match_operand:SF 1 "" "")
1162               (const_string "SF")
1163             (match_operand:DF 1 "" "")
1164               (const_string "DF")
1165            ]
1166            (const_string "XF")))])
1168 (define_insn "*cmpfp_<mode>"
1169   [(set (match_operand:HI 0 "register_operand" "=a")
1170         (unspec:HI
1171           [(compare:CCFP
1172              (match_operand 1 "register_operand" "f")
1173              (match_operator 3 "float_operator"
1174                [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1175           UNSPEC_FNSTSW))]
1176   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1177    && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)
1178    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1179   "* return output_fp_compare (insn, operands, 0, 0);"
1180   [(set_attr "type" "multi")
1181    (set_attr "unit" "i387")
1182    (set_attr "fp_int_src" "true")
1183    (set_attr "mode" "<MODE>")])
1185 (define_insn_and_split "*cmpfp_<mode>_cc"
1186   [(set (reg:CCFP FLAGS_REG)
1187         (compare:CCFP
1188           (match_operand 1 "register_operand" "f")
1189           (match_operator 3 "float_operator"
1190             [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1191    (clobber (match_operand:HI 0 "register_operand" "=a"))]
1192   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1193    && TARGET_SAHF && !TARGET_CMOVE
1194    && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)
1195    && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1196   "#"
1197   "&& reload_completed"
1198   [(set (match_dup 0)
1199         (unspec:HI
1200           [(compare:CCFP
1201              (match_dup 1)
1202              (match_op_dup 3 [(match_dup 2)]))]
1203         UNSPEC_FNSTSW))
1204    (set (reg:CC FLAGS_REG)
1205         (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1206   ""
1207   [(set_attr "type" "multi")
1208    (set_attr "unit" "i387")
1209    (set_attr "fp_int_src" "true")
1210    (set_attr "mode" "<MODE>")])
1212 ;; FP compares, step 2
1213 ;; Move the fpsw to ax.
1215 (define_insn "x86_fnstsw_1"
1216   [(set (match_operand:HI 0 "register_operand" "=a")
1217         (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1218   "TARGET_80387"
1219   "fnstsw\t%0"
1220   [(set_attr "length" "2")
1221    (set_attr "mode" "SI")
1222    (set_attr "unit" "i387")])
1224 ;; FP compares, step 3
1225 ;; Get ax into flags, general case.
1227 (define_insn "x86_sahf_1"
1228   [(set (reg:CC FLAGS_REG)
1229         (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1230                    UNSPEC_SAHF))]
1231   "TARGET_SAHF"
1233 #ifdef HAVE_AS_IX86_SAHF
1234   return "sahf";
1235 #else
1236   return ".byte\t0x9e";
1237 #endif
1239   [(set_attr "length" "1")
1240    (set_attr "athlon_decode" "vector")
1241    (set_attr "amdfam10_decode" "direct")
1242    (set_attr "mode" "SI")])
1244 ;; Pentium Pro can do steps 1 through 3 in one go.
1245 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1246 (define_insn "*cmpfp_i_mixed"
1247   [(set (reg:CCFP FLAGS_REG)
1248         (compare:CCFP (match_operand 0 "register_operand" "f,x")
1249                       (match_operand 1 "nonimmediate_operand" "f,xm")))]
1250   "TARGET_MIX_SSE_I387
1251    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1252    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1253   "* return output_fp_compare (insn, operands, 1, 0);"
1254   [(set_attr "type" "fcmp,ssecomi")
1255    (set (attr "mode")
1256      (if_then_else (match_operand:SF 1 "" "")
1257         (const_string "SF")
1258         (const_string "DF")))
1259    (set_attr "athlon_decode" "vector")
1260    (set_attr "amdfam10_decode" "direct")])
1262 (define_insn "*cmpfp_i_sse"
1263   [(set (reg:CCFP FLAGS_REG)
1264         (compare:CCFP (match_operand 0 "register_operand" "x")
1265                       (match_operand 1 "nonimmediate_operand" "xm")))]
1266   "TARGET_SSE_MATH
1267    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1268    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1269   "* return output_fp_compare (insn, operands, 1, 0);"
1270   [(set_attr "type" "ssecomi")
1271    (set (attr "mode")
1272      (if_then_else (match_operand:SF 1 "" "")
1273         (const_string "SF")
1274         (const_string "DF")))
1275    (set_attr "athlon_decode" "vector")
1276    (set_attr "amdfam10_decode" "direct")])
1278 (define_insn "*cmpfp_i_i387"
1279   [(set (reg:CCFP FLAGS_REG)
1280         (compare:CCFP (match_operand 0 "register_operand" "f")
1281                       (match_operand 1 "register_operand" "f")))]
1282   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1283    && TARGET_CMOVE
1284    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1285    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1286   "* return output_fp_compare (insn, operands, 1, 0);"
1287   [(set_attr "type" "fcmp")
1288    (set (attr "mode")
1289      (cond [(match_operand:SF 1 "" "")
1290               (const_string "SF")
1291             (match_operand:DF 1 "" "")
1292               (const_string "DF")
1293            ]
1294            (const_string "XF")))
1295    (set_attr "athlon_decode" "vector")
1296    (set_attr "amdfam10_decode" "direct")])
1298 (define_insn "*cmpfp_iu_mixed"
1299   [(set (reg:CCFPU FLAGS_REG)
1300         (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1301                        (match_operand 1 "nonimmediate_operand" "f,xm")))]
1302   "TARGET_MIX_SSE_I387
1303    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1304    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1305   "* return output_fp_compare (insn, operands, 1, 1);"
1306   [(set_attr "type" "fcmp,ssecomi")
1307    (set (attr "mode")
1308      (if_then_else (match_operand:SF 1 "" "")
1309         (const_string "SF")
1310         (const_string "DF")))
1311    (set_attr "athlon_decode" "vector")
1312    (set_attr "amdfam10_decode" "direct")])
1314 (define_insn "*cmpfp_iu_sse"
1315   [(set (reg:CCFPU FLAGS_REG)
1316         (compare:CCFPU (match_operand 0 "register_operand" "x")
1317                        (match_operand 1 "nonimmediate_operand" "xm")))]
1318   "TARGET_SSE_MATH
1319    && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1320    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1321   "* return output_fp_compare (insn, operands, 1, 1);"
1322   [(set_attr "type" "ssecomi")
1323    (set (attr "mode")
1324      (if_then_else (match_operand:SF 1 "" "")
1325         (const_string "SF")
1326         (const_string "DF")))
1327    (set_attr "athlon_decode" "vector")
1328    (set_attr "amdfam10_decode" "direct")])
1330 (define_insn "*cmpfp_iu_387"
1331   [(set (reg:CCFPU FLAGS_REG)
1332         (compare:CCFPU (match_operand 0 "register_operand" "f")
1333                        (match_operand 1 "register_operand" "f")))]
1334   "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1335    && TARGET_CMOVE
1336    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1337    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1338   "* return output_fp_compare (insn, operands, 1, 1);"
1339   [(set_attr "type" "fcmp")
1340    (set (attr "mode")
1341      (cond [(match_operand:SF 1 "" "")
1342               (const_string "SF")
1343             (match_operand:DF 1 "" "")
1344               (const_string "DF")
1345            ]
1346            (const_string "XF")))
1347    (set_attr "athlon_decode" "vector")
1348    (set_attr "amdfam10_decode" "direct")])
1350 ;; Move instructions.
1352 ;; General case of fullword move.
1354 (define_expand "movsi"
1355   [(set (match_operand:SI 0 "nonimmediate_operand" "")
1356         (match_operand:SI 1 "general_operand" ""))]
1357   ""
1358   "ix86_expand_move (SImode, operands); DONE;")
1360 ;; Push/pop instructions.  They are separate since autoinc/dec is not a
1361 ;; general_operand.
1363 ;; %%% We don't use a post-inc memory reference because x86 is not a
1364 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1365 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1366 ;; targets without our curiosities, and it is just as easy to represent
1367 ;; this differently.
1369 (define_insn "*pushsi2"
1370   [(set (match_operand:SI 0 "push_operand" "=<")
1371         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1372   "!TARGET_64BIT"
1373   "push{l}\t%1"
1374   [(set_attr "type" "push")
1375    (set_attr "mode" "SI")])
1377 ;; For 64BIT abi we always round up to 8 bytes.
1378 (define_insn "*pushsi2_rex64"
1379   [(set (match_operand:SI 0 "push_operand" "=X")
1380         (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1381   "TARGET_64BIT"
1382   "push{q}\t%q1"
1383   [(set_attr "type" "push")
1384    (set_attr "mode" "SI")])
1386 (define_insn "*pushsi2_prologue"
1387   [(set (match_operand:SI 0 "push_operand" "=<")
1388         (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1389    (clobber (mem:BLK (scratch)))]
1390   "!TARGET_64BIT"
1391   "push{l}\t%1"
1392   [(set_attr "type" "push")
1393    (set_attr "mode" "SI")])
1395 (define_insn "*popsi1_epilogue"
1396   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1397         (mem:SI (reg:SI SP_REG)))
1398    (set (reg:SI SP_REG)
1399         (plus:SI (reg:SI SP_REG) (const_int 4)))
1400    (clobber (mem:BLK (scratch)))]
1401   "!TARGET_64BIT"
1402   "pop{l}\t%0"
1403   [(set_attr "type" "pop")
1404    (set_attr "mode" "SI")])
1406 (define_insn "popsi1"
1407   [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1408         (mem:SI (reg:SI SP_REG)))
1409    (set (reg:SI SP_REG)
1410         (plus:SI (reg:SI SP_REG) (const_int 4)))]
1411   "!TARGET_64BIT"
1412   "pop{l}\t%0"
1413   [(set_attr "type" "pop")
1414    (set_attr "mode" "SI")])
1416 (define_insn "*movsi_xor"
1417   [(set (match_operand:SI 0 "register_operand" "=r")
1418         (match_operand:SI 1 "const0_operand" ""))
1419    (clobber (reg:CC FLAGS_REG))]
1420   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1421   "xor{l}\t%0, %0"
1422   [(set_attr "type" "alu1")
1423    (set_attr "mode" "SI")
1424    (set_attr "length_immediate" "0")])
1426 (define_insn "*movsi_or"
1427   [(set (match_operand:SI 0 "register_operand" "=r")
1428         (match_operand:SI 1 "immediate_operand" "i"))
1429    (clobber (reg:CC FLAGS_REG))]
1430   "reload_completed
1431    && operands[1] == constm1_rtx
1432    && (TARGET_MOVE_M1_VIA_OR || optimize_size)"
1434   operands[1] = constm1_rtx;
1435   return "or{l}\t{%1, %0|%0, %1}";
1437   [(set_attr "type" "alu1")
1438    (set_attr "mode" "SI")
1439    (set_attr "length_immediate" "1")])
1441 (define_insn "*movsi_1"
1442   [(set (match_operand:SI 0 "nonimmediate_operand"
1443                         "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1444         (match_operand:SI 1 "general_operand"
1445                         "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r   ,m "))]
1446   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1448   switch (get_attr_type (insn))
1449     {
1450     case TYPE_SSELOG1:
1451       if (get_attr_mode (insn) == MODE_TI)
1452         return "pxor\t%0, %0";
1453       return "xorps\t%0, %0";
1455     case TYPE_SSEMOV:
1456       switch (get_attr_mode (insn))
1457         {
1458         case MODE_TI:
1459           return "movdqa\t{%1, %0|%0, %1}";
1460         case MODE_V4SF:
1461           return "movaps\t{%1, %0|%0, %1}";
1462         case MODE_SI:
1463           return "movd\t{%1, %0|%0, %1}";
1464         case MODE_SF:
1465           return "movss\t{%1, %0|%0, %1}";
1466         default:
1467           gcc_unreachable ();
1468         }
1470     case TYPE_MMXADD:
1471       return "pxor\t%0, %0";
1473     case TYPE_MMXMOV:
1474       if (get_attr_mode (insn) == MODE_DI)
1475         return "movq\t{%1, %0|%0, %1}";
1476       return "movd\t{%1, %0|%0, %1}";
1478     case TYPE_LEA:
1479       return "lea{l}\t{%1, %0|%0, %1}";
1481     default:
1482       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1483       return "mov{l}\t{%1, %0|%0, %1}";
1484     }
1486   [(set (attr "type")
1487      (cond [(eq_attr "alternative" "2")
1488               (const_string "mmxadd")
1489             (eq_attr "alternative" "3,4,5")
1490               (const_string "mmxmov")
1491             (eq_attr "alternative" "6")
1492               (const_string "sselog1")
1493             (eq_attr "alternative" "7,8,9,10,11")
1494               (const_string "ssemov")
1495             (match_operand:DI 1 "pic_32bit_operand" "")
1496               (const_string "lea")
1497            ]
1498            (const_string "imov")))
1499    (set (attr "mode")
1500      (cond [(eq_attr "alternative" "2,3")
1501               (const_string "DI")
1502             (eq_attr "alternative" "6,7")
1503               (if_then_else
1504                 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1505                 (const_string "V4SF")
1506                 (const_string "TI"))
1507             (and (eq_attr "alternative" "8,9,10,11")
1508                  (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1509               (const_string "SF")
1510            ]
1511            (const_string "SI")))])
1513 ;; Stores and loads of ax to arbitrary constant address.
1514 ;; We fake an second form of instruction to force reload to load address
1515 ;; into register when rax is not available
1516 (define_insn "*movabssi_1_rex64"
1517   [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1518         (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1519   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1520   "@
1521    movabs{l}\t{%1, %P0|%P0, %1}
1522    mov{l}\t{%1, %a0|%a0, %1}"
1523   [(set_attr "type" "imov")
1524    (set_attr "modrm" "0,*")
1525    (set_attr "length_address" "8,0")
1526    (set_attr "length_immediate" "0,*")
1527    (set_attr "memory" "store")
1528    (set_attr "mode" "SI")])
1530 (define_insn "*movabssi_2_rex64"
1531   [(set (match_operand:SI 0 "register_operand" "=a,r")
1532         (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1533   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1534   "@
1535    movabs{l}\t{%P1, %0|%0, %P1}
1536    mov{l}\t{%a1, %0|%0, %a1}"
1537   [(set_attr "type" "imov")
1538    (set_attr "modrm" "0,*")
1539    (set_attr "length_address" "8,0")
1540    (set_attr "length_immediate" "0")
1541    (set_attr "memory" "load")
1542    (set_attr "mode" "SI")])
1544 (define_insn "*swapsi"
1545   [(set (match_operand:SI 0 "register_operand" "+r")
1546         (match_operand:SI 1 "register_operand" "+r"))
1547    (set (match_dup 1)
1548         (match_dup 0))]
1549   ""
1550   "xchg{l}\t%1, %0"
1551   [(set_attr "type" "imov")
1552    (set_attr "mode" "SI")
1553    (set_attr "pent_pair" "np")
1554    (set_attr "athlon_decode" "vector")
1555    (set_attr "amdfam10_decode" "double")])
1557 (define_expand "movhi"
1558   [(set (match_operand:HI 0 "nonimmediate_operand" "")
1559         (match_operand:HI 1 "general_operand" ""))]
1560   ""
1561   "ix86_expand_move (HImode, operands); DONE;")
1563 (define_insn "*pushhi2"
1564   [(set (match_operand:HI 0 "push_operand" "=X")
1565         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1566   "!TARGET_64BIT"
1567   "push{l}\t%k1"
1568   [(set_attr "type" "push")
1569    (set_attr "mode" "SI")])
1571 ;; For 64BIT abi we always round up to 8 bytes.
1572 (define_insn "*pushhi2_rex64"
1573   [(set (match_operand:HI 0 "push_operand" "=X")
1574         (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1575   "TARGET_64BIT"
1576   "push{q}\t%q1"
1577   [(set_attr "type" "push")
1578    (set_attr "mode" "DI")])
1580 (define_insn "*movhi_1"
1581   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1582         (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1583   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1585   switch (get_attr_type (insn))
1586     {
1587     case TYPE_IMOVX:
1588       /* movzwl is faster than movw on p2 due to partial word stalls,
1589          though not as fast as an aligned movl.  */
1590       return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1591     default:
1592       if (get_attr_mode (insn) == MODE_SI)
1593         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1594       else
1595         return "mov{w}\t{%1, %0|%0, %1}";
1596     }
1598   [(set (attr "type")
1599      (cond [(ne (symbol_ref "optimize_size") (const_int 0))
1600               (const_string "imov")
1601             (and (eq_attr "alternative" "0")
1602                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1603                           (const_int 0))
1604                       (eq (symbol_ref "TARGET_HIMODE_MATH")
1605                           (const_int 0))))
1606               (const_string "imov")
1607             (and (eq_attr "alternative" "1,2")
1608                  (match_operand:HI 1 "aligned_operand" ""))
1609               (const_string "imov")
1610             (and (ne (symbol_ref "TARGET_MOVX")
1611                      (const_int 0))
1612                  (eq_attr "alternative" "0,2"))
1613               (const_string "imovx")
1614            ]
1615            (const_string "imov")))
1616     (set (attr "mode")
1617       (cond [(eq_attr "type" "imovx")
1618                (const_string "SI")
1619              (and (eq_attr "alternative" "1,2")
1620                   (match_operand:HI 1 "aligned_operand" ""))
1621                (const_string "SI")
1622              (and (eq_attr "alternative" "0")
1623                   (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1624                            (const_int 0))
1625                        (eq (symbol_ref "TARGET_HIMODE_MATH")
1626                            (const_int 0))))
1627                (const_string "SI")
1628             ]
1629             (const_string "HI")))])
1631 ;; Stores and loads of ax to arbitrary constant address.
1632 ;; We fake an second form of instruction to force reload to load address
1633 ;; into register when rax is not available
1634 (define_insn "*movabshi_1_rex64"
1635   [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1636         (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1637   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1638   "@
1639    movabs{w}\t{%1, %P0|%P0, %1}
1640    mov{w}\t{%1, %a0|%a0, %1}"
1641   [(set_attr "type" "imov")
1642    (set_attr "modrm" "0,*")
1643    (set_attr "length_address" "8,0")
1644    (set_attr "length_immediate" "0,*")
1645    (set_attr "memory" "store")
1646    (set_attr "mode" "HI")])
1648 (define_insn "*movabshi_2_rex64"
1649   [(set (match_operand:HI 0 "register_operand" "=a,r")
1650         (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1651   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1652   "@
1653    movabs{w}\t{%P1, %0|%0, %P1}
1654    mov{w}\t{%a1, %0|%0, %a1}"
1655   [(set_attr "type" "imov")
1656    (set_attr "modrm" "0,*")
1657    (set_attr "length_address" "8,0")
1658    (set_attr "length_immediate" "0")
1659    (set_attr "memory" "load")
1660    (set_attr "mode" "HI")])
1662 (define_insn "*swaphi_1"
1663   [(set (match_operand:HI 0 "register_operand" "+r")
1664         (match_operand:HI 1 "register_operand" "+r"))
1665    (set (match_dup 1)
1666         (match_dup 0))]
1667   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1668   "xchg{l}\t%k1, %k0"
1669   [(set_attr "type" "imov")
1670    (set_attr "mode" "SI")
1671    (set_attr "pent_pair" "np")
1672    (set_attr "athlon_decode" "vector")
1673    (set_attr "amdfam10_decode" "double")])
1675 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1676 (define_insn "*swaphi_2"
1677   [(set (match_operand:HI 0 "register_operand" "+r")
1678         (match_operand:HI 1 "register_operand" "+r"))
1679    (set (match_dup 1)
1680         (match_dup 0))]
1681   "TARGET_PARTIAL_REG_STALL"
1682   "xchg{w}\t%1, %0"
1683   [(set_attr "type" "imov")
1684    (set_attr "mode" "HI")
1685    (set_attr "pent_pair" "np")
1686    (set_attr "athlon_decode" "vector")])
1688 (define_expand "movstricthi"
1689   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1690         (match_operand:HI 1 "general_operand" ""))]
1691   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1693   /* Don't generate memory->memory moves, go through a register */
1694   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1695     operands[1] = force_reg (HImode, operands[1]);
1698 (define_insn "*movstricthi_1"
1699   [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1700         (match_operand:HI 1 "general_operand" "rn,m"))]
1701   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1702    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1703   "mov{w}\t{%1, %0|%0, %1}"
1704   [(set_attr "type" "imov")
1705    (set_attr "mode" "HI")])
1707 (define_insn "*movstricthi_xor"
1708   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1709         (match_operand:HI 1 "const0_operand" ""))
1710    (clobber (reg:CC FLAGS_REG))]
1711   "reload_completed
1712    && ((!TARGET_USE_MOV0 && !TARGET_PARTIAL_REG_STALL) || optimize_size)"
1713   "xor{w}\t%0, %0"
1714   [(set_attr "type" "alu1")
1715    (set_attr "mode" "HI")
1716    (set_attr "length_immediate" "0")])
1718 (define_expand "movqi"
1719   [(set (match_operand:QI 0 "nonimmediate_operand" "")
1720         (match_operand:QI 1 "general_operand" ""))]
1721   ""
1722   "ix86_expand_move (QImode, operands); DONE;")
1724 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1725 ;; "push a byte".  But actually we use pushl, which has the effect
1726 ;; of rounding the amount pushed up to a word.
1728 (define_insn "*pushqi2"
1729   [(set (match_operand:QI 0 "push_operand" "=X")
1730         (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1731   "!TARGET_64BIT"
1732   "push{l}\t%k1"
1733   [(set_attr "type" "push")
1734    (set_attr "mode" "SI")])
1736 ;; For 64BIT abi we always round up to 8 bytes.
1737 (define_insn "*pushqi2_rex64"
1738   [(set (match_operand:QI 0 "push_operand" "=X")
1739         (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1740   "TARGET_64BIT"
1741   "push{q}\t%q1"
1742   [(set_attr "type" "push")
1743    (set_attr "mode" "DI")])
1745 ;; Situation is quite tricky about when to choose full sized (SImode) move
1746 ;; over QImode moves.  For Q_REG -> Q_REG move we use full size only for
1747 ;; partial register dependency machines (such as AMD Athlon), where QImode
1748 ;; moves issue extra dependency and for partial register stalls machines
1749 ;; that don't use QImode patterns (and QImode move cause stall on the next
1750 ;; instruction).
1752 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1753 ;; register stall machines with, where we use QImode instructions, since
1754 ;; partial register stall can be caused there.  Then we use movzx.
1755 (define_insn "*movqi_1"
1756   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1757         (match_operand:QI 1 "general_operand"      " q,qn,qm,q,rn,qm,qn"))]
1758   "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1760   switch (get_attr_type (insn))
1761     {
1762     case TYPE_IMOVX:
1763       gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1764       return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1765     default:
1766       if (get_attr_mode (insn) == MODE_SI)
1767         return "mov{l}\t{%k1, %k0|%k0, %k1}";
1768       else
1769         return "mov{b}\t{%1, %0|%0, %1}";
1770     }
1772   [(set (attr "type")
1773      (cond [(and (eq_attr "alternative" "5")
1774                  (not (match_operand:QI 1 "aligned_operand" "")))
1775               (const_string "imovx")
1776             (ne (symbol_ref "optimize_size") (const_int 0))
1777               (const_string "imov")
1778             (and (eq_attr "alternative" "3")
1779                  (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1780                           (const_int 0))
1781                       (eq (symbol_ref "TARGET_QIMODE_MATH")
1782                           (const_int 0))))
1783               (const_string "imov")
1784             (eq_attr "alternative" "3,5")
1785               (const_string "imovx")
1786             (and (ne (symbol_ref "TARGET_MOVX")
1787                      (const_int 0))
1788                  (eq_attr "alternative" "2"))
1789               (const_string "imovx")
1790            ]
1791            (const_string "imov")))
1792    (set (attr "mode")
1793       (cond [(eq_attr "alternative" "3,4,5")
1794                (const_string "SI")
1795              (eq_attr "alternative" "6")
1796                (const_string "QI")
1797              (eq_attr "type" "imovx")
1798                (const_string "SI")
1799              (and (eq_attr "type" "imov")
1800                   (and (eq_attr "alternative" "0,1")
1801                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1802                                 (const_int 0))
1803                             (and (eq (symbol_ref "optimize_size")
1804                                      (const_int 0))
1805                                  (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1806                                      (const_int 0))))))
1807                (const_string "SI")
1808              ;; Avoid partial register stalls when not using QImode arithmetic
1809              (and (eq_attr "type" "imov")
1810                   (and (eq_attr "alternative" "0,1")
1811                        (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1812                                 (const_int 0))
1813                             (eq (symbol_ref "TARGET_QIMODE_MATH")
1814                                 (const_int 0)))))
1815                (const_string "SI")
1816            ]
1817            (const_string "QI")))])
1819 (define_insn "*swapqi_1"
1820   [(set (match_operand:QI 0 "register_operand" "+r")
1821         (match_operand:QI 1 "register_operand" "+r"))
1822    (set (match_dup 1)
1823         (match_dup 0))]
1824   "!TARGET_PARTIAL_REG_STALL || optimize_size"
1825   "xchg{l}\t%k1, %k0"
1826   [(set_attr "type" "imov")
1827    (set_attr "mode" "SI")
1828    (set_attr "pent_pair" "np")
1829    (set_attr "athlon_decode" "vector")
1830    (set_attr "amdfam10_decode" "vector")])
1832 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1833 (define_insn "*swapqi_2"
1834   [(set (match_operand:QI 0 "register_operand" "+q")
1835         (match_operand:QI 1 "register_operand" "+q"))
1836    (set (match_dup 1)
1837         (match_dup 0))]
1838   "TARGET_PARTIAL_REG_STALL"
1839   "xchg{b}\t%1, %0"
1840   [(set_attr "type" "imov")
1841    (set_attr "mode" "QI")
1842    (set_attr "pent_pair" "np")
1843    (set_attr "athlon_decode" "vector")])
1845 (define_expand "movstrictqi"
1846   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
1847         (match_operand:QI 1 "general_operand" ""))]
1848   "! TARGET_PARTIAL_REG_STALL || optimize_size"
1850   /* Don't generate memory->memory moves, go through a register.  */
1851   if (MEM_P (operands[0]) && MEM_P (operands[1]))
1852     operands[1] = force_reg (QImode, operands[1]);
1855 (define_insn "*movstrictqi_1"
1856   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
1857         (match_operand:QI 1 "general_operand" "*qn,m"))]
1858   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
1859    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1860   "mov{b}\t{%1, %0|%0, %1}"
1861   [(set_attr "type" "imov")
1862    (set_attr "mode" "QI")])
1864 (define_insn "*movstrictqi_xor"
1865   [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
1866         (match_operand:QI 1 "const0_operand" ""))
1867    (clobber (reg:CC FLAGS_REG))]
1868   "reload_completed && (!TARGET_USE_MOV0 || optimize_size)"
1869   "xor{b}\t%0, %0"
1870   [(set_attr "type" "alu1")
1871    (set_attr "mode" "QI")
1872    (set_attr "length_immediate" "0")])
1874 (define_insn "*movsi_extv_1"
1875   [(set (match_operand:SI 0 "register_operand" "=R")
1876         (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
1877                          (const_int 8)
1878                          (const_int 8)))]
1879   ""
1880   "movs{bl|x}\t{%h1, %0|%0, %h1}"
1881   [(set_attr "type" "imovx")
1882    (set_attr "mode" "SI")])
1884 (define_insn "*movhi_extv_1"
1885   [(set (match_operand:HI 0 "register_operand" "=R")
1886         (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
1887                          (const_int 8)
1888                          (const_int 8)))]
1889   ""
1890   "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
1891   [(set_attr "type" "imovx")
1892    (set_attr "mode" "SI")])
1894 (define_insn "*movqi_extv_1"
1895   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
1896         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1897                          (const_int 8)
1898                          (const_int 8)))]
1899   "!TARGET_64BIT"
1901   switch (get_attr_type (insn))
1902     {
1903     case TYPE_IMOVX:
1904       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1905     default:
1906       return "mov{b}\t{%h1, %0|%0, %h1}";
1907     }
1909   [(set (attr "type")
1910      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1911                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1912                              (ne (symbol_ref "TARGET_MOVX")
1913                                  (const_int 0))))
1914         (const_string "imovx")
1915         (const_string "imov")))
1916    (set (attr "mode")
1917      (if_then_else (eq_attr "type" "imovx")
1918         (const_string "SI")
1919         (const_string "QI")))])
1921 (define_insn "*movqi_extv_1_rex64"
1922   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
1923         (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
1924                          (const_int 8)
1925                          (const_int 8)))]
1926   "TARGET_64BIT"
1928   switch (get_attr_type (insn))
1929     {
1930     case TYPE_IMOVX:
1931       return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
1932     default:
1933       return "mov{b}\t{%h1, %0|%0, %h1}";
1934     }
1936   [(set (attr "type")
1937      (if_then_else (and (match_operand:QI 0 "register_operand" "")
1938                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
1939                              (ne (symbol_ref "TARGET_MOVX")
1940                                  (const_int 0))))
1941         (const_string "imovx")
1942         (const_string "imov")))
1943    (set (attr "mode")
1944      (if_then_else (eq_attr "type" "imovx")
1945         (const_string "SI")
1946         (const_string "QI")))])
1948 ;; Stores and loads of ax to arbitrary constant address.
1949 ;; We fake an second form of instruction to force reload to load address
1950 ;; into register when rax is not available
1951 (define_insn "*movabsqi_1_rex64"
1952   [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1953         (match_operand:QI 1 "nonmemory_operand" "a,er"))]
1954   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1955   "@
1956    movabs{b}\t{%1, %P0|%P0, %1}
1957    mov{b}\t{%1, %a0|%a0, %1}"
1958   [(set_attr "type" "imov")
1959    (set_attr "modrm" "0,*")
1960    (set_attr "length_address" "8,0")
1961    (set_attr "length_immediate" "0,*")
1962    (set_attr "memory" "store")
1963    (set_attr "mode" "QI")])
1965 (define_insn "*movabsqi_2_rex64"
1966   [(set (match_operand:QI 0 "register_operand" "=a,r")
1967         (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1968   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1969   "@
1970    movabs{b}\t{%P1, %0|%0, %P1}
1971    mov{b}\t{%a1, %0|%0, %a1}"
1972   [(set_attr "type" "imov")
1973    (set_attr "modrm" "0,*")
1974    (set_attr "length_address" "8,0")
1975    (set_attr "length_immediate" "0")
1976    (set_attr "memory" "load")
1977    (set_attr "mode" "QI")])
1979 (define_insn "*movdi_extzv_1"
1980   [(set (match_operand:DI 0 "register_operand" "=R")
1981         (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
1982                          (const_int 8)
1983                          (const_int 8)))]
1984   "TARGET_64BIT"
1985   "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
1986   [(set_attr "type" "imovx")
1987    (set_attr "mode" "DI")])
1989 (define_insn "*movsi_extzv_1"
1990   [(set (match_operand:SI 0 "register_operand" "=R")
1991         (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
1992                          (const_int 8)
1993                          (const_int 8)))]
1994   ""
1995   "movz{bl|x}\t{%h1, %0|%0, %h1}"
1996   [(set_attr "type" "imovx")
1997    (set_attr "mode" "SI")])
1999 (define_insn "*movqi_extzv_2"
2000   [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2001         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2002                                     (const_int 8)
2003                                     (const_int 8)) 0))]
2004   "!TARGET_64BIT"
2006   switch (get_attr_type (insn))
2007     {
2008     case TYPE_IMOVX:
2009       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2010     default:
2011       return "mov{b}\t{%h1, %0|%0, %h1}";
2012     }
2014   [(set (attr "type")
2015      (if_then_else (and (match_operand:QI 0 "register_operand" "")
2016                         (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2017                              (ne (symbol_ref "TARGET_MOVX")
2018                                  (const_int 0))))
2019         (const_string "imovx")
2020         (const_string "imov")))
2021    (set (attr "mode")
2022      (if_then_else (eq_attr "type" "imovx")
2023         (const_string "SI")
2024         (const_string "QI")))])
2026 (define_insn "*movqi_extzv_2_rex64"
2027   [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2028         (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2029                                     (const_int 8)
2030                                     (const_int 8)) 0))]
2031   "TARGET_64BIT"
2033   switch (get_attr_type (insn))
2034     {
2035     case TYPE_IMOVX:
2036       return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2037     default:
2038       return "mov{b}\t{%h1, %0|%0, %h1}";
2039     }
2041   [(set (attr "type")
2042      (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2043                         (ne (symbol_ref "TARGET_MOVX")
2044                             (const_int 0)))
2045         (const_string "imovx")
2046         (const_string "imov")))
2047    (set (attr "mode")
2048      (if_then_else (eq_attr "type" "imovx")
2049         (const_string "SI")
2050         (const_string "QI")))])
2052 (define_insn "movsi_insv_1"
2053   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2054                          (const_int 8)
2055                          (const_int 8))
2056         (match_operand:SI 1 "general_operand" "Qmn"))]
2057   "!TARGET_64BIT"
2058   "mov{b}\t{%b1, %h0|%h0, %b1}"
2059   [(set_attr "type" "imov")
2060    (set_attr "mode" "QI")])
2062 (define_insn "*movsi_insv_1_rex64"
2063   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2064                          (const_int 8)
2065                          (const_int 8))
2066         (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2067   "TARGET_64BIT"
2068   "mov{b}\t{%b1, %h0|%h0, %b1}"
2069   [(set_attr "type" "imov")
2070    (set_attr "mode" "QI")])
2072 (define_insn "movdi_insv_1_rex64"
2073   [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2074                          (const_int 8)
2075                          (const_int 8))
2076         (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2077   "TARGET_64BIT"
2078   "mov{b}\t{%b1, %h0|%h0, %b1}"
2079   [(set_attr "type" "imov")
2080    (set_attr "mode" "QI")])
2082 (define_insn "*movqi_insv_2"
2083   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2084                          (const_int 8)
2085                          (const_int 8))
2086         (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2087                      (const_int 8)))]
2088   ""
2089   "mov{b}\t{%h1, %h0|%h0, %h1}"
2090   [(set_attr "type" "imov")
2091    (set_attr "mode" "QI")])
2093 (define_expand "movdi"
2094   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2095         (match_operand:DI 1 "general_operand" ""))]
2096   ""
2097   "ix86_expand_move (DImode, operands); DONE;")
2099 (define_insn "*pushdi"
2100   [(set (match_operand:DI 0 "push_operand" "=<")
2101         (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2102   "!TARGET_64BIT"
2103   "#")
2105 (define_insn "*pushdi2_rex64"
2106   [(set (match_operand:DI 0 "push_operand" "=<,!<")
2107         (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2108   "TARGET_64BIT"
2109   "@
2110    push{q}\t%1
2111    #"
2112   [(set_attr "type" "push,multi")
2113    (set_attr "mode" "DI")])
2115 ;; Convert impossible pushes of immediate to existing instructions.
2116 ;; First try to get scratch register and go through it.  In case this
2117 ;; fails, push sign extended lower part first and then overwrite
2118 ;; upper part by 32bit move.
2119 (define_peephole2
2120   [(match_scratch:DI 2 "r")
2121    (set (match_operand:DI 0 "push_operand" "")
2122         (match_operand:DI 1 "immediate_operand" ""))]
2123   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2124    && !x86_64_immediate_operand (operands[1], DImode)"
2125   [(set (match_dup 2) (match_dup 1))
2126    (set (match_dup 0) (match_dup 2))]
2127   "")
2129 ;; We need to define this as both peepholer and splitter for case
2130 ;; peephole2 pass is not run.
2131 ;; "&& 1" is needed to keep it from matching the previous pattern.
2132 (define_peephole2
2133   [(set (match_operand:DI 0 "push_operand" "")
2134         (match_operand:DI 1 "immediate_operand" ""))]
2135   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2136    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2137   [(set (match_dup 0) (match_dup 1))
2138    (set (match_dup 2) (match_dup 3))]
2139   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2140    operands[1] = gen_lowpart (DImode, operands[2]);
2141    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2142                                                     GEN_INT (4)));
2143   ")
2145 (define_split
2146   [(set (match_operand:DI 0 "push_operand" "")
2147         (match_operand:DI 1 "immediate_operand" ""))]
2148   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2149                     ? epilogue_completed : reload_completed)
2150    && !symbolic_operand (operands[1], DImode)
2151    && !x86_64_immediate_operand (operands[1], DImode)"
2152   [(set (match_dup 0) (match_dup 1))
2153    (set (match_dup 2) (match_dup 3))]
2154   "split_di (&operands[1], 1, &operands[2], &operands[3]);
2155    operands[1] = gen_lowpart (DImode, operands[2]);
2156    operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2157                                                     GEN_INT (4)));
2158   ")
2160 (define_insn "*pushdi2_prologue_rex64"
2161   [(set (match_operand:DI 0 "push_operand" "=<")
2162         (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2163    (clobber (mem:BLK (scratch)))]
2164   "TARGET_64BIT"
2165   "push{q}\t%1"
2166   [(set_attr "type" "push")
2167    (set_attr "mode" "DI")])
2169 (define_insn "*popdi1_epilogue_rex64"
2170   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2171         (mem:DI (reg:DI SP_REG)))
2172    (set (reg:DI SP_REG)
2173         (plus:DI (reg:DI SP_REG) (const_int 8)))
2174    (clobber (mem:BLK (scratch)))]
2175   "TARGET_64BIT"
2176   "pop{q}\t%0"
2177   [(set_attr "type" "pop")
2178    (set_attr "mode" "DI")])
2180 (define_insn "popdi1"
2181   [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2182         (mem:DI (reg:DI SP_REG)))
2183    (set (reg:DI SP_REG)
2184         (plus:DI (reg:DI SP_REG) (const_int 8)))]
2185   "TARGET_64BIT"
2186   "pop{q}\t%0"
2187   [(set_attr "type" "pop")
2188    (set_attr "mode" "DI")])
2190 (define_insn "*movdi_xor_rex64"
2191   [(set (match_operand:DI 0 "register_operand" "=r")
2192         (match_operand:DI 1 "const0_operand" ""))
2193    (clobber (reg:CC FLAGS_REG))]
2194   "TARGET_64BIT && (!TARGET_USE_MOV0 || optimize_size)
2195    && reload_completed"
2196   "xor{l}\t%k0, %k0";
2197   [(set_attr "type" "alu1")
2198    (set_attr "mode" "SI")
2199    (set_attr "length_immediate" "0")])
2201 (define_insn "*movdi_or_rex64"
2202   [(set (match_operand:DI 0 "register_operand" "=r")
2203         (match_operand:DI 1 "const_int_operand" "i"))
2204    (clobber (reg:CC FLAGS_REG))]
2205   "TARGET_64BIT && (TARGET_MOVE_M1_VIA_OR || optimize_size)
2206    && reload_completed
2207    && operands[1] == constm1_rtx"
2209   operands[1] = constm1_rtx;
2210   return "or{q}\t{%1, %0|%0, %1}";
2212   [(set_attr "type" "alu1")
2213    (set_attr "mode" "DI")
2214    (set_attr "length_immediate" "1")])
2216 (define_insn "*movdi_2"
2217   [(set (match_operand:DI 0 "nonimmediate_operand"
2218                         "=r  ,o  ,*y,m*y,*y,*Y2,m  ,*Y2,*Y2,*x,m ,*x,*x")
2219         (match_operand:DI 1 "general_operand"
2220                         "riFo,riF,C ,*y ,m ,C  ,*Y2,*Y2,m  ,C ,*x,*x,m "))]
2221   "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2222   "@
2223    #
2224    #
2225    pxor\t%0, %0
2226    movq\t{%1, %0|%0, %1}
2227    movq\t{%1, %0|%0, %1}
2228    pxor\t%0, %0
2229    movq\t{%1, %0|%0, %1}
2230    movdqa\t{%1, %0|%0, %1}
2231    movq\t{%1, %0|%0, %1}
2232    xorps\t%0, %0
2233    movlps\t{%1, %0|%0, %1}
2234    movaps\t{%1, %0|%0, %1}
2235    movlps\t{%1, %0|%0, %1}"
2236   [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2237    (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2239 (define_split
2240   [(set (match_operand:DI 0 "push_operand" "")
2241         (match_operand:DI 1 "general_operand" ""))]
2242   "!TARGET_64BIT && reload_completed
2243    && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2244   [(const_int 0)]
2245   "ix86_split_long_move (operands); DONE;")
2247 ;; %%% This multiword shite has got to go.
2248 (define_split
2249   [(set (match_operand:DI 0 "nonimmediate_operand" "")
2250         (match_operand:DI 1 "general_operand" ""))]
2251   "!TARGET_64BIT && reload_completed
2252    && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2253    && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2254   [(const_int 0)]
2255   "ix86_split_long_move (operands); DONE;")
2257 (define_insn "*movdi_1_rex64"
2258   [(set (match_operand:DI 0 "nonimmediate_operand"
2259           "=r,r  ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2260         (match_operand:DI 1 "general_operand"
2261           "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r   ,m  ,C ,*x,*Yi,*x,r  ,m ,*Ym,*x"))]
2262   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2264   switch (get_attr_type (insn))
2265     {
2266     case TYPE_SSECVT:
2267       if (SSE_REG_P (operands[0]))
2268         return "movq2dq\t{%1, %0|%0, %1}";
2269       else
2270         return "movdq2q\t{%1, %0|%0, %1}";
2272     case TYPE_SSEMOV:
2273       if (get_attr_mode (insn) == MODE_TI)
2274         return "movdqa\t{%1, %0|%0, %1}";
2275       /* FALLTHRU */
2277     case TYPE_MMXMOV:
2278       /* Moves from and into integer register is done using movd
2279          opcode with REX prefix.  */
2280       if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2281         return "movd\t{%1, %0|%0, %1}";
2282       return "movq\t{%1, %0|%0, %1}";
2284     case TYPE_SSELOG1:
2285     case TYPE_MMXADD:
2286       return "pxor\t%0, %0";
2288     case TYPE_MULTI:
2289       return "#";
2291     case TYPE_LEA:
2292       return "lea{q}\t{%a1, %0|%0, %a1}";
2294     default:
2295       gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2296       if (get_attr_mode (insn) == MODE_SI)
2297         return "mov{l}\t{%k1, %k0|%k0, %k1}";
2298       else if (which_alternative == 2)
2299         return "movabs{q}\t{%1, %0|%0, %1}";
2300       else
2301         return "mov{q}\t{%1, %0|%0, %1}";
2302     }
2304   [(set (attr "type")
2305      (cond [(eq_attr "alternative" "5")
2306               (const_string "mmxadd")
2307             (eq_attr "alternative" "6,7,8,9,10")
2308               (const_string "mmxmov")
2309             (eq_attr "alternative" "11")
2310               (const_string "sselog1")
2311             (eq_attr "alternative" "12,13,14,15,16")
2312               (const_string "ssemov")
2313             (eq_attr "alternative" "17,18")
2314               (const_string "ssecvt")
2315             (eq_attr "alternative" "4")
2316               (const_string "multi")
2317             (match_operand:DI 1 "pic_32bit_operand" "")
2318               (const_string "lea")
2319            ]
2320            (const_string "imov")))
2321    (set_attr "modrm" "*,0,0,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2322    (set_attr "length_immediate" "*,4,8,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*")
2323    (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2325 ;; Stores and loads of ax to arbitrary constant address.
2326 ;; We fake an second form of instruction to force reload to load address
2327 ;; into register when rax is not available
2328 (define_insn "*movabsdi_1_rex64"
2329   [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2330         (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2331   "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2332   "@
2333    movabs{q}\t{%1, %P0|%P0, %1}
2334    mov{q}\t{%1, %a0|%a0, %1}"
2335   [(set_attr "type" "imov")
2336    (set_attr "modrm" "0,*")
2337    (set_attr "length_address" "8,0")
2338    (set_attr "length_immediate" "0,*")
2339    (set_attr "memory" "store")
2340    (set_attr "mode" "DI")])
2342 (define_insn "*movabsdi_2_rex64"
2343   [(set (match_operand:DI 0 "register_operand" "=a,r")
2344         (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2345   "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2346   "@
2347    movabs{q}\t{%P1, %0|%0, %P1}
2348    mov{q}\t{%a1, %0|%0, %a1}"
2349   [(set_attr "type" "imov")
2350    (set_attr "modrm" "0,*")
2351    (set_attr "length_address" "8,0")
2352    (set_attr "length_immediate" "0")
2353    (set_attr "memory" "load")
2354    (set_attr "mode" "DI")])
2356 ;; Convert impossible stores of immediate to existing instructions.
2357 ;; First try to get scratch register and go through it.  In case this
2358 ;; fails, move by 32bit parts.
2359 (define_peephole2
2360   [(match_scratch:DI 2 "r")
2361    (set (match_operand:DI 0 "memory_operand" "")
2362         (match_operand:DI 1 "immediate_operand" ""))]
2363   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2364    && !x86_64_immediate_operand (operands[1], DImode)"
2365   [(set (match_dup 2) (match_dup 1))
2366    (set (match_dup 0) (match_dup 2))]
2367   "")
2369 ;; We need to define this as both peepholer and splitter for case
2370 ;; peephole2 pass is not run.
2371 ;; "&& 1" is needed to keep it from matching the previous pattern.
2372 (define_peephole2
2373   [(set (match_operand:DI 0 "memory_operand" "")
2374         (match_operand:DI 1 "immediate_operand" ""))]
2375   "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2376    && !x86_64_immediate_operand (operands[1], DImode) && 1"
2377   [(set (match_dup 2) (match_dup 3))
2378    (set (match_dup 4) (match_dup 5))]
2379   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2381 (define_split
2382   [(set (match_operand:DI 0 "memory_operand" "")
2383         (match_operand:DI 1 "immediate_operand" ""))]
2384   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2385                     ? epilogue_completed : reload_completed)
2386    && !symbolic_operand (operands[1], DImode)
2387    && !x86_64_immediate_operand (operands[1], DImode)"
2388   [(set (match_dup 2) (match_dup 3))
2389    (set (match_dup 4) (match_dup 5))]
2390   "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2392 (define_insn "*swapdi_rex64"
2393   [(set (match_operand:DI 0 "register_operand" "+r")
2394         (match_operand:DI 1 "register_operand" "+r"))
2395    (set (match_dup 1)
2396         (match_dup 0))]
2397   "TARGET_64BIT"
2398   "xchg{q}\t%1, %0"
2399   [(set_attr "type" "imov")
2400    (set_attr "mode" "DI")
2401    (set_attr "pent_pair" "np")
2402    (set_attr "athlon_decode" "vector")
2403    (set_attr "amdfam10_decode" "double")])
2405 (define_expand "movti"
2406   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2407         (match_operand:TI 1 "nonimmediate_operand" ""))]
2408   "TARGET_SSE || TARGET_64BIT"
2410   if (TARGET_64BIT)
2411     ix86_expand_move (TImode, operands);
2412   else if (push_operand (operands[0], TImode))
2413     ix86_expand_push (TImode, operands[1]);
2414   else
2415     ix86_expand_vector_move (TImode, operands);
2416   DONE;
2419 (define_insn "*movti_internal"
2420   [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2421         (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2422   "TARGET_SSE && !TARGET_64BIT
2423    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2425   switch (which_alternative)
2426     {
2427     case 0:
2428       if (get_attr_mode (insn) == MODE_V4SF)
2429         return "xorps\t%0, %0";
2430       else
2431         return "pxor\t%0, %0";
2432     case 1:
2433     case 2:
2434       /* TDmode values are passed as TImode on the stack.  Moving them
2435          to stack may result in unaligned memory access.  */
2436       if (misaligned_operand (operands[0], TImode)
2437           || misaligned_operand (operands[1], TImode))
2438         { 
2439           if (get_attr_mode (insn) == MODE_V4SF)
2440             return "movups\t{%1, %0|%0, %1}";
2441          else
2442            return "movdqu\t{%1, %0|%0, %1}";
2443         }
2444       else
2445         { 
2446           if (get_attr_mode (insn) == MODE_V4SF)
2447             return "movaps\t{%1, %0|%0, %1}";
2448          else
2449            return "movdqa\t{%1, %0|%0, %1}";
2450         }
2451     default:
2452       gcc_unreachable ();
2453     }
2455   [(set_attr "type" "sselog1,ssemov,ssemov")
2456    (set (attr "mode")
2457         (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2458                     (ne (symbol_ref "optimize_size") (const_int 0)))
2459                  (const_string "V4SF")
2460                (and (eq_attr "alternative" "2")
2461                     (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2462                         (const_int 0)))
2463                  (const_string "V4SF")]
2464               (const_string "TI")))])
2466 (define_insn "*movti_rex64"
2467   [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2468         (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2469   "TARGET_64BIT
2470    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2472   switch (which_alternative)
2473     {
2474     case 0:
2475     case 1:
2476       return "#";
2477     case 2:
2478       if (get_attr_mode (insn) == MODE_V4SF)
2479         return "xorps\t%0, %0";
2480       else
2481         return "pxor\t%0, %0";
2482     case 3:
2483     case 4:
2484       /* TDmode values are passed as TImode on the stack.  Moving them
2485          to stack may result in unaligned memory access.  */
2486       if (misaligned_operand (operands[0], TImode)
2487           || misaligned_operand (operands[1], TImode))
2488         { 
2489           if (get_attr_mode (insn) == MODE_V4SF)
2490             return "movups\t{%1, %0|%0, %1}";
2491          else
2492            return "movdqu\t{%1, %0|%0, %1}";
2493         }
2494       else
2495         { 
2496           if (get_attr_mode (insn) == MODE_V4SF)
2497             return "movaps\t{%1, %0|%0, %1}";
2498          else
2499            return "movdqa\t{%1, %0|%0, %1}";
2500         }
2501     default:
2502       gcc_unreachable ();
2503     }
2505   [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2506    (set (attr "mode")
2507         (cond [(eq_attr "alternative" "2,3")
2508                  (if_then_else
2509                    (ne (symbol_ref "optimize_size")
2510                        (const_int 0))
2511                    (const_string "V4SF")
2512                    (const_string "TI"))
2513                (eq_attr "alternative" "4")
2514                  (if_then_else
2515                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2516                             (const_int 0))
2517                         (ne (symbol_ref "optimize_size")
2518                             (const_int 0)))
2519                    (const_string "V4SF")
2520                    (const_string "TI"))]
2521                (const_string "DI")))])
2523 (define_split
2524   [(set (match_operand:TI 0 "nonimmediate_operand" "")
2525         (match_operand:TI 1 "general_operand" ""))]
2526   "reload_completed && !SSE_REG_P (operands[0])
2527    && !SSE_REG_P (operands[1])"
2528   [(const_int 0)]
2529   "ix86_split_long_move (operands); DONE;")
2531 ;; This expands to what emit_move_complex would generate if we didn't
2532 ;; have a movti pattern.  Having this avoids problems with reload on
2533 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2534 ;; to have around all the time.
2535 (define_expand "movcdi"
2536   [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2537         (match_operand:CDI 1 "general_operand" ""))]
2538   ""
2540   if (push_operand (operands[0], CDImode))
2541     emit_move_complex_push (CDImode, operands[0], operands[1]);
2542   else
2543     emit_move_complex_parts (operands[0], operands[1]);
2544   DONE;
2547 (define_expand "movsf"
2548   [(set (match_operand:SF 0 "nonimmediate_operand" "")
2549         (match_operand:SF 1 "general_operand" ""))]
2550   ""
2551   "ix86_expand_move (SFmode, operands); DONE;")
2553 (define_insn "*pushsf"
2554   [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2555         (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2556   "!TARGET_64BIT"
2558   /* Anything else should be already split before reg-stack.  */
2559   gcc_assert (which_alternative == 1);
2560   return "push{l}\t%1";
2562   [(set_attr "type" "multi,push,multi")
2563    (set_attr "unit" "i387,*,*")
2564    (set_attr "mode" "SF,SI,SF")])
2566 (define_insn "*pushsf_rex64"
2567   [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2568         (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2569   "TARGET_64BIT"
2571   /* Anything else should be already split before reg-stack.  */
2572   gcc_assert (which_alternative == 1);
2573   return "push{q}\t%q1";
2575   [(set_attr "type" "multi,push,multi")
2576    (set_attr "unit" "i387,*,*")
2577    (set_attr "mode" "SF,DI,SF")])
2579 (define_split
2580   [(set (match_operand:SF 0 "push_operand" "")
2581         (match_operand:SF 1 "memory_operand" ""))]
2582   "reload_completed
2583    && MEM_P (operands[1])
2584    && (operands[2] = find_constant_src (insn))"
2585   [(set (match_dup 0)
2586         (match_dup 2))])
2589 ;; %%% Kill this when call knows how to work this out.
2590 (define_split
2591   [(set (match_operand:SF 0 "push_operand" "")
2592         (match_operand:SF 1 "any_fp_register_operand" ""))]
2593   "!TARGET_64BIT"
2594   [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2595    (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2597 (define_split
2598   [(set (match_operand:SF 0 "push_operand" "")
2599         (match_operand:SF 1 "any_fp_register_operand" ""))]
2600   "TARGET_64BIT"
2601   [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2602    (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2604 (define_insn "*movsf_1"
2605   [(set (match_operand:SF 0 "nonimmediate_operand"
2606           "=f,m,f,r  ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2607         (match_operand:SF 1 "general_operand"
2608           "fm,f,G,rmF,Fr,C,x,xm,x,m  ,*y,*y ,r  ,Yi,r   ,*Ym"))]
2609   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2610    && (reload_in_progress || reload_completed
2611        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2612        || (!TARGET_SSE_MATH && optimize_size
2613            && standard_80387_constant_p (operands[1]))
2614        || GET_CODE (operands[1]) != CONST_DOUBLE
2615        || memory_operand (operands[0], SFmode))"
2617   switch (which_alternative)
2618     {
2619     case 0:
2620     case 1:
2621       return output_387_reg_move (insn, operands);
2623     case 2:
2624       return standard_80387_constant_opcode (operands[1]);
2626     case 3:
2627     case 4:
2628       return "mov{l}\t{%1, %0|%0, %1}";
2629     case 5:
2630       if (get_attr_mode (insn) == MODE_TI)
2631         return "pxor\t%0, %0";
2632       else
2633         return "xorps\t%0, %0";
2634     case 6:
2635       if (get_attr_mode (insn) == MODE_V4SF)
2636         return "movaps\t{%1, %0|%0, %1}";
2637       else
2638         return "movss\t{%1, %0|%0, %1}";
2639     case 7: case 8:
2640       return "movss\t{%1, %0|%0, %1}";
2642     case 9: case 10:
2643     case 12: case 13: case 14: case 15:
2644       return "movd\t{%1, %0|%0, %1}";
2646     case 11:
2647       return "movq\t{%1, %0|%0, %1}";
2649     default:
2650       gcc_unreachable ();
2651     }
2653   [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2654    (set (attr "mode")
2655         (cond [(eq_attr "alternative" "3,4,9,10")
2656                  (const_string "SI")
2657                (eq_attr "alternative" "5")
2658                  (if_then_else
2659                    (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2660                                  (const_int 0))
2661                              (ne (symbol_ref "TARGET_SSE2")
2662                                  (const_int 0)))
2663                         (eq (symbol_ref "optimize_size")
2664                             (const_int 0)))
2665                    (const_string "TI")
2666                    (const_string "V4SF"))
2667                /* For architectures resolving dependencies on
2668                   whole SSE registers use APS move to break dependency
2669                   chains, otherwise use short move to avoid extra work.
2671                   Do the same for architectures resolving dependencies on
2672                   the parts.  While in DF mode it is better to always handle
2673                   just register parts, the SF mode is different due to lack
2674                   of instructions to load just part of the register.  It is
2675                   better to maintain the whole registers in single format
2676                   to avoid problems on using packed logical operations.  */
2677                (eq_attr "alternative" "6")
2678                  (if_then_else
2679                    (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2680                             (const_int 0))
2681                         (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2682                             (const_int 0)))
2683                    (const_string "V4SF")
2684                    (const_string "SF"))
2685                (eq_attr "alternative" "11")
2686                  (const_string "DI")]
2687                (const_string "SF")))])
2689 (define_insn "*swapsf"
2690   [(set (match_operand:SF 0 "fp_register_operand" "+f")
2691         (match_operand:SF 1 "fp_register_operand" "+f"))
2692    (set (match_dup 1)
2693         (match_dup 0))]
2694   "reload_completed || TARGET_80387"
2696   if (STACK_TOP_P (operands[0]))
2697     return "fxch\t%1";
2698   else
2699     return "fxch\t%0";
2701   [(set_attr "type" "fxch")
2702    (set_attr "mode" "SF")])
2704 (define_expand "movdf"
2705   [(set (match_operand:DF 0 "nonimmediate_operand" "")
2706         (match_operand:DF 1 "general_operand" ""))]
2707   ""
2708   "ix86_expand_move (DFmode, operands); DONE;")
2710 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2711 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2712 ;; On the average, pushdf using integers can be still shorter.  Allow this
2713 ;; pattern for optimize_size too.
2715 (define_insn "*pushdf_nointeger"
2716   [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2717         (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2718   "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2720   /* This insn should be already split before reg-stack.  */
2721   gcc_unreachable ();
2723   [(set_attr "type" "multi")
2724    (set_attr "unit" "i387,*,*,*")
2725    (set_attr "mode" "DF,SI,SI,DF")])
2727 (define_insn "*pushdf_integer"
2728   [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2729         (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2730   "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2732   /* This insn should be already split before reg-stack.  */
2733   gcc_unreachable ();
2735   [(set_attr "type" "multi")
2736    (set_attr "unit" "i387,*,*")
2737    (set_attr "mode" "DF,SI,DF")])
2739 ;; %%% Kill this when call knows how to work this out.
2740 (define_split
2741   [(set (match_operand:DF 0 "push_operand" "")
2742         (match_operand:DF 1 "any_fp_register_operand" ""))]
2743   "reload_completed"
2744   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2745    (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2746   "")
2748 (define_split
2749   [(set (match_operand:DF 0 "push_operand" "")
2750         (match_operand:DF 1 "general_operand" ""))]
2751   "reload_completed"
2752   [(const_int 0)]
2753   "ix86_split_long_move (operands); DONE;")
2755 ;; Moving is usually shorter when only FP registers are used. This separate
2756 ;; movdf pattern avoids the use of integer registers for FP operations
2757 ;; when optimizing for size.
2759 (define_insn "*movdf_nointeger"
2760   [(set (match_operand:DF 0 "nonimmediate_operand"
2761                         "=f,m,f,*r  ,o  ,Y2*x,Y2*x,Y2*x ,m  ")
2762         (match_operand:DF 1 "general_operand"
2763                         "fm,f,G,*roF,*Fr,C   ,Y2*x,mY2*x,Y2*x"))]
2764   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2765    && ((optimize_size || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
2766    && (reload_in_progress || reload_completed
2767        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2768        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2769            && !memory_operand (operands[0], DFmode)
2770            && standard_80387_constant_p (operands[1]))
2771        || GET_CODE (operands[1]) != CONST_DOUBLE
2772        || ((optimize_size
2773             || !TARGET_MEMORY_MISMATCH_STALL
2774             || reload_in_progress || reload_completed)
2775            && memory_operand (operands[0], DFmode)))"
2777   switch (which_alternative)
2778     {
2779     case 0:
2780     case 1:
2781       return output_387_reg_move (insn, operands);
2783     case 2:
2784       return standard_80387_constant_opcode (operands[1]);
2786     case 3:
2787     case 4:
2788       return "#";
2789     case 5:
2790       switch (get_attr_mode (insn))
2791         {
2792         case MODE_V4SF:
2793           return "xorps\t%0, %0";
2794         case MODE_V2DF:
2795           return "xorpd\t%0, %0";
2796         case MODE_TI:
2797           return "pxor\t%0, %0";
2798         default:
2799           gcc_unreachable ();
2800         }
2801     case 6:
2802     case 7:
2803     case 8:
2804       switch (get_attr_mode (insn))
2805         {
2806         case MODE_V4SF:
2807           return "movaps\t{%1, %0|%0, %1}";
2808         case MODE_V2DF:
2809           return "movapd\t{%1, %0|%0, %1}";
2810         case MODE_TI:
2811           return "movdqa\t{%1, %0|%0, %1}";
2812         case MODE_DI:
2813           return "movq\t{%1, %0|%0, %1}";
2814         case MODE_DF:
2815           return "movsd\t{%1, %0|%0, %1}";
2816         case MODE_V1DF:
2817           return "movlpd\t{%1, %0|%0, %1}";
2818         case MODE_V2SF:
2819           return "movlps\t{%1, %0|%0, %1}";
2820         default:
2821           gcc_unreachable ();
2822         }
2824     default:
2825       gcc_unreachable ();
2826     }
2828   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
2829    (set (attr "mode")
2830         (cond [(eq_attr "alternative" "0,1,2")
2831                  (const_string "DF")
2832                (eq_attr "alternative" "3,4")
2833                  (const_string "SI")
2835                /* For SSE1, we have many fewer alternatives.  */
2836                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2837                  (cond [(eq_attr "alternative" "5,6")
2838                           (const_string "V4SF")
2839                        ]
2840                    (const_string "V2SF"))
2842                /* xorps is one byte shorter.  */
2843                (eq_attr "alternative" "5")
2844                  (cond [(ne (symbol_ref "optimize_size")
2845                             (const_int 0))
2846                           (const_string "V4SF")
2847                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2848                             (const_int 0))
2849                           (const_string "TI")
2850                        ]
2851                        (const_string "V2DF"))
2853                /* For architectures resolving dependencies on
2854                   whole SSE registers use APD move to break dependency
2855                   chains, otherwise use short move to avoid extra work.
2857                   movaps encodes one byte shorter.  */
2858                (eq_attr "alternative" "6")
2859                  (cond
2860                    [(ne (symbol_ref "optimize_size")
2861                         (const_int 0))
2862                       (const_string "V4SF")
2863                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2864                         (const_int 0))
2865                       (const_string "V2DF")
2866                    ]
2867                    (const_string "DF"))
2868                /* For architectures resolving dependencies on register
2869                   parts we may avoid extra work to zero out upper part
2870                   of register.  */
2871                (eq_attr "alternative" "7")
2872                  (if_then_else
2873                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2874                        (const_int 0))
2875                    (const_string "V1DF")
2876                    (const_string "DF"))
2877               ]
2878               (const_string "DF")))])
2880 (define_insn "*movdf_integer_rex64"
2881   [(set (match_operand:DF 0 "nonimmediate_operand"
2882                 "=f,m,f,r  ,m ,Y2*x,Y2*x,Y2*x,m   ,Yi,r ")
2883         (match_operand:DF 1 "general_operand"
2884                 "fm,f,G,rmF,Fr,C   ,Y2*x,m   ,Y2*x,r ,Yi"))]
2885   "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2886    && (reload_in_progress || reload_completed
2887        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2888        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
2889            && standard_80387_constant_p (operands[1]))
2890        || GET_CODE (operands[1]) != CONST_DOUBLE
2891        || memory_operand (operands[0], DFmode))"
2893   switch (which_alternative)
2894     {
2895     case 0:
2896     case 1:
2897       return output_387_reg_move (insn, operands);
2899     case 2:
2900       return standard_80387_constant_opcode (operands[1]);
2902     case 3:
2903     case 4:
2904       return "#";
2906     case 5:
2907       switch (get_attr_mode (insn))
2908         {
2909         case MODE_V4SF:
2910           return "xorps\t%0, %0";
2911         case MODE_V2DF:
2912           return "xorpd\t%0, %0";
2913         case MODE_TI:
2914           return "pxor\t%0, %0";
2915         default:
2916           gcc_unreachable ();
2917         }
2918     case 6:
2919     case 7:
2920     case 8:
2921       switch (get_attr_mode (insn))
2922         {
2923         case MODE_V4SF:
2924           return "movaps\t{%1, %0|%0, %1}";
2925         case MODE_V2DF:
2926           return "movapd\t{%1, %0|%0, %1}";
2927         case MODE_TI:
2928           return "movdqa\t{%1, %0|%0, %1}";
2929         case MODE_DI:
2930           return "movq\t{%1, %0|%0, %1}";
2931         case MODE_DF:
2932           return "movsd\t{%1, %0|%0, %1}";
2933         case MODE_V1DF:
2934           return "movlpd\t{%1, %0|%0, %1}";
2935         case MODE_V2SF:
2936           return "movlps\t{%1, %0|%0, %1}";
2937         default:
2938           gcc_unreachable ();
2939         }
2941     case 9:
2942     case 10:
2943       return "movd\t{%1, %0|%0, %1}";
2945     default:
2946       gcc_unreachable();
2947     }
2949   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2950    (set (attr "mode")
2951         (cond [(eq_attr "alternative" "0,1,2")
2952                  (const_string "DF")
2953                (eq_attr "alternative" "3,4,9,10")
2954                  (const_string "DI")
2956                /* For SSE1, we have many fewer alternatives.  */
2957                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2958                  (cond [(eq_attr "alternative" "5,6")
2959                           (const_string "V4SF")
2960                        ]
2961                    (const_string "V2SF"))
2963                /* xorps is one byte shorter.  */
2964                (eq_attr "alternative" "5")
2965                  (cond [(ne (symbol_ref "optimize_size")
2966                             (const_int 0))
2967                           (const_string "V4SF")
2968                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2969                             (const_int 0))
2970                           (const_string "TI")
2971                        ]
2972                        (const_string "V2DF"))
2974                /* For architectures resolving dependencies on
2975                   whole SSE registers use APD move to break dependency
2976                   chains, otherwise use short move to avoid extra work.
2978                   movaps encodes one byte shorter.  */
2979                (eq_attr "alternative" "6")
2980                  (cond
2981                    [(ne (symbol_ref "optimize_size")
2982                         (const_int 0))
2983                       (const_string "V4SF")
2984                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2985                         (const_int 0))
2986                       (const_string "V2DF")
2987                    ]
2988                    (const_string "DF"))
2989                /* For architectures resolving dependencies on register
2990                   parts we may avoid extra work to zero out upper part
2991                   of register.  */
2992                (eq_attr "alternative" "7")
2993                  (if_then_else
2994                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2995                        (const_int 0))
2996                    (const_string "V1DF")
2997                    (const_string "DF"))
2998               ]
2999               (const_string "DF")))])
3001 (define_insn "*movdf_integer"
3002   [(set (match_operand:DF 0 "nonimmediate_operand"
3003                 "=f,m,f,r  ,o ,Y2*x,Y2*x,Y2*x,m   ")
3004         (match_operand:DF 1 "general_operand"
3005                 "fm,f,G,roF,Fr,C   ,Y2*x,m   ,Y2*x"))]
3006   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3007    && !optimize_size && TARGET_INTEGER_DFMODE_MOVES
3008    && (reload_in_progress || reload_completed
3009        || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3010        || (!(TARGET_SSE2 && TARGET_SSE_MATH) && optimize_size
3011            && standard_80387_constant_p (operands[1]))
3012        || GET_CODE (operands[1]) != CONST_DOUBLE
3013        || memory_operand (operands[0], DFmode))"
3015   switch (which_alternative)
3016     {
3017     case 0:
3018     case 1:
3019       return output_387_reg_move (insn, operands);
3021     case 2:
3022       return standard_80387_constant_opcode (operands[1]);
3024     case 3:
3025     case 4:
3026       return "#";
3028     case 5:
3029       switch (get_attr_mode (insn))
3030         {
3031         case MODE_V4SF:
3032           return "xorps\t%0, %0";
3033         case MODE_V2DF:
3034           return "xorpd\t%0, %0";
3035         case MODE_TI:
3036           return "pxor\t%0, %0";
3037         default:
3038           gcc_unreachable ();
3039         }
3040     case 6:
3041     case 7:
3042     case 8:
3043       switch (get_attr_mode (insn))
3044         {
3045         case MODE_V4SF:
3046           return "movaps\t{%1, %0|%0, %1}";
3047         case MODE_V2DF:
3048           return "movapd\t{%1, %0|%0, %1}";
3049         case MODE_TI:
3050           return "movdqa\t{%1, %0|%0, %1}";
3051         case MODE_DI:
3052           return "movq\t{%1, %0|%0, %1}";
3053         case MODE_DF:
3054           return "movsd\t{%1, %0|%0, %1}";
3055         case MODE_V1DF:
3056           return "movlpd\t{%1, %0|%0, %1}";
3057         case MODE_V2SF:
3058           return "movlps\t{%1, %0|%0, %1}";
3059         default:
3060           gcc_unreachable ();
3061         }
3063     default:
3064       gcc_unreachable();
3065     }
3067   [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3068    (set (attr "mode")
3069         (cond [(eq_attr "alternative" "0,1,2")
3070                  (const_string "DF")
3071                (eq_attr "alternative" "3,4")
3072                  (const_string "SI")
3074                /* For SSE1, we have many fewer alternatives.  */
3075                (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3076                  (cond [(eq_attr "alternative" "5,6")
3077                           (const_string "V4SF")
3078                        ]
3079                    (const_string "V2SF"))
3081                /* xorps is one byte shorter.  */
3082                (eq_attr "alternative" "5")
3083                  (cond [(ne (symbol_ref "optimize_size")
3084                             (const_int 0))
3085                           (const_string "V4SF")
3086                         (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3087                             (const_int 0))
3088                           (const_string "TI")
3089                        ]
3090                        (const_string "V2DF"))
3092                /* For architectures resolving dependencies on
3093                   whole SSE registers use APD move to break dependency
3094                   chains, otherwise use short move to avoid extra work.
3096                   movaps encodes one byte shorter.  */
3097                (eq_attr "alternative" "6")
3098                  (cond
3099                    [(ne (symbol_ref "optimize_size")
3100                         (const_int 0))
3101                       (const_string "V4SF")
3102                     (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3103                         (const_int 0))
3104                       (const_string "V2DF")
3105                    ]
3106                    (const_string "DF"))
3107                /* For architectures resolving dependencies on register
3108                   parts we may avoid extra work to zero out upper part
3109                   of register.  */
3110                (eq_attr "alternative" "7")
3111                  (if_then_else
3112                    (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3113                        (const_int 0))
3114                    (const_string "V1DF")
3115                    (const_string "DF"))
3116               ]
3117               (const_string "DF")))])
3119 (define_split
3120   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3121         (match_operand:DF 1 "general_operand" ""))]
3122   "reload_completed
3123    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3124    && ! (ANY_FP_REG_P (operands[0]) ||
3125          (GET_CODE (operands[0]) == SUBREG
3126           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3127    && ! (ANY_FP_REG_P (operands[1]) ||
3128          (GET_CODE (operands[1]) == SUBREG
3129           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3130   [(const_int 0)]
3131   "ix86_split_long_move (operands); DONE;")
3133 (define_insn "*swapdf"
3134   [(set (match_operand:DF 0 "fp_register_operand" "+f")
3135         (match_operand:DF 1 "fp_register_operand" "+f"))
3136    (set (match_dup 1)
3137         (match_dup 0))]
3138   "reload_completed || TARGET_80387"
3140   if (STACK_TOP_P (operands[0]))
3141     return "fxch\t%1";
3142   else
3143     return "fxch\t%0";
3145   [(set_attr "type" "fxch")
3146    (set_attr "mode" "DF")])
3148 (define_expand "movxf"
3149   [(set (match_operand:XF 0 "nonimmediate_operand" "")
3150         (match_operand:XF 1 "general_operand" ""))]
3151   ""
3152   "ix86_expand_move (XFmode, operands); DONE;")
3154 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3155 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3156 ;; Pushing using integer instructions is longer except for constants
3157 ;; and direct memory references.
3158 ;; (assuming that any given constant is pushed only once, but this ought to be
3159 ;;  handled elsewhere).
3161 (define_insn "*pushxf_nointeger"
3162   [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3163         (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3164   "optimize_size"
3166   /* This insn should be already split before reg-stack.  */
3167   gcc_unreachable ();
3169   [(set_attr "type" "multi")
3170    (set_attr "unit" "i387,*,*")
3171    (set_attr "mode" "XF,SI,SI")])
3173 (define_insn "*pushxf_integer"
3174   [(set (match_operand:XF 0 "push_operand" "=<,<")
3175         (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3176   "!optimize_size"
3178   /* This insn should be already split before reg-stack.  */
3179   gcc_unreachable ();
3181   [(set_attr "type" "multi")
3182    (set_attr "unit" "i387,*")
3183    (set_attr "mode" "XF,SI")])
3185 (define_split
3186   [(set (match_operand 0 "push_operand" "")
3187         (match_operand 1 "general_operand" ""))]
3188   "reload_completed
3189    && (GET_MODE (operands[0]) == XFmode
3190        || GET_MODE (operands[0]) == DFmode)
3191    && !ANY_FP_REG_P (operands[1])"
3192   [(const_int 0)]
3193   "ix86_split_long_move (operands); DONE;")
3195 (define_split
3196   [(set (match_operand:XF 0 "push_operand" "")
3197         (match_operand:XF 1 "any_fp_register_operand" ""))]
3198   ""
3199   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3200    (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3201   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3203 ;; Do not use integer registers when optimizing for size
3204 (define_insn "*movxf_nointeger"
3205   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3206         (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3207   "optimize_size
3208    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3209    && (reload_in_progress || reload_completed
3210        || (optimize_size && standard_80387_constant_p (operands[1]))
3211        || GET_CODE (operands[1]) != CONST_DOUBLE
3212        || memory_operand (operands[0], XFmode))"
3214   switch (which_alternative)
3215     {
3216     case 0:
3217     case 1:
3218       return output_387_reg_move (insn, operands);
3220     case 2:
3221       return standard_80387_constant_opcode (operands[1]);
3223     case 3: case 4:
3224       return "#";
3225     default:
3226       gcc_unreachable ();
3227     }
3229   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3230    (set_attr "mode" "XF,XF,XF,SI,SI")])
3232 (define_insn "*movxf_integer"
3233   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3234         (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3235   "!optimize_size
3236    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3237    && (reload_in_progress || reload_completed
3238        || (optimize_size && standard_80387_constant_p (operands[1]))
3239        || GET_CODE (operands[1]) != CONST_DOUBLE
3240        || memory_operand (operands[0], XFmode))"
3242   switch (which_alternative)
3243     {
3244     case 0:
3245     case 1:
3246       return output_387_reg_move (insn, operands);
3248     case 2:
3249       return standard_80387_constant_opcode (operands[1]);
3251     case 3: case 4:
3252       return "#";
3254     default:
3255       gcc_unreachable ();
3256     }
3258   [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3259    (set_attr "mode" "XF,XF,XF,SI,SI")])
3261 (define_expand "movtf"
3262   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3263         (match_operand:TF 1 "nonimmediate_operand" ""))]
3264   "TARGET_SSE2"
3266   ix86_expand_move (TFmode, operands);
3267   DONE;
3270 (define_insn "*movtf_internal"
3271   [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3272         (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3273   "TARGET_SSE2
3274    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3276   switch (which_alternative)
3277     {
3278     case 0:
3279     case 1:
3280       if (get_attr_mode (insn) == MODE_V4SF)
3281         return "movaps\t{%1, %0|%0, %1}";
3282       else
3283         return "movdqa\t{%1, %0|%0, %1}";
3284     case 2:
3285       if (get_attr_mode (insn) == MODE_V4SF)
3286         return "xorps\t%0, %0";
3287       else
3288         return "pxor\t%0, %0";
3289     case 3:
3290     case 4:
3291         return "#";
3292     default:
3293       gcc_unreachable ();
3294     }
3296   [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3297    (set (attr "mode")
3298         (cond [(eq_attr "alternative" "0,2")
3299                  (if_then_else
3300                    (ne (symbol_ref "optimize_size")
3301                        (const_int 0))
3302                    (const_string "V4SF")
3303                    (const_string "TI"))
3304                (eq_attr "alternative" "1")
3305                  (if_then_else
3306                    (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3307                             (const_int 0))
3308                         (ne (symbol_ref "optimize_size")
3309                             (const_int 0)))
3310                    (const_string "V4SF")
3311                    (const_string "TI"))]
3312                (const_string "DI")))])
3314 (define_split
3315   [(set (match_operand 0 "nonimmediate_operand" "")
3316         (match_operand 1 "general_operand" ""))]
3317   "reload_completed
3318    && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3319    && GET_MODE (operands[0]) == XFmode
3320    && ! (ANY_FP_REG_P (operands[0]) ||
3321          (GET_CODE (operands[0]) == SUBREG
3322           && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3323    && ! (ANY_FP_REG_P (operands[1]) ||
3324          (GET_CODE (operands[1]) == SUBREG
3325           && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3326   [(const_int 0)]
3327   "ix86_split_long_move (operands); DONE;")
3329 (define_split
3330   [(set (match_operand 0 "register_operand" "")
3331         (match_operand 1 "memory_operand" ""))]
3332   "reload_completed
3333    && MEM_P (operands[1])
3334    && (GET_MODE (operands[0]) == TFmode
3335        || GET_MODE (operands[0]) == XFmode
3336        || GET_MODE (operands[0]) == SFmode
3337        || GET_MODE (operands[0]) == DFmode)
3338    && (operands[2] = find_constant_src (insn))"
3339   [(set (match_dup 0) (match_dup 2))]
3341   rtx c = operands[2];
3342   rtx r = operands[0];
3344   if (GET_CODE (r) == SUBREG)
3345     r = SUBREG_REG (r);
3347   if (SSE_REG_P (r))
3348     {
3349       if (!standard_sse_constant_p (c))
3350         FAIL;
3351     }
3352   else if (FP_REG_P (r))
3353     {
3354       if (!standard_80387_constant_p (c))
3355         FAIL;
3356     }
3357   else if (MMX_REG_P (r))
3358     FAIL;
3361 (define_split
3362   [(set (match_operand 0 "register_operand" "")
3363         (float_extend (match_operand 1 "memory_operand" "")))]
3364   "reload_completed
3365    && MEM_P (operands[1])
3366    && (GET_MODE (operands[0]) == TFmode
3367        || GET_MODE (operands[0]) == XFmode
3368        || GET_MODE (operands[0]) == SFmode
3369        || GET_MODE (operands[0]) == DFmode)
3370    && (operands[2] = find_constant_src (insn))"
3371   [(set (match_dup 0) (match_dup 2))]
3373   rtx c = operands[2];
3374   rtx r = operands[0];
3376   if (GET_CODE (r) == SUBREG)
3377     r = SUBREG_REG (r);
3379   if (SSE_REG_P (r))
3380     {
3381       if (!standard_sse_constant_p (c))
3382         FAIL;
3383     }
3384   else if (FP_REG_P (r))
3385     {
3386       if (!standard_80387_constant_p (c))
3387         FAIL;
3388     }
3389   else if (MMX_REG_P (r))
3390     FAIL;
3393 (define_insn "swapxf"
3394   [(set (match_operand:XF 0 "register_operand" "+f")
3395         (match_operand:XF 1 "register_operand" "+f"))
3396    (set (match_dup 1)
3397         (match_dup 0))]
3398   "TARGET_80387"
3400   if (STACK_TOP_P (operands[0]))
3401     return "fxch\t%1";
3402   else
3403     return "fxch\t%0";
3405   [(set_attr "type" "fxch")
3406    (set_attr "mode" "XF")])
3408 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3409 (define_split
3410   [(set (match_operand:X87MODEF 0 "register_operand" "")
3411         (match_operand:X87MODEF 1 "immediate_operand" ""))]
3412   "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3413    && (standard_80387_constant_p (operands[1]) == 8
3414        || standard_80387_constant_p (operands[1]) == 9)"
3415   [(set (match_dup 0)(match_dup 1))
3416    (set (match_dup 0)
3417         (neg:X87MODEF (match_dup 0)))]
3419   REAL_VALUE_TYPE r;
3421   REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3422   if (real_isnegzero (&r))
3423     operands[1] = CONST0_RTX (<MODE>mode);
3424   else
3425     operands[1] = CONST1_RTX (<MODE>mode);
3428 (define_split
3429   [(set (match_operand:TF 0 "nonimmediate_operand" "")
3430         (match_operand:TF 1 "general_operand" ""))]
3431   "reload_completed
3432    && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3433   [(const_int 0)]
3434   "ix86_split_long_move (operands); DONE;")
3436 ;; Zero extension instructions
3438 (define_expand "zero_extendhisi2"
3439   [(set (match_operand:SI 0 "register_operand" "")
3440      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3441   ""
3443   if (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3444     {
3445       operands[1] = force_reg (HImode, operands[1]);
3446       emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3447       DONE;
3448     }
3451 (define_insn "zero_extendhisi2_and"
3452   [(set (match_operand:SI 0 "register_operand" "=r")
3453      (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3454    (clobber (reg:CC FLAGS_REG))]
3455   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3456   "#"
3457   [(set_attr "type" "alu1")
3458    (set_attr "mode" "SI")])
3460 (define_split
3461   [(set (match_operand:SI 0 "register_operand" "")
3462         (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3463    (clobber (reg:CC FLAGS_REG))]
3464   "reload_completed && TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3465   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3466               (clobber (reg:CC FLAGS_REG))])]
3467   "")
3469 (define_insn "*zero_extendhisi2_movzwl"
3470   [(set (match_operand:SI 0 "register_operand" "=r")
3471      (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3472   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3473   "movz{wl|x}\t{%1, %0|%0, %1}"
3474   [(set_attr "type" "imovx")
3475    (set_attr "mode" "SI")])
3477 (define_expand "zero_extendqihi2"
3478   [(parallel
3479     [(set (match_operand:HI 0 "register_operand" "")
3480        (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3481      (clobber (reg:CC FLAGS_REG))])]
3482   ""
3483   "")
3485 (define_insn "*zero_extendqihi2_and"
3486   [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3487      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3488    (clobber (reg:CC FLAGS_REG))]
3489   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3490   "#"
3491   [(set_attr "type" "alu1")
3492    (set_attr "mode" "HI")])
3494 (define_insn "*zero_extendqihi2_movzbw_and"
3495   [(set (match_operand:HI 0 "register_operand" "=r,r")
3496      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3497    (clobber (reg:CC FLAGS_REG))]
3498   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3499   "#"
3500   [(set_attr "type" "imovx,alu1")
3501    (set_attr "mode" "HI")])
3503 ; zero extend to SImode here to avoid partial register stalls
3504 (define_insn "*zero_extendqihi2_movzbl"
3505   [(set (match_operand:HI 0 "register_operand" "=r")
3506      (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3507   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3508   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3509   [(set_attr "type" "imovx")
3510    (set_attr "mode" "SI")])
3512 ;; For the movzbw case strip only the clobber
3513 (define_split
3514   [(set (match_operand:HI 0 "register_operand" "")
3515         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3516    (clobber (reg:CC FLAGS_REG))]
3517   "reload_completed
3518    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3519    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3520   [(set (match_operand:HI 0 "register_operand" "")
3521         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3523 ;; When source and destination does not overlap, clear destination
3524 ;; first and then do the movb
3525 (define_split
3526   [(set (match_operand:HI 0 "register_operand" "")
3527         (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3528    (clobber (reg:CC FLAGS_REG))]
3529   "reload_completed
3530    && ANY_QI_REG_P (operands[0])
3531    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3532    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3533   [(set (match_dup 0) (const_int 0))
3534    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3535   "operands[2] = gen_lowpart (QImode, operands[0]);")
3537 ;; Rest is handled by single and.
3538 (define_split
3539   [(set (match_operand:HI 0 "register_operand" "")
3540         (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3541    (clobber (reg:CC FLAGS_REG))]
3542   "reload_completed
3543    && true_regnum (operands[0]) == true_regnum (operands[1])"
3544   [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3545               (clobber (reg:CC FLAGS_REG))])]
3546   "")
3548 (define_expand "zero_extendqisi2"
3549   [(parallel
3550     [(set (match_operand:SI 0 "register_operand" "")
3551        (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3552      (clobber (reg:CC FLAGS_REG))])]
3553   ""
3554   "")
3556 (define_insn "*zero_extendqisi2_and"
3557   [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3558      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3559    (clobber (reg:CC FLAGS_REG))]
3560   "TARGET_ZERO_EXTEND_WITH_AND && !optimize_size"
3561   "#"
3562   [(set_attr "type" "alu1")
3563    (set_attr "mode" "SI")])
3565 (define_insn "*zero_extendqisi2_movzbw_and"
3566   [(set (match_operand:SI 0 "register_operand" "=r,r")
3567      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3568    (clobber (reg:CC FLAGS_REG))]
3569   "!TARGET_ZERO_EXTEND_WITH_AND || optimize_size"
3570   "#"
3571   [(set_attr "type" "imovx,alu1")
3572    (set_attr "mode" "SI")])
3574 (define_insn "*zero_extendqisi2_movzbw"
3575   [(set (match_operand:SI 0 "register_operand" "=r")
3576      (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3577   "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_size) && reload_completed"
3578   "movz{bl|x}\t{%1, %0|%0, %1}"
3579   [(set_attr "type" "imovx")
3580    (set_attr "mode" "SI")])
3582 ;; For the movzbl case strip only the clobber
3583 (define_split
3584   [(set (match_operand:SI 0 "register_operand" "")
3585         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3586    (clobber (reg:CC FLAGS_REG))]
3587   "reload_completed
3588    && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_size)
3589    && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3590   [(set (match_dup 0)
3591         (zero_extend:SI (match_dup 1)))])
3593 ;; When source and destination does not overlap, clear destination
3594 ;; first and then do the movb
3595 (define_split
3596   [(set (match_operand:SI 0 "register_operand" "")
3597         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3598    (clobber (reg:CC FLAGS_REG))]
3599   "reload_completed
3600    && ANY_QI_REG_P (operands[0])
3601    && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3602    && (TARGET_ZERO_EXTEND_WITH_AND && !optimize_size)
3603    && !reg_overlap_mentioned_p (operands[0], operands[1])"
3604   [(set (match_dup 0) (const_int 0))
3605    (set (strict_low_part (match_dup 2)) (match_dup 1))]
3606   "operands[2] = gen_lowpart (QImode, operands[0]);")
3608 ;; Rest is handled by single and.
3609 (define_split
3610   [(set (match_operand:SI 0 "register_operand" "")
3611         (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3612    (clobber (reg:CC FLAGS_REG))]
3613   "reload_completed
3614    && true_regnum (operands[0]) == true_regnum (operands[1])"
3615   [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3616               (clobber (reg:CC FLAGS_REG))])]
3617   "")
3619 ;; %%% Kill me once multi-word ops are sane.
3620 (define_expand "zero_extendsidi2"
3621   [(set (match_operand:DI 0 "register_operand" "")
3622      (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3623   ""
3625   if (!TARGET_64BIT)
3626     {
3627       emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3628       DONE;
3629     }
3632 (define_insn "zero_extendsidi2_32"
3633   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3634         (zero_extend:DI
3635          (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r   ,m  ,r   ,m")))
3636    (clobber (reg:CC FLAGS_REG))]
3637   "!TARGET_64BIT"
3638   "@
3639    #
3640    #
3641    #
3642    movd\t{%1, %0|%0, %1}
3643    movd\t{%1, %0|%0, %1}
3644    movd\t{%1, %0|%0, %1}
3645    movd\t{%1, %0|%0, %1}"
3646   [(set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")
3647    (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")])
3649 (define_insn "zero_extendsidi2_rex64"
3650   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3651      (zero_extend:DI
3652        (match_operand:SI 1 "nonimmediate_operand"  "rm,0,r   ,m  ,r   ,m")))]
3653   "TARGET_64BIT"
3654   "@
3655    mov\t{%k1, %k0|%k0, %k1}
3656    #
3657    movd\t{%1, %0|%0, %1}
3658    movd\t{%1, %0|%0, %1}
3659    movd\t{%1, %0|%0, %1}
3660    movd\t{%1, %0|%0, %1}"
3661   [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3662    (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3664 (define_split
3665   [(set (match_operand:DI 0 "memory_operand" "")
3666      (zero_extend:DI (match_dup 0)))]
3667   "TARGET_64BIT"
3668   [(set (match_dup 4) (const_int 0))]
3669   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3671 (define_split
3672   [(set (match_operand:DI 0 "register_operand" "")
3673         (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3674    (clobber (reg:CC FLAGS_REG))]
3675   "!TARGET_64BIT && reload_completed
3676    && true_regnum (operands[0]) == true_regnum (operands[1])"
3677   [(set (match_dup 4) (const_int 0))]
3678   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3680 (define_split
3681   [(set (match_operand:DI 0 "nonimmediate_operand" "")
3682         (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3683    (clobber (reg:CC FLAGS_REG))]
3684   "!TARGET_64BIT && reload_completed
3685    && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
3686   [(set (match_dup 3) (match_dup 1))
3687    (set (match_dup 4) (const_int 0))]
3688   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3690 (define_insn "zero_extendhidi2"
3691   [(set (match_operand:DI 0 "register_operand" "=r")
3692      (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3693   "TARGET_64BIT"
3694   "movz{wl|x}\t{%1, %k0|%k0, %1}"
3695   [(set_attr "type" "imovx")
3696    (set_attr "mode" "DI")])
3698 (define_insn "zero_extendqidi2"
3699   [(set (match_operand:DI 0 "register_operand" "=r")
3700      (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
3701   "TARGET_64BIT"
3702   "movz{bl|x}\t{%1, %k0|%k0, %1}"
3703   [(set_attr "type" "imovx")
3704    (set_attr "mode" "DI")])
3706 ;; Sign extension instructions
3708 (define_expand "extendsidi2"
3709   [(parallel [(set (match_operand:DI 0 "register_operand" "")
3710                    (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3711               (clobber (reg:CC FLAGS_REG))
3712               (clobber (match_scratch:SI 2 ""))])]
3713   ""
3715   if (TARGET_64BIT)
3716     {
3717       emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
3718       DONE;
3719     }
3722 (define_insn "*extendsidi2_1"
3723   [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3724         (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3725    (clobber (reg:CC FLAGS_REG))
3726    (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3727   "!TARGET_64BIT"
3728   "#")
3730 (define_insn "extendsidi2_rex64"
3731   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3732         (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3733   "TARGET_64BIT"
3734   "@
3735    {cltq|cdqe}
3736    movs{lq|x}\t{%1,%0|%0, %1}"
3737   [(set_attr "type" "imovx")
3738    (set_attr "mode" "DI")
3739    (set_attr "prefix_0f" "0")
3740    (set_attr "modrm" "0,1")])
3742 (define_insn "extendhidi2"
3743   [(set (match_operand:DI 0 "register_operand" "=r")
3744         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3745   "TARGET_64BIT"
3746   "movs{wq|x}\t{%1,%0|%0, %1}"
3747   [(set_attr "type" "imovx")
3748    (set_attr "mode" "DI")])
3750 (define_insn "extendqidi2"
3751   [(set (match_operand:DI 0 "register_operand" "=r")
3752         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3753   "TARGET_64BIT"
3754   "movs{bq|x}\t{%1,%0|%0, %1}"
3755    [(set_attr "type" "imovx")
3756     (set_attr "mode" "DI")])
3758 ;; Extend to memory case when source register does die.
3759 (define_split
3760   [(set (match_operand:DI 0 "memory_operand" "")
3761         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3762    (clobber (reg:CC FLAGS_REG))
3763    (clobber (match_operand:SI 2 "register_operand" ""))]
3764   "(reload_completed
3765     && dead_or_set_p (insn, operands[1])
3766     && !reg_mentioned_p (operands[1], operands[0]))"
3767   [(set (match_dup 3) (match_dup 1))
3768    (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3769               (clobber (reg:CC FLAGS_REG))])
3770    (set (match_dup 4) (match_dup 1))]
3771   "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3773 ;; Extend to memory case when source register does not die.
3774 (define_split
3775   [(set (match_operand:DI 0 "memory_operand" "")
3776         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3777    (clobber (reg:CC FLAGS_REG))
3778    (clobber (match_operand:SI 2 "register_operand" ""))]
3779   "reload_completed"
3780   [(const_int 0)]
3782   split_di (&operands[0], 1, &operands[3], &operands[4]);
3784   emit_move_insn (operands[3], operands[1]);
3786   /* Generate a cltd if possible and doing so it profitable.  */
3787   if ((optimize_size || TARGET_USE_CLTD)
3788       && true_regnum (operands[1]) == AX_REG
3789       && true_regnum (operands[2]) == DX_REG)
3790     {
3791       emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
3792     }
3793   else
3794     {
3795       emit_move_insn (operands[2], operands[1]);
3796       emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
3797     }
3798   emit_move_insn (operands[4], operands[2]);
3799   DONE;
3802 ;; Extend to register case.  Optimize case where source and destination
3803 ;; registers match and cases where we can use cltd.
3804 (define_split
3805   [(set (match_operand:DI 0 "register_operand" "")
3806         (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3807    (clobber (reg:CC FLAGS_REG))
3808    (clobber (match_scratch:SI 2 ""))]
3809   "reload_completed"
3810   [(const_int 0)]
3812   split_di (&operands[0], 1, &operands[3], &operands[4]);
3814   if (true_regnum (operands[3]) != true_regnum (operands[1]))
3815     emit_move_insn (operands[3], operands[1]);
3817   /* Generate a cltd if possible and doing so it profitable.  */
3818   if ((optimize_size || TARGET_USE_CLTD)
3819       && true_regnum (operands[3]) == AX_REG)
3820     {
3821       emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
3822       DONE;
3823     }
3825   if (true_regnum (operands[4]) != true_regnum (operands[1]))
3826     emit_move_insn (operands[4], operands[1]);
3828   emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
3829   DONE;
3832 (define_insn "extendhisi2"
3833   [(set (match_operand:SI 0 "register_operand" "=*a,r")
3834         (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3835   ""
3837   switch (get_attr_prefix_0f (insn))
3838     {
3839     case 0:
3840       return "{cwtl|cwde}";
3841     default:
3842       return "movs{wl|x}\t{%1,%0|%0, %1}";
3843     }
3845   [(set_attr "type" "imovx")
3846    (set_attr "mode" "SI")
3847    (set (attr "prefix_0f")
3848      ;; movsx is short decodable while cwtl is vector decoded.
3849      (if_then_else (and (eq_attr "cpu" "!k6")
3850                         (eq_attr "alternative" "0"))
3851         (const_string "0")
3852         (const_string "1")))
3853    (set (attr "modrm")
3854      (if_then_else (eq_attr "prefix_0f" "0")
3855         (const_string "0")
3856         (const_string "1")))])
3858 (define_insn "*extendhisi2_zext"
3859   [(set (match_operand:DI 0 "register_operand" "=*a,r")
3860         (zero_extend:DI
3861           (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3862   "TARGET_64BIT"
3864   switch (get_attr_prefix_0f (insn))
3865     {
3866     case 0:
3867       return "{cwtl|cwde}";
3868     default:
3869       return "movs{wl|x}\t{%1,%k0|%k0, %1}";
3870     }
3872   [(set_attr "type" "imovx")
3873    (set_attr "mode" "SI")
3874    (set (attr "prefix_0f")
3875      ;; movsx is short decodable while cwtl is vector decoded.
3876      (if_then_else (and (eq_attr "cpu" "!k6")
3877                         (eq_attr "alternative" "0"))
3878         (const_string "0")
3879         (const_string "1")))
3880    (set (attr "modrm")
3881      (if_then_else (eq_attr "prefix_0f" "0")
3882         (const_string "0")
3883         (const_string "1")))])
3885 (define_insn "extendqihi2"
3886   [(set (match_operand:HI 0 "register_operand" "=*a,r")
3887         (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3888   ""
3890   switch (get_attr_prefix_0f (insn))
3891     {
3892     case 0:
3893       return "{cbtw|cbw}";
3894     default:
3895       return "movs{bw|x}\t{%1,%0|%0, %1}";
3896     }
3898   [(set_attr "type" "imovx")
3899    (set_attr "mode" "HI")
3900    (set (attr "prefix_0f")
3901      ;; movsx is short decodable while cwtl is vector decoded.
3902      (if_then_else (and (eq_attr "cpu" "!k6")
3903                         (eq_attr "alternative" "0"))
3904         (const_string "0")
3905         (const_string "1")))
3906    (set (attr "modrm")
3907      (if_then_else (eq_attr "prefix_0f" "0")
3908         (const_string "0")
3909         (const_string "1")))])
3911 (define_insn "extendqisi2"
3912   [(set (match_operand:SI 0 "register_operand" "=r")
3913         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3914   ""
3915   "movs{bl|x}\t{%1,%0|%0, %1}"
3916    [(set_attr "type" "imovx")
3917     (set_attr "mode" "SI")])
3919 (define_insn "*extendqisi2_zext"
3920   [(set (match_operand:DI 0 "register_operand" "=r")
3921         (zero_extend:DI
3922           (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3923   "TARGET_64BIT"
3924   "movs{bl|x}\t{%1,%k0|%k0, %1}"
3925    [(set_attr "type" "imovx")
3926     (set_attr "mode" "SI")])
3928 ;; Conversions between float and double.
3930 ;; These are all no-ops in the model used for the 80387.  So just
3931 ;; emit moves.
3933 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3934 (define_insn "*dummy_extendsfdf2"
3935   [(set (match_operand:DF 0 "push_operand" "=<")
3936         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3937   "0"
3938   "#")
3940 (define_split
3941   [(set (match_operand:DF 0 "push_operand" "")
3942         (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3943   ""
3944   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3945    (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3947 (define_insn "*dummy_extendsfxf2"
3948   [(set (match_operand:XF 0 "push_operand" "=<")
3949         (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3950   "0"
3951   "#")
3953 (define_split
3954   [(set (match_operand:XF 0 "push_operand" "")
3955         (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
3956   ""
3957   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3958    (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3959   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3961 (define_split
3962   [(set (match_operand:XF 0 "push_operand" "")
3963         (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
3964   ""
3965   [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3966    (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3967   "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3969 (define_expand "extendsfdf2"
3970   [(set (match_operand:DF 0 "nonimmediate_operand" "")
3971         (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3972   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3974   /* ??? Needed for compress_float_constant since all fp constants
3975      are LEGITIMATE_CONSTANT_P.  */
3976   if (GET_CODE (operands[1]) == CONST_DOUBLE)
3977     {
3978       if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3979           && standard_80387_constant_p (operands[1]) > 0)
3980         {
3981           operands[1] = simplify_const_unary_operation
3982             (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3983           emit_move_insn_1 (operands[0], operands[1]);
3984           DONE;
3985         }
3986       operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3987     }
3990 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3991    cvtss2sd:
3992       unpcklps xmm2,xmm2   ; packed conversion might crash on signaling NaNs
3993       cvtps2pd xmm2,xmm1
3994    We do the conversion post reload to avoid producing of 128bit spills
3995    that might lead to ICE on 32bit target.  The sequence unlikely combine
3996    anyway.  */
3997 (define_split
3998   [(set (match_operand:DF 0 "register_operand" "")
3999         (float_extend:DF
4000           (match_operand:SF 1 "nonimmediate_operand" "")))]
4001   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4002    && reload_completed && SSE_REG_P (operands[0])"
4003    [(set (match_dup 2)
4004          (float_extend:V2DF
4005            (vec_select:V2SF
4006              (match_dup 3)
4007              (parallel [(const_int 0) (const_int 1)]))))]
4009   operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4010   operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4011   /* Use movss for loading from memory, unpcklps reg, reg for registers.
4012      Try to avoid move when unpacking can be done in source.  */
4013   if (REG_P (operands[1]))
4014     {
4015       /* If it is unsafe to overwrite upper half of source, we need
4016          to move to destination and unpack there.  */
4017       if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4018            || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4019           && true_regnum (operands[0]) != true_regnum (operands[1]))
4020         {
4021           rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4022           emit_move_insn (tmp, operands[1]);
4023         }
4024       else
4025         operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4026       emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4027     }
4028   else
4029     emit_insn (gen_vec_setv4sf_0 (operands[3],
4030                                   CONST0_RTX (V4SFmode), operands[1]));
4033 (define_insn "*extendsfdf2_mixed"
4034   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4035         (float_extend:DF
4036           (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4037   "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4039   switch (which_alternative)
4040     {
4041     case 0:
4042     case 1:
4043       return output_387_reg_move (insn, operands);
4045     case 2:
4046       return "cvtss2sd\t{%1, %0|%0, %1}";
4048     default:
4049       gcc_unreachable ();
4050     }
4052   [(set_attr "type" "fmov,fmov,ssecvt")
4053    (set_attr "mode" "SF,XF,DF")])
4055 (define_insn "*extendsfdf2_sse"
4056   [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4057         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4058   "TARGET_SSE2 && TARGET_SSE_MATH"
4059   "cvtss2sd\t{%1, %0|%0, %1}"
4060   [(set_attr "type" "ssecvt")
4061    (set_attr "mode" "DF")])
4063 (define_insn "*extendsfdf2_i387"
4064   [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4065         (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4066   "TARGET_80387"
4067   "* return output_387_reg_move (insn, operands);"
4068   [(set_attr "type" "fmov")
4069    (set_attr "mode" "SF,XF")])
4071 (define_expand "extend<mode>xf2"
4072   [(set (match_operand:XF 0 "nonimmediate_operand" "")
4073         (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4074   "TARGET_80387"
4076   /* ??? Needed for compress_float_constant since all fp constants
4077      are LEGITIMATE_CONSTANT_P.  */
4078   if (GET_CODE (operands[1]) == CONST_DOUBLE)
4079     {
4080       if (standard_80387_constant_p (operands[1]) > 0)
4081         {
4082           operands[1] = simplify_const_unary_operation
4083             (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4084           emit_move_insn_1 (operands[0], operands[1]);
4085           DONE;
4086         }
4087       operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4088     }
4091 (define_insn "*extend<mode>xf2_i387"
4092   [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4093         (float_extend:XF
4094           (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4095   "TARGET_80387"
4096   "* return output_387_reg_move (insn, operands);"
4097   [(set_attr "type" "fmov")
4098    (set_attr "mode" "<MODE>,XF")])
4100 ;; %%% This seems bad bad news.
4101 ;; This cannot output into an f-reg because there is no way to be sure
4102 ;; of truncating in that case.  Otherwise this is just like a simple move
4103 ;; insn.  So we pretend we can output to a reg in order to get better
4104 ;; register preferencing, but we really use a stack slot.
4106 ;; Conversion from DFmode to SFmode.
4108 (define_expand "truncdfsf2"
4109   [(set (match_operand:SF 0 "nonimmediate_operand" "")
4110         (float_truncate:SF
4111           (match_operand:DF 1 "nonimmediate_operand" "")))]
4112   "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4114   if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4115     ;
4116   else if (flag_unsafe_math_optimizations)
4117     ;
4118   else
4119     {
4120       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4121       rtx temp = assign_386_stack_local (SFmode, slot);
4122       emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4123       DONE;
4124     }
4127 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4128    cvtsd2ss:
4129       unpcklpd xmm2,xmm2   ; packed conversion might crash on signaling NaNs
4130       cvtpd2ps xmm2,xmm1
4131    We do the conversion post reload to avoid producing of 128bit spills
4132    that might lead to ICE on 32bit target.  The sequence unlikely combine
4133    anyway.  */
4134 (define_split
4135   [(set (match_operand:SF 0 "register_operand" "")
4136         (float_truncate:SF
4137           (match_operand:DF 1 "nonimmediate_operand" "")))]
4138   "(TARGET_USE_VECTOR_CONVERTS || TARGET_GENERIC) && !optimize_size
4139    && reload_completed && SSE_REG_P (operands[0])"
4140    [(set (match_dup 2)
4141          (vec_concat:V4SF
4142            (float_truncate:V2SF
4143              (match_dup 4))
4144            (match_dup 3)))]
4146   operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4147   operands[3] = CONST0_RTX (V2SFmode);
4148   operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4149   /* Use movsd for loading from memory, unpcklpd for registers.
4150      Try to avoid move when unpacking can be done in source, or SSE3
4151      movddup is available.  */
4152   if (REG_P (operands[1]))
4153     {
4154       if (!TARGET_SSE3
4155           && true_regnum (operands[0]) != true_regnum (operands[1])
4156           && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4157               || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4158         {
4159           rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4160           emit_move_insn (tmp, operands[1]);
4161           operands[1] = tmp;
4162         }
4163       else if (!TARGET_SSE3)
4164         operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4165       emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4166     }
4167   else
4168     emit_insn (gen_sse2_loadlpd (operands[4],
4169                                  CONST0_RTX (V2DFmode), operands[1]));
4172 (define_expand "truncdfsf2_with_temp"
4173   [(parallel [(set (match_operand:SF 0 "" "")
4174                    (float_truncate:SF (match_operand:DF 1 "" "")))
4175               (clobber (match_operand:SF 2 "" ""))])]
4176   "")
4178 (define_insn "*truncdfsf_fast_mixed"
4179   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm,x")
4180         (float_truncate:SF
4181           (match_operand:DF 1 "nonimmediate_operand" "f  ,xm")))]
4182   "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4184   switch (which_alternative)
4185     {
4186     case 0:
4187       return output_387_reg_move (insn, operands);
4188     case 1:
4189       return "cvtsd2ss\t{%1, %0|%0, %1}";
4190     default:
4191       gcc_unreachable ();
4192     }
4194   [(set_attr "type" "fmov,ssecvt")
4195    (set_attr "mode" "SF")])
4197 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4198 ;; because nothing we do here is unsafe.
4199 (define_insn "*truncdfsf_fast_sse"
4200   [(set (match_operand:SF 0 "nonimmediate_operand"   "=x")
4201         (float_truncate:SF
4202           (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4203   "TARGET_SSE2 && TARGET_SSE_MATH"
4204   "cvtsd2ss\t{%1, %0|%0, %1}"
4205   [(set_attr "type" "ssecvt")
4206    (set_attr "mode" "SF")])
4208 (define_insn "*truncdfsf_fast_i387"
4209   [(set (match_operand:SF 0 "nonimmediate_operand"   "=fm")
4210         (float_truncate:SF
4211           (match_operand:DF 1 "nonimmediate_operand" "f")))]
4212   "TARGET_80387 && flag_unsafe_math_optimizations"
4213   "* return output_387_reg_move (insn, operands);"
4214   [(set_attr "type" "fmov")
4215    (set_attr "mode" "SF")])
4217 (define_insn "*truncdfsf_mixed"
4218   [(set (match_operand:SF 0 "nonimmediate_operand"   "=m,?fx*r,Y2")
4219         (float_truncate:SF
4220           (match_operand:DF 1 "nonimmediate_operand" "f ,f    ,Y2m")))
4221    (clobber (match_operand:SF 2 "memory_operand"     "=X,m    ,X"))]
4222   "TARGET_MIX_SSE_I387"
4224   switch (which_alternative)
4225     {
4226     case 0:
4227       return output_387_reg_move (insn, operands);
4229     case 1:
4230       return "#";
4231     case 2:
4232       return "cvtsd2ss\t{%1, %0|%0, %1}";
4233     default:
4234       gcc_unreachable ();
4235     }
4237   [(set_attr "type" "fmov,multi,ssecvt")
4238    (set_attr "unit" "*,i387,*")
4239    (set_attr "mode" "SF")])
4241 (define_insn "*truncdfsf_i387"
4242   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4243         (float_truncate:SF
4244           (match_operand:DF 1 "nonimmediate_operand" "f,f")))
4245    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4246   "TARGET_80387"
4248   switch (which_alternative)
4249     {
4250     case 0:
4251       return output_387_reg_move (insn, operands);
4253     case 1:
4254       return "#";
4255     default:
4256       gcc_unreachable ();
4257     }
4259   [(set_attr "type" "fmov,multi")
4260    (set_attr "unit" "*,i387")
4261    (set_attr "mode" "SF")])
4263 (define_insn "*truncdfsf2_i387_1"
4264   [(set (match_operand:SF 0 "memory_operand" "=m")
4265         (float_truncate:SF
4266           (match_operand:DF 1 "register_operand" "f")))]
4267   "TARGET_80387
4268    && !(TARGET_SSE2 && TARGET_SSE_MATH)
4269    && !TARGET_MIX_SSE_I387"
4270   "* return output_387_reg_move (insn, operands);"
4271   [(set_attr "type" "fmov")
4272    (set_attr "mode" "SF")])
4274 (define_split
4275   [(set (match_operand:SF 0 "register_operand" "")
4276         (float_truncate:SF
4277          (match_operand:DF 1 "fp_register_operand" "")))
4278    (clobber (match_operand 2 "" ""))]
4279   "reload_completed"
4280   [(set (match_dup 2) (match_dup 1))
4281    (set (match_dup 0) (match_dup 2))]
4283   operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4286 ;; Conversion from XFmode to {SF,DF}mode
4288 (define_expand "truncxf<mode>2"
4289   [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4290                    (float_truncate:MODEF
4291                      (match_operand:XF 1 "register_operand" "")))
4292               (clobber (match_dup 2))])]
4293   "TARGET_80387"
4295   if (flag_unsafe_math_optimizations)
4296     {
4297       rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4298       emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4299       if (reg != operands[0])
4300         emit_move_insn (operands[0], reg);
4301       DONE;
4302     }
4303   else
4304     {
4305       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
4306       operands[2] = assign_386_stack_local (<MODE>mode, slot);
4307     }
4310 (define_insn "*truncxfsf2_mixed"
4311   [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?fx*r")
4312         (float_truncate:SF
4313           (match_operand:XF 1 "register_operand" "f,f")))
4314    (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
4315   "TARGET_80387"
4317   gcc_assert (!which_alternative);
4318   return output_387_reg_move (insn, operands);
4320   [(set_attr "type" "fmov,multi")
4321    (set_attr "unit" "*,i387")
4322    (set_attr "mode" "SF")])
4324 (define_insn "*truncxfdf2_mixed"
4325   [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?fY2*r")
4326         (float_truncate:DF
4327           (match_operand:XF 1 "register_operand" "f,f")))
4328    (clobber (match_operand:DF 2 "memory_operand" "=X,m"))]
4329   "TARGET_80387"
4331   gcc_assert (!which_alternative);
4332   return output_387_reg_move (insn, operands);
4334   [(set_attr "type" "fmov,multi")
4335    (set_attr "unit" "*,i387")
4336    (set_attr "mode" "DF")])
4338 (define_insn "truncxf<mode>2_i387_noop"
4339   [(set (match_operand:MODEF 0 "register_operand" "=f")
4340         (float_truncate:MODEF
4341           (match_operand:XF 1 "register_operand" "f")))]
4342   "TARGET_80387 && flag_unsafe_math_optimizations"
4343   "* return output_387_reg_move (insn, operands);"
4344   [(set_attr "type" "fmov")
4345    (set_attr "mode" "<MODE>")])
4347 (define_insn "*truncxf<mode>2_i387"
4348   [(set (match_operand:MODEF 0 "memory_operand" "=m")
4349         (float_truncate:MODEF
4350           (match_operand:XF 1 "register_operand" "f")))]
4351   "TARGET_80387"
4352   "* return output_387_reg_move (insn, operands);"
4353   [(set_attr "type" "fmov")
4354    (set_attr "mode" "<MODE>")])
4356 (define_split
4357   [(set (match_operand:MODEF 0 "register_operand" "")
4358         (float_truncate:MODEF
4359           (match_operand:XF 1 "register_operand" "")))
4360    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4361   "TARGET_80387 && reload_completed"
4362   [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4363    (set (match_dup 0) (match_dup 2))]
4364   "")
4366 (define_split
4367   [(set (match_operand:MODEF 0 "memory_operand" "")
4368         (float_truncate:MODEF
4369           (match_operand:XF 1 "register_operand" "")))
4370    (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4371   "TARGET_80387"
4372   [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4373   "")
4375 ;; Signed conversion to DImode.
4377 (define_expand "fix_truncxfdi2"
4378   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4379                    (fix:DI (match_operand:XF 1 "register_operand" "")))
4380               (clobber (reg:CC FLAGS_REG))])]
4381   "TARGET_80387"
4383   if (TARGET_FISTTP)
4384    {
4385      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4386      DONE;
4387    }
4390 (define_expand "fix_trunc<mode>di2"
4391   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4392                    (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4393               (clobber (reg:CC FLAGS_REG))])]
4394   "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4396   if (TARGET_FISTTP
4397       && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4398    {
4399      emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4400      DONE;
4401    }
4402   if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4403    {
4404      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4405      emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4406      if (out != operands[0])
4407         emit_move_insn (operands[0], out);
4408      DONE;
4409    }
4412 ;; Signed conversion to SImode.
4414 (define_expand "fix_truncxfsi2"
4415   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4416                    (fix:SI (match_operand:XF 1 "register_operand" "")))
4417               (clobber (reg:CC FLAGS_REG))])]
4418   "TARGET_80387"
4420   if (TARGET_FISTTP)
4421    {
4422      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4423      DONE;
4424    }
4427 (define_expand "fix_trunc<mode>si2"
4428   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4429                    (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4430               (clobber (reg:CC FLAGS_REG))])]
4431   "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4433   if (TARGET_FISTTP
4434       && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4435    {
4436      emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4437      DONE;
4438    }
4439   if (SSE_FLOAT_MODE_P (<MODE>mode))
4440    {
4441      rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4442      emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4443      if (out != operands[0])
4444         emit_move_insn (operands[0], out);
4445      DONE;
4446    }
4449 ;; Signed conversion to HImode.
4451 (define_expand "fix_trunc<mode>hi2"
4452   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4453                    (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4454               (clobber (reg:CC FLAGS_REG))])]
4455   "TARGET_80387
4456    && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4458   if (TARGET_FISTTP)
4459    {
4460      emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4461      DONE;
4462    }
4465 ;; Unsigned conversion to SImode.
4467 (define_expand "fixuns_trunc<mode>si2"
4468   [(parallel
4469     [(set (match_operand:SI 0 "register_operand" "")
4470           (unsigned_fix:SI
4471             (match_operand:MODEF 1 "nonimmediate_operand" "")))
4472      (use (match_dup 2))
4473      (clobber (match_scratch:<ssevecmode> 3 ""))
4474      (clobber (match_scratch:<ssevecmode> 4 ""))])]
4475   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4477   enum machine_mode mode = <MODE>mode;
4478   enum machine_mode vecmode = <ssevecmode>mode;
4479   REAL_VALUE_TYPE TWO31r;
4480   rtx two31;
4482   real_ldexp (&TWO31r, &dconst1, 31);
4483   two31 = const_double_from_real_value (TWO31r, mode);
4484   two31 = ix86_build_const_vector (mode, true, two31);
4485   operands[2] = force_reg (vecmode, two31);
4488 (define_insn_and_split "*fixuns_trunc<mode>_1"
4489   [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4490         (unsigned_fix:SI
4491           (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4492    (use (match_operand:<ssevecmode> 4  "nonimmediate_operand" "m,x"))
4493    (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4494    (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4495   "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH && !optimize_size"
4496   "#"
4497   "&& reload_completed"
4498   [(const_int 0)]
4500   ix86_split_convert_uns_si_sse (operands);
4501   DONE;
4504 ;; Unsigned conversion to HImode.
4505 ;; Without these patterns, we'll try the unsigned SI conversion which
4506 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4508 (define_expand "fixuns_trunc<mode>hi2"
4509   [(set (match_dup 2)
4510         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4511    (set (match_operand:HI 0 "nonimmediate_operand" "")
4512         (subreg:HI (match_dup 2) 0))]
4513   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4514   "operands[2] = gen_reg_rtx (SImode);")
4516 ;; When SSE is available, it is always faster to use it!
4517 (define_insn "fix_trunc<mode>di_sse"
4518   [(set (match_operand:DI 0 "register_operand" "=r,r")
4519         (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4520   "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4521    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4522   "cvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4523   [(set_attr "type" "sseicvt")
4524    (set_attr "mode" "<MODE>")
4525    (set_attr "athlon_decode" "double,vector")
4526    (set_attr "amdfam10_decode" "double,double")])
4528 (define_insn "fix_trunc<mode>si_sse"
4529   [(set (match_operand:SI 0 "register_operand" "=r,r")
4530         (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4531   "SSE_FLOAT_MODE_P (<MODE>mode)
4532    && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4533   "cvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4534   [(set_attr "type" "sseicvt")
4535    (set_attr "mode" "<MODE>")
4536    (set_attr "athlon_decode" "double,vector")
4537    (set_attr "amdfam10_decode" "double,double")])
4539 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4540 (define_peephole2
4541   [(set (match_operand:MODEF 0 "register_operand" "")
4542         (match_operand:MODEF 1 "memory_operand" ""))
4543    (set (match_operand:SSEMODEI24 2 "register_operand" "")
4544         (fix:SSEMODEI24 (match_dup 0)))]
4545   "TARGET_SHORTEN_X87_SSE
4546    && peep2_reg_dead_p (2, operands[0])"
4547   [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4548   "")
4550 ;; Avoid vector decoded forms of the instruction.
4551 (define_peephole2
4552   [(match_scratch:DF 2 "Y2")
4553    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4554         (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4555   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4556   [(set (match_dup 2) (match_dup 1))
4557    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4558   "")
4560 (define_peephole2
4561   [(match_scratch:SF 2 "x")
4562    (set (match_operand:SSEMODEI24 0 "register_operand" "")
4563         (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4564   "TARGET_AVOID_VECTOR_DECODE && !optimize_size"
4565   [(set (match_dup 2) (match_dup 1))
4566    (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4567   "")
4569 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4570   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4571         (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4572   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4573    && TARGET_FISTTP
4574    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4575          && (TARGET_64BIT || <MODE>mode != DImode))
4576         && TARGET_SSE_MATH)
4577    && !(reload_completed || reload_in_progress)"
4578   "#"
4579   "&& 1"
4580   [(const_int 0)]
4582   if (memory_operand (operands[0], VOIDmode))
4583     emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4584   else
4585     {
4586       operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4587       emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4588                                                             operands[1],
4589                                                             operands[2]));
4590     }
4591   DONE;
4593   [(set_attr "type" "fisttp")
4594    (set_attr "mode" "<MODE>")])
4596 (define_insn "fix_trunc<mode>_i387_fisttp"
4597   [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4598         (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4599    (clobber (match_scratch:XF 2 "=&1f"))]
4600   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4601    && TARGET_FISTTP
4602    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4603          && (TARGET_64BIT || <MODE>mode != DImode))
4604         && TARGET_SSE_MATH)"
4605   "* return output_fix_trunc (insn, operands, 1);"
4606   [(set_attr "type" "fisttp")
4607    (set_attr "mode" "<MODE>")])
4609 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4610   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4611         (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4612    (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4613    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4614   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4615    && TARGET_FISTTP
4616    && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4617         && (TARGET_64BIT || <MODE>mode != DImode))
4618         && TARGET_SSE_MATH)"
4619   "#"
4620   [(set_attr "type" "fisttp")
4621    (set_attr "mode" "<MODE>")])
4623 (define_split
4624   [(set (match_operand:X87MODEI 0 "register_operand" "")
4625         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4626    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4627    (clobber (match_scratch 3 ""))]
4628   "reload_completed"
4629   [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4630               (clobber (match_dup 3))])
4631    (set (match_dup 0) (match_dup 2))]
4632   "")
4634 (define_split
4635   [(set (match_operand:X87MODEI 0 "memory_operand" "")
4636         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4637    (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4638    (clobber (match_scratch 3 ""))]
4639   "reload_completed"
4640   [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4641               (clobber (match_dup 3))])]
4642   "")
4644 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4645 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4646 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4647 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4648 ;; function in i386.c.
4649 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4650   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4651         (fix:X87MODEI (match_operand 1 "register_operand" "")))
4652    (clobber (reg:CC FLAGS_REG))]
4653   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4654    && !TARGET_FISTTP
4655    && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4656          && (TARGET_64BIT || <MODE>mode != DImode))
4657    && !(reload_completed || reload_in_progress)"
4658   "#"
4659   "&& 1"
4660   [(const_int 0)]
4662   ix86_optimize_mode_switching[I387_TRUNC] = 1;
4664   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4665   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4666   if (memory_operand (operands[0], VOIDmode))
4667     emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4668                                          operands[2], operands[3]));
4669   else
4670     {
4671       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4672       emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4673                                                      operands[2], operands[3],
4674                                                      operands[4]));
4675     }
4676   DONE;
4678   [(set_attr "type" "fistp")
4679    (set_attr "i387_cw" "trunc")
4680    (set_attr "mode" "<MODE>")])
4682 (define_insn "fix_truncdi_i387"
4683   [(set (match_operand:DI 0 "memory_operand" "=m")
4684         (fix:DI (match_operand 1 "register_operand" "f")))
4685    (use (match_operand:HI 2 "memory_operand" "m"))
4686    (use (match_operand:HI 3 "memory_operand" "m"))
4687    (clobber (match_scratch:XF 4 "=&1f"))]
4688   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4689    && !TARGET_FISTTP
4690    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4691   "* return output_fix_trunc (insn, operands, 0);"
4692   [(set_attr "type" "fistp")
4693    (set_attr "i387_cw" "trunc")
4694    (set_attr "mode" "DI")])
4696 (define_insn "fix_truncdi_i387_with_temp"
4697   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4698         (fix:DI (match_operand 1 "register_operand" "f,f")))
4699    (use (match_operand:HI 2 "memory_operand" "m,m"))
4700    (use (match_operand:HI 3 "memory_operand" "m,m"))
4701    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4702    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4703   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4704    && !TARGET_FISTTP
4705    && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4706   "#"
4707   [(set_attr "type" "fistp")
4708    (set_attr "i387_cw" "trunc")
4709    (set_attr "mode" "DI")])
4711 (define_split
4712   [(set (match_operand:DI 0 "register_operand" "")
4713         (fix:DI (match_operand 1 "register_operand" "")))
4714    (use (match_operand:HI 2 "memory_operand" ""))
4715    (use (match_operand:HI 3 "memory_operand" ""))
4716    (clobber (match_operand:DI 4 "memory_operand" ""))
4717    (clobber (match_scratch 5 ""))]
4718   "reload_completed"
4719   [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4720               (use (match_dup 2))
4721               (use (match_dup 3))
4722               (clobber (match_dup 5))])
4723    (set (match_dup 0) (match_dup 4))]
4724   "")
4726 (define_split
4727   [(set (match_operand:DI 0 "memory_operand" "")
4728         (fix:DI (match_operand 1 "register_operand" "")))
4729    (use (match_operand:HI 2 "memory_operand" ""))
4730    (use (match_operand:HI 3 "memory_operand" ""))
4731    (clobber (match_operand:DI 4 "memory_operand" ""))
4732    (clobber (match_scratch 5 ""))]
4733   "reload_completed"
4734   [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4735               (use (match_dup 2))
4736               (use (match_dup 3))
4737               (clobber (match_dup 5))])]
4738   "")
4740 (define_insn "fix_trunc<mode>_i387"
4741   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4742         (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4743    (use (match_operand:HI 2 "memory_operand" "m"))
4744    (use (match_operand:HI 3 "memory_operand" "m"))]
4745   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4746    && !TARGET_FISTTP
4747    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4748   "* return output_fix_trunc (insn, operands, 0);"
4749   [(set_attr "type" "fistp")
4750    (set_attr "i387_cw" "trunc")
4751    (set_attr "mode" "<MODE>")])
4753 (define_insn "fix_trunc<mode>_i387_with_temp"
4754   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4755         (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4756    (use (match_operand:HI 2 "memory_operand" "m,m"))
4757    (use (match_operand:HI 3 "memory_operand" "m,m"))
4758    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4759   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4760    && !TARGET_FISTTP
4761    && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4762   "#"
4763   [(set_attr "type" "fistp")
4764    (set_attr "i387_cw" "trunc")
4765    (set_attr "mode" "<MODE>")])
4767 (define_split
4768   [(set (match_operand:X87MODEI12 0 "register_operand" "")
4769         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4770    (use (match_operand:HI 2 "memory_operand" ""))
4771    (use (match_operand:HI 3 "memory_operand" ""))
4772    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4773   "reload_completed"
4774   [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4775               (use (match_dup 2))
4776               (use (match_dup 3))])
4777    (set (match_dup 0) (match_dup 4))]
4778   "")
4780 (define_split
4781   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4782         (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4783    (use (match_operand:HI 2 "memory_operand" ""))
4784    (use (match_operand:HI 3 "memory_operand" ""))
4785    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4786   "reload_completed"
4787   [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4788               (use (match_dup 2))
4789               (use (match_dup 3))])]
4790   "")
4792 (define_insn "x86_fnstcw_1"
4793   [(set (match_operand:HI 0 "memory_operand" "=m")
4794         (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4795   "TARGET_80387"
4796   "fnstcw\t%0"
4797   [(set_attr "length" "2")
4798    (set_attr "mode" "HI")
4799    (set_attr "unit" "i387")])
4801 (define_insn "x86_fldcw_1"
4802   [(set (reg:HI FPCR_REG)
4803         (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4804   "TARGET_80387"
4805   "fldcw\t%0"
4806   [(set_attr "length" "2")
4807    (set_attr "mode" "HI")
4808    (set_attr "unit" "i387")
4809    (set_attr "athlon_decode" "vector")
4810    (set_attr "amdfam10_decode" "vector")])
4812 ;; Conversion between fixed point and floating point.
4814 ;; Even though we only accept memory inputs, the backend _really_
4815 ;; wants to be able to do this between registers.
4817 (define_expand "floathi<mode>2"
4818   [(set (match_operand:X87MODEF 0 "register_operand" "")
4819         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4820   "TARGET_80387
4821    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4822        || TARGET_MIX_SSE_I387)"
4823   "")
4825 ;; Pre-reload splitter to add memory clobber to the pattern.
4826 (define_insn_and_split "*floathi<mode>2_1"
4827   [(set (match_operand:X87MODEF 0 "register_operand" "")
4828         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4829   "TARGET_80387
4830    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4831        || TARGET_MIX_SSE_I387)
4832    && !(reload_completed || reload_in_progress)"
4833   "#"
4834   "&& 1"
4835   [(parallel [(set (match_dup 0)
4836               (float:X87MODEF (match_dup 1)))
4837    (clobber (match_dup 2))])]
4838   "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4840 (define_insn "*floathi<mode>2_i387_with_temp"
4841   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4842         (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4843   (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4844   "TARGET_80387
4845    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4846        || TARGET_MIX_SSE_I387)"
4847   "#"
4848   [(set_attr "type" "fmov,multi")
4849    (set_attr "mode" "<MODE>")
4850    (set_attr "unit" "*,i387")
4851    (set_attr "fp_int_src" "true")])
4853 (define_insn "*floathi<mode>2_i387"
4854   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4855         (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4856   "TARGET_80387
4857    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4858        || TARGET_MIX_SSE_I387)"
4859   "fild%z1\t%1"
4860   [(set_attr "type" "fmov")
4861    (set_attr "mode" "<MODE>")
4862    (set_attr "fp_int_src" "true")])
4864 (define_split
4865   [(set (match_operand:X87MODEF 0 "register_operand" "")
4866         (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4867    (clobber (match_operand:HI 2 "memory_operand" ""))]
4868   "TARGET_80387
4869    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4870        || TARGET_MIX_SSE_I387)
4871    && reload_completed"
4872   [(set (match_dup 2) (match_dup 1))
4873    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4874   "")
4876 (define_split
4877   [(set (match_operand:X87MODEF 0 "register_operand" "")
4878         (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4879    (clobber (match_operand:HI 2 "memory_operand" ""))]
4880    "TARGET_80387
4881     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4882         || TARGET_MIX_SSE_I387)
4883     && reload_completed"
4884   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
4885   "")
4887 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4888   [(set (match_operand:X87MODEF 0 "register_operand" "")
4889         (float:X87MODEF
4890           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4891   "TARGET_80387
4892    || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4893        && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4894   "")
4896 ;; Pre-reload splitter to add memory clobber to the pattern.
4897 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4898   [(set (match_operand:X87MODEF 0 "register_operand" "")
4899         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4900   "((TARGET_80387
4901      && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4902            && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4903          || TARGET_MIX_SSE_I387))
4904     || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4905         && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4906         && ((<SSEMODEI24:MODE>mode == SImode
4907              && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS && !optimize_size
4908              && flag_trapping_math)
4909             || !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size))))
4910    && !(reload_completed || reload_in_progress)"
4911   "#"
4912   "&& 1"
4913   [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4914               (clobber (match_dup 2))])]
4916   operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4918   /* Avoid store forwarding (partial memory) stall penalty
4919      by passing DImode value through XMM registers.  */
4920   if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT 
4921       && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES 
4922       && !optimize_size)
4923     {
4924       emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4925                                                             operands[1],
4926                                                             operands[2]));
4927       DONE;
4928     }
4931 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4932   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4933         (float:MODEF
4934           (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4935    (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4936   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4937    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4938   "#"
4939   [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4940    (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4941    (set_attr "unit" "*,i387,*,*,*")
4942    (set_attr "athlon_decode" "*,*,double,direct,double")
4943    (set_attr "amdfam10_decode" "*,*,vector,double,double")
4944    (set_attr "fp_int_src" "true")])
4946 (define_insn "*floatsi<mode>2_vector_mixed"
4947   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4948         (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4949   "TARGET_SSE2 && TARGET_MIX_SSE_I387
4950    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
4951   "@
4952    fild%z1\t%1
4953    #"
4954   [(set_attr "type" "fmov,sseicvt")
4955    (set_attr "mode" "<MODE>,<ssevecmode>")
4956    (set_attr "unit" "i387,*")
4957    (set_attr "athlon_decode" "*,direct")
4958    (set_attr "amdfam10_decode" "*,double")
4959    (set_attr "fp_int_src" "true")])
4961 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
4962   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4963         (float:MODEF
4964           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
4965   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
4966   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4967    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4968   "#"
4969   [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4970    (set_attr "mode" "<MODEF:MODE>")
4971    (set_attr "unit" "*,i387,*,*")
4972    (set_attr "athlon_decode" "*,*,double,direct")
4973    (set_attr "amdfam10_decode" "*,*,vector,double")
4974    (set_attr "fp_int_src" "true")])
4976 (define_split
4977   [(set (match_operand:MODEF 0 "register_operand" "")
4978         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4979    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4980   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4981    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4982    && TARGET_INTER_UNIT_CONVERSIONS
4983    && reload_completed
4984    && (SSE_REG_P (operands[0])
4985        || (GET_CODE (operands[0]) == SUBREG
4986            && SSE_REG_P (operands[0])))"
4987   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
4988   "")
4990 (define_split
4991   [(set (match_operand:MODEF 0 "register_operand" "")
4992         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
4993    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
4994   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4995    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4996    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
4997    && reload_completed
4998    && (SSE_REG_P (operands[0])
4999        || (GET_CODE (operands[0]) == SUBREG
5000            && SSE_REG_P (operands[0])))"
5001   [(set (match_dup 2) (match_dup 1))
5002    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5003   "")
5005 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5006   [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5007         (float:MODEF
5008           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5009   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5010    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5011    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5012   "@
5013    fild%z1\t%1
5014    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}
5015    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5016   [(set_attr "type" "fmov,sseicvt,sseicvt")
5017    (set_attr "mode" "<MODEF:MODE>")
5018    (set_attr "unit" "i387,*,*")
5019    (set_attr "athlon_decode" "*,double,direct")
5020    (set_attr "amdfam10_decode" "*,vector,double")
5021    (set_attr "fp_int_src" "true")])
5023 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5024   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5025         (float:MODEF
5026           (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5027   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5028    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5029    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5030   "@
5031    fild%z1\t%1
5032    cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5033   [(set_attr "type" "fmov,sseicvt")
5034    (set_attr "mode" "<MODEF:MODE>")
5035    (set_attr "athlon_decode" "*,direct")
5036    (set_attr "amdfam10_decode" "*,double")
5037    (set_attr "fp_int_src" "true")])
5039 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5040   [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5041         (float:MODEF
5042           (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5043    (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5044   "TARGET_SSE2 && TARGET_SSE_MATH
5045    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5046   "#"
5047   [(set_attr "type" "sseicvt")
5048    (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5049    (set_attr "athlon_decode" "double,direct,double")
5050    (set_attr "amdfam10_decode" "vector,double,double")
5051    (set_attr "fp_int_src" "true")])
5053 (define_insn "*floatsi<mode>2_vector_sse"
5054   [(set (match_operand:MODEF 0 "register_operand" "=x")
5055         (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5056   "TARGET_SSE2 && TARGET_SSE_MATH
5057    && TARGET_USE_VECTOR_CONVERTS && !optimize_size"
5058   "#"
5059   [(set_attr "type" "sseicvt")
5060    (set_attr "mode" "<MODE>")
5061    (set_attr "athlon_decode" "direct")
5062    (set_attr "amdfam10_decode" "double")
5063    (set_attr "fp_int_src" "true")])
5065 (define_split
5066   [(set (match_operand:MODEF 0 "register_operand" "")
5067         (float:MODEF (match_operand:SI 1 "register_operand" "")))
5068    (clobber (match_operand:SI 2 "memory_operand" ""))]
5069   "TARGET_SSE2 && TARGET_SSE_MATH
5070    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5071    && reload_completed
5072    && (SSE_REG_P (operands[0])
5073        || (GET_CODE (operands[0]) == SUBREG
5074            && SSE_REG_P (operands[0])))"
5075   [(const_int 0)]
5077   rtx op1 = operands[1];
5079   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5080                                      <MODE>mode, 0);
5081   if (GET_CODE (op1) == SUBREG)
5082     op1 = SUBREG_REG (op1);
5084   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5085     {
5086       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5087       emit_insn (gen_sse2_loadld (operands[4],
5088                                   CONST0_RTX (V4SImode), operands[1]));
5089     }
5090   /* We can ignore possible trapping value in the
5091      high part of SSE register for non-trapping math. */
5092   else if (SSE_REG_P (op1) && !flag_trapping_math)
5093     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5094   else
5095     {
5096       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5097       emit_move_insn (operands[2], operands[1]);
5098       emit_insn (gen_sse2_loadld (operands[4],
5099                                   CONST0_RTX (V4SImode), operands[2]));
5100     }
5101   emit_insn
5102     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5103   DONE;
5106 (define_split
5107   [(set (match_operand:MODEF 0 "register_operand" "")
5108         (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5109    (clobber (match_operand:SI 2 "memory_operand" ""))]
5110   "TARGET_SSE2 && TARGET_SSE_MATH
5111    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5112    && reload_completed
5113    && (SSE_REG_P (operands[0])
5114        || (GET_CODE (operands[0]) == SUBREG
5115            && SSE_REG_P (operands[0])))"
5116   [(const_int 0)]
5118   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5119                                      <MODE>mode, 0);
5120   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5122   emit_insn (gen_sse2_loadld (operands[4],
5123                               CONST0_RTX (V4SImode), operands[1]));
5124   emit_insn
5125     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5126   DONE;
5129 (define_split
5130   [(set (match_operand:MODEF 0 "register_operand" "")
5131         (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5132   "TARGET_SSE2 && TARGET_SSE_MATH
5133    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5134    && reload_completed
5135    && (SSE_REG_P (operands[0])
5136        || (GET_CODE (operands[0]) == SUBREG
5137            && SSE_REG_P (operands[0])))"
5138   [(const_int 0)]
5140   rtx op1 = operands[1];
5142   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5143                                      <MODE>mode, 0);
5144   if (GET_CODE (op1) == SUBREG)
5145     op1 = SUBREG_REG (op1);
5147   if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5148     {
5149       operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5150       emit_insn (gen_sse2_loadld (operands[4],
5151                                   CONST0_RTX (V4SImode), operands[1]));
5152     }
5153   /* We can ignore possible trapping value in the
5154      high part of SSE register for non-trapping math. */
5155   else if (SSE_REG_P (op1) && !flag_trapping_math)
5156     operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5157   else
5158     gcc_unreachable ();
5161 (define_split
5162   [(set (match_operand:MODEF 0 "register_operand" "")
5163         (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5164   "TARGET_SSE2 && TARGET_SSE_MATH
5165    && TARGET_USE_VECTOR_CONVERTS && !optimize_size
5166    && reload_completed
5167    && (SSE_REG_P (operands[0])
5168        || (GET_CODE (operands[0]) == SUBREG
5169            && SSE_REG_P (operands[0])))"
5170   [(const_int 0)]
5172   operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5173                                      <MODE>mode, 0);
5174   operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5176   emit_insn (gen_sse2_loadld (operands[4],
5177                               CONST0_RTX (V4SImode), operands[1]));
5178   emit_insn
5179     (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5180   DONE;
5183 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5184   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5185         (float:MODEF
5186           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5187   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5188   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5189    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5190   "#"
5191   [(set_attr "type" "sseicvt")
5192    (set_attr "mode" "<MODEF:MODE>")
5193    (set_attr "athlon_decode" "double,direct")
5194    (set_attr "amdfam10_decode" "vector,double")
5195    (set_attr "fp_int_src" "true")])
5197 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5198   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5199         (float:MODEF
5200           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5201   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5202    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5203    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5204   "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5205   [(set_attr "type" "sseicvt")
5206    (set_attr "mode" "<MODEF:MODE>")
5207    (set_attr "athlon_decode" "double,direct")
5208    (set_attr "amdfam10_decode" "vector,double")
5209    (set_attr "fp_int_src" "true")])
5211 (define_split
5212   [(set (match_operand:MODEF 0 "register_operand" "")
5213         (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5214    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5215   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5216    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5217    && (TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5218    && reload_completed
5219    && (SSE_REG_P (operands[0])
5220        || (GET_CODE (operands[0]) == SUBREG
5221            && SSE_REG_P (operands[0])))"
5222   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5223   "")
5225 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5226   [(set (match_operand:MODEF 0 "register_operand" "=x")
5227         (float:MODEF
5228           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5229   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5230    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5231    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)"
5232   "cvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %0|%0, %1}"
5233   [(set_attr "type" "sseicvt")
5234    (set_attr "mode" "<MODEF:MODE>")
5235    (set_attr "athlon_decode" "direct")
5236    (set_attr "amdfam10_decode" "double")
5237    (set_attr "fp_int_src" "true")])
5239 (define_split
5240   [(set (match_operand:MODEF 0 "register_operand" "")
5241         (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5242    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5243   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5244    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5245    && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_size)
5246    && reload_completed
5247    && (SSE_REG_P (operands[0])
5248        || (GET_CODE (operands[0]) == SUBREG
5249            && SSE_REG_P (operands[0])))"
5250   [(set (match_dup 2) (match_dup 1))
5251    (set (match_dup 0) (float:MODEF (match_dup 2)))]
5252   "")
5254 (define_split
5255   [(set (match_operand:MODEF 0 "register_operand" "")
5256         (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5257    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5258   "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5259    && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5260    && reload_completed
5261    && (SSE_REG_P (operands[0])
5262        || (GET_CODE (operands[0]) == SUBREG
5263            && SSE_REG_P (operands[0])))"
5264   [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5265   "")
5267 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5268   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5269         (float:X87MODEF
5270           (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5271   (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5272   "TARGET_80387"
5273   "@
5274    fild%z1\t%1
5275    #"
5276   [(set_attr "type" "fmov,multi")
5277    (set_attr "mode" "<X87MODEF:MODE>")
5278    (set_attr "unit" "*,i387")
5279    (set_attr "fp_int_src" "true")])
5281 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5282   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5283         (float:X87MODEF
5284           (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5285   "TARGET_80387"
5286   "fild%z1\t%1"
5287   [(set_attr "type" "fmov")
5288    (set_attr "mode" "<X87MODEF:MODE>")
5289    (set_attr "fp_int_src" "true")])
5291 (define_split
5292   [(set (match_operand:X87MODEF 0 "register_operand" "")
5293         (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5294    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5295   "TARGET_80387
5296    && reload_completed
5297    && FP_REG_P (operands[0])"
5298   [(set (match_dup 2) (match_dup 1))
5299    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5300   "")
5302 (define_split
5303   [(set (match_operand:X87MODEF 0 "register_operand" "")
5304         (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5305    (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5306   "TARGET_80387
5307    && reload_completed
5308    && FP_REG_P (operands[0])"
5309   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5310   "")
5312 ;; Avoid store forwarding (partial memory) stall penalty
5313 ;; by passing DImode value through XMM registers.  */
5315 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5316   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5317         (float:X87MODEF
5318           (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5319    (clobber (match_scratch:V4SI 3 "=X,x"))
5320    (clobber (match_scratch:V4SI 4 "=X,x"))
5321    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5322   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5323    && !TARGET_64BIT && !optimize_size"
5324   "#"
5325   [(set_attr "type" "multi")
5326    (set_attr "mode" "<X87MODEF:MODE>")
5327    (set_attr "unit" "i387")
5328    (set_attr "fp_int_src" "true")])
5330 (define_split
5331   [(set (match_operand:X87MODEF 0 "register_operand" "")
5332         (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5333    (clobber (match_scratch:V4SI 3 ""))
5334    (clobber (match_scratch:V4SI 4 ""))
5335    (clobber (match_operand:DI 2 "memory_operand" ""))]
5336   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5337    && !TARGET_64BIT && !optimize_size
5338    && reload_completed
5339    && FP_REG_P (operands[0])"
5340   [(set (match_dup 2) (match_dup 3))
5341    (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5343   /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5344      Assemble the 64-bit DImode value in an xmm register.  */
5345   emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5346                               gen_rtx_SUBREG (SImode, operands[1], 0)));
5347   emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5348                               gen_rtx_SUBREG (SImode, operands[1], 4)));
5349   emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5351   operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5354 (define_split
5355   [(set (match_operand:X87MODEF 0 "register_operand" "")
5356         (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5357    (clobber (match_scratch:V4SI 3 ""))
5358    (clobber (match_scratch:V4SI 4 ""))
5359    (clobber (match_operand:DI 2 "memory_operand" ""))]
5360   "TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5361    && !TARGET_64BIT && !optimize_size
5362    && reload_completed
5363    && FP_REG_P (operands[0])"
5364   [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5365   "")
5367 ;; Avoid store forwarding (partial memory) stall penalty by extending
5368 ;; SImode value to DImode through XMM register instead of pushing two
5369 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5370 ;; targets benefit from this optimization. Also note that fild
5371 ;; loads from memory only.
5373 (define_insn "*floatunssi<mode>2_1"
5374   [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5375         (unsigned_float:X87MODEF
5376           (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5377    (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5378    (clobber (match_scratch:SI 3 "=X,x"))]
5379   "!TARGET_64BIT
5380    && TARGET_80387 && TARGET_SSE"
5381   "#"
5382   [(set_attr "type" "multi")
5383    (set_attr "mode" "<MODE>")])
5385 (define_split
5386   [(set (match_operand:X87MODEF 0 "register_operand" "")
5387         (unsigned_float:X87MODEF
5388           (match_operand:SI 1 "register_operand" "")))
5389    (clobber (match_operand:DI 2 "memory_operand" ""))
5390    (clobber (match_scratch:SI 3 ""))]
5391   "!TARGET_64BIT
5392    && TARGET_80387 && TARGET_SSE
5393    && reload_completed"
5394   [(set (match_dup 2) (match_dup 1))
5395    (set (match_dup 0)
5396         (float:X87MODEF (match_dup 2)))]
5397   "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5399 (define_split
5400   [(set (match_operand:X87MODEF 0 "register_operand" "")
5401         (unsigned_float:X87MODEF
5402           (match_operand:SI 1 "memory_operand" "")))
5403    (clobber (match_operand:DI 2 "memory_operand" ""))
5404    (clobber (match_scratch:SI 3 ""))]
5405   "!TARGET_64BIT
5406    && TARGET_80387 && TARGET_SSE
5407    && reload_completed"
5408   [(set (match_dup 2) (match_dup 3))
5409    (set (match_dup 0)
5410         (float:X87MODEF (match_dup 2)))]
5412   emit_move_insn (operands[3], operands[1]);
5413   operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5416 (define_expand "floatunssi<mode>2"
5417   [(parallel
5418      [(set (match_operand:X87MODEF 0 "register_operand" "")
5419            (unsigned_float:X87MODEF
5420              (match_operand:SI 1 "nonimmediate_operand" "")))
5421       (clobber (match_dup 2))
5422       (clobber (match_scratch:SI 3 ""))])]
5423   "!TARGET_64BIT
5424    && ((TARGET_80387 && TARGET_SSE)
5425        || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5427   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5428     {
5429       ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5430       DONE;
5431     }
5432   else
5433     {
5434       int slot = virtuals_instantiated ? SLOT_TEMP : SLOT_VIRTUAL;
5435       operands[2] = assign_386_stack_local (DImode, slot);
5436     }
5439 (define_expand "floatunsdisf2"
5440   [(use (match_operand:SF 0 "register_operand" ""))
5441    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5442   "TARGET_64BIT && TARGET_SSE_MATH"
5443   "x86_emit_floatuns (operands); DONE;")
5445 (define_expand "floatunsdidf2"
5446   [(use (match_operand:DF 0 "register_operand" ""))
5447    (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5448   "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5449    && TARGET_SSE2 && TARGET_SSE_MATH"
5451   if (TARGET_64BIT)
5452     x86_emit_floatuns (operands);
5453   else
5454     ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5455   DONE;
5458 ;; Add instructions
5460 ;; %%% splits for addditi3
5462 (define_expand "addti3"
5463   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5464         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5465                  (match_operand:TI 2 "x86_64_general_operand" "")))]
5466   "TARGET_64BIT"
5467   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5469 (define_insn "*addti3_1"
5470   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5471         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5472                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5473    (clobber (reg:CC FLAGS_REG))]
5474   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5475   "#")
5477 (define_split
5478   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5479         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5480                  (match_operand:TI 2 "x86_64_general_operand" "")))
5481    (clobber (reg:CC FLAGS_REG))]
5482   "TARGET_64BIT && reload_completed"
5483   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5484                                           UNSPEC_ADD_CARRY))
5485               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5486    (parallel [(set (match_dup 3)
5487                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5488                                      (match_dup 4))
5489                             (match_dup 5)))
5490               (clobber (reg:CC FLAGS_REG))])]
5491   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5493 ;; %%% splits for addsidi3
5494 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5495 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5496 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5498 (define_expand "adddi3"
5499   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5500         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5501                  (match_operand:DI 2 "x86_64_general_operand" "")))]
5502   ""
5503   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5505 (define_insn "*adddi3_1"
5506   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5507         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5508                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5509    (clobber (reg:CC FLAGS_REG))]
5510   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5511   "#")
5513 (define_split
5514   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5515         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5516                  (match_operand:DI 2 "general_operand" "")))
5517    (clobber (reg:CC FLAGS_REG))]
5518   "!TARGET_64BIT && reload_completed"
5519   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5520                                           UNSPEC_ADD_CARRY))
5521               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5522    (parallel [(set (match_dup 3)
5523                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5524                                      (match_dup 4))
5525                             (match_dup 5)))
5526               (clobber (reg:CC FLAGS_REG))])]
5527   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5529 (define_insn "adddi3_carry_rex64"
5530   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5531           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5532                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5533                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5534    (clobber (reg:CC FLAGS_REG))]
5535   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5536   "adc{q}\t{%2, %0|%0, %2}"
5537   [(set_attr "type" "alu")
5538    (set_attr "pent_pair" "pu")
5539    (set_attr "mode" "DI")])
5541 (define_insn "*adddi3_cc_rex64"
5542   [(set (reg:CC FLAGS_REG)
5543         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5544                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5545                    UNSPEC_ADD_CARRY))
5546    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5547         (plus:DI (match_dup 1) (match_dup 2)))]
5548   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5549   "add{q}\t{%2, %0|%0, %2}"
5550   [(set_attr "type" "alu")
5551    (set_attr "mode" "DI")])
5553 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5554   [(set (reg:CCC FLAGS_REG)
5555         (compare:CCC
5556             (plusminus:SWI
5557                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5558                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5559             (match_dup 1)))
5560    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5561         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5562   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5563   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5564   [(set_attr "type" "alu")
5565    (set_attr "mode" "<MODE>")])
5567 (define_insn "*add<mode>3_cconly_overflow"
5568   [(set (reg:CCC FLAGS_REG)
5569         (compare:CCC
5570                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5571                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5572                 (match_dup 1)))
5573    (clobber (match_scratch:SWI 0 "=<r>"))]
5574   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5575   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5576   [(set_attr "type" "alu")
5577    (set_attr "mode" "<MODE>")])
5579 (define_insn "*sub<mode>3_cconly_overflow"
5580   [(set (reg:CCC FLAGS_REG)
5581         (compare:CCC
5582              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5583                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5584              (match_dup 0)))]
5585   ""
5586   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5587   [(set_attr "type" "icmp")
5588    (set_attr "mode" "<MODE>")])
5590 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5591   [(set (reg:CCC FLAGS_REG)
5592         (compare:CCC
5593             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5594                           (match_operand:SI 2 "general_operand" "g"))
5595             (match_dup 1)))
5596    (set (match_operand:DI 0 "register_operand" "=r")
5597         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5598   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5599   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5600   [(set_attr "type" "alu")
5601    (set_attr "mode" "SI")])
5603 (define_insn "addqi3_carry"
5604   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5605           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5606                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5607                    (match_operand:QI 2 "general_operand" "qn,qm")))
5608    (clobber (reg:CC FLAGS_REG))]
5609   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5610   "adc{b}\t{%2, %0|%0, %2}"
5611   [(set_attr "type" "alu")
5612    (set_attr "pent_pair" "pu")
5613    (set_attr "mode" "QI")])
5615 (define_insn "addhi3_carry"
5616   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5617           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5618                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5619                    (match_operand:HI 2 "general_operand" "rn,rm")))
5620    (clobber (reg:CC FLAGS_REG))]
5621   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5622   "adc{w}\t{%2, %0|%0, %2}"
5623   [(set_attr "type" "alu")
5624    (set_attr "pent_pair" "pu")
5625    (set_attr "mode" "HI")])
5627 (define_insn "addsi3_carry"
5628   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5629           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5630                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5631                    (match_operand:SI 2 "general_operand" "ri,rm")))
5632    (clobber (reg:CC FLAGS_REG))]
5633   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5634   "adc{l}\t{%2, %0|%0, %2}"
5635   [(set_attr "type" "alu")
5636    (set_attr "pent_pair" "pu")
5637    (set_attr "mode" "SI")])
5639 (define_insn "*addsi3_carry_zext"
5640   [(set (match_operand:DI 0 "register_operand" "=r")
5641           (zero_extend:DI
5642             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5643                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5644                      (match_operand:SI 2 "general_operand" "g"))))
5645    (clobber (reg:CC FLAGS_REG))]
5646   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5647   "adc{l}\t{%2, %k0|%k0, %2}"
5648   [(set_attr "type" "alu")
5649    (set_attr "pent_pair" "pu")
5650    (set_attr "mode" "SI")])
5652 (define_insn "*addsi3_cc"
5653   [(set (reg:CC FLAGS_REG)
5654         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5655                     (match_operand:SI 2 "general_operand" "ri,rm")]
5656                    UNSPEC_ADD_CARRY))
5657    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5658         (plus:SI (match_dup 1) (match_dup 2)))]
5659   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5660   "add{l}\t{%2, %0|%0, %2}"
5661   [(set_attr "type" "alu")
5662    (set_attr "mode" "SI")])
5664 (define_insn "addqi3_cc"
5665   [(set (reg:CC FLAGS_REG)
5666         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5667                     (match_operand:QI 2 "general_operand" "qn,qm")]
5668                    UNSPEC_ADD_CARRY))
5669    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5670         (plus:QI (match_dup 1) (match_dup 2)))]
5671   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5672   "add{b}\t{%2, %0|%0, %2}"
5673   [(set_attr "type" "alu")
5674    (set_attr "mode" "QI")])
5676 (define_expand "addsi3"
5677   [(set (match_operand:SI 0 "nonimmediate_operand" "")
5678         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5679                  (match_operand:SI 2 "general_operand" "")))]
5680   ""
5681   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5683 (define_insn "*lea_1"
5684   [(set (match_operand:SI 0 "register_operand" "=r")
5685         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5686   "!TARGET_64BIT"
5687   "lea{l}\t{%a1, %0|%0, %a1}"
5688   [(set_attr "type" "lea")
5689    (set_attr "mode" "SI")])
5691 (define_insn "*lea_1_rex64"
5692   [(set (match_operand:SI 0 "register_operand" "=r")
5693         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5694   "TARGET_64BIT"
5695   "lea{l}\t{%a1, %0|%0, %a1}"
5696   [(set_attr "type" "lea")
5697    (set_attr "mode" "SI")])
5699 (define_insn "*lea_1_zext"
5700   [(set (match_operand:DI 0 "register_operand" "=r")
5701         (zero_extend:DI
5702          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5703   "TARGET_64BIT"
5704   "lea{l}\t{%a1, %k0|%k0, %a1}"
5705   [(set_attr "type" "lea")
5706    (set_attr "mode" "SI")])
5708 (define_insn "*lea_2_rex64"
5709   [(set (match_operand:DI 0 "register_operand" "=r")
5710         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5711   "TARGET_64BIT"
5712   "lea{q}\t{%a1, %0|%0, %a1}"
5713   [(set_attr "type" "lea")
5714    (set_attr "mode" "DI")])
5716 ;; The lea patterns for non-Pmodes needs to be matched by several
5717 ;; insns converted to real lea by splitters.
5719 (define_insn_and_split "*lea_general_1"
5720   [(set (match_operand 0 "register_operand" "=r")
5721         (plus (plus (match_operand 1 "index_register_operand" "l")
5722                     (match_operand 2 "register_operand" "r"))
5723               (match_operand 3 "immediate_operand" "i")))]
5724   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5725     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5726    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5727    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5728    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5729    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5730        || GET_MODE (operands[3]) == VOIDmode)"
5731   "#"
5732   "&& reload_completed"
5733   [(const_int 0)]
5735   rtx pat;
5736   operands[0] = gen_lowpart (SImode, operands[0]);
5737   operands[1] = gen_lowpart (Pmode, operands[1]);
5738   operands[2] = gen_lowpart (Pmode, operands[2]);
5739   operands[3] = gen_lowpart (Pmode, operands[3]);
5740   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5741                       operands[3]);
5742   if (Pmode != SImode)
5743     pat = gen_rtx_SUBREG (SImode, pat, 0);
5744   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5745   DONE;
5747   [(set_attr "type" "lea")
5748    (set_attr "mode" "SI")])
5750 (define_insn_and_split "*lea_general_1_zext"
5751   [(set (match_operand:DI 0 "register_operand" "=r")
5752         (zero_extend:DI
5753           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5754                             (match_operand:SI 2 "register_operand" "r"))
5755                    (match_operand:SI 3 "immediate_operand" "i"))))]
5756   "TARGET_64BIT"
5757   "#"
5758   "&& reload_completed"
5759   [(set (match_dup 0)
5760         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5761                                                      (match_dup 2))
5762                                             (match_dup 3)) 0)))]
5764   operands[1] = gen_lowpart (Pmode, operands[1]);
5765   operands[2] = gen_lowpart (Pmode, operands[2]);
5766   operands[3] = gen_lowpart (Pmode, operands[3]);
5768   [(set_attr "type" "lea")
5769    (set_attr "mode" "SI")])
5771 (define_insn_and_split "*lea_general_2"
5772   [(set (match_operand 0 "register_operand" "=r")
5773         (plus (mult (match_operand 1 "index_register_operand" "l")
5774                     (match_operand 2 "const248_operand" "i"))
5775               (match_operand 3 "nonmemory_operand" "ri")))]
5776   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5777     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5778    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5779    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5780    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5781        || GET_MODE (operands[3]) == VOIDmode)"
5782   "#"
5783   "&& reload_completed"
5784   [(const_int 0)]
5786   rtx pat;
5787   operands[0] = gen_lowpart (SImode, operands[0]);
5788   operands[1] = gen_lowpart (Pmode, operands[1]);
5789   operands[3] = gen_lowpart (Pmode, operands[3]);
5790   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5791                       operands[3]);
5792   if (Pmode != SImode)
5793     pat = gen_rtx_SUBREG (SImode, pat, 0);
5794   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5795   DONE;
5797   [(set_attr "type" "lea")
5798    (set_attr "mode" "SI")])
5800 (define_insn_and_split "*lea_general_2_zext"
5801   [(set (match_operand:DI 0 "register_operand" "=r")
5802         (zero_extend:DI
5803           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5804                             (match_operand:SI 2 "const248_operand" "n"))
5805                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5806   "TARGET_64BIT"
5807   "#"
5808   "&& reload_completed"
5809   [(set (match_dup 0)
5810         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5811                                                      (match_dup 2))
5812                                             (match_dup 3)) 0)))]
5814   operands[1] = gen_lowpart (Pmode, operands[1]);
5815   operands[3] = gen_lowpart (Pmode, operands[3]);
5817   [(set_attr "type" "lea")
5818    (set_attr "mode" "SI")])
5820 (define_insn_and_split "*lea_general_3"
5821   [(set (match_operand 0 "register_operand" "=r")
5822         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5823                           (match_operand 2 "const248_operand" "i"))
5824                     (match_operand 3 "register_operand" "r"))
5825               (match_operand 4 "immediate_operand" "i")))]
5826   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5827     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5828    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5829    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5830    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5831   "#"
5832   "&& reload_completed"
5833   [(const_int 0)]
5835   rtx pat;
5836   operands[0] = gen_lowpart (SImode, operands[0]);
5837   operands[1] = gen_lowpart (Pmode, operands[1]);
5838   operands[3] = gen_lowpart (Pmode, operands[3]);
5839   operands[4] = gen_lowpart (Pmode, operands[4]);
5840   pat = gen_rtx_PLUS (Pmode,
5841                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5842                                                          operands[2]),
5843                                     operands[3]),
5844                       operands[4]);
5845   if (Pmode != SImode)
5846     pat = gen_rtx_SUBREG (SImode, pat, 0);
5847   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5848   DONE;
5850   [(set_attr "type" "lea")
5851    (set_attr "mode" "SI")])
5853 (define_insn_and_split "*lea_general_3_zext"
5854   [(set (match_operand:DI 0 "register_operand" "=r")
5855         (zero_extend:DI
5856           (plus:SI (plus:SI (mult:SI
5857                               (match_operand:SI 1 "index_register_operand" "l")
5858                               (match_operand:SI 2 "const248_operand" "n"))
5859                             (match_operand:SI 3 "register_operand" "r"))
5860                    (match_operand:SI 4 "immediate_operand" "i"))))]
5861   "TARGET_64BIT"
5862   "#"
5863   "&& reload_completed"
5864   [(set (match_dup 0)
5865         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5866                                                               (match_dup 2))
5867                                                      (match_dup 3))
5868                                             (match_dup 4)) 0)))]
5870   operands[1] = gen_lowpart (Pmode, operands[1]);
5871   operands[3] = gen_lowpart (Pmode, operands[3]);
5872   operands[4] = gen_lowpart (Pmode, operands[4]);
5874   [(set_attr "type" "lea")
5875    (set_attr "mode" "SI")])
5877 (define_insn "*adddi_1_rex64"
5878   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5879         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5880                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5881    (clobber (reg:CC FLAGS_REG))]
5882   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5884   switch (get_attr_type (insn))
5885     {
5886     case TYPE_LEA:
5887       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5888       return "lea{q}\t{%a2, %0|%0, %a2}";
5890     case TYPE_INCDEC:
5891       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5892       if (operands[2] == const1_rtx)
5893         return "inc{q}\t%0";
5894       else
5895         {
5896           gcc_assert (operands[2] == constm1_rtx);
5897           return "dec{q}\t%0";
5898         }
5900     default:
5901       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5903       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5904          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5905       if (CONST_INT_P (operands[2])
5906           /* Avoid overflows.  */
5907           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5908           && (INTVAL (operands[2]) == 128
5909               || (INTVAL (operands[2]) < 0
5910                   && INTVAL (operands[2]) != -128)))
5911         {
5912           operands[2] = GEN_INT (-INTVAL (operands[2]));
5913           return "sub{q}\t{%2, %0|%0, %2}";
5914         }
5915       return "add{q}\t{%2, %0|%0, %2}";
5916     }
5918   [(set (attr "type")
5919      (cond [(eq_attr "alternative" "2")
5920               (const_string "lea")
5921             ; Current assemblers are broken and do not allow @GOTOFF in
5922             ; ought but a memory context.
5923             (match_operand:DI 2 "pic_symbolic_operand" "")
5924               (const_string "lea")
5925             (match_operand:DI 2 "incdec_operand" "")
5926               (const_string "incdec")
5927            ]
5928            (const_string "alu")))
5929    (set_attr "mode" "DI")])
5931 ;; Convert lea to the lea pattern to avoid flags dependency.
5932 (define_split
5933   [(set (match_operand:DI 0 "register_operand" "")
5934         (plus:DI (match_operand:DI 1 "register_operand" "")
5935                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5936    (clobber (reg:CC FLAGS_REG))]
5937   "TARGET_64BIT && reload_completed
5938    && true_regnum (operands[0]) != true_regnum (operands[1])"
5939   [(set (match_dup 0)
5940         (plus:DI (match_dup 1)
5941                  (match_dup 2)))]
5942   "")
5944 (define_insn "*adddi_2_rex64"
5945   [(set (reg FLAGS_REG)
5946         (compare
5947           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5948                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5949           (const_int 0)))
5950    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5951         (plus:DI (match_dup 1) (match_dup 2)))]
5952   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5953    && ix86_binary_operator_ok (PLUS, DImode, operands)
5954    /* Current assemblers are broken and do not allow @GOTOFF in
5955       ought but a memory context.  */
5956    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5958   switch (get_attr_type (insn))
5959     {
5960     case TYPE_INCDEC:
5961       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5962       if (operands[2] == const1_rtx)
5963         return "inc{q}\t%0";
5964       else
5965         {
5966           gcc_assert (operands[2] == constm1_rtx);
5967           return "dec{q}\t%0";
5968         }
5970     default:
5971       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5972       /* ???? We ought to handle there the 32bit case too
5973          - do we need new constraint?  */
5974       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5975          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5976       if (CONST_INT_P (operands[2])
5977           /* Avoid overflows.  */
5978           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5979           && (INTVAL (operands[2]) == 128
5980               || (INTVAL (operands[2]) < 0
5981                   && INTVAL (operands[2]) != -128)))
5982         {
5983           operands[2] = GEN_INT (-INTVAL (operands[2]));
5984           return "sub{q}\t{%2, %0|%0, %2}";
5985         }
5986       return "add{q}\t{%2, %0|%0, %2}";
5987     }
5989   [(set (attr "type")
5990      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5991         (const_string "incdec")
5992         (const_string "alu")))
5993    (set_attr "mode" "DI")])
5995 (define_insn "*adddi_3_rex64"
5996   [(set (reg FLAGS_REG)
5997         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
5998                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
5999    (clobber (match_scratch:DI 0 "=r"))]
6000   "TARGET_64BIT
6001    && ix86_match_ccmode (insn, CCZmode)
6002    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6003    /* Current assemblers are broken and do not allow @GOTOFF in
6004       ought but a memory context.  */
6005    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6007   switch (get_attr_type (insn))
6008     {
6009     case TYPE_INCDEC:
6010       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6011       if (operands[2] == const1_rtx)
6012         return "inc{q}\t%0";
6013       else
6014         {
6015           gcc_assert (operands[2] == constm1_rtx);
6016           return "dec{q}\t%0";
6017         }
6019     default:
6020       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6021       /* ???? We ought to handle there the 32bit case too
6022          - do we need new constraint?  */
6023       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6024          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6025       if (CONST_INT_P (operands[2])
6026           /* Avoid overflows.  */
6027           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6028           && (INTVAL (operands[2]) == 128
6029               || (INTVAL (operands[2]) < 0
6030                   && INTVAL (operands[2]) != -128)))
6031         {
6032           operands[2] = GEN_INT (-INTVAL (operands[2]));
6033           return "sub{q}\t{%2, %0|%0, %2}";
6034         }
6035       return "add{q}\t{%2, %0|%0, %2}";
6036     }
6038   [(set (attr "type")
6039      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6040         (const_string "incdec")
6041         (const_string "alu")))
6042    (set_attr "mode" "DI")])
6044 ; For comparisons against 1, -1 and 128, we may generate better code
6045 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6046 ; is matched then.  We can't accept general immediate, because for
6047 ; case of overflows,  the result is messed up.
6048 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6049 ; when negated.
6050 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6051 ; only for comparisons not depending on it.
6052 (define_insn "*adddi_4_rex64"
6053   [(set (reg FLAGS_REG)
6054         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6055                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6056    (clobber (match_scratch:DI 0 "=rm"))]
6057   "TARGET_64BIT
6058    &&  ix86_match_ccmode (insn, CCGCmode)"
6060   switch (get_attr_type (insn))
6061     {
6062     case TYPE_INCDEC:
6063       if (operands[2] == constm1_rtx)
6064         return "inc{q}\t%0";
6065       else
6066         {
6067           gcc_assert (operands[2] == const1_rtx);
6068           return "dec{q}\t%0";
6069         }
6071     default:
6072       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6073       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6074          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6075       if ((INTVAL (operands[2]) == -128
6076            || (INTVAL (operands[2]) > 0
6077                && INTVAL (operands[2]) != 128))
6078           /* Avoid overflows.  */
6079           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6080         return "sub{q}\t{%2, %0|%0, %2}";
6081       operands[2] = GEN_INT (-INTVAL (operands[2]));
6082       return "add{q}\t{%2, %0|%0, %2}";
6083     }
6085   [(set (attr "type")
6086      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6087         (const_string "incdec")
6088         (const_string "alu")))
6089    (set_attr "mode" "DI")])
6091 (define_insn "*adddi_5_rex64"
6092   [(set (reg FLAGS_REG)
6093         (compare
6094           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6095                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6096           (const_int 0)))
6097    (clobber (match_scratch:DI 0 "=r"))]
6098   "TARGET_64BIT
6099    && ix86_match_ccmode (insn, CCGOCmode)
6100    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6101    /* Current assemblers are broken and do not allow @GOTOFF in
6102       ought but a memory context.  */
6103    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6105   switch (get_attr_type (insn))
6106     {
6107     case TYPE_INCDEC:
6108       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6109       if (operands[2] == const1_rtx)
6110         return "inc{q}\t%0";
6111       else
6112         {
6113           gcc_assert (operands[2] == constm1_rtx);
6114           return "dec{q}\t%0";
6115         }
6117     default:
6118       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6119       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6120          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6121       if (CONST_INT_P (operands[2])
6122           /* Avoid overflows.  */
6123           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6124           && (INTVAL (operands[2]) == 128
6125               || (INTVAL (operands[2]) < 0
6126                   && INTVAL (operands[2]) != -128)))
6127         {
6128           operands[2] = GEN_INT (-INTVAL (operands[2]));
6129           return "sub{q}\t{%2, %0|%0, %2}";
6130         }
6131       return "add{q}\t{%2, %0|%0, %2}";
6132     }
6134   [(set (attr "type")
6135      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6136         (const_string "incdec")
6137         (const_string "alu")))
6138    (set_attr "mode" "DI")])
6141 (define_insn "*addsi_1"
6142   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6143         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6144                  (match_operand:SI 2 "general_operand" "g,ri,li")))
6145    (clobber (reg:CC FLAGS_REG))]
6146   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6148   switch (get_attr_type (insn))
6149     {
6150     case TYPE_LEA:
6151       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6152       return "lea{l}\t{%a2, %0|%0, %a2}";
6154     case TYPE_INCDEC:
6155       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6156       if (operands[2] == const1_rtx)
6157         return "inc{l}\t%0";
6158       else
6159         {
6160           gcc_assert (operands[2] == constm1_rtx);
6161           return "dec{l}\t%0";
6162         }
6164     default:
6165       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6167       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6168          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6169       if (CONST_INT_P (operands[2])
6170           && (INTVAL (operands[2]) == 128
6171               || (INTVAL (operands[2]) < 0
6172                   && INTVAL (operands[2]) != -128)))
6173         {
6174           operands[2] = GEN_INT (-INTVAL (operands[2]));
6175           return "sub{l}\t{%2, %0|%0, %2}";
6176         }
6177       return "add{l}\t{%2, %0|%0, %2}";
6178     }
6180   [(set (attr "type")
6181      (cond [(eq_attr "alternative" "2")
6182               (const_string "lea")
6183             ; Current assemblers are broken and do not allow @GOTOFF in
6184             ; ought but a memory context.
6185             (match_operand:SI 2 "pic_symbolic_operand" "")
6186               (const_string "lea")
6187             (match_operand:SI 2 "incdec_operand" "")
6188               (const_string "incdec")
6189            ]
6190            (const_string "alu")))
6191    (set_attr "mode" "SI")])
6193 ;; Convert lea to the lea pattern to avoid flags dependency.
6194 (define_split
6195   [(set (match_operand 0 "register_operand" "")
6196         (plus (match_operand 1 "register_operand" "")
6197               (match_operand 2 "nonmemory_operand" "")))
6198    (clobber (reg:CC FLAGS_REG))]
6199   "reload_completed
6200    && true_regnum (operands[0]) != true_regnum (operands[1])"
6201   [(const_int 0)]
6203   rtx pat;
6204   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6205      may confuse gen_lowpart.  */
6206   if (GET_MODE (operands[0]) != Pmode)
6207     {
6208       operands[1] = gen_lowpart (Pmode, operands[1]);
6209       operands[2] = gen_lowpart (Pmode, operands[2]);
6210     }
6211   operands[0] = gen_lowpart (SImode, operands[0]);
6212   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6213   if (Pmode != SImode)
6214     pat = gen_rtx_SUBREG (SImode, pat, 0);
6215   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6216   DONE;
6219 ;; It may seem that nonimmediate operand is proper one for operand 1.
6220 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6221 ;; we take care in ix86_binary_operator_ok to not allow two memory
6222 ;; operands so proper swapping will be done in reload.  This allow
6223 ;; patterns constructed from addsi_1 to match.
6224 (define_insn "addsi_1_zext"
6225   [(set (match_operand:DI 0 "register_operand" "=r,r")
6226         (zero_extend:DI
6227           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6228                    (match_operand:SI 2 "general_operand" "g,li"))))
6229    (clobber (reg:CC FLAGS_REG))]
6230   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6232   switch (get_attr_type (insn))
6233     {
6234     case TYPE_LEA:
6235       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6236       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6238     case TYPE_INCDEC:
6239       if (operands[2] == const1_rtx)
6240         return "inc{l}\t%k0";
6241       else
6242         {
6243           gcc_assert (operands[2] == constm1_rtx);
6244           return "dec{l}\t%k0";
6245         }
6247     default:
6248       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6249          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6250       if (CONST_INT_P (operands[2])
6251           && (INTVAL (operands[2]) == 128
6252               || (INTVAL (operands[2]) < 0
6253                   && INTVAL (operands[2]) != -128)))
6254         {
6255           operands[2] = GEN_INT (-INTVAL (operands[2]));
6256           return "sub{l}\t{%2, %k0|%k0, %2}";
6257         }
6258       return "add{l}\t{%2, %k0|%k0, %2}";
6259     }
6261   [(set (attr "type")
6262      (cond [(eq_attr "alternative" "1")
6263               (const_string "lea")
6264             ; Current assemblers are broken and do not allow @GOTOFF in
6265             ; ought but a memory context.
6266             (match_operand:SI 2 "pic_symbolic_operand" "")
6267               (const_string "lea")
6268             (match_operand:SI 2 "incdec_operand" "")
6269               (const_string "incdec")
6270            ]
6271            (const_string "alu")))
6272    (set_attr "mode" "SI")])
6274 ;; Convert lea to the lea pattern to avoid flags dependency.
6275 (define_split
6276   [(set (match_operand:DI 0 "register_operand" "")
6277         (zero_extend:DI
6278           (plus:SI (match_operand:SI 1 "register_operand" "")
6279                    (match_operand:SI 2 "nonmemory_operand" ""))))
6280    (clobber (reg:CC FLAGS_REG))]
6281   "TARGET_64BIT && reload_completed
6282    && true_regnum (operands[0]) != true_regnum (operands[1])"
6283   [(set (match_dup 0)
6284         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6286   operands[1] = gen_lowpart (Pmode, operands[1]);
6287   operands[2] = gen_lowpart (Pmode, operands[2]);
6290 (define_insn "*addsi_2"
6291   [(set (reg FLAGS_REG)
6292         (compare
6293           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6294                    (match_operand:SI 2 "general_operand" "g,ri"))
6295           (const_int 0)))
6296    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6297         (plus:SI (match_dup 1) (match_dup 2)))]
6298   "ix86_match_ccmode (insn, CCGOCmode)
6299    && ix86_binary_operator_ok (PLUS, SImode, operands)
6300    /* Current assemblers are broken and do not allow @GOTOFF in
6301       ought but a memory context.  */
6302    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6304   switch (get_attr_type (insn))
6305     {
6306     case TYPE_INCDEC:
6307       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6308       if (operands[2] == const1_rtx)
6309         return "inc{l}\t%0";
6310       else
6311         {
6312           gcc_assert (operands[2] == constm1_rtx);
6313           return "dec{l}\t%0";
6314         }
6316     default:
6317       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6318       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6319          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6320       if (CONST_INT_P (operands[2])
6321           && (INTVAL (operands[2]) == 128
6322               || (INTVAL (operands[2]) < 0
6323                   && INTVAL (operands[2]) != -128)))
6324         {
6325           operands[2] = GEN_INT (-INTVAL (operands[2]));
6326           return "sub{l}\t{%2, %0|%0, %2}";
6327         }
6328       return "add{l}\t{%2, %0|%0, %2}";
6329     }
6331   [(set (attr "type")
6332      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6333         (const_string "incdec")
6334         (const_string "alu")))
6335    (set_attr "mode" "SI")])
6337 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6338 (define_insn "*addsi_2_zext"
6339   [(set (reg FLAGS_REG)
6340         (compare
6341           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6342                    (match_operand:SI 2 "general_operand" "g"))
6343           (const_int 0)))
6344    (set (match_operand:DI 0 "register_operand" "=r")
6345         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6346   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6347    && ix86_binary_operator_ok (PLUS, SImode, operands)
6348    /* Current assemblers are broken and do not allow @GOTOFF in
6349       ought but a memory context.  */
6350    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6352   switch (get_attr_type (insn))
6353     {
6354     case TYPE_INCDEC:
6355       if (operands[2] == const1_rtx)
6356         return "inc{l}\t%k0";
6357       else
6358         {
6359           gcc_assert (operands[2] == constm1_rtx);
6360           return "dec{l}\t%k0";
6361         }
6363     default:
6364       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6365          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6366       if (CONST_INT_P (operands[2])
6367           && (INTVAL (operands[2]) == 128
6368               || (INTVAL (operands[2]) < 0
6369                   && INTVAL (operands[2]) != -128)))
6370         {
6371           operands[2] = GEN_INT (-INTVAL (operands[2]));
6372           return "sub{l}\t{%2, %k0|%k0, %2}";
6373         }
6374       return "add{l}\t{%2, %k0|%k0, %2}";
6375     }
6377   [(set (attr "type")
6378      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6379         (const_string "incdec")
6380         (const_string "alu")))
6381    (set_attr "mode" "SI")])
6383 (define_insn "*addsi_3"
6384   [(set (reg FLAGS_REG)
6385         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6386                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6387    (clobber (match_scratch:SI 0 "=r"))]
6388   "ix86_match_ccmode (insn, CCZmode)
6389    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6390    /* Current assemblers are broken and do not allow @GOTOFF in
6391       ought but a memory context.  */
6392    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6394   switch (get_attr_type (insn))
6395     {
6396     case TYPE_INCDEC:
6397       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6398       if (operands[2] == const1_rtx)
6399         return "inc{l}\t%0";
6400       else
6401         {
6402           gcc_assert (operands[2] == constm1_rtx);
6403           return "dec{l}\t%0";
6404         }
6406     default:
6407       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6408       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6409          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6410       if (CONST_INT_P (operands[2])
6411           && (INTVAL (operands[2]) == 128
6412               || (INTVAL (operands[2]) < 0
6413                   && INTVAL (operands[2]) != -128)))
6414         {
6415           operands[2] = GEN_INT (-INTVAL (operands[2]));
6416           return "sub{l}\t{%2, %0|%0, %2}";
6417         }
6418       return "add{l}\t{%2, %0|%0, %2}";
6419     }
6421   [(set (attr "type")
6422      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6423         (const_string "incdec")
6424         (const_string "alu")))
6425    (set_attr "mode" "SI")])
6427 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6428 (define_insn "*addsi_3_zext"
6429   [(set (reg FLAGS_REG)
6430         (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
6431                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6432    (set (match_operand:DI 0 "register_operand" "=r")
6433         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6434   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6435    && ix86_binary_operator_ok (PLUS, SImode, operands)
6436    /* Current assemblers are broken and do not allow @GOTOFF in
6437       ought but a memory context.  */
6438    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6440   switch (get_attr_type (insn))
6441     {
6442     case TYPE_INCDEC:
6443       if (operands[2] == const1_rtx)
6444         return "inc{l}\t%k0";
6445       else
6446         {
6447           gcc_assert (operands[2] == constm1_rtx);
6448           return "dec{l}\t%k0";
6449         }
6451     default:
6452       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6453          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6454       if (CONST_INT_P (operands[2])
6455           && (INTVAL (operands[2]) == 128
6456               || (INTVAL (operands[2]) < 0
6457                   && INTVAL (operands[2]) != -128)))
6458         {
6459           operands[2] = GEN_INT (-INTVAL (operands[2]));
6460           return "sub{l}\t{%2, %k0|%k0, %2}";
6461         }
6462       return "add{l}\t{%2, %k0|%k0, %2}";
6463     }
6465   [(set (attr "type")
6466      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6467         (const_string "incdec")
6468         (const_string "alu")))
6469    (set_attr "mode" "SI")])
6471 ; For comparisons against 1, -1 and 128, we may generate better code
6472 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6473 ; is matched then.  We can't accept general immediate, because for
6474 ; case of overflows,  the result is messed up.
6475 ; This pattern also don't hold of 0x80000000, since the value overflows
6476 ; when negated.
6477 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6478 ; only for comparisons not depending on it.
6479 (define_insn "*addsi_4"
6480   [(set (reg FLAGS_REG)
6481         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6482                  (match_operand:SI 2 "const_int_operand" "n")))
6483    (clobber (match_scratch:SI 0 "=rm"))]
6484   "ix86_match_ccmode (insn, CCGCmode)
6485    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6487   switch (get_attr_type (insn))
6488     {
6489     case TYPE_INCDEC:
6490       if (operands[2] == constm1_rtx)
6491         return "inc{l}\t%0";
6492       else
6493         {
6494           gcc_assert (operands[2] == const1_rtx);
6495           return "dec{l}\t%0";
6496         }
6498     default:
6499       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6500       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6501          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6502       if ((INTVAL (operands[2]) == -128
6503            || (INTVAL (operands[2]) > 0
6504                && INTVAL (operands[2]) != 128)))
6505         return "sub{l}\t{%2, %0|%0, %2}";
6506       operands[2] = GEN_INT (-INTVAL (operands[2]));
6507       return "add{l}\t{%2, %0|%0, %2}";
6508     }
6510   [(set (attr "type")
6511      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6512         (const_string "incdec")
6513         (const_string "alu")))
6514    (set_attr "mode" "SI")])
6516 (define_insn "*addsi_5"
6517   [(set (reg FLAGS_REG)
6518         (compare
6519           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6520                    (match_operand:SI 2 "general_operand" "g"))
6521           (const_int 0)))
6522    (clobber (match_scratch:SI 0 "=r"))]
6523   "ix86_match_ccmode (insn, CCGOCmode)
6524    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6525    /* Current assemblers are broken and do not allow @GOTOFF in
6526       ought but a memory context.  */
6527    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6529   switch (get_attr_type (insn))
6530     {
6531     case TYPE_INCDEC:
6532       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6533       if (operands[2] == const1_rtx)
6534         return "inc{l}\t%0";
6535       else
6536         {
6537           gcc_assert (operands[2] == constm1_rtx);
6538           return "dec{l}\t%0";
6539         }
6541     default:
6542       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6543       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6544          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6545       if (CONST_INT_P (operands[2])
6546           && (INTVAL (operands[2]) == 128
6547               || (INTVAL (operands[2]) < 0
6548                   && INTVAL (operands[2]) != -128)))
6549         {
6550           operands[2] = GEN_INT (-INTVAL (operands[2]));
6551           return "sub{l}\t{%2, %0|%0, %2}";
6552         }
6553       return "add{l}\t{%2, %0|%0, %2}";
6554     }
6556   [(set (attr "type")
6557      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6558         (const_string "incdec")
6559         (const_string "alu")))
6560    (set_attr "mode" "SI")])
6562 (define_expand "addhi3"
6563   [(set (match_operand:HI 0 "nonimmediate_operand" "")
6564         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6565                  (match_operand:HI 2 "general_operand" "")))]
6566   "TARGET_HIMODE_MATH"
6567   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6569 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6570 ;; type optimizations enabled by define-splits.  This is not important
6571 ;; for PII, and in fact harmful because of partial register stalls.
6573 (define_insn "*addhi_1_lea"
6574   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6575         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6576                  (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6577    (clobber (reg:CC FLAGS_REG))]
6578   "!TARGET_PARTIAL_REG_STALL
6579    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6581   switch (get_attr_type (insn))
6582     {
6583     case TYPE_LEA:
6584       return "#";
6585     case TYPE_INCDEC:
6586       if (operands[2] == const1_rtx)
6587         return "inc{w}\t%0";
6588       else
6589         {
6590           gcc_assert (operands[2] == constm1_rtx);
6591           return "dec{w}\t%0";
6592         }
6594     default:
6595       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6596          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6597       if (CONST_INT_P (operands[2])
6598           && (INTVAL (operands[2]) == 128
6599               || (INTVAL (operands[2]) < 0
6600                   && INTVAL (operands[2]) != -128)))
6601         {
6602           operands[2] = GEN_INT (-INTVAL (operands[2]));
6603           return "sub{w}\t{%2, %0|%0, %2}";
6604         }
6605       return "add{w}\t{%2, %0|%0, %2}";
6606     }
6608   [(set (attr "type")
6609      (if_then_else (eq_attr "alternative" "2")
6610         (const_string "lea")
6611         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6612            (const_string "incdec")
6613            (const_string "alu"))))
6614    (set_attr "mode" "HI,HI,SI")])
6616 (define_insn "*addhi_1"
6617   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6618         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6619                  (match_operand:HI 2 "general_operand" "rn,rm")))
6620    (clobber (reg:CC FLAGS_REG))]
6621   "TARGET_PARTIAL_REG_STALL
6622    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6624   switch (get_attr_type (insn))
6625     {
6626     case TYPE_INCDEC:
6627       if (operands[2] == const1_rtx)
6628         return "inc{w}\t%0";
6629       else
6630         {
6631           gcc_assert (operands[2] == constm1_rtx);
6632           return "dec{w}\t%0";
6633         }
6635     default:
6636       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6637          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6638       if (CONST_INT_P (operands[2])
6639           && (INTVAL (operands[2]) == 128
6640               || (INTVAL (operands[2]) < 0
6641                   && INTVAL (operands[2]) != -128)))
6642         {
6643           operands[2] = GEN_INT (-INTVAL (operands[2]));
6644           return "sub{w}\t{%2, %0|%0, %2}";
6645         }
6646       return "add{w}\t{%2, %0|%0, %2}";
6647     }
6649   [(set (attr "type")
6650      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6651         (const_string "incdec")
6652         (const_string "alu")))
6653    (set_attr "mode" "HI")])
6655 (define_insn "*addhi_2"
6656   [(set (reg FLAGS_REG)
6657         (compare
6658           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6659                    (match_operand:HI 2 "general_operand" "rmn,rn"))
6660           (const_int 0)))
6661    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6662         (plus:HI (match_dup 1) (match_dup 2)))]
6663   "ix86_match_ccmode (insn, CCGOCmode)
6664    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6666   switch (get_attr_type (insn))
6667     {
6668     case TYPE_INCDEC:
6669       if (operands[2] == const1_rtx)
6670         return "inc{w}\t%0";
6671       else
6672         {
6673           gcc_assert (operands[2] == constm1_rtx);
6674           return "dec{w}\t%0";
6675         }
6677     default:
6678       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6679          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6680       if (CONST_INT_P (operands[2])
6681           && (INTVAL (operands[2]) == 128
6682               || (INTVAL (operands[2]) < 0
6683                   && INTVAL (operands[2]) != -128)))
6684         {
6685           operands[2] = GEN_INT (-INTVAL (operands[2]));
6686           return "sub{w}\t{%2, %0|%0, %2}";
6687         }
6688       return "add{w}\t{%2, %0|%0, %2}";
6689     }
6691   [(set (attr "type")
6692      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6693         (const_string "incdec")
6694         (const_string "alu")))
6695    (set_attr "mode" "HI")])
6697 (define_insn "*addhi_3"
6698   [(set (reg FLAGS_REG)
6699         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6700                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6701    (clobber (match_scratch:HI 0 "=r"))]
6702   "ix86_match_ccmode (insn, CCZmode)
6703    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6705   switch (get_attr_type (insn))
6706     {
6707     case TYPE_INCDEC:
6708       if (operands[2] == const1_rtx)
6709         return "inc{w}\t%0";
6710       else
6711         {
6712           gcc_assert (operands[2] == constm1_rtx);
6713           return "dec{w}\t%0";
6714         }
6716     default:
6717       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6718          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6719       if (CONST_INT_P (operands[2])
6720           && (INTVAL (operands[2]) == 128
6721               || (INTVAL (operands[2]) < 0
6722                   && INTVAL (operands[2]) != -128)))
6723         {
6724           operands[2] = GEN_INT (-INTVAL (operands[2]));
6725           return "sub{w}\t{%2, %0|%0, %2}";
6726         }
6727       return "add{w}\t{%2, %0|%0, %2}";
6728     }
6730   [(set (attr "type")
6731      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6732         (const_string "incdec")
6733         (const_string "alu")))
6734    (set_attr "mode" "HI")])
6736 ; See comments above addsi_4 for details.
6737 (define_insn "*addhi_4"
6738   [(set (reg FLAGS_REG)
6739         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6740                  (match_operand:HI 2 "const_int_operand" "n")))
6741    (clobber (match_scratch:HI 0 "=rm"))]
6742   "ix86_match_ccmode (insn, CCGCmode)
6743    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6745   switch (get_attr_type (insn))
6746     {
6747     case TYPE_INCDEC:
6748       if (operands[2] == constm1_rtx)
6749         return "inc{w}\t%0";
6750       else
6751         {
6752           gcc_assert (operands[2] == const1_rtx);
6753           return "dec{w}\t%0";
6754         }
6756     default:
6757       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6758       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6759          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6760       if ((INTVAL (operands[2]) == -128
6761            || (INTVAL (operands[2]) > 0
6762                && INTVAL (operands[2]) != 128)))
6763         return "sub{w}\t{%2, %0|%0, %2}";
6764       operands[2] = GEN_INT (-INTVAL (operands[2]));
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" "SI")])
6775 (define_insn "*addhi_5"
6776   [(set (reg FLAGS_REG)
6777         (compare
6778           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6779                    (match_operand:HI 2 "general_operand" "rmn"))
6780           (const_int 0)))
6781    (clobber (match_scratch:HI 0 "=r"))]
6782   "ix86_match_ccmode (insn, CCGOCmode)
6783    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6785   switch (get_attr_type (insn))
6786     {
6787     case TYPE_INCDEC:
6788       if (operands[2] == const1_rtx)
6789         return "inc{w}\t%0";
6790       else
6791         {
6792           gcc_assert (operands[2] == constm1_rtx);
6793           return "dec{w}\t%0";
6794         }
6796     default:
6797       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6798          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6799       if (CONST_INT_P (operands[2])
6800           && (INTVAL (operands[2]) == 128
6801               || (INTVAL (operands[2]) < 0
6802                   && INTVAL (operands[2]) != -128)))
6803         {
6804           operands[2] = GEN_INT (-INTVAL (operands[2]));
6805           return "sub{w}\t{%2, %0|%0, %2}";
6806         }
6807       return "add{w}\t{%2, %0|%0, %2}";
6808     }
6810   [(set (attr "type")
6811      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6812         (const_string "incdec")
6813         (const_string "alu")))
6814    (set_attr "mode" "HI")])
6816 (define_expand "addqi3"
6817   [(set (match_operand:QI 0 "nonimmediate_operand" "")
6818         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6819                  (match_operand:QI 2 "general_operand" "")))]
6820   "TARGET_QIMODE_MATH"
6821   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6823 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6824 (define_insn "*addqi_1_lea"
6825   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6826         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6827                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6828    (clobber (reg:CC FLAGS_REG))]
6829   "!TARGET_PARTIAL_REG_STALL
6830    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6832   int widen = (which_alternative == 2);
6833   switch (get_attr_type (insn))
6834     {
6835     case TYPE_LEA:
6836       return "#";
6837     case TYPE_INCDEC:
6838       if (operands[2] == const1_rtx)
6839         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6840       else
6841         {
6842           gcc_assert (operands[2] == constm1_rtx);
6843           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6844         }
6846     default:
6847       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6848          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6849       if (CONST_INT_P (operands[2])
6850           && (INTVAL (operands[2]) == 128
6851               || (INTVAL (operands[2]) < 0
6852                   && INTVAL (operands[2]) != -128)))
6853         {
6854           operands[2] = GEN_INT (-INTVAL (operands[2]));
6855           if (widen)
6856             return "sub{l}\t{%2, %k0|%k0, %2}";
6857           else
6858             return "sub{b}\t{%2, %0|%0, %2}";
6859         }
6860       if (widen)
6861         return "add{l}\t{%k2, %k0|%k0, %k2}";
6862       else
6863         return "add{b}\t{%2, %0|%0, %2}";
6864     }
6866   [(set (attr "type")
6867      (if_then_else (eq_attr "alternative" "3")
6868         (const_string "lea")
6869         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6870            (const_string "incdec")
6871            (const_string "alu"))))
6872    (set_attr "mode" "QI,QI,SI,SI")])
6874 (define_insn "*addqi_1"
6875   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6876         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6877                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6878    (clobber (reg:CC FLAGS_REG))]
6879   "TARGET_PARTIAL_REG_STALL
6880    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6882   int widen = (which_alternative == 2);
6883   switch (get_attr_type (insn))
6884     {
6885     case TYPE_INCDEC:
6886       if (operands[2] == const1_rtx)
6887         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6888       else
6889         {
6890           gcc_assert (operands[2] == constm1_rtx);
6891           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6892         }
6894     default:
6895       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6896          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6897       if (CONST_INT_P (operands[2])
6898           && (INTVAL (operands[2]) == 128
6899               || (INTVAL (operands[2]) < 0
6900                   && INTVAL (operands[2]) != -128)))
6901         {
6902           operands[2] = GEN_INT (-INTVAL (operands[2]));
6903           if (widen)
6904             return "sub{l}\t{%2, %k0|%k0, %2}";
6905           else
6906             return "sub{b}\t{%2, %0|%0, %2}";
6907         }
6908       if (widen)
6909         return "add{l}\t{%k2, %k0|%k0, %k2}";
6910       else
6911         return "add{b}\t{%2, %0|%0, %2}";
6912     }
6914   [(set (attr "type")
6915      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6916         (const_string "incdec")
6917         (const_string "alu")))
6918    (set_attr "mode" "QI,QI,SI")])
6920 (define_insn "*addqi_1_slp"
6921   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6922         (plus:QI (match_dup 0)
6923                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6924    (clobber (reg:CC FLAGS_REG))]
6925   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6926    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6928   switch (get_attr_type (insn))
6929     {
6930     case TYPE_INCDEC:
6931       if (operands[1] == const1_rtx)
6932         return "inc{b}\t%0";
6933       else
6934         {
6935           gcc_assert (operands[1] == constm1_rtx);
6936           return "dec{b}\t%0";
6937         }
6939     default:
6940       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6941       if (CONST_INT_P (operands[1])
6942           && INTVAL (operands[1]) < 0)
6943         {
6944           operands[1] = GEN_INT (-INTVAL (operands[1]));
6945           return "sub{b}\t{%1, %0|%0, %1}";
6946         }
6947       return "add{b}\t{%1, %0|%0, %1}";
6948     }
6950   [(set (attr "type")
6951      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6952         (const_string "incdec")
6953         (const_string "alu1")))
6954    (set (attr "memory")
6955      (if_then_else (match_operand 1 "memory_operand" "")
6956         (const_string "load")
6957         (const_string "none")))
6958    (set_attr "mode" "QI")])
6960 (define_insn "*addqi_2"
6961   [(set (reg FLAGS_REG)
6962         (compare
6963           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6964                    (match_operand:QI 2 "general_operand" "qmn,qn"))
6965           (const_int 0)))
6966    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6967         (plus:QI (match_dup 1) (match_dup 2)))]
6968   "ix86_match_ccmode (insn, CCGOCmode)
6969    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6971   switch (get_attr_type (insn))
6972     {
6973     case TYPE_INCDEC:
6974       if (operands[2] == const1_rtx)
6975         return "inc{b}\t%0";
6976       else
6977         {
6978           gcc_assert (operands[2] == constm1_rtx
6979                       || (CONST_INT_P (operands[2])
6980                           && INTVAL (operands[2]) == 255));
6981           return "dec{b}\t%0";
6982         }
6984     default:
6985       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6986       if (CONST_INT_P (operands[2])
6987           && INTVAL (operands[2]) < 0)
6988         {
6989           operands[2] = GEN_INT (-INTVAL (operands[2]));
6990           return "sub{b}\t{%2, %0|%0, %2}";
6991         }
6992       return "add{b}\t{%2, %0|%0, %2}";
6993     }
6995   [(set (attr "type")
6996      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6997         (const_string "incdec")
6998         (const_string "alu")))
6999    (set_attr "mode" "QI")])
7001 (define_insn "*addqi_3"
7002   [(set (reg FLAGS_REG)
7003         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7004                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7005    (clobber (match_scratch:QI 0 "=q"))]
7006   "ix86_match_ccmode (insn, CCZmode)
7007    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7009   switch (get_attr_type (insn))
7010     {
7011     case TYPE_INCDEC:
7012       if (operands[2] == const1_rtx)
7013         return "inc{b}\t%0";
7014       else
7015         {
7016           gcc_assert (operands[2] == constm1_rtx
7017                       || (CONST_INT_P (operands[2])
7018                           && INTVAL (operands[2]) == 255));
7019           return "dec{b}\t%0";
7020         }
7022     default:
7023       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7024       if (CONST_INT_P (operands[2])
7025           && INTVAL (operands[2]) < 0)
7026         {
7027           operands[2] = GEN_INT (-INTVAL (operands[2]));
7028           return "sub{b}\t{%2, %0|%0, %2}";
7029         }
7030       return "add{b}\t{%2, %0|%0, %2}";
7031     }
7033   [(set (attr "type")
7034      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7035         (const_string "incdec")
7036         (const_string "alu")))
7037    (set_attr "mode" "QI")])
7039 ; See comments above addsi_4 for details.
7040 (define_insn "*addqi_4"
7041   [(set (reg FLAGS_REG)
7042         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7043                  (match_operand:QI 2 "const_int_operand" "n")))
7044    (clobber (match_scratch:QI 0 "=qm"))]
7045   "ix86_match_ccmode (insn, CCGCmode)
7046    && (INTVAL (operands[2]) & 0xff) != 0x80"
7048   switch (get_attr_type (insn))
7049     {
7050     case TYPE_INCDEC:
7051       if (operands[2] == constm1_rtx
7052           || (CONST_INT_P (operands[2])
7053               && INTVAL (operands[2]) == 255))
7054         return "inc{b}\t%0";
7055       else
7056         {
7057           gcc_assert (operands[2] == const1_rtx);
7058           return "dec{b}\t%0";
7059         }
7061     default:
7062       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7063       if (INTVAL (operands[2]) < 0)
7064         {
7065           operands[2] = GEN_INT (-INTVAL (operands[2]));
7066           return "add{b}\t{%2, %0|%0, %2}";
7067         }
7068       return "sub{b}\t{%2, %0|%0, %2}";
7069     }
7071   [(set (attr "type")
7072      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7073         (const_string "incdec")
7074         (const_string "alu")))
7075    (set_attr "mode" "QI")])
7078 (define_insn "*addqi_5"
7079   [(set (reg FLAGS_REG)
7080         (compare
7081           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7082                    (match_operand:QI 2 "general_operand" "qmn"))
7083           (const_int 0)))
7084    (clobber (match_scratch:QI 0 "=q"))]
7085   "ix86_match_ccmode (insn, CCGOCmode)
7086    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7088   switch (get_attr_type (insn))
7089     {
7090     case TYPE_INCDEC:
7091       if (operands[2] == const1_rtx)
7092         return "inc{b}\t%0";
7093       else
7094         {
7095           gcc_assert (operands[2] == constm1_rtx
7096                       || (CONST_INT_P (operands[2])
7097                           && INTVAL (operands[2]) == 255));
7098           return "dec{b}\t%0";
7099         }
7101     default:
7102       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7103       if (CONST_INT_P (operands[2])
7104           && INTVAL (operands[2]) < 0)
7105         {
7106           operands[2] = GEN_INT (-INTVAL (operands[2]));
7107           return "sub{b}\t{%2, %0|%0, %2}";
7108         }
7109       return "add{b}\t{%2, %0|%0, %2}";
7110     }
7112   [(set (attr "type")
7113      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7114         (const_string "incdec")
7115         (const_string "alu")))
7116    (set_attr "mode" "QI")])
7119 (define_insn "addqi_ext_1"
7120   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7121                          (const_int 8)
7122                          (const_int 8))
7123         (plus:SI
7124           (zero_extract:SI
7125             (match_operand 1 "ext_register_operand" "0")
7126             (const_int 8)
7127             (const_int 8))
7128           (match_operand:QI 2 "general_operand" "Qmn")))
7129    (clobber (reg:CC FLAGS_REG))]
7130   "!TARGET_64BIT"
7132   switch (get_attr_type (insn))
7133     {
7134     case TYPE_INCDEC:
7135       if (operands[2] == const1_rtx)
7136         return "inc{b}\t%h0";
7137       else
7138         {
7139           gcc_assert (operands[2] == constm1_rtx
7140                       || (CONST_INT_P (operands[2])
7141                           && INTVAL (operands[2]) == 255));
7142           return "dec{b}\t%h0";
7143         }
7145     default:
7146       return "add{b}\t{%2, %h0|%h0, %2}";
7147     }
7149   [(set (attr "type")
7150      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7151         (const_string "incdec")
7152         (const_string "alu")))
7153    (set_attr "mode" "QI")])
7155 (define_insn "*addqi_ext_1_rex64"
7156   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7157                          (const_int 8)
7158                          (const_int 8))
7159         (plus:SI
7160           (zero_extract:SI
7161             (match_operand 1 "ext_register_operand" "0")
7162             (const_int 8)
7163             (const_int 8))
7164           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7165    (clobber (reg:CC FLAGS_REG))]
7166   "TARGET_64BIT"
7168   switch (get_attr_type (insn))
7169     {
7170     case TYPE_INCDEC:
7171       if (operands[2] == const1_rtx)
7172         return "inc{b}\t%h0";
7173       else
7174         {
7175           gcc_assert (operands[2] == constm1_rtx
7176                       || (CONST_INT_P (operands[2])
7177                           && INTVAL (operands[2]) == 255));
7178           return "dec{b}\t%h0";
7179         }
7181     default:
7182       return "add{b}\t{%2, %h0|%h0, %2}";
7183     }
7185   [(set (attr "type")
7186      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7187         (const_string "incdec")
7188         (const_string "alu")))
7189    (set_attr "mode" "QI")])
7191 (define_insn "*addqi_ext_2"
7192   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7193                          (const_int 8)
7194                          (const_int 8))
7195         (plus:SI
7196           (zero_extract:SI
7197             (match_operand 1 "ext_register_operand" "%0")
7198             (const_int 8)
7199             (const_int 8))
7200           (zero_extract:SI
7201             (match_operand 2 "ext_register_operand" "Q")
7202             (const_int 8)
7203             (const_int 8))))
7204    (clobber (reg:CC FLAGS_REG))]
7205   ""
7206   "add{b}\t{%h2, %h0|%h0, %h2}"
7207   [(set_attr "type" "alu")
7208    (set_attr "mode" "QI")])
7210 ;; The patterns that match these are at the end of this file.
7212 (define_expand "addxf3"
7213   [(set (match_operand:XF 0 "register_operand" "")
7214         (plus:XF (match_operand:XF 1 "register_operand" "")
7215                  (match_operand:XF 2 "register_operand" "")))]
7216   "TARGET_80387"
7217   "")
7219 (define_expand "add<mode>3"
7220   [(set (match_operand:MODEF 0 "register_operand" "")
7221         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7222                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7223   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7224   "")
7226 ;; Subtract instructions
7228 ;; %%% splits for subditi3
7230 (define_expand "subti3"
7231   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7232         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7233                   (match_operand:TI 2 "x86_64_general_operand" "")))]
7234   "TARGET_64BIT"
7235   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7237 (define_insn "*subti3_1"
7238   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7239         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7240                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7241    (clobber (reg:CC FLAGS_REG))]
7242   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7243   "#")
7245 (define_split
7246   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7247         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7248                   (match_operand:TI 2 "x86_64_general_operand" "")))
7249    (clobber (reg:CC FLAGS_REG))]
7250   "TARGET_64BIT && reload_completed"
7251   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7252               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7253    (parallel [(set (match_dup 3)
7254                    (minus:DI (match_dup 4)
7255                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7256                                       (match_dup 5))))
7257               (clobber (reg:CC FLAGS_REG))])]
7258   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7260 ;; %%% splits for subsidi3
7262 (define_expand "subdi3"
7263   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7264         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7265                   (match_operand:DI 2 "x86_64_general_operand" "")))]
7266   ""
7267   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7269 (define_insn "*subdi3_1"
7270   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7271         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7272                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7273    (clobber (reg:CC FLAGS_REG))]
7274   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7275   "#")
7277 (define_split
7278   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7279         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7280                   (match_operand:DI 2 "general_operand" "")))
7281    (clobber (reg:CC FLAGS_REG))]
7282   "!TARGET_64BIT && reload_completed"
7283   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7284               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7285    (parallel [(set (match_dup 3)
7286                    (minus:SI (match_dup 4)
7287                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7288                                       (match_dup 5))))
7289               (clobber (reg:CC FLAGS_REG))])]
7290   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7292 (define_insn "subdi3_carry_rex64"
7293   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7294           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7295             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7296                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7297    (clobber (reg:CC FLAGS_REG))]
7298   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7299   "sbb{q}\t{%2, %0|%0, %2}"
7300   [(set_attr "type" "alu")
7301    (set_attr "pent_pair" "pu")
7302    (set_attr "mode" "DI")])
7304 (define_insn "*subdi_1_rex64"
7305   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7306         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7307                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7308    (clobber (reg:CC FLAGS_REG))]
7309   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7310   "sub{q}\t{%2, %0|%0, %2}"
7311   [(set_attr "type" "alu")
7312    (set_attr "mode" "DI")])
7314 (define_insn "*subdi_2_rex64"
7315   [(set (reg FLAGS_REG)
7316         (compare
7317           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7318                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7319           (const_int 0)))
7320    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7321         (minus:DI (match_dup 1) (match_dup 2)))]
7322   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7323    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7324   "sub{q}\t{%2, %0|%0, %2}"
7325   [(set_attr "type" "alu")
7326    (set_attr "mode" "DI")])
7328 (define_insn "*subdi_3_rex63"
7329   [(set (reg FLAGS_REG)
7330         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7331                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7332    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7333         (minus:DI (match_dup 1) (match_dup 2)))]
7334   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7335    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7336   "sub{q}\t{%2, %0|%0, %2}"
7337   [(set_attr "type" "alu")
7338    (set_attr "mode" "DI")])
7340 (define_insn "subqi3_carry"
7341   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7342           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7343             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7344                (match_operand:QI 2 "general_operand" "qn,qm"))))
7345    (clobber (reg:CC FLAGS_REG))]
7346   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7347   "sbb{b}\t{%2, %0|%0, %2}"
7348   [(set_attr "type" "alu")
7349    (set_attr "pent_pair" "pu")
7350    (set_attr "mode" "QI")])
7352 (define_insn "subhi3_carry"
7353   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7354           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7355             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7356                (match_operand:HI 2 "general_operand" "rn,rm"))))
7357    (clobber (reg:CC FLAGS_REG))]
7358   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7359   "sbb{w}\t{%2, %0|%0, %2}"
7360   [(set_attr "type" "alu")
7361    (set_attr "pent_pair" "pu")
7362    (set_attr "mode" "HI")])
7364 (define_insn "subsi3_carry"
7365   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7366           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7367             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7368                (match_operand:SI 2 "general_operand" "ri,rm"))))
7369    (clobber (reg:CC FLAGS_REG))]
7370   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7371   "sbb{l}\t{%2, %0|%0, %2}"
7372   [(set_attr "type" "alu")
7373    (set_attr "pent_pair" "pu")
7374    (set_attr "mode" "SI")])
7376 (define_insn "subsi3_carry_zext"
7377   [(set (match_operand:DI 0 "register_operand" "=r")
7378           (zero_extend:DI
7379             (minus:SI (match_operand:SI 1 "register_operand" "0")
7380               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7381                  (match_operand:SI 2 "general_operand" "g")))))
7382    (clobber (reg:CC FLAGS_REG))]
7383   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7384   "sbb{l}\t{%2, %k0|%k0, %2}"
7385   [(set_attr "type" "alu")
7386    (set_attr "pent_pair" "pu")
7387    (set_attr "mode" "SI")])
7389 (define_expand "subsi3"
7390   [(set (match_operand:SI 0 "nonimmediate_operand" "")
7391         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7392                   (match_operand:SI 2 "general_operand" "")))]
7393   ""
7394   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7396 (define_insn "*subsi_1"
7397   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7398         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7399                   (match_operand:SI 2 "general_operand" "ri,rm")))
7400    (clobber (reg:CC FLAGS_REG))]
7401   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7402   "sub{l}\t{%2, %0|%0, %2}"
7403   [(set_attr "type" "alu")
7404    (set_attr "mode" "SI")])
7406 (define_insn "*subsi_1_zext"
7407   [(set (match_operand:DI 0 "register_operand" "=r")
7408         (zero_extend:DI
7409           (minus:SI (match_operand:SI 1 "register_operand" "0")
7410                     (match_operand:SI 2 "general_operand" "g"))))
7411    (clobber (reg:CC FLAGS_REG))]
7412   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7413   "sub{l}\t{%2, %k0|%k0, %2}"
7414   [(set_attr "type" "alu")
7415    (set_attr "mode" "SI")])
7417 (define_insn "*subsi_2"
7418   [(set (reg FLAGS_REG)
7419         (compare
7420           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7421                     (match_operand:SI 2 "general_operand" "ri,rm"))
7422           (const_int 0)))
7423    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7424         (minus:SI (match_dup 1) (match_dup 2)))]
7425   "ix86_match_ccmode (insn, CCGOCmode)
7426    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7427   "sub{l}\t{%2, %0|%0, %2}"
7428   [(set_attr "type" "alu")
7429    (set_attr "mode" "SI")])
7431 (define_insn "*subsi_2_zext"
7432   [(set (reg FLAGS_REG)
7433         (compare
7434           (minus:SI (match_operand:SI 1 "register_operand" "0")
7435                     (match_operand:SI 2 "general_operand" "g"))
7436           (const_int 0)))
7437    (set (match_operand:DI 0 "register_operand" "=r")
7438         (zero_extend:DI
7439           (minus:SI (match_dup 1)
7440                     (match_dup 2))))]
7441   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7442    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7443   "sub{l}\t{%2, %k0|%k0, %2}"
7444   [(set_attr "type" "alu")
7445    (set_attr "mode" "SI")])
7447 (define_insn "*subsi_3"
7448   [(set (reg FLAGS_REG)
7449         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7450                  (match_operand:SI 2 "general_operand" "ri,rm")))
7451    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7452         (minus:SI (match_dup 1) (match_dup 2)))]
7453   "ix86_match_ccmode (insn, CCmode)
7454    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7455   "sub{l}\t{%2, %0|%0, %2}"
7456   [(set_attr "type" "alu")
7457    (set_attr "mode" "SI")])
7459 (define_insn "*subsi_3_zext"
7460   [(set (reg FLAGS_REG)
7461         (compare (match_operand:SI 1 "register_operand" "0")
7462                  (match_operand:SI 2 "general_operand" "g")))
7463    (set (match_operand:DI 0 "register_operand" "=r")
7464         (zero_extend:DI
7465           (minus:SI (match_dup 1)
7466                     (match_dup 2))))]
7467   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7468    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7469   "sub{l}\t{%2, %1|%1, %2}"
7470   [(set_attr "type" "alu")
7471    (set_attr "mode" "DI")])
7473 (define_expand "subhi3"
7474   [(set (match_operand:HI 0 "nonimmediate_operand" "")
7475         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7476                   (match_operand:HI 2 "general_operand" "")))]
7477   "TARGET_HIMODE_MATH"
7478   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7480 (define_insn "*subhi_1"
7481   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7482         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7483                   (match_operand:HI 2 "general_operand" "rn,rm")))
7484    (clobber (reg:CC FLAGS_REG))]
7485   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7486   "sub{w}\t{%2, %0|%0, %2}"
7487   [(set_attr "type" "alu")
7488    (set_attr "mode" "HI")])
7490 (define_insn "*subhi_2"
7491   [(set (reg FLAGS_REG)
7492         (compare
7493           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7494                     (match_operand:HI 2 "general_operand" "rn,rm"))
7495           (const_int 0)))
7496    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7497         (minus:HI (match_dup 1) (match_dup 2)))]
7498   "ix86_match_ccmode (insn, CCGOCmode)
7499    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7500   "sub{w}\t{%2, %0|%0, %2}"
7501   [(set_attr "type" "alu")
7502    (set_attr "mode" "HI")])
7504 (define_insn "*subhi_3"
7505   [(set (reg FLAGS_REG)
7506         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7507                  (match_operand:HI 2 "general_operand" "rn,rm")))
7508    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7509         (minus:HI (match_dup 1) (match_dup 2)))]
7510   "ix86_match_ccmode (insn, CCmode)
7511    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7512   "sub{w}\t{%2, %0|%0, %2}"
7513   [(set_attr "type" "alu")
7514    (set_attr "mode" "HI")])
7516 (define_expand "subqi3"
7517   [(set (match_operand:QI 0 "nonimmediate_operand" "")
7518         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7519                   (match_operand:QI 2 "general_operand" "")))]
7520   "TARGET_QIMODE_MATH"
7521   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7523 (define_insn "*subqi_1"
7524   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7525         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7526                   (match_operand:QI 2 "general_operand" "qn,qm")))
7527    (clobber (reg:CC FLAGS_REG))]
7528   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7529   "sub{b}\t{%2, %0|%0, %2}"
7530   [(set_attr "type" "alu")
7531    (set_attr "mode" "QI")])
7533 (define_insn "*subqi_1_slp"
7534   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7535         (minus:QI (match_dup 0)
7536                   (match_operand:QI 1 "general_operand" "qn,qm")))
7537    (clobber (reg:CC FLAGS_REG))]
7538   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7539    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7540   "sub{b}\t{%1, %0|%0, %1}"
7541   [(set_attr "type" "alu1")
7542    (set_attr "mode" "QI")])
7544 (define_insn "*subqi_2"
7545   [(set (reg FLAGS_REG)
7546         (compare
7547           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7548                     (match_operand:QI 2 "general_operand" "qn,qm"))
7549           (const_int 0)))
7550    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7551         (minus:QI (match_dup 1) (match_dup 2)))]
7552   "ix86_match_ccmode (insn, CCGOCmode)
7553    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7554   "sub{b}\t{%2, %0|%0, %2}"
7555   [(set_attr "type" "alu")
7556    (set_attr "mode" "QI")])
7558 (define_insn "*subqi_3"
7559   [(set (reg FLAGS_REG)
7560         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7561                  (match_operand:QI 2 "general_operand" "qn,qm")))
7562    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7563         (minus:QI (match_dup 1) (match_dup 2)))]
7564   "ix86_match_ccmode (insn, CCmode)
7565    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7566   "sub{b}\t{%2, %0|%0, %2}"
7567   [(set_attr "type" "alu")
7568    (set_attr "mode" "QI")])
7570 ;; The patterns that match these are at the end of this file.
7572 (define_expand "subxf3"
7573   [(set (match_operand:XF 0 "register_operand" "")
7574         (minus:XF (match_operand:XF 1 "register_operand" "")
7575                   (match_operand:XF 2 "register_operand" "")))]
7576   "TARGET_80387"
7577   "")
7579 (define_expand "sub<mode>3"
7580   [(set (match_operand:MODEF 0 "register_operand" "")
7581         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7582                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7583   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7584   "")
7586 ;; Multiply instructions
7588 (define_expand "muldi3"
7589   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7590                    (mult:DI (match_operand:DI 1 "register_operand" "")
7591                             (match_operand:DI 2 "x86_64_general_operand" "")))
7592               (clobber (reg:CC FLAGS_REG))])]
7593   "TARGET_64BIT"
7594   "")
7596 ;; On AMDFAM10
7597 ;; IMUL reg64, reg64, imm8      Direct
7598 ;; IMUL reg64, mem64, imm8      VectorPath
7599 ;; IMUL reg64, reg64, imm32     Direct
7600 ;; IMUL reg64, mem64, imm32     VectorPath
7601 ;; IMUL reg64, reg64            Direct
7602 ;; IMUL reg64, mem64            Direct
7604 (define_insn "*muldi3_1_rex64"
7605   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7606         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7607                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7608    (clobber (reg:CC FLAGS_REG))]
7609   "TARGET_64BIT
7610    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7611   "@
7612    imul{q}\t{%2, %1, %0|%0, %1, %2}
7613    imul{q}\t{%2, %1, %0|%0, %1, %2}
7614    imul{q}\t{%2, %0|%0, %2}"
7615   [(set_attr "type" "imul")
7616    (set_attr "prefix_0f" "0,0,1")
7617    (set (attr "athlon_decode")
7618         (cond [(eq_attr "cpu" "athlon")
7619                   (const_string "vector")
7620                (eq_attr "alternative" "1")
7621                   (const_string "vector")
7622                (and (eq_attr "alternative" "2")
7623                     (match_operand 1 "memory_operand" ""))
7624                   (const_string "vector")]
7625               (const_string "direct")))
7626    (set (attr "amdfam10_decode")
7627         (cond [(and (eq_attr "alternative" "0,1")
7628                     (match_operand 1 "memory_operand" ""))
7629                   (const_string "vector")]
7630               (const_string "direct")))
7631    (set_attr "mode" "DI")])
7633 (define_expand "mulsi3"
7634   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7635                    (mult:SI (match_operand:SI 1 "register_operand" "")
7636                             (match_operand:SI 2 "general_operand" "")))
7637               (clobber (reg:CC FLAGS_REG))])]
7638   ""
7639   "")
7641 ;; On AMDFAM10
7642 ;; IMUL reg32, reg32, imm8      Direct
7643 ;; IMUL reg32, mem32, imm8      VectorPath
7644 ;; IMUL reg32, reg32, imm32     Direct
7645 ;; IMUL reg32, mem32, imm32     VectorPath
7646 ;; IMUL reg32, reg32            Direct
7647 ;; IMUL reg32, mem32            Direct
7649 (define_insn "*mulsi3_1"
7650   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7651         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7652                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7653    (clobber (reg:CC FLAGS_REG))]
7654   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7655   "@
7656    imul{l}\t{%2, %1, %0|%0, %1, %2}
7657    imul{l}\t{%2, %1, %0|%0, %1, %2}
7658    imul{l}\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" "SI")])
7677 (define_insn "*mulsi3_1_zext"
7678   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7679         (zero_extend:DI
7680           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7681                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7682    (clobber (reg:CC FLAGS_REG))]
7683   "TARGET_64BIT
7684    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7685   "@
7686    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7687    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7688    imul{l}\t{%2, %k0|%k0, %2}"
7689   [(set_attr "type" "imul")
7690    (set_attr "prefix_0f" "0,0,1")
7691    (set (attr "athlon_decode")
7692         (cond [(eq_attr "cpu" "athlon")
7693                   (const_string "vector")
7694                (eq_attr "alternative" "1")
7695                   (const_string "vector")
7696                (and (eq_attr "alternative" "2")
7697                     (match_operand 1 "memory_operand" ""))
7698                   (const_string "vector")]
7699               (const_string "direct")))
7700    (set (attr "amdfam10_decode")
7701         (cond [(and (eq_attr "alternative" "0,1")
7702                     (match_operand 1 "memory_operand" ""))
7703                   (const_string "vector")]
7704               (const_string "direct")))
7705    (set_attr "mode" "SI")])
7707 (define_expand "mulhi3"
7708   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7709                    (mult:HI (match_operand:HI 1 "register_operand" "")
7710                             (match_operand:HI 2 "general_operand" "")))
7711               (clobber (reg:CC FLAGS_REG))])]
7712   "TARGET_HIMODE_MATH"
7713   "")
7715 ;; On AMDFAM10
7716 ;; IMUL reg16, reg16, imm8      VectorPath
7717 ;; IMUL reg16, mem16, imm8      VectorPath
7718 ;; IMUL reg16, reg16, imm16     VectorPath
7719 ;; IMUL reg16, mem16, imm16     VectorPath
7720 ;; IMUL reg16, reg16            Direct
7721 ;; IMUL reg16, mem16            Direct
7722 (define_insn "*mulhi3_1"
7723   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7724         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7725                  (match_operand:HI 2 "general_operand" "K,n,mr")))
7726    (clobber (reg:CC FLAGS_REG))]
7727   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7728   "@
7729    imul{w}\t{%2, %1, %0|%0, %1, %2}
7730    imul{w}\t{%2, %1, %0|%0, %1, %2}
7731    imul{w}\t{%2, %0|%0, %2}"
7732   [(set_attr "type" "imul")
7733    (set_attr "prefix_0f" "0,0,1")
7734    (set (attr "athlon_decode")
7735         (cond [(eq_attr "cpu" "athlon")
7736                   (const_string "vector")
7737                (eq_attr "alternative" "1,2")
7738                   (const_string "vector")]
7739               (const_string "direct")))
7740    (set (attr "amdfam10_decode")
7741         (cond [(eq_attr "alternative" "0,1")
7742                   (const_string "vector")]
7743               (const_string "direct")))
7744    (set_attr "mode" "HI")])
7746 (define_expand "mulqi3"
7747   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7748                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7749                             (match_operand:QI 2 "register_operand" "")))
7750               (clobber (reg:CC FLAGS_REG))])]
7751   "TARGET_QIMODE_MATH"
7752   "")
7754 ;;On AMDFAM10
7755 ;; MUL reg8     Direct
7756 ;; MUL mem8     Direct
7758 (define_insn "*mulqi3_1"
7759   [(set (match_operand:QI 0 "register_operand" "=a")
7760         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7761                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7762    (clobber (reg:CC FLAGS_REG))]
7763   "TARGET_QIMODE_MATH
7764    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7765   "mul{b}\t%2"
7766   [(set_attr "type" "imul")
7767    (set_attr "length_immediate" "0")
7768    (set (attr "athlon_decode")
7769      (if_then_else (eq_attr "cpu" "athlon")
7770         (const_string "vector")
7771         (const_string "direct")))
7772    (set_attr "amdfam10_decode" "direct")
7773    (set_attr "mode" "QI")])
7775 (define_expand "umulqihi3"
7776   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7777                    (mult:HI (zero_extend:HI
7778                               (match_operand:QI 1 "nonimmediate_operand" ""))
7779                             (zero_extend:HI
7780                               (match_operand:QI 2 "register_operand" ""))))
7781               (clobber (reg:CC FLAGS_REG))])]
7782   "TARGET_QIMODE_MATH"
7783   "")
7785 (define_insn "*umulqihi3_1"
7786   [(set (match_operand:HI 0 "register_operand" "=a")
7787         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7788                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7789    (clobber (reg:CC FLAGS_REG))]
7790   "TARGET_QIMODE_MATH
7791    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7792   "mul{b}\t%2"
7793   [(set_attr "type" "imul")
7794    (set_attr "length_immediate" "0")
7795    (set (attr "athlon_decode")
7796      (if_then_else (eq_attr "cpu" "athlon")
7797         (const_string "vector")
7798         (const_string "direct")))
7799    (set_attr "amdfam10_decode" "direct")
7800    (set_attr "mode" "QI")])
7802 (define_expand "mulqihi3"
7803   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7804                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7805                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7806               (clobber (reg:CC FLAGS_REG))])]
7807   "TARGET_QIMODE_MATH"
7808   "")
7810 (define_insn "*mulqihi3_insn"
7811   [(set (match_operand:HI 0 "register_operand" "=a")
7812         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7813                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7814    (clobber (reg:CC FLAGS_REG))]
7815   "TARGET_QIMODE_MATH
7816    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7817   "imul{b}\t%2"
7818   [(set_attr "type" "imul")
7819    (set_attr "length_immediate" "0")
7820    (set (attr "athlon_decode")
7821      (if_then_else (eq_attr "cpu" "athlon")
7822         (const_string "vector")
7823         (const_string "direct")))
7824    (set_attr "amdfam10_decode" "direct")
7825    (set_attr "mode" "QI")])
7827 (define_expand "umulditi3"
7828   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7829                    (mult:TI (zero_extend:TI
7830                               (match_operand:DI 1 "nonimmediate_operand" ""))
7831                             (zero_extend:TI
7832                               (match_operand:DI 2 "register_operand" ""))))
7833               (clobber (reg:CC FLAGS_REG))])]
7834   "TARGET_64BIT"
7835   "")
7837 (define_insn "*umulditi3_insn"
7838   [(set (match_operand:TI 0 "register_operand" "=A")
7839         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7840                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7841    (clobber (reg:CC FLAGS_REG))]
7842   "TARGET_64BIT
7843    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7844   "mul{q}\t%2"
7845   [(set_attr "type" "imul")
7846    (set_attr "length_immediate" "0")
7847    (set (attr "athlon_decode")
7848      (if_then_else (eq_attr "cpu" "athlon")
7849         (const_string "vector")
7850         (const_string "double")))
7851    (set_attr "amdfam10_decode" "double")
7852    (set_attr "mode" "DI")])
7854 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7855 (define_expand "umulsidi3"
7856   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7857                    (mult:DI (zero_extend:DI
7858                               (match_operand:SI 1 "nonimmediate_operand" ""))
7859                             (zero_extend:DI
7860                               (match_operand:SI 2 "register_operand" ""))))
7861               (clobber (reg:CC FLAGS_REG))])]
7862   "!TARGET_64BIT"
7863   "")
7865 (define_insn "*umulsidi3_insn"
7866   [(set (match_operand:DI 0 "register_operand" "=A")
7867         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7868                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7869    (clobber (reg:CC FLAGS_REG))]
7870   "!TARGET_64BIT
7871    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7872   "mul{l}\t%2"
7873   [(set_attr "type" "imul")
7874    (set_attr "length_immediate" "0")
7875    (set (attr "athlon_decode")
7876      (if_then_else (eq_attr "cpu" "athlon")
7877         (const_string "vector")
7878         (const_string "double")))
7879    (set_attr "amdfam10_decode" "double")
7880    (set_attr "mode" "SI")])
7882 (define_expand "mulditi3"
7883   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7884                    (mult:TI (sign_extend:TI
7885                               (match_operand:DI 1 "nonimmediate_operand" ""))
7886                             (sign_extend:TI
7887                               (match_operand:DI 2 "register_operand" ""))))
7888               (clobber (reg:CC FLAGS_REG))])]
7889   "TARGET_64BIT"
7890   "")
7892 (define_insn "*mulditi3_insn"
7893   [(set (match_operand:TI 0 "register_operand" "=A")
7894         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7895                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7896    (clobber (reg:CC FLAGS_REG))]
7897   "TARGET_64BIT
7898    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7899   "imul{q}\t%2"
7900   [(set_attr "type" "imul")
7901    (set_attr "length_immediate" "0")
7902    (set (attr "athlon_decode")
7903      (if_then_else (eq_attr "cpu" "athlon")
7904         (const_string "vector")
7905         (const_string "double")))
7906    (set_attr "amdfam10_decode" "double")
7907    (set_attr "mode" "DI")])
7909 (define_expand "mulsidi3"
7910   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7911                    (mult:DI (sign_extend:DI
7912                               (match_operand:SI 1 "nonimmediate_operand" ""))
7913                             (sign_extend:DI
7914                               (match_operand:SI 2 "register_operand" ""))))
7915               (clobber (reg:CC FLAGS_REG))])]
7916   "!TARGET_64BIT"
7917   "")
7919 (define_insn "*mulsidi3_insn"
7920   [(set (match_operand:DI 0 "register_operand" "=A")
7921         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7922                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7923    (clobber (reg:CC FLAGS_REG))]
7924   "!TARGET_64BIT
7925    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7926   "imul{l}\t%2"
7927   [(set_attr "type" "imul")
7928    (set_attr "length_immediate" "0")
7929    (set (attr "athlon_decode")
7930      (if_then_else (eq_attr "cpu" "athlon")
7931         (const_string "vector")
7932         (const_string "double")))
7933    (set_attr "amdfam10_decode" "double")
7934    (set_attr "mode" "SI")])
7936 (define_expand "umuldi3_highpart"
7937   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7938                    (truncate:DI
7939                      (lshiftrt:TI
7940                        (mult:TI (zero_extend:TI
7941                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7942                                 (zero_extend:TI
7943                                   (match_operand:DI 2 "register_operand" "")))
7944                        (const_int 64))))
7945               (clobber (match_scratch:DI 3 ""))
7946               (clobber (reg:CC FLAGS_REG))])]
7947   "TARGET_64BIT"
7948   "")
7950 (define_insn "*umuldi3_highpart_rex64"
7951   [(set (match_operand:DI 0 "register_operand" "=d")
7952         (truncate:DI
7953           (lshiftrt:TI
7954             (mult:TI (zero_extend:TI
7955                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7956                      (zero_extend:TI
7957                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7958             (const_int 64))))
7959    (clobber (match_scratch:DI 3 "=1"))
7960    (clobber (reg:CC FLAGS_REG))]
7961   "TARGET_64BIT
7962    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7963   "mul{q}\t%2"
7964   [(set_attr "type" "imul")
7965    (set_attr "length_immediate" "0")
7966    (set (attr "athlon_decode")
7967      (if_then_else (eq_attr "cpu" "athlon")
7968         (const_string "vector")
7969         (const_string "double")))
7970    (set_attr "amdfam10_decode" "double")
7971    (set_attr "mode" "DI")])
7973 (define_expand "umulsi3_highpart"
7974   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7975                    (truncate:SI
7976                      (lshiftrt:DI
7977                        (mult:DI (zero_extend:DI
7978                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7979                                 (zero_extend:DI
7980                                   (match_operand:SI 2 "register_operand" "")))
7981                        (const_int 32))))
7982               (clobber (match_scratch:SI 3 ""))
7983               (clobber (reg:CC FLAGS_REG))])]
7984   ""
7985   "")
7987 (define_insn "*umulsi3_highpart_insn"
7988   [(set (match_operand:SI 0 "register_operand" "=d")
7989         (truncate:SI
7990           (lshiftrt:DI
7991             (mult:DI (zero_extend:DI
7992                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
7993                      (zero_extend:DI
7994                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
7995             (const_int 32))))
7996    (clobber (match_scratch:SI 3 "=1"))
7997    (clobber (reg:CC FLAGS_REG))]
7998   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7999   "mul{l}\t%2"
8000   [(set_attr "type" "imul")
8001    (set_attr "length_immediate" "0")
8002    (set (attr "athlon_decode")
8003      (if_then_else (eq_attr "cpu" "athlon")
8004         (const_string "vector")
8005         (const_string "double")))
8006    (set_attr "amdfam10_decode" "double")
8007    (set_attr "mode" "SI")])
8009 (define_insn "*umulsi3_highpart_zext"
8010   [(set (match_operand:DI 0 "register_operand" "=d")
8011         (zero_extend:DI (truncate:SI
8012           (lshiftrt:DI
8013             (mult:DI (zero_extend:DI
8014                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8015                      (zero_extend:DI
8016                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8017             (const_int 32)))))
8018    (clobber (match_scratch:SI 3 "=1"))
8019    (clobber (reg:CC FLAGS_REG))]
8020   "TARGET_64BIT
8021    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8022   "mul{l}\t%2"
8023   [(set_attr "type" "imul")
8024    (set_attr "length_immediate" "0")
8025    (set (attr "athlon_decode")
8026      (if_then_else (eq_attr "cpu" "athlon")
8027         (const_string "vector")
8028         (const_string "double")))
8029    (set_attr "amdfam10_decode" "double")
8030    (set_attr "mode" "SI")])
8032 (define_expand "smuldi3_highpart"
8033   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8034                    (truncate:DI
8035                      (lshiftrt:TI
8036                        (mult:TI (sign_extend:TI
8037                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8038                                 (sign_extend:TI
8039                                   (match_operand:DI 2 "register_operand" "")))
8040                        (const_int 64))))
8041               (clobber (match_scratch:DI 3 ""))
8042               (clobber (reg:CC FLAGS_REG))])]
8043   "TARGET_64BIT"
8044   "")
8046 (define_insn "*smuldi3_highpart_rex64"
8047   [(set (match_operand:DI 0 "register_operand" "=d")
8048         (truncate:DI
8049           (lshiftrt:TI
8050             (mult:TI (sign_extend:TI
8051                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8052                      (sign_extend:TI
8053                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8054             (const_int 64))))
8055    (clobber (match_scratch:DI 3 "=1"))
8056    (clobber (reg:CC FLAGS_REG))]
8057   "TARGET_64BIT
8058    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8059   "imul{q}\t%2"
8060   [(set_attr "type" "imul")
8061    (set (attr "athlon_decode")
8062      (if_then_else (eq_attr "cpu" "athlon")
8063         (const_string "vector")
8064         (const_string "double")))
8065    (set_attr "amdfam10_decode" "double")
8066    (set_attr "mode" "DI")])
8068 (define_expand "smulsi3_highpart"
8069   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8070                    (truncate:SI
8071                      (lshiftrt:DI
8072                        (mult:DI (sign_extend:DI
8073                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8074                                 (sign_extend:DI
8075                                   (match_operand:SI 2 "register_operand" "")))
8076                        (const_int 32))))
8077               (clobber (match_scratch:SI 3 ""))
8078               (clobber (reg:CC FLAGS_REG))])]
8079   ""
8080   "")
8082 (define_insn "*smulsi3_highpart_insn"
8083   [(set (match_operand:SI 0 "register_operand" "=d")
8084         (truncate:SI
8085           (lshiftrt:DI
8086             (mult:DI (sign_extend:DI
8087                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8088                      (sign_extend:DI
8089                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8090             (const_int 32))))
8091    (clobber (match_scratch:SI 3 "=1"))
8092    (clobber (reg:CC FLAGS_REG))]
8093   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8094   "imul{l}\t%2"
8095   [(set_attr "type" "imul")
8096    (set (attr "athlon_decode")
8097      (if_then_else (eq_attr "cpu" "athlon")
8098         (const_string "vector")
8099         (const_string "double")))
8100    (set_attr "amdfam10_decode" "double")
8101    (set_attr "mode" "SI")])
8103 (define_insn "*smulsi3_highpart_zext"
8104   [(set (match_operand:DI 0 "register_operand" "=d")
8105         (zero_extend:DI (truncate:SI
8106           (lshiftrt:DI
8107             (mult:DI (sign_extend:DI
8108                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8109                      (sign_extend:DI
8110                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8111             (const_int 32)))))
8112    (clobber (match_scratch:SI 3 "=1"))
8113    (clobber (reg:CC FLAGS_REG))]
8114   "TARGET_64BIT
8115    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8116   "imul{l}\t%2"
8117   [(set_attr "type" "imul")
8118    (set (attr "athlon_decode")
8119      (if_then_else (eq_attr "cpu" "athlon")
8120         (const_string "vector")
8121         (const_string "double")))
8122    (set_attr "amdfam10_decode" "double")
8123    (set_attr "mode" "SI")])
8125 ;; The patterns that match these are at the end of this file.
8127 (define_expand "mulxf3"
8128   [(set (match_operand:XF 0 "register_operand" "")
8129         (mult:XF (match_operand:XF 1 "register_operand" "")
8130                  (match_operand:XF 2 "register_operand" "")))]
8131   "TARGET_80387"
8132   "")
8134 (define_expand "mul<mode>3"
8135   [(set (match_operand:MODEF 0 "register_operand" "")
8136         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8137                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8138   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8139   "")
8141 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8144 ;; Divide instructions
8146 (define_insn "divqi3"
8147   [(set (match_operand:QI 0 "register_operand" "=a")
8148         (div:QI (match_operand:HI 1 "register_operand" "0")
8149                 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8150    (clobber (reg:CC FLAGS_REG))]
8151   "TARGET_QIMODE_MATH"
8152   "idiv{b}\t%2"
8153   [(set_attr "type" "idiv")
8154    (set_attr "mode" "QI")])
8156 (define_insn "udivqi3"
8157   [(set (match_operand:QI 0 "register_operand" "=a")
8158         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8159                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8160    (clobber (reg:CC FLAGS_REG))]
8161   "TARGET_QIMODE_MATH"
8162   "div{b}\t%2"
8163   [(set_attr "type" "idiv")
8164    (set_attr "mode" "QI")])
8166 ;; The patterns that match these are at the end of this file.
8168 (define_expand "divxf3"
8169   [(set (match_operand:XF 0 "register_operand" "")
8170         (div:XF (match_operand:XF 1 "register_operand" "")
8171                 (match_operand:XF 2 "register_operand" "")))]
8172   "TARGET_80387"
8173   "")
8175 (define_expand "divdf3"
8176   [(set (match_operand:DF 0 "register_operand" "")
8177         (div:DF (match_operand:DF 1 "register_operand" "")
8178                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8179    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8180    "")
8182 (define_expand "divsf3"
8183   [(set (match_operand:SF 0 "register_operand" "")
8184         (div:SF (match_operand:SF 1 "register_operand" "")
8185                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8186   "TARGET_80387 || TARGET_SSE_MATH"
8188   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8189       && flag_finite_math_only && !flag_trapping_math
8190       && flag_unsafe_math_optimizations)
8191     {
8192       ix86_emit_swdivsf (operands[0], operands[1],
8193                          operands[2], SFmode);
8194       DONE;
8195     }
8198 ;; Remainder instructions.
8200 (define_expand "divmoddi4"
8201   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8202                    (div:DI (match_operand:DI 1 "register_operand" "")
8203                            (match_operand:DI 2 "nonimmediate_operand" "")))
8204               (set (match_operand:DI 3 "register_operand" "")
8205                    (mod:DI (match_dup 1) (match_dup 2)))
8206               (clobber (reg:CC FLAGS_REG))])]
8207   "TARGET_64BIT"
8208   "")
8210 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8211 ;; Penalize eax case slightly because it results in worse scheduling
8212 ;; of code.
8213 (define_insn "*divmoddi4_nocltd_rex64"
8214   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8215         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8216                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8217    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8218         (mod:DI (match_dup 2) (match_dup 3)))
8219    (clobber (reg:CC FLAGS_REG))]
8220   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8221   "#"
8222   [(set_attr "type" "multi")])
8224 (define_insn "*divmoddi4_cltd_rex64"
8225   [(set (match_operand:DI 0 "register_operand" "=a")
8226         (div:DI (match_operand:DI 2 "register_operand" "a")
8227                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8228    (set (match_operand:DI 1 "register_operand" "=&d")
8229         (mod:DI (match_dup 2) (match_dup 3)))
8230    (clobber (reg:CC FLAGS_REG))]
8231   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8232   "#"
8233   [(set_attr "type" "multi")])
8235 (define_insn "*divmoddi_noext_rex64"
8236   [(set (match_operand:DI 0 "register_operand" "=a")
8237         (div:DI (match_operand:DI 1 "register_operand" "0")
8238                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8239    (set (match_operand:DI 3 "register_operand" "=d")
8240         (mod:DI (match_dup 1) (match_dup 2)))
8241    (use (match_operand:DI 4 "register_operand" "3"))
8242    (clobber (reg:CC FLAGS_REG))]
8243   "TARGET_64BIT"
8244   "idiv{q}\t%2"
8245   [(set_attr "type" "idiv")
8246    (set_attr "mode" "DI")])
8248 (define_split
8249   [(set (match_operand:DI 0 "register_operand" "")
8250         (div:DI (match_operand:DI 1 "register_operand" "")
8251                 (match_operand:DI 2 "nonimmediate_operand" "")))
8252    (set (match_operand:DI 3 "register_operand" "")
8253         (mod:DI (match_dup 1) (match_dup 2)))
8254    (clobber (reg:CC FLAGS_REG))]
8255   "TARGET_64BIT && reload_completed"
8256   [(parallel [(set (match_dup 3)
8257                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8258               (clobber (reg:CC FLAGS_REG))])
8259    (parallel [(set (match_dup 0)
8260                    (div:DI (reg:DI 0) (match_dup 2)))
8261               (set (match_dup 3)
8262                    (mod:DI (reg:DI 0) (match_dup 2)))
8263               (use (match_dup 3))
8264               (clobber (reg:CC FLAGS_REG))])]
8266   /* Avoid use of cltd in favor of a mov+shift.  */
8267   if (!TARGET_USE_CLTD && !optimize_size)
8268     {
8269       if (true_regnum (operands[1]))
8270         emit_move_insn (operands[0], operands[1]);
8271       else
8272         emit_move_insn (operands[3], operands[1]);
8273       operands[4] = operands[3];
8274     }
8275   else
8276     {
8277       gcc_assert (!true_regnum (operands[1]));
8278       operands[4] = operands[1];
8279     }
8283 (define_expand "divmodsi4"
8284   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8285                    (div:SI (match_operand:SI 1 "register_operand" "")
8286                            (match_operand:SI 2 "nonimmediate_operand" "")))
8287               (set (match_operand:SI 3 "register_operand" "")
8288                    (mod:SI (match_dup 1) (match_dup 2)))
8289               (clobber (reg:CC FLAGS_REG))])]
8290   ""
8291   "")
8293 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8294 ;; Penalize eax case slightly because it results in worse scheduling
8295 ;; of code.
8296 (define_insn "*divmodsi4_nocltd"
8297   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8298         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8299                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8300    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8301         (mod:SI (match_dup 2) (match_dup 3)))
8302    (clobber (reg:CC FLAGS_REG))]
8303   "!optimize_size && !TARGET_USE_CLTD"
8304   "#"
8305   [(set_attr "type" "multi")])
8307 (define_insn "*divmodsi4_cltd"
8308   [(set (match_operand:SI 0 "register_operand" "=a")
8309         (div:SI (match_operand:SI 2 "register_operand" "a")
8310                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8311    (set (match_operand:SI 1 "register_operand" "=&d")
8312         (mod:SI (match_dup 2) (match_dup 3)))
8313    (clobber (reg:CC FLAGS_REG))]
8314   "optimize_size || TARGET_USE_CLTD"
8315   "#"
8316   [(set_attr "type" "multi")])
8318 (define_insn "*divmodsi_noext"
8319   [(set (match_operand:SI 0 "register_operand" "=a")
8320         (div:SI (match_operand:SI 1 "register_operand" "0")
8321                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8322    (set (match_operand:SI 3 "register_operand" "=d")
8323         (mod:SI (match_dup 1) (match_dup 2)))
8324    (use (match_operand:SI 4 "register_operand" "3"))
8325    (clobber (reg:CC FLAGS_REG))]
8326   ""
8327   "idiv{l}\t%2"
8328   [(set_attr "type" "idiv")
8329    (set_attr "mode" "SI")])
8331 (define_split
8332   [(set (match_operand:SI 0 "register_operand" "")
8333         (div:SI (match_operand:SI 1 "register_operand" "")
8334                 (match_operand:SI 2 "nonimmediate_operand" "")))
8335    (set (match_operand:SI 3 "register_operand" "")
8336         (mod:SI (match_dup 1) (match_dup 2)))
8337    (clobber (reg:CC FLAGS_REG))]
8338   "reload_completed"
8339   [(parallel [(set (match_dup 3)
8340                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8341               (clobber (reg:CC FLAGS_REG))])
8342    (parallel [(set (match_dup 0)
8343                    (div:SI (reg:SI 0) (match_dup 2)))
8344               (set (match_dup 3)
8345                    (mod:SI (reg:SI 0) (match_dup 2)))
8346               (use (match_dup 3))
8347               (clobber (reg:CC FLAGS_REG))])]
8349   /* Avoid use of cltd in favor of a mov+shift.  */
8350   if (!TARGET_USE_CLTD && !optimize_size)
8351     {
8352       if (true_regnum (operands[1]))
8353         emit_move_insn (operands[0], operands[1]);
8354       else
8355         emit_move_insn (operands[3], operands[1]);
8356       operands[4] = operands[3];
8357     }
8358   else
8359     {
8360       gcc_assert (!true_regnum (operands[1]));
8361       operands[4] = operands[1];
8362     }
8364 ;; %%% Split me.
8365 (define_insn "divmodhi4"
8366   [(set (match_operand:HI 0 "register_operand" "=a")
8367         (div:HI (match_operand:HI 1 "register_operand" "0")
8368                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8369    (set (match_operand:HI 3 "register_operand" "=&d")
8370         (mod:HI (match_dup 1) (match_dup 2)))
8371    (clobber (reg:CC FLAGS_REG))]
8372   "TARGET_HIMODE_MATH"
8373   "cwtd\;idiv{w}\t%2"
8374   [(set_attr "type" "multi")
8375    (set_attr "length_immediate" "0")
8376    (set_attr "mode" "SI")])
8378 (define_insn "udivmoddi4"
8379   [(set (match_operand:DI 0 "register_operand" "=a")
8380         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8381                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8382    (set (match_operand:DI 3 "register_operand" "=&d")
8383         (umod:DI (match_dup 1) (match_dup 2)))
8384    (clobber (reg:CC FLAGS_REG))]
8385   "TARGET_64BIT"
8386   "xor{q}\t%3, %3\;div{q}\t%2"
8387   [(set_attr "type" "multi")
8388    (set_attr "length_immediate" "0")
8389    (set_attr "mode" "DI")])
8391 (define_insn "*udivmoddi4_noext"
8392   [(set (match_operand:DI 0 "register_operand" "=a")
8393         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8394                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8395    (set (match_operand:DI 3 "register_operand" "=d")
8396         (umod:DI (match_dup 1) (match_dup 2)))
8397    (use (match_dup 3))
8398    (clobber (reg:CC FLAGS_REG))]
8399   "TARGET_64BIT"
8400   "div{q}\t%2"
8401   [(set_attr "type" "idiv")
8402    (set_attr "mode" "DI")])
8404 (define_split
8405   [(set (match_operand:DI 0 "register_operand" "")
8406         (udiv:DI (match_operand:DI 1 "register_operand" "")
8407                  (match_operand:DI 2 "nonimmediate_operand" "")))
8408    (set (match_operand:DI 3 "register_operand" "")
8409         (umod:DI (match_dup 1) (match_dup 2)))
8410    (clobber (reg:CC FLAGS_REG))]
8411   "TARGET_64BIT && reload_completed"
8412   [(set (match_dup 3) (const_int 0))
8413    (parallel [(set (match_dup 0)
8414                    (udiv:DI (match_dup 1) (match_dup 2)))
8415               (set (match_dup 3)
8416                    (umod:DI (match_dup 1) (match_dup 2)))
8417               (use (match_dup 3))
8418               (clobber (reg:CC FLAGS_REG))])]
8419   "")
8421 (define_insn "udivmodsi4"
8422   [(set (match_operand:SI 0 "register_operand" "=a")
8423         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8424                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8425    (set (match_operand:SI 3 "register_operand" "=&d")
8426         (umod:SI (match_dup 1) (match_dup 2)))
8427    (clobber (reg:CC FLAGS_REG))]
8428   ""
8429   "xor{l}\t%3, %3\;div{l}\t%2"
8430   [(set_attr "type" "multi")
8431    (set_attr "length_immediate" "0")
8432    (set_attr "mode" "SI")])
8434 (define_insn "*udivmodsi4_noext"
8435   [(set (match_operand:SI 0 "register_operand" "=a")
8436         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8437                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8438    (set (match_operand:SI 3 "register_operand" "=d")
8439         (umod:SI (match_dup 1) (match_dup 2)))
8440    (use (match_dup 3))
8441    (clobber (reg:CC FLAGS_REG))]
8442   ""
8443   "div{l}\t%2"
8444   [(set_attr "type" "idiv")
8445    (set_attr "mode" "SI")])
8447 (define_split
8448   [(set (match_operand:SI 0 "register_operand" "")
8449         (udiv:SI (match_operand:SI 1 "register_operand" "")
8450                  (match_operand:SI 2 "nonimmediate_operand" "")))
8451    (set (match_operand:SI 3 "register_operand" "")
8452         (umod:SI (match_dup 1) (match_dup 2)))
8453    (clobber (reg:CC FLAGS_REG))]
8454   "reload_completed"
8455   [(set (match_dup 3) (const_int 0))
8456    (parallel [(set (match_dup 0)
8457                    (udiv:SI (match_dup 1) (match_dup 2)))
8458               (set (match_dup 3)
8459                    (umod:SI (match_dup 1) (match_dup 2)))
8460               (use (match_dup 3))
8461               (clobber (reg:CC FLAGS_REG))])]
8462   "")
8464 (define_expand "udivmodhi4"
8465   [(set (match_dup 4) (const_int 0))
8466    (parallel [(set (match_operand:HI 0 "register_operand" "")
8467                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8468                             (match_operand:HI 2 "nonimmediate_operand" "")))
8469               (set (match_operand:HI 3 "register_operand" "")
8470                    (umod:HI (match_dup 1) (match_dup 2)))
8471               (use (match_dup 4))
8472               (clobber (reg:CC FLAGS_REG))])]
8473   "TARGET_HIMODE_MATH"
8474   "operands[4] = gen_reg_rtx (HImode);")
8476 (define_insn "*udivmodhi_noext"
8477   [(set (match_operand:HI 0 "register_operand" "=a")
8478         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8479                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8480    (set (match_operand:HI 3 "register_operand" "=d")
8481         (umod:HI (match_dup 1) (match_dup 2)))
8482    (use (match_operand:HI 4 "register_operand" "3"))
8483    (clobber (reg:CC FLAGS_REG))]
8484   ""
8485   "div{w}\t%2"
8486   [(set_attr "type" "idiv")
8487    (set_attr "mode" "HI")])
8489 ;; We cannot use div/idiv for double division, because it causes
8490 ;; "division by zero" on the overflow and that's not what we expect
8491 ;; from truncate.  Because true (non truncating) double division is
8492 ;; never generated, we can't create this insn anyway.
8494 ;(define_insn ""
8495 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8496 ;       (truncate:SI
8497 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8498 ;                  (zero_extend:DI
8499 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8500 ;   (set (match_operand:SI 3 "register_operand" "=d")
8501 ;       (truncate:SI
8502 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8503 ;   (clobber (reg:CC FLAGS_REG))]
8504 ;  ""
8505 ;  "div{l}\t{%2, %0|%0, %2}"
8506 ;  [(set_attr "type" "idiv")])
8508 ;;- Logical AND instructions
8510 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8511 ;; Note that this excludes ah.
8513 (define_insn "*testdi_1_rex64"
8514   [(set (reg FLAGS_REG)
8515         (compare
8516           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8517                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8518           (const_int 0)))]
8519   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8520    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8521   "@
8522    test{l}\t{%k1, %k0|%k0, %k1}
8523    test{l}\t{%k1, %k0|%k0, %k1}
8524    test{q}\t{%1, %0|%0, %1}
8525    test{q}\t{%1, %0|%0, %1}
8526    test{q}\t{%1, %0|%0, %1}"
8527   [(set_attr "type" "test")
8528    (set_attr "modrm" "0,1,0,1,1")
8529    (set_attr "mode" "SI,SI,DI,DI,DI")
8530    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8532 (define_insn "testsi_1"
8533   [(set (reg FLAGS_REG)
8534         (compare
8535           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8536                   (match_operand:SI 1 "general_operand" "i,i,ri"))
8537           (const_int 0)))]
8538   "ix86_match_ccmode (insn, CCNOmode)
8539    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8540   "test{l}\t{%1, %0|%0, %1}"
8541   [(set_attr "type" "test")
8542    (set_attr "modrm" "0,1,1")
8543    (set_attr "mode" "SI")
8544    (set_attr "pent_pair" "uv,np,uv")])
8546 (define_expand "testsi_ccno_1"
8547   [(set (reg:CCNO FLAGS_REG)
8548         (compare:CCNO
8549           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8550                   (match_operand:SI 1 "nonmemory_operand" ""))
8551           (const_int 0)))]
8552   ""
8553   "")
8555 (define_insn "*testhi_1"
8556   [(set (reg FLAGS_REG)
8557         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8558                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8559                  (const_int 0)))]
8560   "ix86_match_ccmode (insn, CCNOmode)
8561    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8562   "test{w}\t{%1, %0|%0, %1}"
8563   [(set_attr "type" "test")
8564    (set_attr "modrm" "0,1,1")
8565    (set_attr "mode" "HI")
8566    (set_attr "pent_pair" "uv,np,uv")])
8568 (define_expand "testqi_ccz_1"
8569   [(set (reg:CCZ FLAGS_REG)
8570         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8571                              (match_operand:QI 1 "nonmemory_operand" ""))
8572                  (const_int 0)))]
8573   ""
8574   "")
8576 (define_insn "*testqi_1_maybe_si"
8577   [(set (reg FLAGS_REG)
8578         (compare
8579           (and:QI
8580             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8581             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8582           (const_int 0)))]
8583    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8584     && ix86_match_ccmode (insn,
8585                          CONST_INT_P (operands[1])
8586                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8588   if (which_alternative == 3)
8589     {
8590       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8591         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8592       return "test{l}\t{%1, %k0|%k0, %1}";
8593     }
8594   return "test{b}\t{%1, %0|%0, %1}";
8596   [(set_attr "type" "test")
8597    (set_attr "modrm" "0,1,1,1")
8598    (set_attr "mode" "QI,QI,QI,SI")
8599    (set_attr "pent_pair" "uv,np,uv,np")])
8601 (define_insn "*testqi_1"
8602   [(set (reg FLAGS_REG)
8603         (compare
8604           (and:QI
8605             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8606             (match_operand:QI 1 "general_operand" "n,n,qn"))
8607           (const_int 0)))]
8608   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8609    && ix86_match_ccmode (insn, CCNOmode)"
8610   "test{b}\t{%1, %0|%0, %1}"
8611   [(set_attr "type" "test")
8612    (set_attr "modrm" "0,1,1")
8613    (set_attr "mode" "QI")
8614    (set_attr "pent_pair" "uv,np,uv")])
8616 (define_expand "testqi_ext_ccno_0"
8617   [(set (reg:CCNO FLAGS_REG)
8618         (compare:CCNO
8619           (and:SI
8620             (zero_extract:SI
8621               (match_operand 0 "ext_register_operand" "")
8622               (const_int 8)
8623               (const_int 8))
8624             (match_operand 1 "const_int_operand" ""))
8625           (const_int 0)))]
8626   ""
8627   "")
8629 (define_insn "*testqi_ext_0"
8630   [(set (reg FLAGS_REG)
8631         (compare
8632           (and:SI
8633             (zero_extract:SI
8634               (match_operand 0 "ext_register_operand" "Q")
8635               (const_int 8)
8636               (const_int 8))
8637             (match_operand 1 "const_int_operand" "n"))
8638           (const_int 0)))]
8639   "ix86_match_ccmode (insn, CCNOmode)"
8640   "test{b}\t{%1, %h0|%h0, %1}"
8641   [(set_attr "type" "test")
8642    (set_attr "mode" "QI")
8643    (set_attr "length_immediate" "1")
8644    (set_attr "pent_pair" "np")])
8646 (define_insn "*testqi_ext_1"
8647   [(set (reg FLAGS_REG)
8648         (compare
8649           (and:SI
8650             (zero_extract:SI
8651               (match_operand 0 "ext_register_operand" "Q")
8652               (const_int 8)
8653               (const_int 8))
8654             (zero_extend:SI
8655               (match_operand:QI 1 "general_operand" "Qm")))
8656           (const_int 0)))]
8657   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8658    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8659   "test{b}\t{%1, %h0|%h0, %1}"
8660   [(set_attr "type" "test")
8661    (set_attr "mode" "QI")])
8663 (define_insn "*testqi_ext_1_rex64"
8664   [(set (reg FLAGS_REG)
8665         (compare
8666           (and:SI
8667             (zero_extract:SI
8668               (match_operand 0 "ext_register_operand" "Q")
8669               (const_int 8)
8670               (const_int 8))
8671             (zero_extend:SI
8672               (match_operand:QI 1 "register_operand" "Q")))
8673           (const_int 0)))]
8674   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8675   "test{b}\t{%1, %h0|%h0, %1}"
8676   [(set_attr "type" "test")
8677    (set_attr "mode" "QI")])
8679 (define_insn "*testqi_ext_2"
8680   [(set (reg FLAGS_REG)
8681         (compare
8682           (and:SI
8683             (zero_extract:SI
8684               (match_operand 0 "ext_register_operand" "Q")
8685               (const_int 8)
8686               (const_int 8))
8687             (zero_extract:SI
8688               (match_operand 1 "ext_register_operand" "Q")
8689               (const_int 8)
8690               (const_int 8)))
8691           (const_int 0)))]
8692   "ix86_match_ccmode (insn, CCNOmode)"
8693   "test{b}\t{%h1, %h0|%h0, %h1}"
8694   [(set_attr "type" "test")
8695    (set_attr "mode" "QI")])
8697 ;; Combine likes to form bit extractions for some tests.  Humor it.
8698 (define_insn "*testqi_ext_3"
8699   [(set (reg FLAGS_REG)
8700         (compare (zero_extract:SI
8701                    (match_operand 0 "nonimmediate_operand" "rm")
8702                    (match_operand:SI 1 "const_int_operand" "")
8703                    (match_operand:SI 2 "const_int_operand" ""))
8704                  (const_int 0)))]
8705   "ix86_match_ccmode (insn, CCNOmode)
8706    && INTVAL (operands[1]) > 0
8707    && INTVAL (operands[2]) >= 0
8708    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8709    && (GET_MODE (operands[0]) == SImode
8710        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8711        || GET_MODE (operands[0]) == HImode
8712        || GET_MODE (operands[0]) == QImode)"
8713   "#")
8715 (define_insn "*testqi_ext_3_rex64"
8716   [(set (reg FLAGS_REG)
8717         (compare (zero_extract:DI
8718                    (match_operand 0 "nonimmediate_operand" "rm")
8719                    (match_operand:DI 1 "const_int_operand" "")
8720                    (match_operand:DI 2 "const_int_operand" ""))
8721                  (const_int 0)))]
8722   "TARGET_64BIT
8723    && ix86_match_ccmode (insn, CCNOmode)
8724    && INTVAL (operands[1]) > 0
8725    && INTVAL (operands[2]) >= 0
8726    /* Ensure that resulting mask is zero or sign extended operand.  */
8727    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8728        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8729            && INTVAL (operands[1]) > 32))
8730    && (GET_MODE (operands[0]) == SImode
8731        || GET_MODE (operands[0]) == DImode
8732        || GET_MODE (operands[0]) == HImode
8733        || GET_MODE (operands[0]) == QImode)"
8734   "#")
8736 (define_split
8737   [(set (match_operand 0 "flags_reg_operand" "")
8738         (match_operator 1 "compare_operator"
8739           [(zero_extract
8740              (match_operand 2 "nonimmediate_operand" "")
8741              (match_operand 3 "const_int_operand" "")
8742              (match_operand 4 "const_int_operand" ""))
8743            (const_int 0)]))]
8744   "ix86_match_ccmode (insn, CCNOmode)"
8745   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8747   rtx val = operands[2];
8748   HOST_WIDE_INT len = INTVAL (operands[3]);
8749   HOST_WIDE_INT pos = INTVAL (operands[4]);
8750   HOST_WIDE_INT mask;
8751   enum machine_mode mode, submode;
8753   mode = GET_MODE (val);
8754   if (MEM_P (val))
8755     {
8756       /* ??? Combine likes to put non-volatile mem extractions in QImode
8757          no matter the size of the test.  So find a mode that works.  */
8758       if (! MEM_VOLATILE_P (val))
8759         {
8760           mode = smallest_mode_for_size (pos + len, MODE_INT);
8761           val = adjust_address (val, mode, 0);
8762         }
8763     }
8764   else if (GET_CODE (val) == SUBREG
8765            && (submode = GET_MODE (SUBREG_REG (val)),
8766                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8767            && pos + len <= GET_MODE_BITSIZE (submode))
8768     {
8769       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8770       mode = submode;
8771       val = SUBREG_REG (val);
8772     }
8773   else if (mode == HImode && pos + len <= 8)
8774     {
8775       /* Small HImode tests can be converted to QImode.  */
8776       mode = QImode;
8777       val = gen_lowpart (QImode, val);
8778     }
8780   if (len == HOST_BITS_PER_WIDE_INT)
8781     mask = -1;
8782   else
8783     mask = ((HOST_WIDE_INT)1 << len) - 1;
8784   mask <<= pos;
8786   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8789 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8790 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8791 ;; this is relatively important trick.
8792 ;; Do the conversion only post-reload to avoid limiting of the register class
8793 ;; to QI regs.
8794 (define_split
8795   [(set (match_operand 0 "flags_reg_operand" "")
8796         (match_operator 1 "compare_operator"
8797           [(and (match_operand 2 "register_operand" "")
8798                 (match_operand 3 "const_int_operand" ""))
8799            (const_int 0)]))]
8800    "reload_completed
8801     && QI_REG_P (operands[2])
8802     && GET_MODE (operands[2]) != QImode
8803     && ((ix86_match_ccmode (insn, CCZmode)
8804          && !(INTVAL (operands[3]) & ~(255 << 8)))
8805         || (ix86_match_ccmode (insn, CCNOmode)
8806             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8807   [(set (match_dup 0)
8808         (match_op_dup 1
8809           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8810                    (match_dup 3))
8811            (const_int 0)]))]
8812   "operands[2] = gen_lowpart (SImode, operands[2]);
8813    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8815 (define_split
8816   [(set (match_operand 0 "flags_reg_operand" "")
8817         (match_operator 1 "compare_operator"
8818           [(and (match_operand 2 "nonimmediate_operand" "")
8819                 (match_operand 3 "const_int_operand" ""))
8820            (const_int 0)]))]
8821    "reload_completed
8822     && GET_MODE (operands[2]) != QImode
8823     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8824     && ((ix86_match_ccmode (insn, CCZmode)
8825          && !(INTVAL (operands[3]) & ~255))
8826         || (ix86_match_ccmode (insn, CCNOmode)
8827             && !(INTVAL (operands[3]) & ~127)))"
8828   [(set (match_dup 0)
8829         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8830                          (const_int 0)]))]
8831   "operands[2] = gen_lowpart (QImode, operands[2]);
8832    operands[3] = gen_lowpart (QImode, operands[3]);")
8835 ;; %%% This used to optimize known byte-wide and operations to memory,
8836 ;; and sometimes to QImode registers.  If this is considered useful,
8837 ;; it should be done with splitters.
8839 (define_expand "anddi3"
8840   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8841         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8842                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
8843   "TARGET_64BIT"
8844   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8846 (define_insn "*anddi_1_rex64"
8847   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8848         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8849                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8850    (clobber (reg:CC FLAGS_REG))]
8851   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8853   switch (get_attr_type (insn))
8854     {
8855     case TYPE_IMOVX:
8856       {
8857         enum machine_mode mode;
8859         gcc_assert (CONST_INT_P (operands[2]));
8860         if (INTVAL (operands[2]) == 0xff)
8861           mode = QImode;
8862         else
8863           {
8864             gcc_assert (INTVAL (operands[2]) == 0xffff);
8865             mode = HImode;
8866           }
8868         operands[1] = gen_lowpart (mode, operands[1]);
8869         if (mode == QImode)
8870           return "movz{bq|x}\t{%1,%0|%0, %1}";
8871         else
8872           return "movz{wq|x}\t{%1,%0|%0, %1}";
8873       }
8875     default:
8876       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8877       if (get_attr_mode (insn) == MODE_SI)
8878         return "and{l}\t{%k2, %k0|%k0, %k2}";
8879       else
8880         return "and{q}\t{%2, %0|%0, %2}";
8881     }
8883   [(set_attr "type" "alu,alu,alu,imovx")
8884    (set_attr "length_immediate" "*,*,*,0")
8885    (set_attr "mode" "SI,DI,DI,DI")])
8887 (define_insn "*anddi_2"
8888   [(set (reg FLAGS_REG)
8889         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8890                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8891                  (const_int 0)))
8892    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8893         (and:DI (match_dup 1) (match_dup 2)))]
8894   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8895    && ix86_binary_operator_ok (AND, DImode, operands)"
8896   "@
8897    and{l}\t{%k2, %k0|%k0, %k2}
8898    and{q}\t{%2, %0|%0, %2}
8899    and{q}\t{%2, %0|%0, %2}"
8900   [(set_attr "type" "alu")
8901    (set_attr "mode" "SI,DI,DI")])
8903 (define_expand "andsi3"
8904   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8905         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8906                 (match_operand:SI 2 "general_operand" "")))]
8907   ""
8908   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8910 (define_insn "*andsi_1"
8911   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8912         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8913                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8914    (clobber (reg:CC FLAGS_REG))]
8915   "ix86_binary_operator_ok (AND, SImode, operands)"
8917   switch (get_attr_type (insn))
8918     {
8919     case TYPE_IMOVX:
8920       {
8921         enum machine_mode mode;
8923         gcc_assert (CONST_INT_P (operands[2]));
8924         if (INTVAL (operands[2]) == 0xff)
8925           mode = QImode;
8926         else
8927           {
8928             gcc_assert (INTVAL (operands[2]) == 0xffff);
8929             mode = HImode;
8930           }
8932         operands[1] = gen_lowpart (mode, operands[1]);
8933         if (mode == QImode)
8934           return "movz{bl|x}\t{%1,%0|%0, %1}";
8935         else
8936           return "movz{wl|x}\t{%1,%0|%0, %1}";
8937       }
8939     default:
8940       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8941       return "and{l}\t{%2, %0|%0, %2}";
8942     }
8944   [(set_attr "type" "alu,alu,imovx")
8945    (set_attr "length_immediate" "*,*,0")
8946    (set_attr "mode" "SI")])
8948 (define_split
8949   [(set (match_operand 0 "register_operand" "")
8950         (and (match_dup 0)
8951              (const_int -65536)))
8952    (clobber (reg:CC FLAGS_REG))]
8953   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8954   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8955   "operands[1] = gen_lowpart (HImode, operands[0]);")
8957 (define_split
8958   [(set (match_operand 0 "ext_register_operand" "")
8959         (and (match_dup 0)
8960              (const_int -256)))
8961    (clobber (reg:CC FLAGS_REG))]
8962   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8963   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8964   "operands[1] = gen_lowpart (QImode, operands[0]);")
8966 (define_split
8967   [(set (match_operand 0 "ext_register_operand" "")
8968         (and (match_dup 0)
8969              (const_int -65281)))
8970    (clobber (reg:CC FLAGS_REG))]
8971   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8972   [(parallel [(set (zero_extract:SI (match_dup 0)
8973                                     (const_int 8)
8974                                     (const_int 8))
8975                    (xor:SI
8976                      (zero_extract:SI (match_dup 0)
8977                                       (const_int 8)
8978                                       (const_int 8))
8979                      (zero_extract:SI (match_dup 0)
8980                                       (const_int 8)
8981                                       (const_int 8))))
8982               (clobber (reg:CC FLAGS_REG))])]
8983   "operands[0] = gen_lowpart (SImode, operands[0]);")
8985 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8986 (define_insn "*andsi_1_zext"
8987   [(set (match_operand:DI 0 "register_operand" "=r")
8988         (zero_extend:DI
8989           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8990                   (match_operand:SI 2 "general_operand" "g"))))
8991    (clobber (reg:CC FLAGS_REG))]
8992   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8993   "and{l}\t{%2, %k0|%k0, %2}"
8994   [(set_attr "type" "alu")
8995    (set_attr "mode" "SI")])
8997 (define_insn "*andsi_2"
8998   [(set (reg FLAGS_REG)
8999         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9000                          (match_operand:SI 2 "general_operand" "g,ri"))
9001                  (const_int 0)))
9002    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9003         (and:SI (match_dup 1) (match_dup 2)))]
9004   "ix86_match_ccmode (insn, CCNOmode)
9005    && ix86_binary_operator_ok (AND, SImode, operands)"
9006   "and{l}\t{%2, %0|%0, %2}"
9007   [(set_attr "type" "alu")
9008    (set_attr "mode" "SI")])
9010 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9011 (define_insn "*andsi_2_zext"
9012   [(set (reg FLAGS_REG)
9013         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9014                          (match_operand:SI 2 "general_operand" "g"))
9015                  (const_int 0)))
9016    (set (match_operand:DI 0 "register_operand" "=r")
9017         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9018   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9019    && ix86_binary_operator_ok (AND, SImode, operands)"
9020   "and{l}\t{%2, %k0|%k0, %2}"
9021   [(set_attr "type" "alu")
9022    (set_attr "mode" "SI")])
9024 (define_expand "andhi3"
9025   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9026         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9027                 (match_operand:HI 2 "general_operand" "")))]
9028   "TARGET_HIMODE_MATH"
9029   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9031 (define_insn "*andhi_1"
9032   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9033         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9034                 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9035    (clobber (reg:CC FLAGS_REG))]
9036   "ix86_binary_operator_ok (AND, HImode, operands)"
9038   switch (get_attr_type (insn))
9039     {
9040     case TYPE_IMOVX:
9041       gcc_assert (CONST_INT_P (operands[2]));
9042       gcc_assert (INTVAL (operands[2]) == 0xff);
9043       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9045     default:
9046       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9048       return "and{w}\t{%2, %0|%0, %2}";
9049     }
9051   [(set_attr "type" "alu,alu,imovx")
9052    (set_attr "length_immediate" "*,*,0")
9053    (set_attr "mode" "HI,HI,SI")])
9055 (define_insn "*andhi_2"
9056   [(set (reg FLAGS_REG)
9057         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9058                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9059                  (const_int 0)))
9060    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9061         (and:HI (match_dup 1) (match_dup 2)))]
9062   "ix86_match_ccmode (insn, CCNOmode)
9063    && ix86_binary_operator_ok (AND, HImode, operands)"
9064   "and{w}\t{%2, %0|%0, %2}"
9065   [(set_attr "type" "alu")
9066    (set_attr "mode" "HI")])
9068 (define_expand "andqi3"
9069   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9070         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9071                 (match_operand:QI 2 "general_operand" "")))]
9072   "TARGET_QIMODE_MATH"
9073   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9075 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9076 (define_insn "*andqi_1"
9077   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9078         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9079                 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9080    (clobber (reg:CC FLAGS_REG))]
9081   "ix86_binary_operator_ok (AND, QImode, operands)"
9082   "@
9083    and{b}\t{%2, %0|%0, %2}
9084    and{b}\t{%2, %0|%0, %2}
9085    and{l}\t{%k2, %k0|%k0, %k2}"
9086   [(set_attr "type" "alu")
9087    (set_attr "mode" "QI,QI,SI")])
9089 (define_insn "*andqi_1_slp"
9090   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9091         (and:QI (match_dup 0)
9092                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9093    (clobber (reg:CC FLAGS_REG))]
9094   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9095    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9096   "and{b}\t{%1, %0|%0, %1}"
9097   [(set_attr "type" "alu1")
9098    (set_attr "mode" "QI")])
9100 (define_insn "*andqi_2_maybe_si"
9101   [(set (reg FLAGS_REG)
9102         (compare (and:QI
9103                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9104                       (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9105                  (const_int 0)))
9106    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9107         (and:QI (match_dup 1) (match_dup 2)))]
9108   "ix86_binary_operator_ok (AND, QImode, operands)
9109    && ix86_match_ccmode (insn,
9110                          CONST_INT_P (operands[2])
9111                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9113   if (which_alternative == 2)
9114     {
9115       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9116         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9117       return "and{l}\t{%2, %k0|%k0, %2}";
9118     }
9119   return "and{b}\t{%2, %0|%0, %2}";
9121   [(set_attr "type" "alu")
9122    (set_attr "mode" "QI,QI,SI")])
9124 (define_insn "*andqi_2"
9125   [(set (reg FLAGS_REG)
9126         (compare (and:QI
9127                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9128                    (match_operand:QI 2 "general_operand" "qmn,qn"))
9129                  (const_int 0)))
9130    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9131         (and:QI (match_dup 1) (match_dup 2)))]
9132   "ix86_match_ccmode (insn, CCNOmode)
9133    && ix86_binary_operator_ok (AND, QImode, operands)"
9134   "and{b}\t{%2, %0|%0, %2}"
9135   [(set_attr "type" "alu")
9136    (set_attr "mode" "QI")])
9138 (define_insn "*andqi_2_slp"
9139   [(set (reg FLAGS_REG)
9140         (compare (and:QI
9141                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9142                    (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9143                  (const_int 0)))
9144    (set (strict_low_part (match_dup 0))
9145         (and:QI (match_dup 0) (match_dup 1)))]
9146   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9147    && ix86_match_ccmode (insn, CCNOmode)
9148    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9149   "and{b}\t{%1, %0|%0, %1}"
9150   [(set_attr "type" "alu1")
9151    (set_attr "mode" "QI")])
9153 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9154 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9155 ;; for a QImode operand, which of course failed.
9157 (define_insn "andqi_ext_0"
9158   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9159                          (const_int 8)
9160                          (const_int 8))
9161         (and:SI
9162           (zero_extract:SI
9163             (match_operand 1 "ext_register_operand" "0")
9164             (const_int 8)
9165             (const_int 8))
9166           (match_operand 2 "const_int_operand" "n")))
9167    (clobber (reg:CC FLAGS_REG))]
9168   ""
9169   "and{b}\t{%2, %h0|%h0, %2}"
9170   [(set_attr "type" "alu")
9171    (set_attr "length_immediate" "1")
9172    (set_attr "mode" "QI")])
9174 ;; Generated by peephole translating test to and.  This shows up
9175 ;; often in fp comparisons.
9177 (define_insn "*andqi_ext_0_cc"
9178   [(set (reg FLAGS_REG)
9179         (compare
9180           (and:SI
9181             (zero_extract:SI
9182               (match_operand 1 "ext_register_operand" "0")
9183               (const_int 8)
9184               (const_int 8))
9185             (match_operand 2 "const_int_operand" "n"))
9186           (const_int 0)))
9187    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9188                          (const_int 8)
9189                          (const_int 8))
9190         (and:SI
9191           (zero_extract:SI
9192             (match_dup 1)
9193             (const_int 8)
9194             (const_int 8))
9195           (match_dup 2)))]
9196   "ix86_match_ccmode (insn, CCNOmode)"
9197   "and{b}\t{%2, %h0|%h0, %2}"
9198   [(set_attr "type" "alu")
9199    (set_attr "length_immediate" "1")
9200    (set_attr "mode" "QI")])
9202 (define_insn "*andqi_ext_1"
9203   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9204                          (const_int 8)
9205                          (const_int 8))
9206         (and:SI
9207           (zero_extract:SI
9208             (match_operand 1 "ext_register_operand" "0")
9209             (const_int 8)
9210             (const_int 8))
9211           (zero_extend:SI
9212             (match_operand:QI 2 "general_operand" "Qm"))))
9213    (clobber (reg:CC FLAGS_REG))]
9214   "!TARGET_64BIT"
9215   "and{b}\t{%2, %h0|%h0, %2}"
9216   [(set_attr "type" "alu")
9217    (set_attr "length_immediate" "0")
9218    (set_attr "mode" "QI")])
9220 (define_insn "*andqi_ext_1_rex64"
9221   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9222                          (const_int 8)
9223                          (const_int 8))
9224         (and:SI
9225           (zero_extract:SI
9226             (match_operand 1 "ext_register_operand" "0")
9227             (const_int 8)
9228             (const_int 8))
9229           (zero_extend:SI
9230             (match_operand 2 "ext_register_operand" "Q"))))
9231    (clobber (reg:CC FLAGS_REG))]
9232   "TARGET_64BIT"
9233   "and{b}\t{%2, %h0|%h0, %2}"
9234   [(set_attr "type" "alu")
9235    (set_attr "length_immediate" "0")
9236    (set_attr "mode" "QI")])
9238 (define_insn "*andqi_ext_2"
9239   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9240                          (const_int 8)
9241                          (const_int 8))
9242         (and:SI
9243           (zero_extract:SI
9244             (match_operand 1 "ext_register_operand" "%0")
9245             (const_int 8)
9246             (const_int 8))
9247           (zero_extract:SI
9248             (match_operand 2 "ext_register_operand" "Q")
9249             (const_int 8)
9250             (const_int 8))))
9251    (clobber (reg:CC FLAGS_REG))]
9252   ""
9253   "and{b}\t{%h2, %h0|%h0, %h2}"
9254   [(set_attr "type" "alu")
9255    (set_attr "length_immediate" "0")
9256    (set_attr "mode" "QI")])
9258 ;; Convert wide AND instructions with immediate operand to shorter QImode
9259 ;; equivalents when possible.
9260 ;; Don't do the splitting with memory operands, since it introduces risk
9261 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9262 ;; for size, but that can (should?) be handled by generic code instead.
9263 (define_split
9264   [(set (match_operand 0 "register_operand" "")
9265         (and (match_operand 1 "register_operand" "")
9266              (match_operand 2 "const_int_operand" "")))
9267    (clobber (reg:CC FLAGS_REG))]
9268    "reload_completed
9269     && QI_REG_P (operands[0])
9270     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9271     && !(~INTVAL (operands[2]) & ~(255 << 8))
9272     && GET_MODE (operands[0]) != QImode"
9273   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9274                    (and:SI (zero_extract:SI (match_dup 1)
9275                                             (const_int 8) (const_int 8))
9276                            (match_dup 2)))
9277               (clobber (reg:CC FLAGS_REG))])]
9278   "operands[0] = gen_lowpart (SImode, operands[0]);
9279    operands[1] = gen_lowpart (SImode, operands[1]);
9280    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9282 ;; Since AND can be encoded with sign extended immediate, this is only
9283 ;; profitable when 7th bit is not set.
9284 (define_split
9285   [(set (match_operand 0 "register_operand" "")
9286         (and (match_operand 1 "general_operand" "")
9287              (match_operand 2 "const_int_operand" "")))
9288    (clobber (reg:CC FLAGS_REG))]
9289    "reload_completed
9290     && ANY_QI_REG_P (operands[0])
9291     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9292     && !(~INTVAL (operands[2]) & ~255)
9293     && !(INTVAL (operands[2]) & 128)
9294     && GET_MODE (operands[0]) != QImode"
9295   [(parallel [(set (strict_low_part (match_dup 0))
9296                    (and:QI (match_dup 1)
9297                            (match_dup 2)))
9298               (clobber (reg:CC FLAGS_REG))])]
9299   "operands[0] = gen_lowpart (QImode, operands[0]);
9300    operands[1] = gen_lowpart (QImode, operands[1]);
9301    operands[2] = gen_lowpart (QImode, operands[2]);")
9303 ;; Logical inclusive OR instructions
9305 ;; %%% This used to optimize known byte-wide and operations to memory.
9306 ;; If this is considered useful, it should be done with splitters.
9308 (define_expand "iordi3"
9309   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9310         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9311                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9312   "TARGET_64BIT"
9313   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9315 (define_insn "*iordi_1_rex64"
9316   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9317         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9318                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9319    (clobber (reg:CC FLAGS_REG))]
9320   "TARGET_64BIT
9321    && ix86_binary_operator_ok (IOR, DImode, operands)"
9322   "or{q}\t{%2, %0|%0, %2}"
9323   [(set_attr "type" "alu")
9324    (set_attr "mode" "DI")])
9326 (define_insn "*iordi_2_rex64"
9327   [(set (reg FLAGS_REG)
9328         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9329                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9330                  (const_int 0)))
9331    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9332         (ior:DI (match_dup 1) (match_dup 2)))]
9333   "TARGET_64BIT
9334    && ix86_match_ccmode (insn, CCNOmode)
9335    && ix86_binary_operator_ok (IOR, DImode, operands)"
9336   "or{q}\t{%2, %0|%0, %2}"
9337   [(set_attr "type" "alu")
9338    (set_attr "mode" "DI")])
9340 (define_insn "*iordi_3_rex64"
9341   [(set (reg FLAGS_REG)
9342         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9343                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9344                  (const_int 0)))
9345    (clobber (match_scratch:DI 0 "=r"))]
9346   "TARGET_64BIT
9347    && ix86_match_ccmode (insn, CCNOmode)
9348    && ix86_binary_operator_ok (IOR, DImode, operands)"
9349   "or{q}\t{%2, %0|%0, %2}"
9350   [(set_attr "type" "alu")
9351    (set_attr "mode" "DI")])
9354 (define_expand "iorsi3"
9355   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9356         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9357                 (match_operand:SI 2 "general_operand" "")))]
9358   ""
9359   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9361 (define_insn "*iorsi_1"
9362   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9363         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9364                 (match_operand:SI 2 "general_operand" "ri,g")))
9365    (clobber (reg:CC FLAGS_REG))]
9366   "ix86_binary_operator_ok (IOR, SImode, operands)"
9367   "or{l}\t{%2, %0|%0, %2}"
9368   [(set_attr "type" "alu")
9369    (set_attr "mode" "SI")])
9371 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9372 (define_insn "*iorsi_1_zext"
9373   [(set (match_operand:DI 0 "register_operand" "=r")
9374         (zero_extend:DI
9375           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9376                   (match_operand:SI 2 "general_operand" "g"))))
9377    (clobber (reg:CC FLAGS_REG))]
9378   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9379   "or{l}\t{%2, %k0|%k0, %2}"
9380   [(set_attr "type" "alu")
9381    (set_attr "mode" "SI")])
9383 (define_insn "*iorsi_1_zext_imm"
9384   [(set (match_operand:DI 0 "register_operand" "=r")
9385         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9386                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9387    (clobber (reg:CC FLAGS_REG))]
9388   "TARGET_64BIT"
9389   "or{l}\t{%2, %k0|%k0, %2}"
9390   [(set_attr "type" "alu")
9391    (set_attr "mode" "SI")])
9393 (define_insn "*iorsi_2"
9394   [(set (reg FLAGS_REG)
9395         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9396                          (match_operand:SI 2 "general_operand" "g,ri"))
9397                  (const_int 0)))
9398    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9399         (ior:SI (match_dup 1) (match_dup 2)))]
9400   "ix86_match_ccmode (insn, CCNOmode)
9401    && ix86_binary_operator_ok (IOR, SImode, operands)"
9402   "or{l}\t{%2, %0|%0, %2}"
9403   [(set_attr "type" "alu")
9404    (set_attr "mode" "SI")])
9406 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9407 ;; ??? Special case for immediate operand is missing - it is tricky.
9408 (define_insn "*iorsi_2_zext"
9409   [(set (reg FLAGS_REG)
9410         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9411                          (match_operand:SI 2 "general_operand" "g"))
9412                  (const_int 0)))
9413    (set (match_operand:DI 0 "register_operand" "=r")
9414         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9415   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9416    && ix86_binary_operator_ok (IOR, SImode, operands)"
9417   "or{l}\t{%2, %k0|%k0, %2}"
9418   [(set_attr "type" "alu")
9419    (set_attr "mode" "SI")])
9421 (define_insn "*iorsi_2_zext_imm"
9422   [(set (reg FLAGS_REG)
9423         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9424                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9425                  (const_int 0)))
9426    (set (match_operand:DI 0 "register_operand" "=r")
9427         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9428   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9429    && ix86_binary_operator_ok (IOR, SImode, operands)"
9430   "or{l}\t{%2, %k0|%k0, %2}"
9431   [(set_attr "type" "alu")
9432    (set_attr "mode" "SI")])
9434 (define_insn "*iorsi_3"
9435   [(set (reg FLAGS_REG)
9436         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9437                          (match_operand:SI 2 "general_operand" "g"))
9438                  (const_int 0)))
9439    (clobber (match_scratch:SI 0 "=r"))]
9440   "ix86_match_ccmode (insn, CCNOmode)
9441    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9442   "or{l}\t{%2, %0|%0, %2}"
9443   [(set_attr "type" "alu")
9444    (set_attr "mode" "SI")])
9446 (define_expand "iorhi3"
9447   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9448         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9449                 (match_operand:HI 2 "general_operand" "")))]
9450   "TARGET_HIMODE_MATH"
9451   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9453 (define_insn "*iorhi_1"
9454   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9455         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9456                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9457    (clobber (reg:CC FLAGS_REG))]
9458   "ix86_binary_operator_ok (IOR, HImode, operands)"
9459   "or{w}\t{%2, %0|%0, %2}"
9460   [(set_attr "type" "alu")
9461    (set_attr "mode" "HI")])
9463 (define_insn "*iorhi_2"
9464   [(set (reg FLAGS_REG)
9465         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9466                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9467                  (const_int 0)))
9468    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9469         (ior:HI (match_dup 1) (match_dup 2)))]
9470   "ix86_match_ccmode (insn, CCNOmode)
9471    && ix86_binary_operator_ok (IOR, HImode, operands)"
9472   "or{w}\t{%2, %0|%0, %2}"
9473   [(set_attr "type" "alu")
9474    (set_attr "mode" "HI")])
9476 (define_insn "*iorhi_3"
9477   [(set (reg FLAGS_REG)
9478         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9479                          (match_operand:HI 2 "general_operand" "rmn"))
9480                  (const_int 0)))
9481    (clobber (match_scratch:HI 0 "=r"))]
9482   "ix86_match_ccmode (insn, CCNOmode)
9483    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9484   "or{w}\t{%2, %0|%0, %2}"
9485   [(set_attr "type" "alu")
9486    (set_attr "mode" "HI")])
9488 (define_expand "iorqi3"
9489   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9490         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9491                 (match_operand:QI 2 "general_operand" "")))]
9492   "TARGET_QIMODE_MATH"
9493   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9495 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9496 (define_insn "*iorqi_1"
9497   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9498         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9499                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9500    (clobber (reg:CC FLAGS_REG))]
9501   "ix86_binary_operator_ok (IOR, QImode, operands)"
9502   "@
9503    or{b}\t{%2, %0|%0, %2}
9504    or{b}\t{%2, %0|%0, %2}
9505    or{l}\t{%k2, %k0|%k0, %k2}"
9506   [(set_attr "type" "alu")
9507    (set_attr "mode" "QI,QI,SI")])
9509 (define_insn "*iorqi_1_slp"
9510   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9511         (ior:QI (match_dup 0)
9512                 (match_operand:QI 1 "general_operand" "qmn,qn")))
9513    (clobber (reg:CC FLAGS_REG))]
9514   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9515    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9516   "or{b}\t{%1, %0|%0, %1}"
9517   [(set_attr "type" "alu1")
9518    (set_attr "mode" "QI")])
9520 (define_insn "*iorqi_2"
9521   [(set (reg FLAGS_REG)
9522         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9523                          (match_operand:QI 2 "general_operand" "qmn,qn"))
9524                  (const_int 0)))
9525    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9526         (ior:QI (match_dup 1) (match_dup 2)))]
9527   "ix86_match_ccmode (insn, CCNOmode)
9528    && ix86_binary_operator_ok (IOR, QImode, operands)"
9529   "or{b}\t{%2, %0|%0, %2}"
9530   [(set_attr "type" "alu")
9531    (set_attr "mode" "QI")])
9533 (define_insn "*iorqi_2_slp"
9534   [(set (reg FLAGS_REG)
9535         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9536                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9537                  (const_int 0)))
9538    (set (strict_low_part (match_dup 0))
9539         (ior:QI (match_dup 0) (match_dup 1)))]
9540   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9541    && ix86_match_ccmode (insn, CCNOmode)
9542    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9543   "or{b}\t{%1, %0|%0, %1}"
9544   [(set_attr "type" "alu1")
9545    (set_attr "mode" "QI")])
9547 (define_insn "*iorqi_3"
9548   [(set (reg FLAGS_REG)
9549         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9550                          (match_operand:QI 2 "general_operand" "qmn"))
9551                  (const_int 0)))
9552    (clobber (match_scratch:QI 0 "=q"))]
9553   "ix86_match_ccmode (insn, CCNOmode)
9554    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9555   "or{b}\t{%2, %0|%0, %2}"
9556   [(set_attr "type" "alu")
9557    (set_attr "mode" "QI")])
9559 (define_insn "iorqi_ext_0"
9560   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9561                          (const_int 8)
9562                          (const_int 8))
9563         (ior:SI
9564           (zero_extract:SI
9565             (match_operand 1 "ext_register_operand" "0")
9566             (const_int 8)
9567             (const_int 8))
9568           (match_operand 2 "const_int_operand" "n")))
9569    (clobber (reg:CC FLAGS_REG))]
9570   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9571   "or{b}\t{%2, %h0|%h0, %2}"
9572   [(set_attr "type" "alu")
9573    (set_attr "length_immediate" "1")
9574    (set_attr "mode" "QI")])
9576 (define_insn "*iorqi_ext_1"
9577   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9578                          (const_int 8)
9579                          (const_int 8))
9580         (ior:SI
9581           (zero_extract:SI
9582             (match_operand 1 "ext_register_operand" "0")
9583             (const_int 8)
9584             (const_int 8))
9585           (zero_extend:SI
9586             (match_operand:QI 2 "general_operand" "Qm"))))
9587    (clobber (reg:CC FLAGS_REG))]
9588   "!TARGET_64BIT
9589    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9590   "or{b}\t{%2, %h0|%h0, %2}"
9591   [(set_attr "type" "alu")
9592    (set_attr "length_immediate" "0")
9593    (set_attr "mode" "QI")])
9595 (define_insn "*iorqi_ext_1_rex64"
9596   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9597                          (const_int 8)
9598                          (const_int 8))
9599         (ior:SI
9600           (zero_extract:SI
9601             (match_operand 1 "ext_register_operand" "0")
9602             (const_int 8)
9603             (const_int 8))
9604           (zero_extend:SI
9605             (match_operand 2 "ext_register_operand" "Q"))))
9606    (clobber (reg:CC FLAGS_REG))]
9607   "TARGET_64BIT
9608    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9609   "or{b}\t{%2, %h0|%h0, %2}"
9610   [(set_attr "type" "alu")
9611    (set_attr "length_immediate" "0")
9612    (set_attr "mode" "QI")])
9614 (define_insn "*iorqi_ext_2"
9615   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9616                          (const_int 8)
9617                          (const_int 8))
9618         (ior:SI
9619           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9620                            (const_int 8)
9621                            (const_int 8))
9622           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9623                            (const_int 8)
9624                            (const_int 8))))
9625    (clobber (reg:CC FLAGS_REG))]
9626   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9627   "ior{b}\t{%h2, %h0|%h0, %h2}"
9628   [(set_attr "type" "alu")
9629    (set_attr "length_immediate" "0")
9630    (set_attr "mode" "QI")])
9632 (define_split
9633   [(set (match_operand 0 "register_operand" "")
9634         (ior (match_operand 1 "register_operand" "")
9635              (match_operand 2 "const_int_operand" "")))
9636    (clobber (reg:CC FLAGS_REG))]
9637    "reload_completed
9638     && QI_REG_P (operands[0])
9639     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9640     && !(INTVAL (operands[2]) & ~(255 << 8))
9641     && GET_MODE (operands[0]) != QImode"
9642   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9643                    (ior:SI (zero_extract:SI (match_dup 1)
9644                                             (const_int 8) (const_int 8))
9645                            (match_dup 2)))
9646               (clobber (reg:CC FLAGS_REG))])]
9647   "operands[0] = gen_lowpart (SImode, operands[0]);
9648    operands[1] = gen_lowpart (SImode, operands[1]);
9649    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9651 ;; Since OR can be encoded with sign extended immediate, this is only
9652 ;; profitable when 7th bit is set.
9653 (define_split
9654   [(set (match_operand 0 "register_operand" "")
9655         (ior (match_operand 1 "general_operand" "")
9656              (match_operand 2 "const_int_operand" "")))
9657    (clobber (reg:CC FLAGS_REG))]
9658    "reload_completed
9659     && ANY_QI_REG_P (operands[0])
9660     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9661     && !(INTVAL (operands[2]) & ~255)
9662     && (INTVAL (operands[2]) & 128)
9663     && GET_MODE (operands[0]) != QImode"
9664   [(parallel [(set (strict_low_part (match_dup 0))
9665                    (ior:QI (match_dup 1)
9666                            (match_dup 2)))
9667               (clobber (reg:CC FLAGS_REG))])]
9668   "operands[0] = gen_lowpart (QImode, operands[0]);
9669    operands[1] = gen_lowpart (QImode, operands[1]);
9670    operands[2] = gen_lowpart (QImode, operands[2]);")
9672 ;; Logical XOR instructions
9674 ;; %%% This used to optimize known byte-wide and operations to memory.
9675 ;; If this is considered useful, it should be done with splitters.
9677 (define_expand "xordi3"
9678   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9679         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9680                 (match_operand:DI 2 "x86_64_general_operand" "")))]
9681   "TARGET_64BIT"
9682   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9684 (define_insn "*xordi_1_rex64"
9685   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9686         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9687                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9688    (clobber (reg:CC FLAGS_REG))]
9689   "TARGET_64BIT
9690    && ix86_binary_operator_ok (XOR, DImode, operands)"
9691   "xor{q}\t{%2, %0|%0, %2}"
9692   [(set_attr "type" "alu")
9693    (set_attr "mode" "DI")])
9695 (define_insn "*xordi_2_rex64"
9696   [(set (reg FLAGS_REG)
9697         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9698                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9699                  (const_int 0)))
9700    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9701         (xor:DI (match_dup 1) (match_dup 2)))]
9702   "TARGET_64BIT
9703    && ix86_match_ccmode (insn, CCNOmode)
9704    && ix86_binary_operator_ok (XOR, DImode, operands)"
9705   "xor{q}\t{%2, %0|%0, %2}"
9706   [(set_attr "type" "alu")
9707    (set_attr "mode" "DI")])
9709 (define_insn "*xordi_3_rex64"
9710   [(set (reg FLAGS_REG)
9711         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9712                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9713                  (const_int 0)))
9714    (clobber (match_scratch:DI 0 "=r"))]
9715   "TARGET_64BIT
9716    && ix86_match_ccmode (insn, CCNOmode)
9717    && ix86_binary_operator_ok (XOR, DImode, operands)"
9718   "xor{q}\t{%2, %0|%0, %2}"
9719   [(set_attr "type" "alu")
9720    (set_attr "mode" "DI")])
9722 (define_expand "xorsi3"
9723   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9724         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9725                 (match_operand:SI 2 "general_operand" "")))]
9726   ""
9727   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9729 (define_insn "*xorsi_1"
9730   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9731         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9732                 (match_operand:SI 2 "general_operand" "ri,rm")))
9733    (clobber (reg:CC FLAGS_REG))]
9734   "ix86_binary_operator_ok (XOR, SImode, operands)"
9735   "xor{l}\t{%2, %0|%0, %2}"
9736   [(set_attr "type" "alu")
9737    (set_attr "mode" "SI")])
9739 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9740 ;; Add speccase for immediates
9741 (define_insn "*xorsi_1_zext"
9742   [(set (match_operand:DI 0 "register_operand" "=r")
9743         (zero_extend:DI
9744           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9745                   (match_operand:SI 2 "general_operand" "g"))))
9746    (clobber (reg:CC FLAGS_REG))]
9747   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9748   "xor{l}\t{%2, %k0|%k0, %2}"
9749   [(set_attr "type" "alu")
9750    (set_attr "mode" "SI")])
9752 (define_insn "*xorsi_1_zext_imm"
9753   [(set (match_operand:DI 0 "register_operand" "=r")
9754         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9755                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9756    (clobber (reg:CC FLAGS_REG))]
9757   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9758   "xor{l}\t{%2, %k0|%k0, %2}"
9759   [(set_attr "type" "alu")
9760    (set_attr "mode" "SI")])
9762 (define_insn "*xorsi_2"
9763   [(set (reg FLAGS_REG)
9764         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9765                          (match_operand:SI 2 "general_operand" "g,ri"))
9766                  (const_int 0)))
9767    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9768         (xor:SI (match_dup 1) (match_dup 2)))]
9769   "ix86_match_ccmode (insn, CCNOmode)
9770    && ix86_binary_operator_ok (XOR, SImode, operands)"
9771   "xor{l}\t{%2, %0|%0, %2}"
9772   [(set_attr "type" "alu")
9773    (set_attr "mode" "SI")])
9775 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9776 ;; ??? Special case for immediate operand is missing - it is tricky.
9777 (define_insn "*xorsi_2_zext"
9778   [(set (reg FLAGS_REG)
9779         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9780                          (match_operand:SI 2 "general_operand" "g"))
9781                  (const_int 0)))
9782    (set (match_operand:DI 0 "register_operand" "=r")
9783         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9784   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9785    && ix86_binary_operator_ok (XOR, SImode, operands)"
9786   "xor{l}\t{%2, %k0|%k0, %2}"
9787   [(set_attr "type" "alu")
9788    (set_attr "mode" "SI")])
9790 (define_insn "*xorsi_2_zext_imm"
9791   [(set (reg FLAGS_REG)
9792         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9793                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9794                  (const_int 0)))
9795    (set (match_operand:DI 0 "register_operand" "=r")
9796         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9797   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9798    && ix86_binary_operator_ok (XOR, SImode, operands)"
9799   "xor{l}\t{%2, %k0|%k0, %2}"
9800   [(set_attr "type" "alu")
9801    (set_attr "mode" "SI")])
9803 (define_insn "*xorsi_3"
9804   [(set (reg FLAGS_REG)
9805         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9806                          (match_operand:SI 2 "general_operand" "g"))
9807                  (const_int 0)))
9808    (clobber (match_scratch:SI 0 "=r"))]
9809   "ix86_match_ccmode (insn, CCNOmode)
9810    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9811   "xor{l}\t{%2, %0|%0, %2}"
9812   [(set_attr "type" "alu")
9813    (set_attr "mode" "SI")])
9815 (define_expand "xorhi3"
9816   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9817         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9818                 (match_operand:HI 2 "general_operand" "")))]
9819   "TARGET_HIMODE_MATH"
9820   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9822 (define_insn "*xorhi_1"
9823   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9824         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9825                 (match_operand:HI 2 "general_operand" "rmn,rn")))
9826    (clobber (reg:CC FLAGS_REG))]
9827   "ix86_binary_operator_ok (XOR, HImode, operands)"
9828   "xor{w}\t{%2, %0|%0, %2}"
9829   [(set_attr "type" "alu")
9830    (set_attr "mode" "HI")])
9832 (define_insn "*xorhi_2"
9833   [(set (reg FLAGS_REG)
9834         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9835                          (match_operand:HI 2 "general_operand" "rmn,rn"))
9836                  (const_int 0)))
9837    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9838         (xor:HI (match_dup 1) (match_dup 2)))]
9839   "ix86_match_ccmode (insn, CCNOmode)
9840    && ix86_binary_operator_ok (XOR, HImode, operands)"
9841   "xor{w}\t{%2, %0|%0, %2}"
9842   [(set_attr "type" "alu")
9843    (set_attr "mode" "HI")])
9845 (define_insn "*xorhi_3"
9846   [(set (reg FLAGS_REG)
9847         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9848                          (match_operand:HI 2 "general_operand" "rmn"))
9849                  (const_int 0)))
9850    (clobber (match_scratch:HI 0 "=r"))]
9851   "ix86_match_ccmode (insn, CCNOmode)
9852    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9853   "xor{w}\t{%2, %0|%0, %2}"
9854   [(set_attr "type" "alu")
9855    (set_attr "mode" "HI")])
9857 (define_expand "xorqi3"
9858   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9859         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9860                 (match_operand:QI 2 "general_operand" "")))]
9861   "TARGET_QIMODE_MATH"
9862   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9864 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9865 (define_insn "*xorqi_1"
9866   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9867         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9868                 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9869    (clobber (reg:CC FLAGS_REG))]
9870   "ix86_binary_operator_ok (XOR, QImode, operands)"
9871   "@
9872    xor{b}\t{%2, %0|%0, %2}
9873    xor{b}\t{%2, %0|%0, %2}
9874    xor{l}\t{%k2, %k0|%k0, %k2}"
9875   [(set_attr "type" "alu")
9876    (set_attr "mode" "QI,QI,SI")])
9878 (define_insn "*xorqi_1_slp"
9879   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9880         (xor:QI (match_dup 0)
9881                 (match_operand:QI 1 "general_operand" "qn,qmn")))
9882    (clobber (reg:CC FLAGS_REG))]
9883   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9884    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9885   "xor{b}\t{%1, %0|%0, %1}"
9886   [(set_attr "type" "alu1")
9887    (set_attr "mode" "QI")])
9889 (define_insn "xorqi_ext_0"
9890   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9891                          (const_int 8)
9892                          (const_int 8))
9893         (xor:SI
9894           (zero_extract:SI
9895             (match_operand 1 "ext_register_operand" "0")
9896             (const_int 8)
9897             (const_int 8))
9898           (match_operand 2 "const_int_operand" "n")))
9899    (clobber (reg:CC FLAGS_REG))]
9900   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9901   "xor{b}\t{%2, %h0|%h0, %2}"
9902   [(set_attr "type" "alu")
9903    (set_attr "length_immediate" "1")
9904    (set_attr "mode" "QI")])
9906 (define_insn "*xorqi_ext_1"
9907   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9908                          (const_int 8)
9909                          (const_int 8))
9910         (xor:SI
9911           (zero_extract:SI
9912             (match_operand 1 "ext_register_operand" "0")
9913             (const_int 8)
9914             (const_int 8))
9915           (zero_extend:SI
9916             (match_operand:QI 2 "general_operand" "Qm"))))
9917    (clobber (reg:CC FLAGS_REG))]
9918   "!TARGET_64BIT
9919    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9920   "xor{b}\t{%2, %h0|%h0, %2}"
9921   [(set_attr "type" "alu")
9922    (set_attr "length_immediate" "0")
9923    (set_attr "mode" "QI")])
9925 (define_insn "*xorqi_ext_1_rex64"
9926   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9927                          (const_int 8)
9928                          (const_int 8))
9929         (xor:SI
9930           (zero_extract:SI
9931             (match_operand 1 "ext_register_operand" "0")
9932             (const_int 8)
9933             (const_int 8))
9934           (zero_extend:SI
9935             (match_operand 2 "ext_register_operand" "Q"))))
9936    (clobber (reg:CC FLAGS_REG))]
9937   "TARGET_64BIT
9938    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9939   "xor{b}\t{%2, %h0|%h0, %2}"
9940   [(set_attr "type" "alu")
9941    (set_attr "length_immediate" "0")
9942    (set_attr "mode" "QI")])
9944 (define_insn "*xorqi_ext_2"
9945   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9946                          (const_int 8)
9947                          (const_int 8))
9948         (xor:SI
9949           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9950                            (const_int 8)
9951                            (const_int 8))
9952           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9953                            (const_int 8)
9954                            (const_int 8))))
9955    (clobber (reg:CC FLAGS_REG))]
9956   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9957   "xor{b}\t{%h2, %h0|%h0, %h2}"
9958   [(set_attr "type" "alu")
9959    (set_attr "length_immediate" "0")
9960    (set_attr "mode" "QI")])
9962 (define_insn "*xorqi_cc_1"
9963   [(set (reg FLAGS_REG)
9964         (compare
9965           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9966                   (match_operand:QI 2 "general_operand" "qmn,qn"))
9967           (const_int 0)))
9968    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9969         (xor:QI (match_dup 1) (match_dup 2)))]
9970   "ix86_match_ccmode (insn, CCNOmode)
9971    && ix86_binary_operator_ok (XOR, QImode, operands)"
9972   "xor{b}\t{%2, %0|%0, %2}"
9973   [(set_attr "type" "alu")
9974    (set_attr "mode" "QI")])
9976 (define_insn "*xorqi_2_slp"
9977   [(set (reg FLAGS_REG)
9978         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9979                          (match_operand:QI 1 "general_operand" "qmn,qn"))
9980                  (const_int 0)))
9981    (set (strict_low_part (match_dup 0))
9982         (xor:QI (match_dup 0) (match_dup 1)))]
9983   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9984    && ix86_match_ccmode (insn, CCNOmode)
9985    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9986   "xor{b}\t{%1, %0|%0, %1}"
9987   [(set_attr "type" "alu1")
9988    (set_attr "mode" "QI")])
9990 (define_insn "*xorqi_cc_2"
9991   [(set (reg FLAGS_REG)
9992         (compare
9993           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9994                   (match_operand:QI 2 "general_operand" "qmn"))
9995           (const_int 0)))
9996    (clobber (match_scratch:QI 0 "=q"))]
9997   "ix86_match_ccmode (insn, CCNOmode)
9998    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9999   "xor{b}\t{%2, %0|%0, %2}"
10000   [(set_attr "type" "alu")
10001    (set_attr "mode" "QI")])
10003 (define_insn "*xorqi_cc_ext_1"
10004   [(set (reg FLAGS_REG)
10005         (compare
10006           (xor:SI
10007             (zero_extract:SI
10008               (match_operand 1 "ext_register_operand" "0")
10009               (const_int 8)
10010               (const_int 8))
10011             (match_operand:QI 2 "general_operand" "qmn"))
10012           (const_int 0)))
10013    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10014                          (const_int 8)
10015                          (const_int 8))
10016         (xor:SI
10017           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10018           (match_dup 2)))]
10019   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10020   "xor{b}\t{%2, %h0|%h0, %2}"
10021   [(set_attr "type" "alu")
10022    (set_attr "mode" "QI")])
10024 (define_insn "*xorqi_cc_ext_1_rex64"
10025   [(set (reg FLAGS_REG)
10026         (compare
10027           (xor:SI
10028             (zero_extract:SI
10029               (match_operand 1 "ext_register_operand" "0")
10030               (const_int 8)
10031               (const_int 8))
10032             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10033           (const_int 0)))
10034    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10035                          (const_int 8)
10036                          (const_int 8))
10037         (xor:SI
10038           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10039           (match_dup 2)))]
10040   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10041   "xor{b}\t{%2, %h0|%h0, %2}"
10042   [(set_attr "type" "alu")
10043    (set_attr "mode" "QI")])
10045 (define_expand "xorqi_cc_ext_1"
10046   [(parallel [
10047      (set (reg:CCNO FLAGS_REG)
10048           (compare:CCNO
10049             (xor:SI
10050               (zero_extract:SI
10051                 (match_operand 1 "ext_register_operand" "")
10052                 (const_int 8)
10053                 (const_int 8))
10054               (match_operand:QI 2 "general_operand" ""))
10055             (const_int 0)))
10056      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10057                            (const_int 8)
10058                            (const_int 8))
10059           (xor:SI
10060             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10061             (match_dup 2)))])]
10062   ""
10063   "")
10065 (define_split
10066   [(set (match_operand 0 "register_operand" "")
10067         (xor (match_operand 1 "register_operand" "")
10068              (match_operand 2 "const_int_operand" "")))
10069    (clobber (reg:CC FLAGS_REG))]
10070    "reload_completed
10071     && QI_REG_P (operands[0])
10072     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10073     && !(INTVAL (operands[2]) & ~(255 << 8))
10074     && GET_MODE (operands[0]) != QImode"
10075   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10076                    (xor:SI (zero_extract:SI (match_dup 1)
10077                                             (const_int 8) (const_int 8))
10078                            (match_dup 2)))
10079               (clobber (reg:CC FLAGS_REG))])]
10080   "operands[0] = gen_lowpart (SImode, operands[0]);
10081    operands[1] = gen_lowpart (SImode, operands[1]);
10082    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10084 ;; Since XOR can be encoded with sign extended immediate, this is only
10085 ;; profitable when 7th bit is set.
10086 (define_split
10087   [(set (match_operand 0 "register_operand" "")
10088         (xor (match_operand 1 "general_operand" "")
10089              (match_operand 2 "const_int_operand" "")))
10090    (clobber (reg:CC FLAGS_REG))]
10091    "reload_completed
10092     && ANY_QI_REG_P (operands[0])
10093     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10094     && !(INTVAL (operands[2]) & ~255)
10095     && (INTVAL (operands[2]) & 128)
10096     && GET_MODE (operands[0]) != QImode"
10097   [(parallel [(set (strict_low_part (match_dup 0))
10098                    (xor:QI (match_dup 1)
10099                            (match_dup 2)))
10100               (clobber (reg:CC FLAGS_REG))])]
10101   "operands[0] = gen_lowpart (QImode, operands[0]);
10102    operands[1] = gen_lowpart (QImode, operands[1]);
10103    operands[2] = gen_lowpart (QImode, operands[2]);")
10105 ;; Negation instructions
10107 (define_expand "negti2"
10108   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10109         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10110   "TARGET_64BIT"
10111   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10113 (define_insn "*negti2_1"
10114   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10115         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10116    (clobber (reg:CC FLAGS_REG))]
10117   "TARGET_64BIT
10118    && ix86_unary_operator_ok (NEG, TImode, operands)"
10119   "#")
10121 (define_split
10122   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10123         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10124    (clobber (reg:CC FLAGS_REG))]
10125   "TARGET_64BIT && reload_completed"
10126   [(parallel
10127     [(set (reg:CCZ FLAGS_REG)
10128           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10129      (set (match_dup 0) (neg:DI (match_dup 1)))])
10130    (parallel
10131     [(set (match_dup 2)
10132           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10133                             (match_dup 3))
10134                    (const_int 0)))
10135      (clobber (reg:CC FLAGS_REG))])
10136    (parallel
10137     [(set (match_dup 2)
10138           (neg:DI (match_dup 2)))
10139      (clobber (reg:CC FLAGS_REG))])]
10140   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10142 (define_expand "negdi2"
10143   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10144         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10145   ""
10146   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10148 (define_insn "*negdi2_1"
10149   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10150         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10151    (clobber (reg:CC FLAGS_REG))]
10152   "!TARGET_64BIT
10153    && ix86_unary_operator_ok (NEG, DImode, operands)"
10154   "#")
10156 (define_split
10157   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10158         (neg:DI (match_operand:DI 1 "general_operand" "")))
10159    (clobber (reg:CC FLAGS_REG))]
10160   "!TARGET_64BIT && reload_completed"
10161   [(parallel
10162     [(set (reg:CCZ FLAGS_REG)
10163           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10164      (set (match_dup 0) (neg:SI (match_dup 1)))])
10165    (parallel
10166     [(set (match_dup 2)
10167           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10168                             (match_dup 3))
10169                    (const_int 0)))
10170      (clobber (reg:CC FLAGS_REG))])
10171    (parallel
10172     [(set (match_dup 2)
10173           (neg:SI (match_dup 2)))
10174      (clobber (reg:CC FLAGS_REG))])]
10175   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10177 (define_insn "*negdi2_1_rex64"
10178   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10179         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10180    (clobber (reg:CC FLAGS_REG))]
10181   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10182   "neg{q}\t%0"
10183   [(set_attr "type" "negnot")
10184    (set_attr "mode" "DI")])
10186 ;; The problem with neg is that it does not perform (compare x 0),
10187 ;; it really performs (compare 0 x), which leaves us with the zero
10188 ;; flag being the only useful item.
10190 (define_insn "*negdi2_cmpz_rex64"
10191   [(set (reg:CCZ FLAGS_REG)
10192         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10193                      (const_int 0)))
10194    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10195         (neg:DI (match_dup 1)))]
10196   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10197   "neg{q}\t%0"
10198   [(set_attr "type" "negnot")
10199    (set_attr "mode" "DI")])
10202 (define_expand "negsi2"
10203   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10204         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10205   ""
10206   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10208 (define_insn "*negsi2_1"
10209   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10210         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10211    (clobber (reg:CC FLAGS_REG))]
10212   "ix86_unary_operator_ok (NEG, SImode, operands)"
10213   "neg{l}\t%0"
10214   [(set_attr "type" "negnot")
10215    (set_attr "mode" "SI")])
10217 ;; Combine is quite creative about this pattern.
10218 (define_insn "*negsi2_1_zext"
10219   [(set (match_operand:DI 0 "register_operand" "=r")
10220         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10221                                         (const_int 32)))
10222                      (const_int 32)))
10223    (clobber (reg:CC FLAGS_REG))]
10224   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10225   "neg{l}\t%k0"
10226   [(set_attr "type" "negnot")
10227    (set_attr "mode" "SI")])
10229 ;; The problem with neg is that it does not perform (compare x 0),
10230 ;; it really performs (compare 0 x), which leaves us with the zero
10231 ;; flag being the only useful item.
10233 (define_insn "*negsi2_cmpz"
10234   [(set (reg:CCZ FLAGS_REG)
10235         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10236                      (const_int 0)))
10237    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10238         (neg:SI (match_dup 1)))]
10239   "ix86_unary_operator_ok (NEG, SImode, operands)"
10240   "neg{l}\t%0"
10241   [(set_attr "type" "negnot")
10242    (set_attr "mode" "SI")])
10244 (define_insn "*negsi2_cmpz_zext"
10245   [(set (reg:CCZ FLAGS_REG)
10246         (compare:CCZ (lshiftrt:DI
10247                        (neg:DI (ashift:DI
10248                                  (match_operand:DI 1 "register_operand" "0")
10249                                  (const_int 32)))
10250                        (const_int 32))
10251                      (const_int 0)))
10252    (set (match_operand:DI 0 "register_operand" "=r")
10253         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10254                                         (const_int 32)))
10255                      (const_int 32)))]
10256   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10257   "neg{l}\t%k0"
10258   [(set_attr "type" "negnot")
10259    (set_attr "mode" "SI")])
10261 (define_expand "neghi2"
10262   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10263         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10264   "TARGET_HIMODE_MATH"
10265   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10267 (define_insn "*neghi2_1"
10268   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10269         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10270    (clobber (reg:CC FLAGS_REG))]
10271   "ix86_unary_operator_ok (NEG, HImode, operands)"
10272   "neg{w}\t%0"
10273   [(set_attr "type" "negnot")
10274    (set_attr "mode" "HI")])
10276 (define_insn "*neghi2_cmpz"
10277   [(set (reg:CCZ FLAGS_REG)
10278         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10279                      (const_int 0)))
10280    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10281         (neg:HI (match_dup 1)))]
10282   "ix86_unary_operator_ok (NEG, HImode, operands)"
10283   "neg{w}\t%0"
10284   [(set_attr "type" "negnot")
10285    (set_attr "mode" "HI")])
10287 (define_expand "negqi2"
10288   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10289         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10290   "TARGET_QIMODE_MATH"
10291   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10293 (define_insn "*negqi2_1"
10294   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10295         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10296    (clobber (reg:CC FLAGS_REG))]
10297   "ix86_unary_operator_ok (NEG, QImode, operands)"
10298   "neg{b}\t%0"
10299   [(set_attr "type" "negnot")
10300    (set_attr "mode" "QI")])
10302 (define_insn "*negqi2_cmpz"
10303   [(set (reg:CCZ FLAGS_REG)
10304         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10305                      (const_int 0)))
10306    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10307         (neg:QI (match_dup 1)))]
10308   "ix86_unary_operator_ok (NEG, QImode, operands)"
10309   "neg{b}\t%0"
10310   [(set_attr "type" "negnot")
10311    (set_attr "mode" "QI")])
10313 ;; Changing of sign for FP values is doable using integer unit too.
10315 (define_expand "<code><mode>2"
10316   [(set (match_operand:X87MODEF 0 "register_operand" "")
10317         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10318   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10319   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10321 (define_insn "*absneg<mode>2_mixed"
10322   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10323         (match_operator:MODEF 3 "absneg_operator"
10324           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10325    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10326    (clobber (reg:CC FLAGS_REG))]
10327   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10328   "#")
10330 (define_insn "*absneg<mode>2_sse"
10331   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10332         (match_operator:MODEF 3 "absneg_operator"
10333           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10334    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10335    (clobber (reg:CC FLAGS_REG))]
10336   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10337   "#")
10339 (define_insn "*absneg<mode>2_i387"
10340   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10341         (match_operator:X87MODEF 3 "absneg_operator"
10342           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10343    (use (match_operand 2 "" ""))
10344    (clobber (reg:CC FLAGS_REG))]
10345   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10346   "#")
10348 (define_expand "<code>tf2"
10349   [(set (match_operand:TF 0 "register_operand" "")
10350         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10351   "TARGET_SSE2"
10352   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10354 (define_insn "*absnegtf2_sse"
10355   [(set (match_operand:TF 0 "register_operand" "=x,x")
10356         (match_operator:TF 3 "absneg_operator"
10357           [(match_operand:TF 1 "register_operand" "0,x")]))
10358    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10359    (clobber (reg:CC FLAGS_REG))]
10360   "TARGET_SSE2"
10361   "#")
10363 ;; Splitters for fp abs and neg.
10365 (define_split
10366   [(set (match_operand 0 "fp_register_operand" "")
10367         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10368    (use (match_operand 2 "" ""))
10369    (clobber (reg:CC FLAGS_REG))]
10370   "reload_completed"
10371   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10373 (define_split
10374   [(set (match_operand 0 "register_operand" "")
10375         (match_operator 3 "absneg_operator"
10376           [(match_operand 1 "register_operand" "")]))
10377    (use (match_operand 2 "nonimmediate_operand" ""))
10378    (clobber (reg:CC FLAGS_REG))]
10379   "reload_completed && SSE_REG_P (operands[0])"
10380   [(set (match_dup 0) (match_dup 3))]
10382   enum machine_mode mode = GET_MODE (operands[0]);
10383   enum machine_mode vmode = GET_MODE (operands[2]);
10384   rtx tmp;
10386   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10387   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10388   if (operands_match_p (operands[0], operands[2]))
10389     {
10390       tmp = operands[1];
10391       operands[1] = operands[2];
10392       operands[2] = tmp;
10393     }
10394   if (GET_CODE (operands[3]) == ABS)
10395     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10396   else
10397     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10398   operands[3] = tmp;
10401 (define_split
10402   [(set (match_operand:SF 0 "register_operand" "")
10403         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10404    (use (match_operand:V4SF 2 "" ""))
10405    (clobber (reg:CC FLAGS_REG))]
10406   "reload_completed"
10407   [(parallel [(set (match_dup 0) (match_dup 1))
10408               (clobber (reg:CC FLAGS_REG))])]
10410   rtx tmp;
10411   operands[0] = gen_lowpart (SImode, operands[0]);
10412   if (GET_CODE (operands[1]) == ABS)
10413     {
10414       tmp = gen_int_mode (0x7fffffff, SImode);
10415       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10416     }
10417   else
10418     {
10419       tmp = gen_int_mode (0x80000000, SImode);
10420       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10421     }
10422   operands[1] = tmp;
10425 (define_split
10426   [(set (match_operand:DF 0 "register_operand" "")
10427         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10428    (use (match_operand 2 "" ""))
10429    (clobber (reg:CC FLAGS_REG))]
10430   "reload_completed"
10431   [(parallel [(set (match_dup 0) (match_dup 1))
10432               (clobber (reg:CC FLAGS_REG))])]
10434   rtx tmp;
10435   if (TARGET_64BIT)
10436     {
10437       tmp = gen_lowpart (DImode, operands[0]);
10438       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10439       operands[0] = tmp;
10441       if (GET_CODE (operands[1]) == ABS)
10442         tmp = const0_rtx;
10443       else
10444         tmp = gen_rtx_NOT (DImode, tmp);
10445     }
10446   else
10447     {
10448       operands[0] = gen_highpart (SImode, operands[0]);
10449       if (GET_CODE (operands[1]) == ABS)
10450         {
10451           tmp = gen_int_mode (0x7fffffff, SImode);
10452           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10453         }
10454       else
10455         {
10456           tmp = gen_int_mode (0x80000000, SImode);
10457           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10458         }
10459     }
10460   operands[1] = tmp;
10463 (define_split
10464   [(set (match_operand:XF 0 "register_operand" "")
10465         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10466    (use (match_operand 2 "" ""))
10467    (clobber (reg:CC FLAGS_REG))]
10468   "reload_completed"
10469   [(parallel [(set (match_dup 0) (match_dup 1))
10470               (clobber (reg:CC FLAGS_REG))])]
10472   rtx tmp;
10473   operands[0] = gen_rtx_REG (SImode,
10474                              true_regnum (operands[0])
10475                              + (TARGET_64BIT ? 1 : 2));
10476   if (GET_CODE (operands[1]) == ABS)
10477     {
10478       tmp = GEN_INT (0x7fff);
10479       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10480     }
10481   else
10482     {
10483       tmp = GEN_INT (0x8000);
10484       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10485     }
10486   operands[1] = tmp;
10489 ;; Conditionalize these after reload. If they match before reload, we
10490 ;; lose the clobber and ability to use integer instructions.
10492 (define_insn "*<code><mode>2_1"
10493   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10494         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10495   "TARGET_80387
10496    && (reload_completed
10497        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10498   "f<absnegprefix>"
10499   [(set_attr "type" "fsgn")
10500    (set_attr "mode" "<MODE>")])
10502 (define_insn "*<code>extendsfdf2"
10503   [(set (match_operand:DF 0 "register_operand" "=f")
10504         (absneg:DF (float_extend:DF
10505                      (match_operand:SF 1 "register_operand" "0"))))]
10506   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10507   "f<absnegprefix>"
10508   [(set_attr "type" "fsgn")
10509    (set_attr "mode" "DF")])
10511 (define_insn "*<code>extendsfxf2"
10512   [(set (match_operand:XF 0 "register_operand" "=f")
10513         (absneg:XF (float_extend:XF
10514                      (match_operand:SF 1 "register_operand" "0"))))]
10515   "TARGET_80387"
10516   "f<absnegprefix>"
10517   [(set_attr "type" "fsgn")
10518    (set_attr "mode" "XF")])
10520 (define_insn "*<code>extenddfxf2"
10521   [(set (match_operand:XF 0 "register_operand" "=f")
10522         (absneg:XF (float_extend:XF
10523                       (match_operand:DF 1 "register_operand" "0"))))]
10524   "TARGET_80387"
10525   "f<absnegprefix>"
10526   [(set_attr "type" "fsgn")
10527    (set_attr "mode" "XF")])
10529 ;; Copysign instructions
10531 (define_mode_iterator CSGNMODE [SF DF TF])
10532 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10534 (define_expand "copysign<mode>3"
10535   [(match_operand:CSGNMODE 0 "register_operand" "")
10536    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10537    (match_operand:CSGNMODE 2 "register_operand" "")]
10538   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10539    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10541   ix86_expand_copysign (operands);
10542   DONE;
10545 (define_insn_and_split "copysign<mode>3_const"
10546   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10547         (unspec:CSGNMODE
10548           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10549            (match_operand:CSGNMODE 2 "register_operand" "0")
10550            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10551           UNSPEC_COPYSIGN))]
10552   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10553    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10554   "#"
10555   "&& reload_completed"
10556   [(const_int 0)]
10558   ix86_split_copysign_const (operands);
10559   DONE;
10562 (define_insn "copysign<mode>3_var"
10563   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10564         (unspec:CSGNMODE
10565           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10566            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10567            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10568            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10569           UNSPEC_COPYSIGN))
10570    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10571   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10572    || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10573   "#")
10575 (define_split
10576   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10577         (unspec:CSGNMODE
10578           [(match_operand:CSGNMODE 2 "register_operand" "")
10579            (match_operand:CSGNMODE 3 "register_operand" "")
10580            (match_operand:<CSGNVMODE> 4 "" "")
10581            (match_operand:<CSGNVMODE> 5 "" "")]
10582           UNSPEC_COPYSIGN))
10583    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10584   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10585     || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10586    && reload_completed"
10587   [(const_int 0)]
10589   ix86_split_copysign_var (operands);
10590   DONE;
10593 ;; One complement instructions
10595 (define_expand "one_cmpldi2"
10596   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10597         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10598   "TARGET_64BIT"
10599   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10601 (define_insn "*one_cmpldi2_1_rex64"
10602   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10603         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10604   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10605   "not{q}\t%0"
10606   [(set_attr "type" "negnot")
10607    (set_attr "mode" "DI")])
10609 (define_insn "*one_cmpldi2_2_rex64"
10610   [(set (reg FLAGS_REG)
10611         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10612                  (const_int 0)))
10613    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10614         (not:DI (match_dup 1)))]
10615   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10616    && ix86_unary_operator_ok (NOT, DImode, operands)"
10617   "#"
10618   [(set_attr "type" "alu1")
10619    (set_attr "mode" "DI")])
10621 (define_split
10622   [(set (match_operand 0 "flags_reg_operand" "")
10623         (match_operator 2 "compare_operator"
10624           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10625            (const_int 0)]))
10626    (set (match_operand:DI 1 "nonimmediate_operand" "")
10627         (not:DI (match_dup 3)))]
10628   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10629   [(parallel [(set (match_dup 0)
10630                    (match_op_dup 2
10631                      [(xor:DI (match_dup 3) (const_int -1))
10632                       (const_int 0)]))
10633               (set (match_dup 1)
10634                    (xor:DI (match_dup 3) (const_int -1)))])]
10635   "")
10637 (define_expand "one_cmplsi2"
10638   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10639         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10640   ""
10641   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10643 (define_insn "*one_cmplsi2_1"
10644   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10645         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10646   "ix86_unary_operator_ok (NOT, SImode, operands)"
10647   "not{l}\t%0"
10648   [(set_attr "type" "negnot")
10649    (set_attr "mode" "SI")])
10651 ;; ??? Currently never generated - xor is used instead.
10652 (define_insn "*one_cmplsi2_1_zext"
10653   [(set (match_operand:DI 0 "register_operand" "=r")
10654         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10655   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10656   "not{l}\t%k0"
10657   [(set_attr "type" "negnot")
10658    (set_attr "mode" "SI")])
10660 (define_insn "*one_cmplsi2_2"
10661   [(set (reg FLAGS_REG)
10662         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10663                  (const_int 0)))
10664    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10665         (not:SI (match_dup 1)))]
10666   "ix86_match_ccmode (insn, CCNOmode)
10667    && ix86_unary_operator_ok (NOT, SImode, operands)"
10668   "#"
10669   [(set_attr "type" "alu1")
10670    (set_attr "mode" "SI")])
10672 (define_split
10673   [(set (match_operand 0 "flags_reg_operand" "")
10674         (match_operator 2 "compare_operator"
10675           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10676            (const_int 0)]))
10677    (set (match_operand:SI 1 "nonimmediate_operand" "")
10678         (not:SI (match_dup 3)))]
10679   "ix86_match_ccmode (insn, CCNOmode)"
10680   [(parallel [(set (match_dup 0)
10681                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10682                                     (const_int 0)]))
10683               (set (match_dup 1)
10684                    (xor:SI (match_dup 3) (const_int -1)))])]
10685   "")
10687 ;; ??? Currently never generated - xor is used instead.
10688 (define_insn "*one_cmplsi2_2_zext"
10689   [(set (reg FLAGS_REG)
10690         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10691                  (const_int 0)))
10692    (set (match_operand:DI 0 "register_operand" "=r")
10693         (zero_extend:DI (not:SI (match_dup 1))))]
10694   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10695    && ix86_unary_operator_ok (NOT, SImode, operands)"
10696   "#"
10697   [(set_attr "type" "alu1")
10698    (set_attr "mode" "SI")])
10700 (define_split
10701   [(set (match_operand 0 "flags_reg_operand" "")
10702         (match_operator 2 "compare_operator"
10703           [(not:SI (match_operand:SI 3 "register_operand" ""))
10704            (const_int 0)]))
10705    (set (match_operand:DI 1 "register_operand" "")
10706         (zero_extend:DI (not:SI (match_dup 3))))]
10707   "ix86_match_ccmode (insn, CCNOmode)"
10708   [(parallel [(set (match_dup 0)
10709                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10710                                     (const_int 0)]))
10711               (set (match_dup 1)
10712                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10713   "")
10715 (define_expand "one_cmplhi2"
10716   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10717         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10718   "TARGET_HIMODE_MATH"
10719   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10721 (define_insn "*one_cmplhi2_1"
10722   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10723         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10724   "ix86_unary_operator_ok (NOT, HImode, operands)"
10725   "not{w}\t%0"
10726   [(set_attr "type" "negnot")
10727    (set_attr "mode" "HI")])
10729 (define_insn "*one_cmplhi2_2"
10730   [(set (reg FLAGS_REG)
10731         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10732                  (const_int 0)))
10733    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10734         (not:HI (match_dup 1)))]
10735   "ix86_match_ccmode (insn, CCNOmode)
10736    && ix86_unary_operator_ok (NEG, HImode, operands)"
10737   "#"
10738   [(set_attr "type" "alu1")
10739    (set_attr "mode" "HI")])
10741 (define_split
10742   [(set (match_operand 0 "flags_reg_operand" "")
10743         (match_operator 2 "compare_operator"
10744           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10745            (const_int 0)]))
10746    (set (match_operand:HI 1 "nonimmediate_operand" "")
10747         (not:HI (match_dup 3)))]
10748   "ix86_match_ccmode (insn, CCNOmode)"
10749   [(parallel [(set (match_dup 0)
10750                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10751                                     (const_int 0)]))
10752               (set (match_dup 1)
10753                    (xor:HI (match_dup 3) (const_int -1)))])]
10754   "")
10756 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10757 (define_expand "one_cmplqi2"
10758   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10759         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10760   "TARGET_QIMODE_MATH"
10761   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10763 (define_insn "*one_cmplqi2_1"
10764   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10765         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10766   "ix86_unary_operator_ok (NOT, QImode, operands)"
10767   "@
10768    not{b}\t%0
10769    not{l}\t%k0"
10770   [(set_attr "type" "negnot")
10771    (set_attr "mode" "QI,SI")])
10773 (define_insn "*one_cmplqi2_2"
10774   [(set (reg FLAGS_REG)
10775         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10776                  (const_int 0)))
10777    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10778         (not:QI (match_dup 1)))]
10779   "ix86_match_ccmode (insn, CCNOmode)
10780    && ix86_unary_operator_ok (NOT, QImode, operands)"
10781   "#"
10782   [(set_attr "type" "alu1")
10783    (set_attr "mode" "QI")])
10785 (define_split
10786   [(set (match_operand 0 "flags_reg_operand" "")
10787         (match_operator 2 "compare_operator"
10788           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10789            (const_int 0)]))
10790    (set (match_operand:QI 1 "nonimmediate_operand" "")
10791         (not:QI (match_dup 3)))]
10792   "ix86_match_ccmode (insn, CCNOmode)"
10793   [(parallel [(set (match_dup 0)
10794                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10795                                     (const_int 0)]))
10796               (set (match_dup 1)
10797                    (xor:QI (match_dup 3) (const_int -1)))])]
10798   "")
10800 ;; Arithmetic shift instructions
10802 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10803 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10804 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10805 ;; from the assembler input.
10807 ;; This instruction shifts the target reg/mem as usual, but instead of
10808 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10809 ;; is a left shift double, bits are taken from the high order bits of
10810 ;; reg, else if the insn is a shift right double, bits are taken from the
10811 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10812 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10814 ;; Since sh[lr]d does not change the `reg' operand, that is done
10815 ;; separately, making all shifts emit pairs of shift double and normal
10816 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10817 ;; support a 63 bit shift, each shift where the count is in a reg expands
10818 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10820 ;; If the shift count is a constant, we need never emit more than one
10821 ;; shift pair, instead using moves and sign extension for counts greater
10822 ;; than 31.
10824 (define_expand "ashlti3"
10825   [(set (match_operand:TI 0 "register_operand" "")
10826         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
10827                    (match_operand:QI 2 "nonmemory_operand" "")))]
10828   "TARGET_64BIT"
10829   "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
10831 ;; This pattern must be defined before *ashlti3_1 to prevent
10832 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
10834 (define_insn "sse2_ashlti3"
10835   [(set (match_operand:TI 0 "register_operand" "=x")
10836         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10837                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10838   "TARGET_SSE2"
10840   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10841   return "pslldq\t{%2, %0|%0, %2}";
10843   [(set_attr "type" "sseishft")
10844    (set_attr "prefix_data16" "1")
10845    (set_attr "mode" "TI")])
10847 (define_insn "*ashlti3_1"
10848   [(set (match_operand:TI 0 "register_operand" "=&r,r")
10849         (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
10850                    (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
10851    (clobber (reg:CC FLAGS_REG))]
10852   "TARGET_64BIT"
10853   "#"
10854   [(set_attr "type" "multi")])
10856 (define_peephole2
10857   [(match_scratch:DI 3 "r")
10858    (parallel [(set (match_operand:TI 0 "register_operand" "")
10859                    (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10860                               (match_operand:QI 2 "nonmemory_operand" "")))
10861               (clobber (reg:CC FLAGS_REG))])
10862    (match_dup 3)]
10863   "TARGET_64BIT"
10864   [(const_int 0)]
10865   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10867 (define_split
10868   [(set (match_operand:TI 0 "register_operand" "")
10869         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10870                    (match_operand:QI 2 "nonmemory_operand" "")))
10871    (clobber (reg:CC FLAGS_REG))]
10872   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10873                     ? epilogue_completed : reload_completed)"
10874   [(const_int 0)]
10875   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10877 (define_insn "x86_64_shld"
10878   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10879         (ior:DI (ashift:DI (match_dup 0)
10880                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
10881                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10882                   (minus:QI (const_int 64) (match_dup 2)))))
10883    (clobber (reg:CC FLAGS_REG))]
10884   "TARGET_64BIT"
10885   "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10886   [(set_attr "type" "ishift")
10887    (set_attr "prefix_0f" "1")
10888    (set_attr "mode" "DI")
10889    (set_attr "athlon_decode" "vector")
10890    (set_attr "amdfam10_decode" "vector")])
10892 (define_expand "x86_64_shift_adj"
10893   [(set (reg:CCZ FLAGS_REG)
10894         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10895                              (const_int 64))
10896                      (const_int 0)))
10897    (set (match_operand:DI 0 "register_operand" "")
10898         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10899                          (match_operand:DI 1 "register_operand" "")
10900                          (match_dup 0)))
10901    (set (match_dup 1)
10902         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10903                          (match_operand:DI 3 "register_operand" "r")
10904                          (match_dup 1)))]
10905   "TARGET_64BIT"
10906   "")
10908 (define_expand "ashldi3"
10909   [(set (match_operand:DI 0 "shiftdi_operand" "")
10910         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10911                    (match_operand:QI 2 "nonmemory_operand" "")))]
10912   ""
10913   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10915 (define_insn "*ashldi3_1_rex64"
10916   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10917         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10918                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10919    (clobber (reg:CC FLAGS_REG))]
10920   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10922   switch (get_attr_type (insn))
10923     {
10924     case TYPE_ALU:
10925       gcc_assert (operands[2] == const1_rtx);
10926       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10927       return "add{q}\t%0, %0";
10929     case TYPE_LEA:
10930       gcc_assert (CONST_INT_P (operands[2]));
10931       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10932       operands[1] = gen_rtx_MULT (DImode, operands[1],
10933                                   GEN_INT (1 << INTVAL (operands[2])));
10934       return "lea{q}\t{%a1, %0|%0, %a1}";
10936     default:
10937       if (REG_P (operands[2]))
10938         return "sal{q}\t{%b2, %0|%0, %b2}";
10939       else if (operands[2] == const1_rtx
10940                && (TARGET_SHIFT1 || optimize_size))
10941         return "sal{q}\t%0";
10942       else
10943         return "sal{q}\t{%2, %0|%0, %2}";
10944     }
10946   [(set (attr "type")
10947      (cond [(eq_attr "alternative" "1")
10948               (const_string "lea")
10949             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10950                           (const_int 0))
10951                       (match_operand 0 "register_operand" ""))
10952                  (match_operand 2 "const1_operand" ""))
10953               (const_string "alu")
10954            ]
10955            (const_string "ishift")))
10956    (set_attr "mode" "DI")])
10958 ;; Convert lea to the lea pattern to avoid flags dependency.
10959 (define_split
10960   [(set (match_operand:DI 0 "register_operand" "")
10961         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10962                    (match_operand:QI 2 "immediate_operand" "")))
10963    (clobber (reg:CC FLAGS_REG))]
10964   "TARGET_64BIT && reload_completed
10965    && true_regnum (operands[0]) != true_regnum (operands[1])"
10966   [(set (match_dup 0)
10967         (mult:DI (match_dup 1)
10968                  (match_dup 2)))]
10969   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10971 ;; This pattern can't accept a variable shift count, since shifts by
10972 ;; zero don't affect the flags.  We assume that shifts by constant
10973 ;; zero are optimized away.
10974 (define_insn "*ashldi3_cmp_rex64"
10975   [(set (reg FLAGS_REG)
10976         (compare
10977           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10978                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
10979           (const_int 0)))
10980    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10981         (ashift:DI (match_dup 1) (match_dup 2)))]
10982   "TARGET_64BIT
10983    && (optimize_size
10984        || !TARGET_PARTIAL_FLAG_REG_STALL
10985        || (operands[2] == const1_rtx
10986            && (TARGET_SHIFT1
10987                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10988    && ix86_match_ccmode (insn, CCGOCmode)
10989    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10991   switch (get_attr_type (insn))
10992     {
10993     case TYPE_ALU:
10994       gcc_assert (operands[2] == const1_rtx);
10995       return "add{q}\t%0, %0";
10997     default:
10998       if (REG_P (operands[2]))
10999         return "sal{q}\t{%b2, %0|%0, %b2}";
11000       else if (operands[2] == const1_rtx
11001                && (TARGET_SHIFT1 || optimize_size))
11002         return "sal{q}\t%0";
11003       else
11004         return "sal{q}\t{%2, %0|%0, %2}";
11005     }
11007   [(set (attr "type")
11008      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11009                           (const_int 0))
11010                       (match_operand 0 "register_operand" ""))
11011                  (match_operand 2 "const1_operand" ""))
11012               (const_string "alu")
11013            ]
11014            (const_string "ishift")))
11015    (set_attr "mode" "DI")])
11017 (define_insn "*ashldi3_cconly_rex64"
11018   [(set (reg FLAGS_REG)
11019         (compare
11020           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11021                      (match_operand:QI 2 "const_1_to_63_operand" "J"))
11022           (const_int 0)))
11023    (clobber (match_scratch:DI 0 "=r"))]
11024   "TARGET_64BIT
11025    && (optimize_size
11026        || !TARGET_PARTIAL_FLAG_REG_STALL
11027        || (operands[2] == const1_rtx
11028            && (TARGET_SHIFT1
11029                || TARGET_DOUBLE_WITH_ADD)))
11030    && ix86_match_ccmode (insn, CCGOCmode)
11031    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11033   switch (get_attr_type (insn))
11034     {
11035     case TYPE_ALU:
11036       gcc_assert (operands[2] == const1_rtx);
11037       return "add{q}\t%0, %0";
11039     default:
11040       if (REG_P (operands[2]))
11041         return "sal{q}\t{%b2, %0|%0, %b2}";
11042       else if (operands[2] == const1_rtx
11043                && (TARGET_SHIFT1 || optimize_size))
11044         return "sal{q}\t%0";
11045       else
11046         return "sal{q}\t{%2, %0|%0, %2}";
11047     }
11049   [(set (attr "type")
11050      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11051                           (const_int 0))
11052                       (match_operand 0 "register_operand" ""))
11053                  (match_operand 2 "const1_operand" ""))
11054               (const_string "alu")
11055            ]
11056            (const_string "ishift")))
11057    (set_attr "mode" "DI")])
11059 (define_insn "*ashldi3_1"
11060   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11061         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11062                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11063    (clobber (reg:CC FLAGS_REG))]
11064   "!TARGET_64BIT"
11065   "#"
11066   [(set_attr "type" "multi")])
11068 ;; By default we don't ask for a scratch register, because when DImode
11069 ;; values are manipulated, registers are already at a premium.  But if
11070 ;; we have one handy, we won't turn it away.
11071 (define_peephole2
11072   [(match_scratch:SI 3 "r")
11073    (parallel [(set (match_operand:DI 0 "register_operand" "")
11074                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11075                               (match_operand:QI 2 "nonmemory_operand" "")))
11076               (clobber (reg:CC FLAGS_REG))])
11077    (match_dup 3)]
11078   "!TARGET_64BIT && TARGET_CMOVE"
11079   [(const_int 0)]
11080   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11082 (define_split
11083   [(set (match_operand:DI 0 "register_operand" "")
11084         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11085                    (match_operand:QI 2 "nonmemory_operand" "")))
11086    (clobber (reg:CC FLAGS_REG))]
11087   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11088                      ? epilogue_completed : reload_completed)"
11089   [(const_int 0)]
11090   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11092 (define_insn "x86_shld"
11093   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11094         (ior:SI (ashift:SI (match_dup 0)
11095                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
11096                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11097                   (minus:QI (const_int 32) (match_dup 2)))))
11098    (clobber (reg:CC FLAGS_REG))]
11099   ""
11100   "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11101   [(set_attr "type" "ishift")
11102    (set_attr "prefix_0f" "1")
11103    (set_attr "mode" "SI")
11104    (set_attr "pent_pair" "np")
11105    (set_attr "athlon_decode" "vector")
11106    (set_attr "amdfam10_decode" "vector")])
11108 (define_expand "x86_shift_adj_1"
11109   [(set (reg:CCZ FLAGS_REG)
11110         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11111                              (const_int 32))
11112                      (const_int 0)))
11113    (set (match_operand:SI 0 "register_operand" "")
11114         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11115                          (match_operand:SI 1 "register_operand" "")
11116                          (match_dup 0)))
11117    (set (match_dup 1)
11118         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11119                          (match_operand:SI 3 "register_operand" "r")
11120                          (match_dup 1)))]
11121   "TARGET_CMOVE"
11122   "")
11124 (define_expand "x86_shift_adj_2"
11125   [(use (match_operand:SI 0 "register_operand" ""))
11126    (use (match_operand:SI 1 "register_operand" ""))
11127    (use (match_operand:QI 2 "register_operand" ""))]
11128   ""
11130   rtx label = gen_label_rtx ();
11131   rtx tmp;
11133   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11135   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11136   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11137   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11138                               gen_rtx_LABEL_REF (VOIDmode, label),
11139                               pc_rtx);
11140   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11141   JUMP_LABEL (tmp) = label;
11143   emit_move_insn (operands[0], operands[1]);
11144   ix86_expand_clear (operands[1]);
11146   emit_label (label);
11147   LABEL_NUSES (label) = 1;
11149   DONE;
11152 (define_expand "ashlsi3"
11153   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11154         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11155                    (match_operand:QI 2 "nonmemory_operand" "")))]
11156   ""
11157   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11159 (define_insn "*ashlsi3_1"
11160   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11161         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11162                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11163    (clobber (reg:CC FLAGS_REG))]
11164   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11166   switch (get_attr_type (insn))
11167     {
11168     case TYPE_ALU:
11169       gcc_assert (operands[2] == const1_rtx);
11170       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11171       return "add{l}\t%0, %0";
11173     case TYPE_LEA:
11174       return "#";
11176     default:
11177       if (REG_P (operands[2]))
11178         return "sal{l}\t{%b2, %0|%0, %b2}";
11179       else if (operands[2] == const1_rtx
11180                && (TARGET_SHIFT1 || optimize_size))
11181         return "sal{l}\t%0";
11182       else
11183         return "sal{l}\t{%2, %0|%0, %2}";
11184     }
11186   [(set (attr "type")
11187      (cond [(eq_attr "alternative" "1")
11188               (const_string "lea")
11189             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11190                           (const_int 0))
11191                       (match_operand 0 "register_operand" ""))
11192                  (match_operand 2 "const1_operand" ""))
11193               (const_string "alu")
11194            ]
11195            (const_string "ishift")))
11196    (set_attr "mode" "SI")])
11198 ;; Convert lea to the lea pattern to avoid flags dependency.
11199 (define_split
11200   [(set (match_operand 0 "register_operand" "")
11201         (ashift (match_operand 1 "index_register_operand" "")
11202                 (match_operand:QI 2 "const_int_operand" "")))
11203    (clobber (reg:CC FLAGS_REG))]
11204   "reload_completed
11205    && true_regnum (operands[0]) != true_regnum (operands[1])
11206    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11207   [(const_int 0)]
11209   rtx pat;
11210   enum machine_mode mode = GET_MODE (operands[0]);
11212   if (GET_MODE_SIZE (mode) < 4)
11213     operands[0] = gen_lowpart (SImode, operands[0]);
11214   if (mode != Pmode)
11215     operands[1] = gen_lowpart (Pmode, operands[1]);
11216   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11218   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11219   if (Pmode != SImode)
11220     pat = gen_rtx_SUBREG (SImode, pat, 0);
11221   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11222   DONE;
11225 ;; Rare case of shifting RSP is handled by generating move and shift
11226 (define_split
11227   [(set (match_operand 0 "register_operand" "")
11228         (ashift (match_operand 1 "register_operand" "")
11229                 (match_operand:QI 2 "const_int_operand" "")))
11230    (clobber (reg:CC FLAGS_REG))]
11231   "reload_completed
11232    && true_regnum (operands[0]) != true_regnum (operands[1])"
11233   [(const_int 0)]
11235   rtx pat, clob;
11236   emit_move_insn (operands[0], operands[1]);
11237   pat = gen_rtx_SET (VOIDmode, operands[0],
11238                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11239                                      operands[0], operands[2]));
11240   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11241   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11242   DONE;
11245 (define_insn "*ashlsi3_1_zext"
11246   [(set (match_operand:DI 0 "register_operand" "=r,r")
11247         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11248                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11249    (clobber (reg:CC FLAGS_REG))]
11250   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11252   switch (get_attr_type (insn))
11253     {
11254     case TYPE_ALU:
11255       gcc_assert (operands[2] == const1_rtx);
11256       return "add{l}\t%k0, %k0";
11258     case TYPE_LEA:
11259       return "#";
11261     default:
11262       if (REG_P (operands[2]))
11263         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11264       else if (operands[2] == const1_rtx
11265                && (TARGET_SHIFT1 || optimize_size))
11266         return "sal{l}\t%k0";
11267       else
11268         return "sal{l}\t{%2, %k0|%k0, %2}";
11269     }
11271   [(set (attr "type")
11272      (cond [(eq_attr "alternative" "1")
11273               (const_string "lea")
11274             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11275                      (const_int 0))
11276                  (match_operand 2 "const1_operand" ""))
11277               (const_string "alu")
11278            ]
11279            (const_string "ishift")))
11280    (set_attr "mode" "SI")])
11282 ;; Convert lea to the lea pattern to avoid flags dependency.
11283 (define_split
11284   [(set (match_operand:DI 0 "register_operand" "")
11285         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11286                                 (match_operand:QI 2 "const_int_operand" ""))))
11287    (clobber (reg:CC FLAGS_REG))]
11288   "TARGET_64BIT && reload_completed
11289    && true_regnum (operands[0]) != true_regnum (operands[1])"
11290   [(set (match_dup 0) (zero_extend:DI
11291                         (subreg:SI (mult:SI (match_dup 1)
11292                                             (match_dup 2)) 0)))]
11294   operands[1] = gen_lowpart (Pmode, operands[1]);
11295   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11298 ;; This pattern can't accept a variable shift count, since shifts by
11299 ;; zero don't affect the flags.  We assume that shifts by constant
11300 ;; zero are optimized away.
11301 (define_insn "*ashlsi3_cmp"
11302   [(set (reg FLAGS_REG)
11303         (compare
11304           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11305                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11306           (const_int 0)))
11307    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11308         (ashift:SI (match_dup 1) (match_dup 2)))]
11309    "(optimize_size
11310      || !TARGET_PARTIAL_FLAG_REG_STALL
11311      || (operands[2] == const1_rtx
11312          && (TARGET_SHIFT1
11313              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11314    && ix86_match_ccmode (insn, CCGOCmode)
11315    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11317   switch (get_attr_type (insn))
11318     {
11319     case TYPE_ALU:
11320       gcc_assert (operands[2] == const1_rtx);
11321       return "add{l}\t%0, %0";
11323     default:
11324       if (REG_P (operands[2]))
11325         return "sal{l}\t{%b2, %0|%0, %b2}";
11326       else if (operands[2] == const1_rtx
11327                && (TARGET_SHIFT1 || optimize_size))
11328         return "sal{l}\t%0";
11329       else
11330         return "sal{l}\t{%2, %0|%0, %2}";
11331     }
11333   [(set (attr "type")
11334      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11335                           (const_int 0))
11336                       (match_operand 0 "register_operand" ""))
11337                  (match_operand 2 "const1_operand" ""))
11338               (const_string "alu")
11339            ]
11340            (const_string "ishift")))
11341    (set_attr "mode" "SI")])
11343 (define_insn "*ashlsi3_cconly"
11344   [(set (reg FLAGS_REG)
11345         (compare
11346           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11347                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11348           (const_int 0)))
11349    (clobber (match_scratch:SI 0 "=r"))]
11350   "(optimize_size
11351     || !TARGET_PARTIAL_FLAG_REG_STALL
11352     || (operands[2] == const1_rtx
11353         && (TARGET_SHIFT1
11354             || TARGET_DOUBLE_WITH_ADD)))
11355    && ix86_match_ccmode (insn, CCGOCmode)
11356    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11358   switch (get_attr_type (insn))
11359     {
11360     case TYPE_ALU:
11361       gcc_assert (operands[2] == const1_rtx);
11362       return "add{l}\t%0, %0";
11364     default:
11365       if (REG_P (operands[2]))
11366         return "sal{l}\t{%b2, %0|%0, %b2}";
11367       else if (operands[2] == const1_rtx
11368                && (TARGET_SHIFT1 || optimize_size))
11369         return "sal{l}\t%0";
11370       else
11371         return "sal{l}\t{%2, %0|%0, %2}";
11372     }
11374   [(set (attr "type")
11375      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11376                           (const_int 0))
11377                       (match_operand 0 "register_operand" ""))
11378                  (match_operand 2 "const1_operand" ""))
11379               (const_string "alu")
11380            ]
11381            (const_string "ishift")))
11382    (set_attr "mode" "SI")])
11384 (define_insn "*ashlsi3_cmp_zext"
11385   [(set (reg FLAGS_REG)
11386         (compare
11387           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11388                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11389           (const_int 0)))
11390    (set (match_operand:DI 0 "register_operand" "=r")
11391         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11392   "TARGET_64BIT
11393    && (optimize_size
11394        || !TARGET_PARTIAL_FLAG_REG_STALL
11395        || (operands[2] == const1_rtx
11396            && (TARGET_SHIFT1
11397                || TARGET_DOUBLE_WITH_ADD)))
11398    && ix86_match_ccmode (insn, CCGOCmode)
11399    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11401   switch (get_attr_type (insn))
11402     {
11403     case TYPE_ALU:
11404       gcc_assert (operands[2] == const1_rtx);
11405       return "add{l}\t%k0, %k0";
11407     default:
11408       if (REG_P (operands[2]))
11409         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11410       else if (operands[2] == const1_rtx
11411                && (TARGET_SHIFT1 || optimize_size))
11412         return "sal{l}\t%k0";
11413       else
11414         return "sal{l}\t{%2, %k0|%k0, %2}";
11415     }
11417   [(set (attr "type")
11418      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11419                      (const_int 0))
11420                  (match_operand 2 "const1_operand" ""))
11421               (const_string "alu")
11422            ]
11423            (const_string "ishift")))
11424    (set_attr "mode" "SI")])
11426 (define_expand "ashlhi3"
11427   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11428         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11429                    (match_operand:QI 2 "nonmemory_operand" "")))]
11430   "TARGET_HIMODE_MATH"
11431   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11433 (define_insn "*ashlhi3_1_lea"
11434   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11435         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11436                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11437    (clobber (reg:CC FLAGS_REG))]
11438   "!TARGET_PARTIAL_REG_STALL
11439    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11441   switch (get_attr_type (insn))
11442     {
11443     case TYPE_LEA:
11444       return "#";
11445     case TYPE_ALU:
11446       gcc_assert (operands[2] == const1_rtx);
11447       return "add{w}\t%0, %0";
11449     default:
11450       if (REG_P (operands[2]))
11451         return "sal{w}\t{%b2, %0|%0, %b2}";
11452       else if (operands[2] == const1_rtx
11453                && (TARGET_SHIFT1 || optimize_size))
11454         return "sal{w}\t%0";
11455       else
11456         return "sal{w}\t{%2, %0|%0, %2}";
11457     }
11459   [(set (attr "type")
11460      (cond [(eq_attr "alternative" "1")
11461               (const_string "lea")
11462             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11463                           (const_int 0))
11464                       (match_operand 0 "register_operand" ""))
11465                  (match_operand 2 "const1_operand" ""))
11466               (const_string "alu")
11467            ]
11468            (const_string "ishift")))
11469    (set_attr "mode" "HI,SI")])
11471 (define_insn "*ashlhi3_1"
11472   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11473         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11474                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11475    (clobber (reg:CC FLAGS_REG))]
11476   "TARGET_PARTIAL_REG_STALL
11477    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11479   switch (get_attr_type (insn))
11480     {
11481     case TYPE_ALU:
11482       gcc_assert (operands[2] == const1_rtx);
11483       return "add{w}\t%0, %0";
11485     default:
11486       if (REG_P (operands[2]))
11487         return "sal{w}\t{%b2, %0|%0, %b2}";
11488       else if (operands[2] == const1_rtx
11489                && (TARGET_SHIFT1 || optimize_size))
11490         return "sal{w}\t%0";
11491       else
11492         return "sal{w}\t{%2, %0|%0, %2}";
11493     }
11495   [(set (attr "type")
11496      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11497                           (const_int 0))
11498                       (match_operand 0 "register_operand" ""))
11499                  (match_operand 2 "const1_operand" ""))
11500               (const_string "alu")
11501            ]
11502            (const_string "ishift")))
11503    (set_attr "mode" "HI")])
11505 ;; This pattern can't accept a variable shift count, since shifts by
11506 ;; zero don't affect the flags.  We assume that shifts by constant
11507 ;; zero are optimized away.
11508 (define_insn "*ashlhi3_cmp"
11509   [(set (reg FLAGS_REG)
11510         (compare
11511           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11512                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11513           (const_int 0)))
11514    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11515         (ashift:HI (match_dup 1) (match_dup 2)))]
11516   "(optimize_size
11517     || !TARGET_PARTIAL_FLAG_REG_STALL
11518     || (operands[2] == const1_rtx
11519         && (TARGET_SHIFT1
11520             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11521    && ix86_match_ccmode (insn, CCGOCmode)
11522    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11524   switch (get_attr_type (insn))
11525     {
11526     case TYPE_ALU:
11527       gcc_assert (operands[2] == const1_rtx);
11528       return "add{w}\t%0, %0";
11530     default:
11531       if (REG_P (operands[2]))
11532         return "sal{w}\t{%b2, %0|%0, %b2}";
11533       else if (operands[2] == const1_rtx
11534                && (TARGET_SHIFT1 || optimize_size))
11535         return "sal{w}\t%0";
11536       else
11537         return "sal{w}\t{%2, %0|%0, %2}";
11538     }
11540   [(set (attr "type")
11541      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11542                           (const_int 0))
11543                       (match_operand 0 "register_operand" ""))
11544                  (match_operand 2 "const1_operand" ""))
11545               (const_string "alu")
11546            ]
11547            (const_string "ishift")))
11548    (set_attr "mode" "HI")])
11550 (define_insn "*ashlhi3_cconly"
11551   [(set (reg FLAGS_REG)
11552         (compare
11553           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11554                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11555           (const_int 0)))
11556    (clobber (match_scratch:HI 0 "=r"))]
11557   "(optimize_size
11558     || !TARGET_PARTIAL_FLAG_REG_STALL
11559     || (operands[2] == const1_rtx
11560         && (TARGET_SHIFT1
11561             || TARGET_DOUBLE_WITH_ADD)))
11562    && ix86_match_ccmode (insn, CCGOCmode)
11563    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11565   switch (get_attr_type (insn))
11566     {
11567     case TYPE_ALU:
11568       gcc_assert (operands[2] == const1_rtx);
11569       return "add{w}\t%0, %0";
11571     default:
11572       if (REG_P (operands[2]))
11573         return "sal{w}\t{%b2, %0|%0, %b2}";
11574       else if (operands[2] == const1_rtx
11575                && (TARGET_SHIFT1 || optimize_size))
11576         return "sal{w}\t%0";
11577       else
11578         return "sal{w}\t{%2, %0|%0, %2}";
11579     }
11581   [(set (attr "type")
11582      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11583                           (const_int 0))
11584                       (match_operand 0 "register_operand" ""))
11585                  (match_operand 2 "const1_operand" ""))
11586               (const_string "alu")
11587            ]
11588            (const_string "ishift")))
11589    (set_attr "mode" "HI")])
11591 (define_expand "ashlqi3"
11592   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11593         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11594                    (match_operand:QI 2 "nonmemory_operand" "")))]
11595   "TARGET_QIMODE_MATH"
11596   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11598 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11600 (define_insn "*ashlqi3_1_lea"
11601   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11602         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11603                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11604    (clobber (reg:CC FLAGS_REG))]
11605   "!TARGET_PARTIAL_REG_STALL
11606    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11608   switch (get_attr_type (insn))
11609     {
11610     case TYPE_LEA:
11611       return "#";
11612     case TYPE_ALU:
11613       gcc_assert (operands[2] == const1_rtx);
11614       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11615         return "add{l}\t%k0, %k0";
11616       else
11617         return "add{b}\t%0, %0";
11619     default:
11620       if (REG_P (operands[2]))
11621         {
11622           if (get_attr_mode (insn) == MODE_SI)
11623             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11624           else
11625             return "sal{b}\t{%b2, %0|%0, %b2}";
11626         }
11627       else if (operands[2] == const1_rtx
11628                && (TARGET_SHIFT1 || optimize_size))
11629         {
11630           if (get_attr_mode (insn) == MODE_SI)
11631             return "sal{l}\t%0";
11632           else
11633             return "sal{b}\t%0";
11634         }
11635       else
11636         {
11637           if (get_attr_mode (insn) == MODE_SI)
11638             return "sal{l}\t{%2, %k0|%k0, %2}";
11639           else
11640             return "sal{b}\t{%2, %0|%0, %2}";
11641         }
11642     }
11644   [(set (attr "type")
11645      (cond [(eq_attr "alternative" "2")
11646               (const_string "lea")
11647             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11648                           (const_int 0))
11649                       (match_operand 0 "register_operand" ""))
11650                  (match_operand 2 "const1_operand" ""))
11651               (const_string "alu")
11652            ]
11653            (const_string "ishift")))
11654    (set_attr "mode" "QI,SI,SI")])
11656 (define_insn "*ashlqi3_1"
11657   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11658         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11659                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11660    (clobber (reg:CC FLAGS_REG))]
11661   "TARGET_PARTIAL_REG_STALL
11662    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11664   switch (get_attr_type (insn))
11665     {
11666     case TYPE_ALU:
11667       gcc_assert (operands[2] == const1_rtx);
11668       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11669         return "add{l}\t%k0, %k0";
11670       else
11671         return "add{b}\t%0, %0";
11673     default:
11674       if (REG_P (operands[2]))
11675         {
11676           if (get_attr_mode (insn) == MODE_SI)
11677             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11678           else
11679             return "sal{b}\t{%b2, %0|%0, %b2}";
11680         }
11681       else if (operands[2] == const1_rtx
11682                && (TARGET_SHIFT1 || optimize_size))
11683         {
11684           if (get_attr_mode (insn) == MODE_SI)
11685             return "sal{l}\t%0";
11686           else
11687             return "sal{b}\t%0";
11688         }
11689       else
11690         {
11691           if (get_attr_mode (insn) == MODE_SI)
11692             return "sal{l}\t{%2, %k0|%k0, %2}";
11693           else
11694             return "sal{b}\t{%2, %0|%0, %2}";
11695         }
11696     }
11698   [(set (attr "type")
11699      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11700                           (const_int 0))
11701                       (match_operand 0 "register_operand" ""))
11702                  (match_operand 2 "const1_operand" ""))
11703               (const_string "alu")
11704            ]
11705            (const_string "ishift")))
11706    (set_attr "mode" "QI,SI")])
11708 ;; This pattern can't accept a variable shift count, since shifts by
11709 ;; zero don't affect the flags.  We assume that shifts by constant
11710 ;; zero are optimized away.
11711 (define_insn "*ashlqi3_cmp"
11712   [(set (reg FLAGS_REG)
11713         (compare
11714           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11715                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11716           (const_int 0)))
11717    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11718         (ashift:QI (match_dup 1) (match_dup 2)))]
11719   "(optimize_size
11720     || !TARGET_PARTIAL_FLAG_REG_STALL
11721     || (operands[2] == const1_rtx
11722         && (TARGET_SHIFT1
11723             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11724    && ix86_match_ccmode (insn, CCGOCmode)
11725    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11727   switch (get_attr_type (insn))
11728     {
11729     case TYPE_ALU:
11730       gcc_assert (operands[2] == const1_rtx);
11731       return "add{b}\t%0, %0";
11733     default:
11734       if (REG_P (operands[2]))
11735         return "sal{b}\t{%b2, %0|%0, %b2}";
11736       else if (operands[2] == const1_rtx
11737                && (TARGET_SHIFT1 || optimize_size))
11738         return "sal{b}\t%0";
11739       else
11740         return "sal{b}\t{%2, %0|%0, %2}";
11741     }
11743   [(set (attr "type")
11744      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11745                           (const_int 0))
11746                       (match_operand 0 "register_operand" ""))
11747                  (match_operand 2 "const1_operand" ""))
11748               (const_string "alu")
11749            ]
11750            (const_string "ishift")))
11751    (set_attr "mode" "QI")])
11753 (define_insn "*ashlqi3_cconly"
11754   [(set (reg FLAGS_REG)
11755         (compare
11756           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11757                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11758           (const_int 0)))
11759    (clobber (match_scratch:QI 0 "=q"))]
11760   "(optimize_size
11761     || !TARGET_PARTIAL_FLAG_REG_STALL
11762     || (operands[2] == const1_rtx
11763         && (TARGET_SHIFT1
11764             || TARGET_DOUBLE_WITH_ADD)))
11765    && ix86_match_ccmode (insn, CCGOCmode)
11766    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11768   switch (get_attr_type (insn))
11769     {
11770     case TYPE_ALU:
11771       gcc_assert (operands[2] == const1_rtx);
11772       return "add{b}\t%0, %0";
11774     default:
11775       if (REG_P (operands[2]))
11776         return "sal{b}\t{%b2, %0|%0, %b2}";
11777       else if (operands[2] == const1_rtx
11778                && (TARGET_SHIFT1 || optimize_size))
11779         return "sal{b}\t%0";
11780       else
11781         return "sal{b}\t{%2, %0|%0, %2}";
11782     }
11784   [(set (attr "type")
11785      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11786                           (const_int 0))
11787                       (match_operand 0 "register_operand" ""))
11788                  (match_operand 2 "const1_operand" ""))
11789               (const_string "alu")
11790            ]
11791            (const_string "ishift")))
11792    (set_attr "mode" "QI")])
11794 ;; See comment above `ashldi3' about how this works.
11796 (define_expand "ashrti3"
11797   [(set (match_operand:TI 0 "register_operand" "")
11798         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11799                      (match_operand:QI 2 "nonmemory_operand" "")))]
11800   "TARGET_64BIT"
11801   "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
11803 (define_insn "*ashrti3_1"
11804   [(set (match_operand:TI 0 "register_operand" "=r")
11805         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11806                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
11807    (clobber (reg:CC FLAGS_REG))]
11808   "TARGET_64BIT"
11809   "#"
11810   [(set_attr "type" "multi")])
11812 (define_peephole2
11813   [(match_scratch:DI 3 "r")
11814    (parallel [(set (match_operand:TI 0 "register_operand" "")
11815                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11816                                 (match_operand:QI 2 "nonmemory_operand" "")))
11817               (clobber (reg:CC FLAGS_REG))])
11818    (match_dup 3)]
11819   "TARGET_64BIT"
11820   [(const_int 0)]
11821   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11823 (define_split
11824   [(set (match_operand:TI 0 "register_operand" "")
11825         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11826                      (match_operand:QI 2 "nonmemory_operand" "")))
11827    (clobber (reg:CC FLAGS_REG))]
11828   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11829                     ? epilogue_completed : reload_completed)"
11830   [(const_int 0)]
11831   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11833 (define_insn "x86_64_shrd"
11834   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11835         (ior:DI (ashiftrt:DI (match_dup 0)
11836                   (match_operand:QI 2 "nonmemory_operand" "Jc"))
11837                 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11838                   (minus:QI (const_int 64) (match_dup 2)))))
11839    (clobber (reg:CC FLAGS_REG))]
11840   "TARGET_64BIT"
11841   "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11842   [(set_attr "type" "ishift")
11843    (set_attr "prefix_0f" "1")
11844    (set_attr "mode" "DI")
11845    (set_attr "athlon_decode" "vector")
11846    (set_attr "amdfam10_decode" "vector")])
11848 (define_expand "ashrdi3"
11849   [(set (match_operand:DI 0 "shiftdi_operand" "")
11850         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11851                      (match_operand:QI 2 "nonmemory_operand" "")))]
11852   ""
11853   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11855 (define_insn "*ashrdi3_63_rex64"
11856   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11857         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11858                      (match_operand:DI 2 "const_int_operand" "i,i")))
11859    (clobber (reg:CC FLAGS_REG))]
11860   "TARGET_64BIT && INTVAL (operands[2]) == 63
11861    && (TARGET_USE_CLTD || optimize_size)
11862    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11863   "@
11864    {cqto|cqo}
11865    sar{q}\t{%2, %0|%0, %2}"
11866   [(set_attr "type" "imovx,ishift")
11867    (set_attr "prefix_0f" "0,*")
11868    (set_attr "length_immediate" "0,*")
11869    (set_attr "modrm" "0,1")
11870    (set_attr "mode" "DI")])
11872 (define_insn "*ashrdi3_1_one_bit_rex64"
11873   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11874         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11875                      (match_operand:QI 2 "const1_operand" "")))
11876    (clobber (reg:CC FLAGS_REG))]
11877   "TARGET_64BIT
11878    && (TARGET_SHIFT1 || optimize_size)
11879    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11880   "sar{q}\t%0"
11881   [(set_attr "type" "ishift")
11882    (set (attr "length")
11883      (if_then_else (match_operand:DI 0 "register_operand" "")
11884         (const_string "2")
11885         (const_string "*")))])
11887 (define_insn "*ashrdi3_1_rex64"
11888   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11889         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11890                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11891    (clobber (reg:CC FLAGS_REG))]
11892   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11893   "@
11894    sar{q}\t{%2, %0|%0, %2}
11895    sar{q}\t{%b2, %0|%0, %b2}"
11896   [(set_attr "type" "ishift")
11897    (set_attr "mode" "DI")])
11899 ;; This pattern can't accept a variable shift count, since shifts by
11900 ;; zero don't affect the flags.  We assume that shifts by constant
11901 ;; zero are optimized away.
11902 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11903   [(set (reg FLAGS_REG)
11904         (compare
11905           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11906                        (match_operand:QI 2 "const1_operand" ""))
11907           (const_int 0)))
11908    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11909         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11910   "TARGET_64BIT
11911    && (TARGET_SHIFT1 || optimize_size)
11912    && ix86_match_ccmode (insn, CCGOCmode)
11913    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11914   "sar{q}\t%0"
11915   [(set_attr "type" "ishift")
11916    (set (attr "length")
11917      (if_then_else (match_operand:DI 0 "register_operand" "")
11918         (const_string "2")
11919         (const_string "*")))])
11921 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11922   [(set (reg FLAGS_REG)
11923         (compare
11924           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11925                        (match_operand:QI 2 "const1_operand" ""))
11926           (const_int 0)))
11927    (clobber (match_scratch:DI 0 "=r"))]
11928   "TARGET_64BIT
11929    && (TARGET_SHIFT1 || optimize_size)
11930    && ix86_match_ccmode (insn, CCGOCmode)
11931    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11932   "sar{q}\t%0"
11933   [(set_attr "type" "ishift")
11934    (set_attr "length" "2")])
11936 ;; This pattern can't accept a variable shift count, since shifts by
11937 ;; zero don't affect the flags.  We assume that shifts by constant
11938 ;; zero are optimized away.
11939 (define_insn "*ashrdi3_cmp_rex64"
11940   [(set (reg FLAGS_REG)
11941         (compare
11942           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11943                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11944           (const_int 0)))
11945    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11946         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11947   "TARGET_64BIT
11948    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11949    && ix86_match_ccmode (insn, CCGOCmode)
11950    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11951   "sar{q}\t{%2, %0|%0, %2}"
11952   [(set_attr "type" "ishift")
11953    (set_attr "mode" "DI")])
11955 (define_insn "*ashrdi3_cconly_rex64"
11956   [(set (reg FLAGS_REG)
11957         (compare
11958           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11959                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
11960           (const_int 0)))
11961    (clobber (match_scratch:DI 0 "=r"))]
11962   "TARGET_64BIT
11963    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
11964    && ix86_match_ccmode (insn, CCGOCmode)
11965    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11966   "sar{q}\t{%2, %0|%0, %2}"
11967   [(set_attr "type" "ishift")
11968    (set_attr "mode" "DI")])
11970 (define_insn "*ashrdi3_1"
11971   [(set (match_operand:DI 0 "register_operand" "=r")
11972         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11973                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
11974    (clobber (reg:CC FLAGS_REG))]
11975   "!TARGET_64BIT"
11976   "#"
11977   [(set_attr "type" "multi")])
11979 ;; By default we don't ask for a scratch register, because when DImode
11980 ;; values are manipulated, registers are already at a premium.  But if
11981 ;; we have one handy, we won't turn it away.
11982 (define_peephole2
11983   [(match_scratch:SI 3 "r")
11984    (parallel [(set (match_operand:DI 0 "register_operand" "")
11985                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11986                                 (match_operand:QI 2 "nonmemory_operand" "")))
11987               (clobber (reg:CC FLAGS_REG))])
11988    (match_dup 3)]
11989   "!TARGET_64BIT && TARGET_CMOVE"
11990   [(const_int 0)]
11991   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11993 (define_split
11994   [(set (match_operand:DI 0 "register_operand" "")
11995         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11996                      (match_operand:QI 2 "nonmemory_operand" "")))
11997    (clobber (reg:CC FLAGS_REG))]
11998   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11999                      ? epilogue_completed : reload_completed)"
12000   [(const_int 0)]
12001   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12003 (define_insn "x86_shrd"
12004   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12005         (ior:SI (ashiftrt:SI (match_dup 0)
12006                   (match_operand:QI 2 "nonmemory_operand" "Ic"))
12007                 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12008                   (minus:QI (const_int 32) (match_dup 2)))))
12009    (clobber (reg:CC FLAGS_REG))]
12010   ""
12011   "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12012   [(set_attr "type" "ishift")
12013    (set_attr "prefix_0f" "1")
12014    (set_attr "pent_pair" "np")
12015    (set_attr "mode" "SI")])
12017 (define_expand "x86_shift_adj_3"
12018   [(use (match_operand:SI 0 "register_operand" ""))
12019    (use (match_operand:SI 1 "register_operand" ""))
12020    (use (match_operand:QI 2 "register_operand" ""))]
12021   ""
12023   rtx label = gen_label_rtx ();
12024   rtx tmp;
12026   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12028   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12029   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12030   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12031                               gen_rtx_LABEL_REF (VOIDmode, label),
12032                               pc_rtx);
12033   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12034   JUMP_LABEL (tmp) = label;
12036   emit_move_insn (operands[0], operands[1]);
12037   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12039   emit_label (label);
12040   LABEL_NUSES (label) = 1;
12042   DONE;
12045 (define_insn "ashrsi3_31"
12046   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12047         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12048                      (match_operand:SI 2 "const_int_operand" "i,i")))
12049    (clobber (reg:CC FLAGS_REG))]
12050   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12051    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12052   "@
12053    {cltd|cdq}
12054    sar{l}\t{%2, %0|%0, %2}"
12055   [(set_attr "type" "imovx,ishift")
12056    (set_attr "prefix_0f" "0,*")
12057    (set_attr "length_immediate" "0,*")
12058    (set_attr "modrm" "0,1")
12059    (set_attr "mode" "SI")])
12061 (define_insn "*ashrsi3_31_zext"
12062   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12063         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12064                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12065    (clobber (reg:CC FLAGS_REG))]
12066   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12067    && INTVAL (operands[2]) == 31
12068    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12069   "@
12070    {cltd|cdq}
12071    sar{l}\t{%2, %k0|%k0, %2}"
12072   [(set_attr "type" "imovx,ishift")
12073    (set_attr "prefix_0f" "0,*")
12074    (set_attr "length_immediate" "0,*")
12075    (set_attr "modrm" "0,1")
12076    (set_attr "mode" "SI")])
12078 (define_expand "ashrsi3"
12079   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12080         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12081                      (match_operand:QI 2 "nonmemory_operand" "")))]
12082   ""
12083   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12085 (define_insn "*ashrsi3_1_one_bit"
12086   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12087         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12088                      (match_operand:QI 2 "const1_operand" "")))
12089    (clobber (reg:CC FLAGS_REG))]
12090   "(TARGET_SHIFT1 || optimize_size)
12091    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12092   "sar{l}\t%0"
12093   [(set_attr "type" "ishift")
12094    (set (attr "length")
12095      (if_then_else (match_operand:SI 0 "register_operand" "")
12096         (const_string "2")
12097         (const_string "*")))])
12099 (define_insn "*ashrsi3_1_one_bit_zext"
12100   [(set (match_operand:DI 0 "register_operand" "=r")
12101         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12102                                      (match_operand:QI 2 "const1_operand" ""))))
12103    (clobber (reg:CC FLAGS_REG))]
12104   "TARGET_64BIT
12105    && (TARGET_SHIFT1 || optimize_size)
12106    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12107   "sar{l}\t%k0"
12108   [(set_attr "type" "ishift")
12109    (set_attr "length" "2")])
12111 (define_insn "*ashrsi3_1"
12112   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12113         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12114                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12115    (clobber (reg:CC FLAGS_REG))]
12116   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12117   "@
12118    sar{l}\t{%2, %0|%0, %2}
12119    sar{l}\t{%b2, %0|%0, %b2}"
12120   [(set_attr "type" "ishift")
12121    (set_attr "mode" "SI")])
12123 (define_insn "*ashrsi3_1_zext"
12124   [(set (match_operand:DI 0 "register_operand" "=r,r")
12125         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12126                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12127    (clobber (reg:CC FLAGS_REG))]
12128   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12129   "@
12130    sar{l}\t{%2, %k0|%k0, %2}
12131    sar{l}\t{%b2, %k0|%k0, %b2}"
12132   [(set_attr "type" "ishift")
12133    (set_attr "mode" "SI")])
12135 ;; This pattern can't accept a variable shift count, since shifts by
12136 ;; zero don't affect the flags.  We assume that shifts by constant
12137 ;; zero are optimized away.
12138 (define_insn "*ashrsi3_one_bit_cmp"
12139   [(set (reg FLAGS_REG)
12140         (compare
12141           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12142                        (match_operand:QI 2 "const1_operand" ""))
12143           (const_int 0)))
12144    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12145         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12146   "(TARGET_SHIFT1 || optimize_size)
12147    && ix86_match_ccmode (insn, CCGOCmode)
12148    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12149   "sar{l}\t%0"
12150   [(set_attr "type" "ishift")
12151    (set (attr "length")
12152      (if_then_else (match_operand:SI 0 "register_operand" "")
12153         (const_string "2")
12154         (const_string "*")))])
12156 (define_insn "*ashrsi3_one_bit_cconly"
12157   [(set (reg FLAGS_REG)
12158         (compare
12159           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12160                        (match_operand:QI 2 "const1_operand" ""))
12161           (const_int 0)))
12162    (clobber (match_scratch:SI 0 "=r"))]
12163   "(TARGET_SHIFT1 || optimize_size)
12164    && ix86_match_ccmode (insn, CCGOCmode)
12165    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12166   "sar{l}\t%0"
12167   [(set_attr "type" "ishift")
12168    (set_attr "length" "2")])
12170 (define_insn "*ashrsi3_one_bit_cmp_zext"
12171   [(set (reg FLAGS_REG)
12172         (compare
12173           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12174                        (match_operand:QI 2 "const1_operand" ""))
12175           (const_int 0)))
12176    (set (match_operand:DI 0 "register_operand" "=r")
12177         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12178   "TARGET_64BIT
12179    && (TARGET_SHIFT1 || optimize_size)
12180    && ix86_match_ccmode (insn, CCmode)
12181    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12182   "sar{l}\t%k0"
12183   [(set_attr "type" "ishift")
12184    (set_attr "length" "2")])
12186 ;; This pattern can't accept a variable shift count, since shifts by
12187 ;; zero don't affect the flags.  We assume that shifts by constant
12188 ;; zero are optimized away.
12189 (define_insn "*ashrsi3_cmp"
12190   [(set (reg FLAGS_REG)
12191         (compare
12192           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12193                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12194           (const_int 0)))
12195    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12196         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12197   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12198    && ix86_match_ccmode (insn, CCGOCmode)
12199    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12200   "sar{l}\t{%2, %0|%0, %2}"
12201   [(set_attr "type" "ishift")
12202    (set_attr "mode" "SI")])
12204 (define_insn "*ashrsi3_cconly"
12205   [(set (reg FLAGS_REG)
12206         (compare
12207           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12208                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12209           (const_int 0)))
12210    (clobber (match_scratch:SI 0 "=r"))]
12211   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12212    && ix86_match_ccmode (insn, CCGOCmode)
12213    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12214   "sar{l}\t{%2, %0|%0, %2}"
12215   [(set_attr "type" "ishift")
12216    (set_attr "mode" "SI")])
12218 (define_insn "*ashrsi3_cmp_zext"
12219   [(set (reg FLAGS_REG)
12220         (compare
12221           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12222                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12223           (const_int 0)))
12224    (set (match_operand:DI 0 "register_operand" "=r")
12225         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12226   "TARGET_64BIT
12227    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12228    && ix86_match_ccmode (insn, CCGOCmode)
12229    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12230   "sar{l}\t{%2, %k0|%k0, %2}"
12231   [(set_attr "type" "ishift")
12232    (set_attr "mode" "SI")])
12234 (define_expand "ashrhi3"
12235   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12236         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12237                      (match_operand:QI 2 "nonmemory_operand" "")))]
12238   "TARGET_HIMODE_MATH"
12239   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12241 (define_insn "*ashrhi3_1_one_bit"
12242   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12243         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12244                      (match_operand:QI 2 "const1_operand" "")))
12245    (clobber (reg:CC FLAGS_REG))]
12246   "(TARGET_SHIFT1 || optimize_size)
12247    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12248   "sar{w}\t%0"
12249   [(set_attr "type" "ishift")
12250    (set (attr "length")
12251      (if_then_else (match_operand 0 "register_operand" "")
12252         (const_string "2")
12253         (const_string "*")))])
12255 (define_insn "*ashrhi3_1"
12256   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12257         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12258                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12259    (clobber (reg:CC FLAGS_REG))]
12260   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12261   "@
12262    sar{w}\t{%2, %0|%0, %2}
12263    sar{w}\t{%b2, %0|%0, %b2}"
12264   [(set_attr "type" "ishift")
12265    (set_attr "mode" "HI")])
12267 ;; This pattern can't accept a variable shift count, since shifts by
12268 ;; zero don't affect the flags.  We assume that shifts by constant
12269 ;; zero are optimized away.
12270 (define_insn "*ashrhi3_one_bit_cmp"
12271   [(set (reg FLAGS_REG)
12272         (compare
12273           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12274                        (match_operand:QI 2 "const1_operand" ""))
12275           (const_int 0)))
12276    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12277         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12278   "(TARGET_SHIFT1 || optimize_size)
12279    && ix86_match_ccmode (insn, CCGOCmode)
12280    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12281   "sar{w}\t%0"
12282   [(set_attr "type" "ishift")
12283    (set (attr "length")
12284      (if_then_else (match_operand 0 "register_operand" "")
12285         (const_string "2")
12286         (const_string "*")))])
12288 (define_insn "*ashrhi3_one_bit_cconly"
12289   [(set (reg FLAGS_REG)
12290         (compare
12291           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12292                        (match_operand:QI 2 "const1_operand" ""))
12293           (const_int 0)))
12294    (clobber (match_scratch:HI 0 "=r"))]
12295   "(TARGET_SHIFT1 || optimize_size)
12296    && ix86_match_ccmode (insn, CCGOCmode)
12297    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12298   "sar{w}\t%0"
12299   [(set_attr "type" "ishift")
12300    (set_attr "length" "2")])
12302 ;; This pattern can't accept a variable shift count, since shifts by
12303 ;; zero don't affect the flags.  We assume that shifts by constant
12304 ;; zero are optimized away.
12305 (define_insn "*ashrhi3_cmp"
12306   [(set (reg FLAGS_REG)
12307         (compare
12308           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12309                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12310           (const_int 0)))
12311    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12312         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12313   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12314    && ix86_match_ccmode (insn, CCGOCmode)
12315    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12316   "sar{w}\t{%2, %0|%0, %2}"
12317   [(set_attr "type" "ishift")
12318    (set_attr "mode" "HI")])
12320 (define_insn "*ashrhi3_cconly"
12321   [(set (reg FLAGS_REG)
12322         (compare
12323           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12324                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12325           (const_int 0)))
12326    (clobber (match_scratch:HI 0 "=r"))]
12327   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12328    && ix86_match_ccmode (insn, CCGOCmode)
12329    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12330   "sar{w}\t{%2, %0|%0, %2}"
12331   [(set_attr "type" "ishift")
12332    (set_attr "mode" "HI")])
12334 (define_expand "ashrqi3"
12335   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12336         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12337                      (match_operand:QI 2 "nonmemory_operand" "")))]
12338   "TARGET_QIMODE_MATH"
12339   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12341 (define_insn "*ashrqi3_1_one_bit"
12342   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12343         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12344                      (match_operand:QI 2 "const1_operand" "")))
12345    (clobber (reg:CC FLAGS_REG))]
12346   "(TARGET_SHIFT1 || optimize_size)
12347    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12348   "sar{b}\t%0"
12349   [(set_attr "type" "ishift")
12350    (set (attr "length")
12351      (if_then_else (match_operand 0 "register_operand" "")
12352         (const_string "2")
12353         (const_string "*")))])
12355 (define_insn "*ashrqi3_1_one_bit_slp"
12356   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12357         (ashiftrt:QI (match_dup 0)
12358                      (match_operand:QI 1 "const1_operand" "")))
12359    (clobber (reg:CC FLAGS_REG))]
12360   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12361    && (TARGET_SHIFT1 || optimize_size)
12362    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12363   "sar{b}\t%0"
12364   [(set_attr "type" "ishift1")
12365    (set (attr "length")
12366      (if_then_else (match_operand 0 "register_operand" "")
12367         (const_string "2")
12368         (const_string "*")))])
12370 (define_insn "*ashrqi3_1"
12371   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12372         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12373                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12374    (clobber (reg:CC FLAGS_REG))]
12375   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12376   "@
12377    sar{b}\t{%2, %0|%0, %2}
12378    sar{b}\t{%b2, %0|%0, %b2}"
12379   [(set_attr "type" "ishift")
12380    (set_attr "mode" "QI")])
12382 (define_insn "*ashrqi3_1_slp"
12383   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12384         (ashiftrt:QI (match_dup 0)
12385                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12386    (clobber (reg:CC FLAGS_REG))]
12387   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12388    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12389   "@
12390    sar{b}\t{%1, %0|%0, %1}
12391    sar{b}\t{%b1, %0|%0, %b1}"
12392   [(set_attr "type" "ishift1")
12393    (set_attr "mode" "QI")])
12395 ;; This pattern can't accept a variable shift count, since shifts by
12396 ;; zero don't affect the flags.  We assume that shifts by constant
12397 ;; zero are optimized away.
12398 (define_insn "*ashrqi3_one_bit_cmp"
12399   [(set (reg FLAGS_REG)
12400         (compare
12401           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12402                        (match_operand:QI 2 "const1_operand" "I"))
12403           (const_int 0)))
12404    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12405         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12406   "(TARGET_SHIFT1 || optimize_size)
12407    && ix86_match_ccmode (insn, CCGOCmode)
12408    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12409   "sar{b}\t%0"
12410   [(set_attr "type" "ishift")
12411    (set (attr "length")
12412      (if_then_else (match_operand 0 "register_operand" "")
12413         (const_string "2")
12414         (const_string "*")))])
12416 (define_insn "*ashrqi3_one_bit_cconly"
12417   [(set (reg FLAGS_REG)
12418         (compare
12419           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12420                        (match_operand:QI 2 "const1_operand" ""))
12421           (const_int 0)))
12422    (clobber (match_scratch:QI 0 "=q"))]
12423   "(TARGET_SHIFT1 || optimize_size)
12424    && ix86_match_ccmode (insn, CCGOCmode)
12425    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12426   "sar{b}\t%0"
12427   [(set_attr "type" "ishift")
12428    (set_attr "length" "2")])
12430 ;; This pattern can't accept a variable shift count, since shifts by
12431 ;; zero don't affect the flags.  We assume that shifts by constant
12432 ;; zero are optimized away.
12433 (define_insn "*ashrqi3_cmp"
12434   [(set (reg FLAGS_REG)
12435         (compare
12436           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12437                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12438           (const_int 0)))
12439    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12440         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12441   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12442    && ix86_match_ccmode (insn, CCGOCmode)
12443    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12444   "sar{b}\t{%2, %0|%0, %2}"
12445   [(set_attr "type" "ishift")
12446    (set_attr "mode" "QI")])
12448 (define_insn "*ashrqi3_cconly"
12449   [(set (reg FLAGS_REG)
12450         (compare
12451           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12452                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12453           (const_int 0)))
12454    (clobber (match_scratch:QI 0 "=q"))]
12455   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12456    && ix86_match_ccmode (insn, CCGOCmode)
12457    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12458   "sar{b}\t{%2, %0|%0, %2}"
12459   [(set_attr "type" "ishift")
12460    (set_attr "mode" "QI")])
12463 ;; Logical shift instructions
12465 ;; See comment above `ashldi3' about how this works.
12467 (define_expand "lshrti3"
12468   [(set (match_operand:TI 0 "register_operand" "")
12469         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12470                      (match_operand:QI 2 "nonmemory_operand" "")))]
12471   "TARGET_64BIT"
12472   "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12474 ;; This pattern must be defined before *lshrti3_1 to prevent
12475 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12477 (define_insn "sse2_lshrti3"
12478   [(set (match_operand:TI 0 "register_operand" "=x")
12479         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12480                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12481   "TARGET_SSE2"
12483   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12484   return "psrldq\t{%2, %0|%0, %2}";
12486   [(set_attr "type" "sseishft")
12487    (set_attr "prefix_data16" "1")
12488    (set_attr "mode" "TI")])
12490 (define_insn "*lshrti3_1"
12491   [(set (match_operand:TI 0 "register_operand" "=r")
12492         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12493                      (match_operand:QI 2 "nonmemory_operand" "Oc")))
12494    (clobber (reg:CC FLAGS_REG))]
12495   "TARGET_64BIT"
12496   "#"
12497   [(set_attr "type" "multi")])
12499 (define_peephole2
12500   [(match_scratch:DI 3 "r")
12501    (parallel [(set (match_operand:TI 0 "register_operand" "")
12502                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12503                                 (match_operand:QI 2 "nonmemory_operand" "")))
12504               (clobber (reg:CC FLAGS_REG))])
12505    (match_dup 3)]
12506   "TARGET_64BIT"
12507   [(const_int 0)]
12508   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12510 (define_split
12511   [(set (match_operand:TI 0 "register_operand" "")
12512         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12513                      (match_operand:QI 2 "nonmemory_operand" "")))
12514    (clobber (reg:CC FLAGS_REG))]
12515   "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12516                     ? epilogue_completed : reload_completed)"
12517   [(const_int 0)]
12518   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12520 (define_expand "lshrdi3"
12521   [(set (match_operand:DI 0 "shiftdi_operand" "")
12522         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12523                      (match_operand:QI 2 "nonmemory_operand" "")))]
12524   ""
12525   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12527 (define_insn "*lshrdi3_1_one_bit_rex64"
12528   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12529         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12530                      (match_operand:QI 2 "const1_operand" "")))
12531    (clobber (reg:CC FLAGS_REG))]
12532   "TARGET_64BIT
12533    && (TARGET_SHIFT1 || optimize_size)
12534    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12535   "shr{q}\t%0"
12536   [(set_attr "type" "ishift")
12537    (set (attr "length")
12538      (if_then_else (match_operand:DI 0 "register_operand" "")
12539         (const_string "2")
12540         (const_string "*")))])
12542 (define_insn "*lshrdi3_1_rex64"
12543   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12544         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12545                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12546    (clobber (reg:CC FLAGS_REG))]
12547   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12548   "@
12549    shr{q}\t{%2, %0|%0, %2}
12550    shr{q}\t{%b2, %0|%0, %b2}"
12551   [(set_attr "type" "ishift")
12552    (set_attr "mode" "DI")])
12554 ;; This pattern can't accept a variable shift count, since shifts by
12555 ;; zero don't affect the flags.  We assume that shifts by constant
12556 ;; zero are optimized away.
12557 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12558   [(set (reg FLAGS_REG)
12559         (compare
12560           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12561                        (match_operand:QI 2 "const1_operand" ""))
12562           (const_int 0)))
12563    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12564         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12565   "TARGET_64BIT
12566    && (TARGET_SHIFT1 || optimize_size)
12567    && ix86_match_ccmode (insn, CCGOCmode)
12568    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12569   "shr{q}\t%0"
12570   [(set_attr "type" "ishift")
12571    (set (attr "length")
12572      (if_then_else (match_operand:DI 0 "register_operand" "")
12573         (const_string "2")
12574         (const_string "*")))])
12576 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12577   [(set (reg FLAGS_REG)
12578         (compare
12579           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12580                        (match_operand:QI 2 "const1_operand" ""))
12581           (const_int 0)))
12582    (clobber (match_scratch:DI 0 "=r"))]
12583   "TARGET_64BIT
12584    && (TARGET_SHIFT1 || optimize_size)
12585    && ix86_match_ccmode (insn, CCGOCmode)
12586    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12587   "shr{q}\t%0"
12588   [(set_attr "type" "ishift")
12589    (set_attr "length" "2")])
12591 ;; This pattern can't accept a variable shift count, since shifts by
12592 ;; zero don't affect the flags.  We assume that shifts by constant
12593 ;; zero are optimized away.
12594 (define_insn "*lshrdi3_cmp_rex64"
12595   [(set (reg FLAGS_REG)
12596         (compare
12597           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12598                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12599           (const_int 0)))
12600    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12601         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12602   "TARGET_64BIT
12603    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12604    && ix86_match_ccmode (insn, CCGOCmode)
12605    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12606   "shr{q}\t{%2, %0|%0, %2}"
12607   [(set_attr "type" "ishift")
12608    (set_attr "mode" "DI")])
12610 (define_insn "*lshrdi3_cconly_rex64"
12611   [(set (reg FLAGS_REG)
12612         (compare
12613           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12614                        (match_operand:QI 2 "const_1_to_63_operand" "J"))
12615           (const_int 0)))
12616    (clobber (match_scratch:DI 0 "=r"))]
12617   "TARGET_64BIT
12618    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12619    && ix86_match_ccmode (insn, CCGOCmode)
12620    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12621   "shr{q}\t{%2, %0|%0, %2}"
12622   [(set_attr "type" "ishift")
12623    (set_attr "mode" "DI")])
12625 (define_insn "*lshrdi3_1"
12626   [(set (match_operand:DI 0 "register_operand" "=r")
12627         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12628                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12629    (clobber (reg:CC FLAGS_REG))]
12630   "!TARGET_64BIT"
12631   "#"
12632   [(set_attr "type" "multi")])
12634 ;; By default we don't ask for a scratch register, because when DImode
12635 ;; values are manipulated, registers are already at a premium.  But if
12636 ;; we have one handy, we won't turn it away.
12637 (define_peephole2
12638   [(match_scratch:SI 3 "r")
12639    (parallel [(set (match_operand:DI 0 "register_operand" "")
12640                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12641                                 (match_operand:QI 2 "nonmemory_operand" "")))
12642               (clobber (reg:CC FLAGS_REG))])
12643    (match_dup 3)]
12644   "!TARGET_64BIT && TARGET_CMOVE"
12645   [(const_int 0)]
12646   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12648 (define_split
12649   [(set (match_operand:DI 0 "register_operand" "")
12650         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12651                      (match_operand:QI 2 "nonmemory_operand" "")))
12652    (clobber (reg:CC FLAGS_REG))]
12653   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12654                      ? epilogue_completed : reload_completed)"
12655   [(const_int 0)]
12656   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12658 (define_expand "lshrsi3"
12659   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12660         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12661                      (match_operand:QI 2 "nonmemory_operand" "")))]
12662   ""
12663   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12665 (define_insn "*lshrsi3_1_one_bit"
12666   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12667         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12668                      (match_operand:QI 2 "const1_operand" "")))
12669    (clobber (reg:CC FLAGS_REG))]
12670   "(TARGET_SHIFT1 || optimize_size)
12671    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12672   "shr{l}\t%0"
12673   [(set_attr "type" "ishift")
12674    (set (attr "length")
12675      (if_then_else (match_operand:SI 0 "register_operand" "")
12676         (const_string "2")
12677         (const_string "*")))])
12679 (define_insn "*lshrsi3_1_one_bit_zext"
12680   [(set (match_operand:DI 0 "register_operand" "=r")
12681         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12682                      (match_operand:QI 2 "const1_operand" "")))
12683    (clobber (reg:CC FLAGS_REG))]
12684   "TARGET_64BIT
12685    && (TARGET_SHIFT1 || optimize_size)
12686    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12687   "shr{l}\t%k0"
12688   [(set_attr "type" "ishift")
12689    (set_attr "length" "2")])
12691 (define_insn "*lshrsi3_1"
12692   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12693         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12694                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12695    (clobber (reg:CC FLAGS_REG))]
12696   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12697   "@
12698    shr{l}\t{%2, %0|%0, %2}
12699    shr{l}\t{%b2, %0|%0, %b2}"
12700   [(set_attr "type" "ishift")
12701    (set_attr "mode" "SI")])
12703 (define_insn "*lshrsi3_1_zext"
12704   [(set (match_operand:DI 0 "register_operand" "=r,r")
12705         (zero_extend:DI
12706           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12707                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12708    (clobber (reg:CC FLAGS_REG))]
12709   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12710   "@
12711    shr{l}\t{%2, %k0|%k0, %2}
12712    shr{l}\t{%b2, %k0|%k0, %b2}"
12713   [(set_attr "type" "ishift")
12714    (set_attr "mode" "SI")])
12716 ;; This pattern can't accept a variable shift count, since shifts by
12717 ;; zero don't affect the flags.  We assume that shifts by constant
12718 ;; zero are optimized away.
12719 (define_insn "*lshrsi3_one_bit_cmp"
12720   [(set (reg FLAGS_REG)
12721         (compare
12722           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12723                        (match_operand:QI 2 "const1_operand" ""))
12724           (const_int 0)))
12725    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12726         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12727   "(TARGET_SHIFT1 || optimize_size)
12728    && ix86_match_ccmode (insn, CCGOCmode)
12729    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12730   "shr{l}\t%0"
12731   [(set_attr "type" "ishift")
12732    (set (attr "length")
12733      (if_then_else (match_operand:SI 0 "register_operand" "")
12734         (const_string "2")
12735         (const_string "*")))])
12737 (define_insn "*lshrsi3_one_bit_cconly"
12738   [(set (reg FLAGS_REG)
12739         (compare
12740           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12741                        (match_operand:QI 2 "const1_operand" ""))
12742           (const_int 0)))
12743    (clobber (match_scratch:SI 0 "=r"))]
12744   "(TARGET_SHIFT1 || optimize_size)
12745    && ix86_match_ccmode (insn, CCGOCmode)
12746    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12747   "shr{l}\t%0"
12748   [(set_attr "type" "ishift")
12749    (set_attr "length" "2")])
12751 (define_insn "*lshrsi3_cmp_one_bit_zext"
12752   [(set (reg FLAGS_REG)
12753         (compare
12754           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12755                        (match_operand:QI 2 "const1_operand" ""))
12756           (const_int 0)))
12757    (set (match_operand:DI 0 "register_operand" "=r")
12758         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12759   "TARGET_64BIT
12760    && (TARGET_SHIFT1 || optimize_size)
12761    && ix86_match_ccmode (insn, CCGOCmode)
12762    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12763   "shr{l}\t%k0"
12764   [(set_attr "type" "ishift")
12765    (set_attr "length" "2")])
12767 ;; This pattern can't accept a variable shift count, since shifts by
12768 ;; zero don't affect the flags.  We assume that shifts by constant
12769 ;; zero are optimized away.
12770 (define_insn "*lshrsi3_cmp"
12771   [(set (reg FLAGS_REG)
12772         (compare
12773           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12774                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12775           (const_int 0)))
12776    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12777         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12778   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12779    && ix86_match_ccmode (insn, CCGOCmode)
12780    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12781   "shr{l}\t{%2, %0|%0, %2}"
12782   [(set_attr "type" "ishift")
12783    (set_attr "mode" "SI")])
12785 (define_insn "*lshrsi3_cconly"
12786   [(set (reg FLAGS_REG)
12787       (compare
12788         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12789                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12790         (const_int 0)))
12791    (clobber (match_scratch:SI 0 "=r"))]
12792   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12793    && ix86_match_ccmode (insn, CCGOCmode)
12794    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12795   "shr{l}\t{%2, %0|%0, %2}"
12796   [(set_attr "type" "ishift")
12797    (set_attr "mode" "SI")])
12799 (define_insn "*lshrsi3_cmp_zext"
12800   [(set (reg FLAGS_REG)
12801         (compare
12802           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12803                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12804           (const_int 0)))
12805    (set (match_operand:DI 0 "register_operand" "=r")
12806         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12807   "TARGET_64BIT
12808    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12809    && ix86_match_ccmode (insn, CCGOCmode)
12810    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12811   "shr{l}\t{%2, %k0|%k0, %2}"
12812   [(set_attr "type" "ishift")
12813    (set_attr "mode" "SI")])
12815 (define_expand "lshrhi3"
12816   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12817         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12818                      (match_operand:QI 2 "nonmemory_operand" "")))]
12819   "TARGET_HIMODE_MATH"
12820   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12822 (define_insn "*lshrhi3_1_one_bit"
12823   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12824         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12825                      (match_operand:QI 2 "const1_operand" "")))
12826    (clobber (reg:CC FLAGS_REG))]
12827   "(TARGET_SHIFT1 || optimize_size)
12828    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12829   "shr{w}\t%0"
12830   [(set_attr "type" "ishift")
12831    (set (attr "length")
12832      (if_then_else (match_operand 0 "register_operand" "")
12833         (const_string "2")
12834         (const_string "*")))])
12836 (define_insn "*lshrhi3_1"
12837   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12838         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12839                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12840    (clobber (reg:CC FLAGS_REG))]
12841   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12842   "@
12843    shr{w}\t{%2, %0|%0, %2}
12844    shr{w}\t{%b2, %0|%0, %b2}"
12845   [(set_attr "type" "ishift")
12846    (set_attr "mode" "HI")])
12848 ;; This pattern can't accept a variable shift count, since shifts by
12849 ;; zero don't affect the flags.  We assume that shifts by constant
12850 ;; zero are optimized away.
12851 (define_insn "*lshrhi3_one_bit_cmp"
12852   [(set (reg FLAGS_REG)
12853         (compare
12854           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12855                        (match_operand:QI 2 "const1_operand" ""))
12856           (const_int 0)))
12857    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12858         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12859   "(TARGET_SHIFT1 || optimize_size)
12860    && ix86_match_ccmode (insn, CCGOCmode)
12861    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12862   "shr{w}\t%0"
12863   [(set_attr "type" "ishift")
12864    (set (attr "length")
12865      (if_then_else (match_operand:SI 0 "register_operand" "")
12866         (const_string "2")
12867         (const_string "*")))])
12869 (define_insn "*lshrhi3_one_bit_cconly"
12870   [(set (reg FLAGS_REG)
12871         (compare
12872           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12873                        (match_operand:QI 2 "const1_operand" ""))
12874           (const_int 0)))
12875    (clobber (match_scratch:HI 0 "=r"))]
12876   "(TARGET_SHIFT1 || optimize_size)
12877    && ix86_match_ccmode (insn, CCGOCmode)
12878    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12879   "shr{w}\t%0"
12880   [(set_attr "type" "ishift")
12881    (set_attr "length" "2")])
12883 ;; This pattern can't accept a variable shift count, since shifts by
12884 ;; zero don't affect the flags.  We assume that shifts by constant
12885 ;; zero are optimized away.
12886 (define_insn "*lshrhi3_cmp"
12887   [(set (reg FLAGS_REG)
12888         (compare
12889           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12890                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12891           (const_int 0)))
12892    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12893         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12894   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12895    && ix86_match_ccmode (insn, CCGOCmode)
12896    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12897   "shr{w}\t{%2, %0|%0, %2}"
12898   [(set_attr "type" "ishift")
12899    (set_attr "mode" "HI")])
12901 (define_insn "*lshrhi3_cconly"
12902   [(set (reg FLAGS_REG)
12903         (compare
12904           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12905                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12906           (const_int 0)))
12907    (clobber (match_scratch:HI 0 "=r"))]
12908   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12909    && ix86_match_ccmode (insn, CCGOCmode)
12910    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12911   "shr{w}\t{%2, %0|%0, %2}"
12912   [(set_attr "type" "ishift")
12913    (set_attr "mode" "HI")])
12915 (define_expand "lshrqi3"
12916   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12917         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12918                      (match_operand:QI 2 "nonmemory_operand" "")))]
12919   "TARGET_QIMODE_MATH"
12920   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12922 (define_insn "*lshrqi3_1_one_bit"
12923   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12924         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12925                      (match_operand:QI 2 "const1_operand" "")))
12926    (clobber (reg:CC FLAGS_REG))]
12927   "(TARGET_SHIFT1 || optimize_size)
12928    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12929   "shr{b}\t%0"
12930   [(set_attr "type" "ishift")
12931    (set (attr "length")
12932      (if_then_else (match_operand 0 "register_operand" "")
12933         (const_string "2")
12934         (const_string "*")))])
12936 (define_insn "*lshrqi3_1_one_bit_slp"
12937   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12938         (lshiftrt:QI (match_dup 0)
12939                      (match_operand:QI 1 "const1_operand" "")))
12940    (clobber (reg:CC FLAGS_REG))]
12941   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12942    && (TARGET_SHIFT1 || optimize_size)"
12943   "shr{b}\t%0"
12944   [(set_attr "type" "ishift1")
12945    (set (attr "length")
12946      (if_then_else (match_operand 0 "register_operand" "")
12947         (const_string "2")
12948         (const_string "*")))])
12950 (define_insn "*lshrqi3_1"
12951   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12952         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12953                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12954    (clobber (reg:CC FLAGS_REG))]
12955   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12956   "@
12957    shr{b}\t{%2, %0|%0, %2}
12958    shr{b}\t{%b2, %0|%0, %b2}"
12959   [(set_attr "type" "ishift")
12960    (set_attr "mode" "QI")])
12962 (define_insn "*lshrqi3_1_slp"
12963   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12964         (lshiftrt:QI (match_dup 0)
12965                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12966    (clobber (reg:CC FLAGS_REG))]
12967   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12968    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12969   "@
12970    shr{b}\t{%1, %0|%0, %1}
12971    shr{b}\t{%b1, %0|%0, %b1}"
12972   [(set_attr "type" "ishift1")
12973    (set_attr "mode" "QI")])
12975 ;; This pattern can't accept a variable shift count, since shifts by
12976 ;; zero don't affect the flags.  We assume that shifts by constant
12977 ;; zero are optimized away.
12978 (define_insn "*lshrqi2_one_bit_cmp"
12979   [(set (reg FLAGS_REG)
12980         (compare
12981           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12982                        (match_operand:QI 2 "const1_operand" ""))
12983           (const_int 0)))
12984    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12985         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12986   "(TARGET_SHIFT1 || optimize_size)
12987    && ix86_match_ccmode (insn, CCGOCmode)
12988    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12989   "shr{b}\t%0"
12990   [(set_attr "type" "ishift")
12991    (set (attr "length")
12992      (if_then_else (match_operand:SI 0 "register_operand" "")
12993         (const_string "2")
12994         (const_string "*")))])
12996 (define_insn "*lshrqi2_one_bit_cconly"
12997   [(set (reg FLAGS_REG)
12998         (compare
12999           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13000                        (match_operand:QI 2 "const1_operand" ""))
13001           (const_int 0)))
13002    (clobber (match_scratch:QI 0 "=q"))]
13003   "(TARGET_SHIFT1 || optimize_size)
13004    && ix86_match_ccmode (insn, CCGOCmode)
13005    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13006   "shr{b}\t%0"
13007   [(set_attr "type" "ishift")
13008    (set_attr "length" "2")])
13010 ;; This pattern can't accept a variable shift count, since shifts by
13011 ;; zero don't affect the flags.  We assume that shifts by constant
13012 ;; zero are optimized away.
13013 (define_insn "*lshrqi2_cmp"
13014   [(set (reg FLAGS_REG)
13015         (compare
13016           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13017                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13018           (const_int 0)))
13019    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13020         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13021   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13022    && ix86_match_ccmode (insn, CCGOCmode)
13023    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13024   "shr{b}\t{%2, %0|%0, %2}"
13025   [(set_attr "type" "ishift")
13026    (set_attr "mode" "QI")])
13028 (define_insn "*lshrqi2_cconly"
13029   [(set (reg FLAGS_REG)
13030         (compare
13031           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13032                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13033           (const_int 0)))
13034    (clobber (match_scratch:QI 0 "=q"))]
13035   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13036    && ix86_match_ccmode (insn, CCGOCmode)
13037    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13038   "shr{b}\t{%2, %0|%0, %2}"
13039   [(set_attr "type" "ishift")
13040    (set_attr "mode" "QI")])
13042 ;; Rotate instructions
13044 (define_expand "rotldi3"
13045   [(set (match_operand:DI 0 "shiftdi_operand" "")
13046         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13047                    (match_operand:QI 2 "nonmemory_operand" "")))]
13048  ""
13050   if (TARGET_64BIT)
13051     {
13052       ix86_expand_binary_operator (ROTATE, DImode, operands);
13053       DONE;
13054     }
13055   if (!const_1_to_31_operand (operands[2], VOIDmode))
13056     FAIL;
13057   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13058   DONE;
13061 ;; Implement rotation using two double-precision shift instructions
13062 ;; and a scratch register.
13063 (define_insn_and_split "ix86_rotldi3"
13064  [(set (match_operand:DI 0 "register_operand" "=r")
13065        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13066                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13067   (clobber (reg:CC FLAGS_REG))
13068   (clobber (match_scratch:SI 3 "=&r"))]
13069  "!TARGET_64BIT"
13070  ""
13071  "&& reload_completed"
13072  [(set (match_dup 3) (match_dup 4))
13073   (parallel
13074    [(set (match_dup 4)
13075          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13076                  (lshiftrt:SI (match_dup 5)
13077                               (minus:QI (const_int 32) (match_dup 2)))))
13078     (clobber (reg:CC FLAGS_REG))])
13079   (parallel
13080    [(set (match_dup 5)
13081          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13082                  (lshiftrt:SI (match_dup 3)
13083                               (minus:QI (const_int 32) (match_dup 2)))))
13084     (clobber (reg:CC FLAGS_REG))])]
13085  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13087 (define_insn "*rotlsi3_1_one_bit_rex64"
13088   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13089         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13090                    (match_operand:QI 2 "const1_operand" "")))
13091    (clobber (reg:CC FLAGS_REG))]
13092   "TARGET_64BIT
13093    && (TARGET_SHIFT1 || optimize_size)
13094    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13095   "rol{q}\t%0"
13096   [(set_attr "type" "rotate")
13097    (set (attr "length")
13098      (if_then_else (match_operand:DI 0 "register_operand" "")
13099         (const_string "2")
13100         (const_string "*")))])
13102 (define_insn "*rotldi3_1_rex64"
13103   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13104         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13105                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13106    (clobber (reg:CC FLAGS_REG))]
13107   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13108   "@
13109    rol{q}\t{%2, %0|%0, %2}
13110    rol{q}\t{%b2, %0|%0, %b2}"
13111   [(set_attr "type" "rotate")
13112    (set_attr "mode" "DI")])
13114 (define_expand "rotlsi3"
13115   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13116         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13117                    (match_operand:QI 2 "nonmemory_operand" "")))]
13118   ""
13119   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13121 (define_insn "*rotlsi3_1_one_bit"
13122   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13123         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13124                    (match_operand:QI 2 "const1_operand" "")))
13125    (clobber (reg:CC FLAGS_REG))]
13126   "(TARGET_SHIFT1 || optimize_size)
13127    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13128   "rol{l}\t%0"
13129   [(set_attr "type" "rotate")
13130    (set (attr "length")
13131      (if_then_else (match_operand:SI 0 "register_operand" "")
13132         (const_string "2")
13133         (const_string "*")))])
13135 (define_insn "*rotlsi3_1_one_bit_zext"
13136   [(set (match_operand:DI 0 "register_operand" "=r")
13137         (zero_extend:DI
13138           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13139                      (match_operand:QI 2 "const1_operand" ""))))
13140    (clobber (reg:CC FLAGS_REG))]
13141   "TARGET_64BIT
13142    && (TARGET_SHIFT1 || optimize_size)
13143    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13144   "rol{l}\t%k0"
13145   [(set_attr "type" "rotate")
13146    (set_attr "length" "2")])
13148 (define_insn "*rotlsi3_1"
13149   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13150         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13151                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13152    (clobber (reg:CC FLAGS_REG))]
13153   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13154   "@
13155    rol{l}\t{%2, %0|%0, %2}
13156    rol{l}\t{%b2, %0|%0, %b2}"
13157   [(set_attr "type" "rotate")
13158    (set_attr "mode" "SI")])
13160 (define_insn "*rotlsi3_1_zext"
13161   [(set (match_operand:DI 0 "register_operand" "=r,r")
13162         (zero_extend:DI
13163           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13164                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13165    (clobber (reg:CC FLAGS_REG))]
13166   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13167   "@
13168    rol{l}\t{%2, %k0|%k0, %2}
13169    rol{l}\t{%b2, %k0|%k0, %b2}"
13170   [(set_attr "type" "rotate")
13171    (set_attr "mode" "SI")])
13173 (define_expand "rotlhi3"
13174   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13175         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13176                    (match_operand:QI 2 "nonmemory_operand" "")))]
13177   "TARGET_HIMODE_MATH"
13178   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13180 (define_insn "*rotlhi3_1_one_bit"
13181   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13182         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13183                    (match_operand:QI 2 "const1_operand" "")))
13184    (clobber (reg:CC FLAGS_REG))]
13185   "(TARGET_SHIFT1 || optimize_size)
13186    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13187   "rol{w}\t%0"
13188   [(set_attr "type" "rotate")
13189    (set (attr "length")
13190      (if_then_else (match_operand 0 "register_operand" "")
13191         (const_string "2")
13192         (const_string "*")))])
13194 (define_insn "*rotlhi3_1"
13195   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13196         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13197                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13198    (clobber (reg:CC FLAGS_REG))]
13199   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13200   "@
13201    rol{w}\t{%2, %0|%0, %2}
13202    rol{w}\t{%b2, %0|%0, %b2}"
13203   [(set_attr "type" "rotate")
13204    (set_attr "mode" "HI")])
13206 (define_split
13207  [(set (match_operand:HI 0 "register_operand" "")
13208        (rotate:HI (match_dup 0) (const_int 8)))
13209   (clobber (reg:CC FLAGS_REG))]
13210  "reload_completed"
13211  [(parallel [(set (strict_low_part (match_dup 0))
13212                   (bswap:HI (match_dup 0)))
13213              (clobber (reg:CC FLAGS_REG))])]
13214  "")
13216 (define_expand "rotlqi3"
13217   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13218         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13219                    (match_operand:QI 2 "nonmemory_operand" "")))]
13220   "TARGET_QIMODE_MATH"
13221   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13223 (define_insn "*rotlqi3_1_one_bit_slp"
13224   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13225         (rotate:QI (match_dup 0)
13226                    (match_operand:QI 1 "const1_operand" "")))
13227    (clobber (reg:CC FLAGS_REG))]
13228   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13229    && (TARGET_SHIFT1 || optimize_size)"
13230   "rol{b}\t%0"
13231   [(set_attr "type" "rotate1")
13232    (set (attr "length")
13233      (if_then_else (match_operand 0 "register_operand" "")
13234         (const_string "2")
13235         (const_string "*")))])
13237 (define_insn "*rotlqi3_1_one_bit"
13238   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13239         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13240                    (match_operand:QI 2 "const1_operand" "")))
13241    (clobber (reg:CC FLAGS_REG))]
13242   "(TARGET_SHIFT1 || optimize_size)
13243    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13244   "rol{b}\t%0"
13245   [(set_attr "type" "rotate")
13246    (set (attr "length")
13247      (if_then_else (match_operand 0 "register_operand" "")
13248         (const_string "2")
13249         (const_string "*")))])
13251 (define_insn "*rotlqi3_1_slp"
13252   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13253         (rotate:QI (match_dup 0)
13254                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13255    (clobber (reg:CC FLAGS_REG))]
13256   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13257    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13258   "@
13259    rol{b}\t{%1, %0|%0, %1}
13260    rol{b}\t{%b1, %0|%0, %b1}"
13261   [(set_attr "type" "rotate1")
13262    (set_attr "mode" "QI")])
13264 (define_insn "*rotlqi3_1"
13265   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13266         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13267                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13268    (clobber (reg:CC FLAGS_REG))]
13269   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13270   "@
13271    rol{b}\t{%2, %0|%0, %2}
13272    rol{b}\t{%b2, %0|%0, %b2}"
13273   [(set_attr "type" "rotate")
13274    (set_attr "mode" "QI")])
13276 (define_expand "rotrdi3"
13277   [(set (match_operand:DI 0 "shiftdi_operand" "")
13278         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13279                    (match_operand:QI 2 "nonmemory_operand" "")))]
13280  ""
13282   if (TARGET_64BIT)
13283     {
13284       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13285       DONE;
13286     }
13287   if (!const_1_to_31_operand (operands[2], VOIDmode))
13288     FAIL;
13289   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13290   DONE;
13293 ;; Implement rotation using two double-precision shift instructions
13294 ;; and a scratch register.
13295 (define_insn_and_split "ix86_rotrdi3"
13296  [(set (match_operand:DI 0 "register_operand" "=r")
13297        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13298                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13299   (clobber (reg:CC FLAGS_REG))
13300   (clobber (match_scratch:SI 3 "=&r"))]
13301  "!TARGET_64BIT"
13302  ""
13303  "&& reload_completed"
13304  [(set (match_dup 3) (match_dup 4))
13305   (parallel
13306    [(set (match_dup 4)
13307          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13308                  (ashift:SI (match_dup 5)
13309                             (minus:QI (const_int 32) (match_dup 2)))))
13310     (clobber (reg:CC FLAGS_REG))])
13311   (parallel
13312    [(set (match_dup 5)
13313          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13314                  (ashift:SI (match_dup 3)
13315                             (minus:QI (const_int 32) (match_dup 2)))))
13316     (clobber (reg:CC FLAGS_REG))])]
13317  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13319 (define_insn "*rotrdi3_1_one_bit_rex64"
13320   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13321         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13322                      (match_operand:QI 2 "const1_operand" "")))
13323    (clobber (reg:CC FLAGS_REG))]
13324   "TARGET_64BIT
13325    && (TARGET_SHIFT1 || optimize_size)
13326    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13327   "ror{q}\t%0"
13328   [(set_attr "type" "rotate")
13329    (set (attr "length")
13330      (if_then_else (match_operand:DI 0 "register_operand" "")
13331         (const_string "2")
13332         (const_string "*")))])
13334 (define_insn "*rotrdi3_1_rex64"
13335   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13336         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13337                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13338    (clobber (reg:CC FLAGS_REG))]
13339   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13340   "@
13341    ror{q}\t{%2, %0|%0, %2}
13342    ror{q}\t{%b2, %0|%0, %b2}"
13343   [(set_attr "type" "rotate")
13344    (set_attr "mode" "DI")])
13346 (define_expand "rotrsi3"
13347   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13348         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13349                      (match_operand:QI 2 "nonmemory_operand" "")))]
13350   ""
13351   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13353 (define_insn "*rotrsi3_1_one_bit"
13354   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13355         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13356                      (match_operand:QI 2 "const1_operand" "")))
13357    (clobber (reg:CC FLAGS_REG))]
13358   "(TARGET_SHIFT1 || optimize_size)
13359    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13360   "ror{l}\t%0"
13361   [(set_attr "type" "rotate")
13362    (set (attr "length")
13363      (if_then_else (match_operand:SI 0 "register_operand" "")
13364         (const_string "2")
13365         (const_string "*")))])
13367 (define_insn "*rotrsi3_1_one_bit_zext"
13368   [(set (match_operand:DI 0 "register_operand" "=r")
13369         (zero_extend:DI
13370           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13371                        (match_operand:QI 2 "const1_operand" ""))))
13372    (clobber (reg:CC FLAGS_REG))]
13373   "TARGET_64BIT
13374    && (TARGET_SHIFT1 || optimize_size)
13375    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13376   "ror{l}\t%k0"
13377   [(set_attr "type" "rotate")
13378    (set (attr "length")
13379      (if_then_else (match_operand:SI 0 "register_operand" "")
13380         (const_string "2")
13381         (const_string "*")))])
13383 (define_insn "*rotrsi3_1"
13384   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13385         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13386                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13387    (clobber (reg:CC FLAGS_REG))]
13388   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13389   "@
13390    ror{l}\t{%2, %0|%0, %2}
13391    ror{l}\t{%b2, %0|%0, %b2}"
13392   [(set_attr "type" "rotate")
13393    (set_attr "mode" "SI")])
13395 (define_insn "*rotrsi3_1_zext"
13396   [(set (match_operand:DI 0 "register_operand" "=r,r")
13397         (zero_extend:DI
13398           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13399                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13400    (clobber (reg:CC FLAGS_REG))]
13401   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13402   "@
13403    ror{l}\t{%2, %k0|%k0, %2}
13404    ror{l}\t{%b2, %k0|%k0, %b2}"
13405   [(set_attr "type" "rotate")
13406    (set_attr "mode" "SI")])
13408 (define_expand "rotrhi3"
13409   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13410         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13411                      (match_operand:QI 2 "nonmemory_operand" "")))]
13412   "TARGET_HIMODE_MATH"
13413   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13415 (define_insn "*rotrhi3_one_bit"
13416   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13417         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13418                      (match_operand:QI 2 "const1_operand" "")))
13419    (clobber (reg:CC FLAGS_REG))]
13420   "(TARGET_SHIFT1 || optimize_size)
13421    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13422   "ror{w}\t%0"
13423   [(set_attr "type" "rotate")
13424    (set (attr "length")
13425      (if_then_else (match_operand 0 "register_operand" "")
13426         (const_string "2")
13427         (const_string "*")))])
13429 (define_insn "*rotrhi3_1"
13430   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13431         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13432                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13433    (clobber (reg:CC FLAGS_REG))]
13434   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13435   "@
13436    ror{w}\t{%2, %0|%0, %2}
13437    ror{w}\t{%b2, %0|%0, %b2}"
13438   [(set_attr "type" "rotate")
13439    (set_attr "mode" "HI")])
13441 (define_split
13442  [(set (match_operand:HI 0 "register_operand" "")
13443        (rotatert:HI (match_dup 0) (const_int 8)))
13444   (clobber (reg:CC FLAGS_REG))]
13445  "reload_completed"
13446  [(parallel [(set (strict_low_part (match_dup 0))
13447                   (bswap:HI (match_dup 0)))
13448              (clobber (reg:CC FLAGS_REG))])]
13449  "")
13451 (define_expand "rotrqi3"
13452   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13453         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13454                      (match_operand:QI 2 "nonmemory_operand" "")))]
13455   "TARGET_QIMODE_MATH"
13456   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13458 (define_insn "*rotrqi3_1_one_bit"
13459   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13460         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13461                      (match_operand:QI 2 "const1_operand" "")))
13462    (clobber (reg:CC FLAGS_REG))]
13463   "(TARGET_SHIFT1 || optimize_size)
13464    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13465   "ror{b}\t%0"
13466   [(set_attr "type" "rotate")
13467    (set (attr "length")
13468      (if_then_else (match_operand 0 "register_operand" "")
13469         (const_string "2")
13470         (const_string "*")))])
13472 (define_insn "*rotrqi3_1_one_bit_slp"
13473   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13474         (rotatert:QI (match_dup 0)
13475                      (match_operand:QI 1 "const1_operand" "")))
13476    (clobber (reg:CC FLAGS_REG))]
13477   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13478    && (TARGET_SHIFT1 || optimize_size)"
13479   "ror{b}\t%0"
13480   [(set_attr "type" "rotate1")
13481    (set (attr "length")
13482      (if_then_else (match_operand 0 "register_operand" "")
13483         (const_string "2")
13484         (const_string "*")))])
13486 (define_insn "*rotrqi3_1"
13487   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13488         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13489                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13490    (clobber (reg:CC FLAGS_REG))]
13491   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13492   "@
13493    ror{b}\t{%2, %0|%0, %2}
13494    ror{b}\t{%b2, %0|%0, %b2}"
13495   [(set_attr "type" "rotate")
13496    (set_attr "mode" "QI")])
13498 (define_insn "*rotrqi3_1_slp"
13499   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13500         (rotatert:QI (match_dup 0)
13501                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13502    (clobber (reg:CC FLAGS_REG))]
13503   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13504    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13505   "@
13506    ror{b}\t{%1, %0|%0, %1}
13507    ror{b}\t{%b1, %0|%0, %b1}"
13508   [(set_attr "type" "rotate1")
13509    (set_attr "mode" "QI")])
13511 ;; Bit set / bit test instructions
13513 (define_expand "extv"
13514   [(set (match_operand:SI 0 "register_operand" "")
13515         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13516                          (match_operand:SI 2 "const8_operand" "")
13517                          (match_operand:SI 3 "const8_operand" "")))]
13518   ""
13520   /* Handle extractions from %ah et al.  */
13521   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13522     FAIL;
13524   /* From mips.md: extract_bit_field doesn't verify that our source
13525      matches the predicate, so check it again here.  */
13526   if (! ext_register_operand (operands[1], VOIDmode))
13527     FAIL;
13530 (define_expand "extzv"
13531   [(set (match_operand:SI 0 "register_operand" "")
13532         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13533                          (match_operand:SI 2 "const8_operand" "")
13534                          (match_operand:SI 3 "const8_operand" "")))]
13535   ""
13537   /* Handle extractions from %ah et al.  */
13538   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13539     FAIL;
13541   /* From mips.md: extract_bit_field doesn't verify that our source
13542      matches the predicate, so check it again here.  */
13543   if (! ext_register_operand (operands[1], VOIDmode))
13544     FAIL;
13547 (define_expand "insv"
13548   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13549                       (match_operand 1 "const8_operand" "")
13550                       (match_operand 2 "const8_operand" ""))
13551         (match_operand 3 "register_operand" ""))]
13552   ""
13554   /* Handle insertions to %ah et al.  */
13555   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13556     FAIL;
13558   /* From mips.md: insert_bit_field doesn't verify that our source
13559      matches the predicate, so check it again here.  */
13560   if (! ext_register_operand (operands[0], VOIDmode))
13561     FAIL;
13563   if (TARGET_64BIT)
13564     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13565   else
13566     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13568   DONE;
13571 ;; %%% bts, btr, btc, bt.
13572 ;; In general these instructions are *slow* when applied to memory,
13573 ;; since they enforce atomic operation.  When applied to registers,
13574 ;; it depends on the cpu implementation.  They're never faster than
13575 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13576 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13577 ;; within the instruction itself, so operating on bits in the high
13578 ;; 32-bits of a register becomes easier.
13580 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13581 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13582 ;; negdf respectively, so they can never be disabled entirely.
13584 (define_insn "*btsq"
13585   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13586                          (const_int 1)
13587                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13588         (const_int 1))
13589    (clobber (reg:CC FLAGS_REG))]
13590   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13591   "bts{q}\t{%1, %0|%0, %1}"
13592   [(set_attr "type" "alu1")])
13594 (define_insn "*btrq"
13595   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13596                          (const_int 1)
13597                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13598         (const_int 0))
13599    (clobber (reg:CC FLAGS_REG))]
13600   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13601   "btr{q}\t{%1, %0|%0, %1}"
13602   [(set_attr "type" "alu1")])
13604 (define_insn "*btcq"
13605   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13606                          (const_int 1)
13607                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13608         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13609    (clobber (reg:CC FLAGS_REG))]
13610   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13611   "btc{q}\t{%1, %0|%0, %1}"
13612   [(set_attr "type" "alu1")])
13614 ;; Allow Nocona to avoid these instructions if a register is available.
13616 (define_peephole2
13617   [(match_scratch:DI 2 "r")
13618    (parallel [(set (zero_extract:DI
13619                      (match_operand:DI 0 "register_operand" "")
13620                      (const_int 1)
13621                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13622                    (const_int 1))
13623               (clobber (reg:CC FLAGS_REG))])]
13624   "TARGET_64BIT && !TARGET_USE_BT"
13625   [(const_int 0)]
13627   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13628   rtx op1;
13630   if (HOST_BITS_PER_WIDE_INT >= 64)
13631     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13632   else if (i < HOST_BITS_PER_WIDE_INT)
13633     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13634   else
13635     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13637   op1 = immed_double_const (lo, hi, DImode);
13638   if (i >= 31)
13639     {
13640       emit_move_insn (operands[2], op1);
13641       op1 = operands[2];
13642     }
13644   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13645   DONE;
13648 (define_peephole2
13649   [(match_scratch:DI 2 "r")
13650    (parallel [(set (zero_extract:DI
13651                      (match_operand:DI 0 "register_operand" "")
13652                      (const_int 1)
13653                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13654                    (const_int 0))
13655               (clobber (reg:CC FLAGS_REG))])]
13656   "TARGET_64BIT && !TARGET_USE_BT"
13657   [(const_int 0)]
13659   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13660   rtx op1;
13662   if (HOST_BITS_PER_WIDE_INT >= 64)
13663     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13664   else if (i < HOST_BITS_PER_WIDE_INT)
13665     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13666   else
13667     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13669   op1 = immed_double_const (~lo, ~hi, DImode);
13670   if (i >= 32)
13671     {
13672       emit_move_insn (operands[2], op1);
13673       op1 = operands[2];
13674     }
13676   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13677   DONE;
13680 (define_peephole2
13681   [(match_scratch:DI 2 "r")
13682    (parallel [(set (zero_extract:DI
13683                      (match_operand:DI 0 "register_operand" "")
13684                      (const_int 1)
13685                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13686               (not:DI (zero_extract:DI
13687                         (match_dup 0) (const_int 1) (match_dup 1))))
13688               (clobber (reg:CC FLAGS_REG))])]
13689   "TARGET_64BIT && !TARGET_USE_BT"
13690   [(const_int 0)]
13692   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13693   rtx op1;
13695   if (HOST_BITS_PER_WIDE_INT >= 64)
13696     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13697   else if (i < HOST_BITS_PER_WIDE_INT)
13698     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13699   else
13700     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13702   op1 = immed_double_const (lo, hi, DImode);
13703   if (i >= 31)
13704     {
13705       emit_move_insn (operands[2], op1);
13706       op1 = operands[2];
13707     }
13709   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13710   DONE;
13713 (define_insn "*btdi_rex64"
13714   [(set (reg:CCC FLAGS_REG)
13715         (compare:CCC
13716           (zero_extract:DI
13717             (match_operand:DI 0 "register_operand" "r")
13718             (const_int 1)
13719             (match_operand:DI 1 "nonmemory_operand" "rN"))
13720           (const_int 0)))]
13721   "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
13722   "bt{q}\t{%1, %0|%0, %1}"
13723   [(set_attr "type" "alu1")])
13725 (define_insn "*btsi"
13726   [(set (reg:CCC FLAGS_REG)
13727         (compare:CCC
13728           (zero_extract:SI
13729             (match_operand:SI 0 "register_operand" "r")
13730             (const_int 1)
13731             (match_operand:SI 1 "nonmemory_operand" "rN"))
13732           (const_int 0)))]
13733   "TARGET_USE_BT || optimize_size"
13734   "bt{l}\t{%1, %0|%0, %1}"
13735   [(set_attr "type" "alu1")])
13737 ;; Store-flag instructions.
13739 ;; For all sCOND expanders, also expand the compare or test insn that
13740 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13742 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13743 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13744 ;; way, which can later delete the movzx if only QImode is needed.
13746 (define_expand "s<code>"
13747   [(set (match_operand:QI 0 "register_operand" "")
13748         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13749   ""
13750   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13752 (define_expand "s<code>"
13753   [(set (match_operand:QI 0 "register_operand" "")
13754         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13755   "TARGET_80387 || TARGET_SSE"
13756   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13758 (define_insn "*setcc_1"
13759   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13760         (match_operator:QI 1 "ix86_comparison_operator"
13761           [(reg FLAGS_REG) (const_int 0)]))]
13762   ""
13763   "set%C1\t%0"
13764   [(set_attr "type" "setcc")
13765    (set_attr "mode" "QI")])
13767 (define_insn "*setcc_2"
13768   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13769         (match_operator:QI 1 "ix86_comparison_operator"
13770           [(reg FLAGS_REG) (const_int 0)]))]
13771   ""
13772   "set%C1\t%0"
13773   [(set_attr "type" "setcc")
13774    (set_attr "mode" "QI")])
13776 ;; In general it is not safe to assume too much about CCmode registers,
13777 ;; so simplify-rtx stops when it sees a second one.  Under certain
13778 ;; conditions this is safe on x86, so help combine not create
13780 ;;      seta    %al
13781 ;;      testb   %al, %al
13782 ;;      sete    %al
13784 (define_split
13785   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13786         (ne:QI (match_operator 1 "ix86_comparison_operator"
13787                  [(reg FLAGS_REG) (const_int 0)])
13788             (const_int 0)))]
13789   ""
13790   [(set (match_dup 0) (match_dup 1))]
13792   PUT_MODE (operands[1], QImode);
13795 (define_split
13796   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13797         (ne:QI (match_operator 1 "ix86_comparison_operator"
13798                  [(reg FLAGS_REG) (const_int 0)])
13799             (const_int 0)))]
13800   ""
13801   [(set (match_dup 0) (match_dup 1))]
13803   PUT_MODE (operands[1], QImode);
13806 (define_split
13807   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13808         (eq:QI (match_operator 1 "ix86_comparison_operator"
13809                  [(reg FLAGS_REG) (const_int 0)])
13810             (const_int 0)))]
13811   ""
13812   [(set (match_dup 0) (match_dup 1))]
13814   rtx new_op1 = copy_rtx (operands[1]);
13815   operands[1] = new_op1;
13816   PUT_MODE (new_op1, QImode);
13817   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13818                                              GET_MODE (XEXP (new_op1, 0))));
13820   /* Make sure that (a) the CCmode we have for the flags is strong
13821      enough for the reversed compare or (b) we have a valid FP compare.  */
13822   if (! ix86_comparison_operator (new_op1, VOIDmode))
13823     FAIL;
13826 (define_split
13827   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13828         (eq:QI (match_operator 1 "ix86_comparison_operator"
13829                  [(reg FLAGS_REG) (const_int 0)])
13830             (const_int 0)))]
13831   ""
13832   [(set (match_dup 0) (match_dup 1))]
13834   rtx new_op1 = copy_rtx (operands[1]);
13835   operands[1] = new_op1;
13836   PUT_MODE (new_op1, QImode);
13837   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13838                                              GET_MODE (XEXP (new_op1, 0))));
13840   /* Make sure that (a) the CCmode we have for the flags is strong
13841      enough for the reversed compare or (b) we have a valid FP compare.  */
13842   if (! ix86_comparison_operator (new_op1, VOIDmode))
13843     FAIL;
13846 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13847 ;; subsequent logical operations are used to imitate conditional moves.
13848 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13849 ;; it directly.
13851 (define_insn "*sse_setcc<mode>"
13852   [(set (match_operand:MODEF 0 "register_operand" "=x")
13853         (match_operator:MODEF 1 "sse_comparison_operator"
13854           [(match_operand:MODEF 2 "register_operand" "0")
13855            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13856   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13857   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13858   [(set_attr "type" "ssecmp")
13859    (set_attr "mode" "<MODE>")])
13861 (define_insn "*sse5_setcc<mode>"
13862   [(set (match_operand:MODEF 0 "register_operand" "=x")
13863         (match_operator:MODEF 1 "sse5_comparison_float_operator"
13864           [(match_operand:MODEF 2 "register_operand" "x")
13865            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13866   "TARGET_SSE5"
13867   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13868   [(set_attr "type" "sse4arg")
13869    (set_attr "mode" "<MODE>")])
13872 ;; Basic conditional jump instructions.
13873 ;; We ignore the overflow flag for signed branch instructions.
13875 ;; For all bCOND expanders, also expand the compare or test insn that
13876 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13878 (define_expand "b<code>"
13879   [(set (pc)
13880         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13881                                    (const_int 0))
13882                       (label_ref (match_operand 0 ""))
13883                       (pc)))]
13884   ""
13885   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13887 (define_expand "b<code>"
13888   [(set (pc)
13889         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
13890                                   (const_int 0))
13891                       (label_ref (match_operand 0 ""))
13892                       (pc)))]
13893   "TARGET_80387 || TARGET_SSE_MATH"
13894   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13896 (define_insn "*jcc_1"
13897   [(set (pc)
13898         (if_then_else (match_operator 1 "ix86_comparison_operator"
13899                                       [(reg FLAGS_REG) (const_int 0)])
13900                       (label_ref (match_operand 0 "" ""))
13901                       (pc)))]
13902   ""
13903   "%+j%C1\t%l0"
13904   [(set_attr "type" "ibr")
13905    (set_attr "modrm" "0")
13906    (set (attr "length")
13907            (if_then_else (and (ge (minus (match_dup 0) (pc))
13908                                   (const_int -126))
13909                               (lt (minus (match_dup 0) (pc))
13910                                   (const_int 128)))
13911              (const_int 2)
13912              (const_int 6)))])
13914 (define_insn "*jcc_2"
13915   [(set (pc)
13916         (if_then_else (match_operator 1 "ix86_comparison_operator"
13917                                       [(reg FLAGS_REG) (const_int 0)])
13918                       (pc)
13919                       (label_ref (match_operand 0 "" ""))))]
13920   ""
13921   "%+j%c1\t%l0"
13922   [(set_attr "type" "ibr")
13923    (set_attr "modrm" "0")
13924    (set (attr "length")
13925            (if_then_else (and (ge (minus (match_dup 0) (pc))
13926                                   (const_int -126))
13927                               (lt (minus (match_dup 0) (pc))
13928                                   (const_int 128)))
13929              (const_int 2)
13930              (const_int 6)))])
13932 ;; ??? Handle alignment requirements for compare and branch fused macro-op;
13933 ;; the branch instruction does not start at a 16-byte boundary or cross
13934 ;; a 16-byte boundary.
13936 (define_insn "*jcc_fused_1"
13937   [(set (pc)
13938         (if_then_else (match_operator 1 "comparison_operator"
13939                         [(match_operand:SWI 2 "register_operand" "<r>")
13940                          (match_operand:SWI 3 "const0_operand" "")])
13941          (label_ref (match_operand 0 "" ""))
13942          (pc)))]
13943   "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT"
13945   return "test{<imodesuffix>}\t%2, %2\n\t"
13946          "%+j%E1\t%l0\t" ASM_COMMENT_START " fused";
13948   [(set_attr "type" "multi")
13949    (set_attr "mode" "<MODE>")])
13951 (define_insn "*jcc_fused_2"
13952   [(set (pc)
13953         (if_then_else (match_operator 1 "comparison_operator"
13954                         [(match_operand:SWI 2 "register_operand" "<r>")
13955                          (match_operand:SWI 3 "const0_operand" "")])
13956          (pc)
13957          (label_ref (match_operand 0 "" ""))))]
13958   "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT"
13960   return "test{<imodesuffix>}\t%2, %2\n\t"
13961          "%+j%e1\t%l0\t" ASM_COMMENT_START " fused";
13963   [(set_attr "type" "multi")
13964    (set_attr "mode" "<MODE>")])
13966 (define_insn "*jcc_fused_3"
13967   [(set (pc)
13968         (if_then_else
13969           (match_operator 1 "ix86_comparison_uns_operator"
13970             [(match_operand:SWI 2 "nonimmediate_operand" "<r>,m,<r>")
13971              (match_operand:SWI 3 "<general_operand>" "<r><i>,<r>,m")])
13972          (label_ref (match_operand 0 "" ""))
13973          (pc)))]
13974   "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT
13975    && !(MEM_P (operands[2])
13976         && (MEM_P (operands[3]) || CONST_INT_P (operands[3])))"
13978   return "cmp{<imodesuffix>}\t{%3, %2|%2, %3}\n\t"
13979          "%+j%E1\t%l0\t" ASM_COMMENT_START " fused";
13981   [(set_attr "type" "multi")
13982    (set_attr "mode" "<MODE>")])
13984 (define_insn "*jcc_fused_4"
13985   [(set (pc)
13986         (if_then_else
13987           (match_operator 1 "ix86_comparison_uns_operator"
13988             [(match_operand:SWI 2 "nonimmediate_operand" "<r>,m,<r>")
13989              (match_operand:SWI 3 "<general_operand>" "<r><i>,<r>,m")])
13990          (pc)
13991          (label_ref (match_operand 0 "" ""))))]
13992   "TARGET_FUSE_CMP_AND_BRANCH && !TARGET_64BIT
13993    && !(MEM_P (operands[2])
13994         && (MEM_P (operands[3]) || CONST_INT_P (operands[3])))"
13996   return "cmp{<imodesuffix>}\t{%3, %2|%2, %3}\n\t"
13997          "%+j%e1\t%l0\t" ASM_COMMENT_START " fused";
13999   [(set_attr "type" "multi")
14000    (set_attr "mode" "<MODE>")])
14002 ;; In general it is not safe to assume too much about CCmode registers,
14003 ;; so simplify-rtx stops when it sees a second one.  Under certain
14004 ;; conditions this is safe on x86, so help combine not create
14006 ;;      seta    %al
14007 ;;      testb   %al, %al
14008 ;;      je      Lfoo
14010 (define_split
14011   [(set (pc)
14012         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14013                                       [(reg FLAGS_REG) (const_int 0)])
14014                           (const_int 0))
14015                       (label_ref (match_operand 1 "" ""))
14016                       (pc)))]
14017   ""
14018   [(set (pc)
14019         (if_then_else (match_dup 0)
14020                       (label_ref (match_dup 1))
14021                       (pc)))]
14023   PUT_MODE (operands[0], VOIDmode);
14026 (define_split
14027   [(set (pc)
14028         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14029                                       [(reg FLAGS_REG) (const_int 0)])
14030                           (const_int 0))
14031                       (label_ref (match_operand 1 "" ""))
14032                       (pc)))]
14033   ""
14034   [(set (pc)
14035         (if_then_else (match_dup 0)
14036                       (label_ref (match_dup 1))
14037                       (pc)))]
14039   rtx new_op0 = copy_rtx (operands[0]);
14040   operands[0] = new_op0;
14041   PUT_MODE (new_op0, VOIDmode);
14042   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14043                                              GET_MODE (XEXP (new_op0, 0))));
14045   /* Make sure that (a) the CCmode we have for the flags is strong
14046      enough for the reversed compare or (b) we have a valid FP compare.  */
14047   if (! ix86_comparison_operator (new_op0, VOIDmode))
14048     FAIL;
14051 ;; zero_extend in SImode is correct, since this is what combine pass
14052 ;; generates from shift insn with QImode operand.  Actually, the mode of
14053 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14054 ;; appropriate modulo of the bit offset value.
14056 (define_insn_and_split "*jcc_btdi_rex64"
14057   [(set (pc)
14058         (if_then_else (match_operator 0 "bt_comparison_operator"
14059                         [(zero_extract:DI
14060                            (match_operand:DI 1 "register_operand" "r")
14061                            (const_int 1)
14062                            (zero_extend:SI
14063                              (match_operand:QI 2 "register_operand" "r")))
14064                          (const_int 0)])
14065                       (label_ref (match_operand 3 "" ""))
14066                       (pc)))]
14067   "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
14068   "#"
14069   "&& 1"
14070   [(set (reg:CCC FLAGS_REG)
14071         (compare:CCC
14072           (zero_extract:DI
14073             (match_dup 1)
14074             (const_int 1)
14075             (match_dup 2))
14076           (const_int 0)))
14077    (set (pc)
14078         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14079                       (label_ref (match_dup 3))
14080                       (pc)))]
14082   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14084   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14087 ;; avoid useless masking of bit offset operand
14088 (define_insn_and_split "*jcc_btdi_mask_rex64"
14089   [(set (pc)
14090         (if_then_else (match_operator 0 "bt_comparison_operator"
14091                         [(zero_extract:DI
14092                            (match_operand:DI 1 "register_operand" "r")
14093                            (const_int 1)
14094                            (and:SI
14095                              (match_operand:SI 2 "register_operand" "r")
14096                              (match_operand:SI 3 "const_int_operand" "n")))])
14097                       (label_ref (match_operand 4 "" ""))
14098                       (pc)))]
14099   "TARGET_64BIT && (TARGET_USE_BT || optimize_size)
14100    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14101   "#"
14102   "&& 1"
14103   [(set (reg:CCC FLAGS_REG)
14104         (compare:CCC
14105           (zero_extract:DI
14106             (match_dup 1)
14107             (const_int 1)
14108             (match_dup 2))
14109           (const_int 0)))
14110    (set (pc)
14111         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14112                       (label_ref (match_dup 4))
14113                       (pc)))]
14115   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14117   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14120 (define_insn_and_split "*jcc_btsi"
14121   [(set (pc)
14122         (if_then_else (match_operator 0 "bt_comparison_operator"
14123                         [(zero_extract:SI
14124                            (match_operand:SI 1 "register_operand" "r")
14125                            (const_int 1)
14126                            (zero_extend:SI
14127                              (match_operand:QI 2 "register_operand" "r")))
14128                          (const_int 0)])
14129                       (label_ref (match_operand 3 "" ""))
14130                       (pc)))]
14131   "TARGET_USE_BT || optimize_size"
14132   "#"
14133   "&& 1"
14134   [(set (reg:CCC FLAGS_REG)
14135         (compare:CCC
14136           (zero_extract:SI
14137             (match_dup 1)
14138             (const_int 1)
14139             (match_dup 2))
14140           (const_int 0)))
14141    (set (pc)
14142         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14143                       (label_ref (match_dup 3))
14144                       (pc)))]
14146   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14148   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14151 ;; avoid useless masking of bit offset operand
14152 (define_insn_and_split "*jcc_btsi_mask"
14153   [(set (pc)
14154         (if_then_else (match_operator 0 "bt_comparison_operator"
14155                         [(zero_extract:SI
14156                            (match_operand:SI 1 "register_operand" "r")
14157                            (const_int 1)
14158                            (and:SI
14159                              (match_operand:SI 2 "register_operand" "r")
14160                              (match_operand:SI 3 "const_int_operand" "n")))])
14161                       (label_ref (match_operand 4 "" ""))
14162                       (pc)))]
14163   "(TARGET_USE_BT || optimize_size)
14164    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14165   "#"
14166   "&& 1"
14167   [(set (reg:CCC FLAGS_REG)
14168         (compare:CCC
14169           (zero_extract:SI
14170             (match_dup 1)
14171             (const_int 1)
14172             (match_dup 2))
14173           (const_int 0)))
14174    (set (pc)
14175         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14176                       (label_ref (match_dup 4))
14177                       (pc)))]
14178   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14180 (define_insn_and_split "*jcc_btsi_1"
14181   [(set (pc)
14182         (if_then_else (match_operator 0 "bt_comparison_operator"
14183                         [(and:SI
14184                            (lshiftrt:SI
14185                              (match_operand:SI 1 "register_operand" "r")
14186                              (match_operand:QI 2 "register_operand" "r"))
14187                            (const_int 1))
14188                          (const_int 0)])
14189                       (label_ref (match_operand 3 "" ""))
14190                       (pc)))]
14191   "TARGET_USE_BT || optimize_size"
14192   "#"
14193   "&& 1"
14194   [(set (reg:CCC FLAGS_REG)
14195         (compare:CCC
14196           (zero_extract:SI
14197             (match_dup 1)
14198             (const_int 1)
14199             (match_dup 2))
14200           (const_int 0)))
14201    (set (pc)
14202         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14203                       (label_ref (match_dup 3))
14204                       (pc)))]
14206   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14208   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14211 ;; avoid useless masking of bit offset operand
14212 (define_insn_and_split "*jcc_btsi_mask_1"
14213   [(set (pc)
14214         (if_then_else
14215           (match_operator 0 "bt_comparison_operator"
14216             [(and:SI
14217                (lshiftrt:SI
14218                  (match_operand:SI 1 "register_operand" "r")
14219                  (subreg:QI
14220                    (and:SI
14221                      (match_operand:SI 2 "register_operand" "r")
14222                      (match_operand:SI 3 "const_int_operand" "n")) 0))
14223                (const_int 1))
14224              (const_int 0)])
14225           (label_ref (match_operand 4 "" ""))
14226           (pc)))]
14227   "(TARGET_USE_BT || optimize_size)
14228    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14229   "#"
14230   "&& 1"
14231   [(set (reg:CCC FLAGS_REG)
14232         (compare:CCC
14233           (zero_extract:SI
14234             (match_dup 1)
14235             (const_int 1)
14236             (match_dup 2))
14237           (const_int 0)))
14238    (set (pc)
14239         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14240                       (label_ref (match_dup 4))
14241                       (pc)))]
14242   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14244 ;; Define combination compare-and-branch fp compare instructions to use
14245 ;; during early optimization.  Splitting the operation apart early makes
14246 ;; for bad code when we want to reverse the operation.
14248 (define_insn "*fp_jcc_1_mixed"
14249   [(set (pc)
14250         (if_then_else (match_operator 0 "comparison_operator"
14251                         [(match_operand 1 "register_operand" "f,x")
14252                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14253           (label_ref (match_operand 3 "" ""))
14254           (pc)))
14255    (clobber (reg:CCFP FPSR_REG))
14256    (clobber (reg:CCFP FLAGS_REG))]
14257   "TARGET_MIX_SSE_I387
14258    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14259    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14260    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14261   "#")
14263 (define_insn "*fp_jcc_1_sse"
14264   [(set (pc)
14265         (if_then_else (match_operator 0 "comparison_operator"
14266                         [(match_operand 1 "register_operand" "x")
14267                          (match_operand 2 "nonimmediate_operand" "xm")])
14268           (label_ref (match_operand 3 "" ""))
14269           (pc)))
14270    (clobber (reg:CCFP FPSR_REG))
14271    (clobber (reg:CCFP FLAGS_REG))]
14272   "TARGET_SSE_MATH
14273    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14274    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14275    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14276   "#")
14278 (define_insn "*fp_jcc_1_387"
14279   [(set (pc)
14280         (if_then_else (match_operator 0 "comparison_operator"
14281                         [(match_operand 1 "register_operand" "f")
14282                          (match_operand 2 "register_operand" "f")])
14283           (label_ref (match_operand 3 "" ""))
14284           (pc)))
14285    (clobber (reg:CCFP FPSR_REG))
14286    (clobber (reg:CCFP FLAGS_REG))]
14287   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14288    && TARGET_CMOVE
14289    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14290    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14291   "#")
14293 (define_insn "*fp_jcc_2_mixed"
14294   [(set (pc)
14295         (if_then_else (match_operator 0 "comparison_operator"
14296                         [(match_operand 1 "register_operand" "f,x")
14297                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14298           (pc)
14299           (label_ref (match_operand 3 "" ""))))
14300    (clobber (reg:CCFP FPSR_REG))
14301    (clobber (reg:CCFP FLAGS_REG))]
14302   "TARGET_MIX_SSE_I387
14303    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14304    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14305    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14306   "#")
14308 (define_insn "*fp_jcc_2_sse"
14309   [(set (pc)
14310         (if_then_else (match_operator 0 "comparison_operator"
14311                         [(match_operand 1 "register_operand" "x")
14312                          (match_operand 2 "nonimmediate_operand" "xm")])
14313           (pc)
14314           (label_ref (match_operand 3 "" ""))))
14315    (clobber (reg:CCFP FPSR_REG))
14316    (clobber (reg:CCFP FLAGS_REG))]
14317   "TARGET_SSE_MATH
14318    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14319    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14320    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14321   "#")
14323 (define_insn "*fp_jcc_2_387"
14324   [(set (pc)
14325         (if_then_else (match_operator 0 "comparison_operator"
14326                         [(match_operand 1 "register_operand" "f")
14327                          (match_operand 2 "register_operand" "f")])
14328           (pc)
14329           (label_ref (match_operand 3 "" ""))))
14330    (clobber (reg:CCFP FPSR_REG))
14331    (clobber (reg:CCFP FLAGS_REG))]
14332   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14333    && TARGET_CMOVE
14334    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14335    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14336   "#")
14338 (define_insn "*fp_jcc_3_387"
14339   [(set (pc)
14340         (if_then_else (match_operator 0 "comparison_operator"
14341                         [(match_operand 1 "register_operand" "f")
14342                          (match_operand 2 "nonimmediate_operand" "fm")])
14343           (label_ref (match_operand 3 "" ""))
14344           (pc)))
14345    (clobber (reg:CCFP FPSR_REG))
14346    (clobber (reg:CCFP FLAGS_REG))
14347    (clobber (match_scratch:HI 4 "=a"))]
14348   "TARGET_80387
14349    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14350    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14351    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14352    && SELECT_CC_MODE (GET_CODE (operands[0]),
14353                       operands[1], operands[2]) == CCFPmode
14354    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14355   "#")
14357 (define_insn "*fp_jcc_4_387"
14358   [(set (pc)
14359         (if_then_else (match_operator 0 "comparison_operator"
14360                         [(match_operand 1 "register_operand" "f")
14361                          (match_operand 2 "nonimmediate_operand" "fm")])
14362           (pc)
14363           (label_ref (match_operand 3 "" ""))))
14364    (clobber (reg:CCFP FPSR_REG))
14365    (clobber (reg:CCFP FLAGS_REG))
14366    (clobber (match_scratch:HI 4 "=a"))]
14367   "TARGET_80387
14368    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14369    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14370    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14371    && SELECT_CC_MODE (GET_CODE (operands[0]),
14372                       operands[1], operands[2]) == CCFPmode
14373    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14374   "#")
14376 (define_insn "*fp_jcc_5_387"
14377   [(set (pc)
14378         (if_then_else (match_operator 0 "comparison_operator"
14379                         [(match_operand 1 "register_operand" "f")
14380                          (match_operand 2 "register_operand" "f")])
14381           (label_ref (match_operand 3 "" ""))
14382           (pc)))
14383    (clobber (reg:CCFP FPSR_REG))
14384    (clobber (reg:CCFP FLAGS_REG))
14385    (clobber (match_scratch:HI 4 "=a"))]
14386   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14387    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14388    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14389   "#")
14391 (define_insn "*fp_jcc_6_387"
14392   [(set (pc)
14393         (if_then_else (match_operator 0 "comparison_operator"
14394                         [(match_operand 1 "register_operand" "f")
14395                          (match_operand 2 "register_operand" "f")])
14396           (pc)
14397           (label_ref (match_operand 3 "" ""))))
14398    (clobber (reg:CCFP FPSR_REG))
14399    (clobber (reg:CCFP FLAGS_REG))
14400    (clobber (match_scratch:HI 4 "=a"))]
14401   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14402    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14403    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14404   "#")
14406 (define_insn "*fp_jcc_7_387"
14407   [(set (pc)
14408         (if_then_else (match_operator 0 "comparison_operator"
14409                         [(match_operand 1 "register_operand" "f")
14410                          (match_operand 2 "const0_operand" "")])
14411           (label_ref (match_operand 3 "" ""))
14412           (pc)))
14413    (clobber (reg:CCFP FPSR_REG))
14414    (clobber (reg:CCFP FLAGS_REG))
14415    (clobber (match_scratch:HI 4 "=a"))]
14416   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14417    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14418    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14419    && SELECT_CC_MODE (GET_CODE (operands[0]),
14420                       operands[1], operands[2]) == CCFPmode
14421    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14422   "#")
14424 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14425 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14426 ;; with a precedence over other operators and is always put in the first
14427 ;; place. Swap condition and operands to match ficom instruction.
14429 (define_insn "*fp_jcc_8<mode>_387"
14430   [(set (pc)
14431         (if_then_else (match_operator 0 "comparison_operator"
14432                         [(match_operator 1 "float_operator"
14433                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14434                            (match_operand 3 "register_operand" "f,f")])
14435           (label_ref (match_operand 4 "" ""))
14436           (pc)))
14437    (clobber (reg:CCFP FPSR_REG))
14438    (clobber (reg:CCFP FLAGS_REG))
14439    (clobber (match_scratch:HI 5 "=a,a"))]
14440   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14441    && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)
14442    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14443    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14444    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14445    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14446   "#")
14448 (define_split
14449   [(set (pc)
14450         (if_then_else (match_operator 0 "comparison_operator"
14451                         [(match_operand 1 "register_operand" "")
14452                          (match_operand 2 "nonimmediate_operand" "")])
14453           (match_operand 3 "" "")
14454           (match_operand 4 "" "")))
14455    (clobber (reg:CCFP FPSR_REG))
14456    (clobber (reg:CCFP FLAGS_REG))]
14457   "reload_completed"
14458   [(const_int 0)]
14460   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14461                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14462   DONE;
14465 (define_split
14466   [(set (pc)
14467         (if_then_else (match_operator 0 "comparison_operator"
14468                         [(match_operand 1 "register_operand" "")
14469                          (match_operand 2 "general_operand" "")])
14470           (match_operand 3 "" "")
14471           (match_operand 4 "" "")))
14472    (clobber (reg:CCFP FPSR_REG))
14473    (clobber (reg:CCFP FLAGS_REG))
14474    (clobber (match_scratch:HI 5 "=a"))]
14475   "reload_completed"
14476   [(const_int 0)]
14478   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14479                         operands[3], operands[4], operands[5], NULL_RTX);
14480   DONE;
14483 (define_split
14484   [(set (pc)
14485         (if_then_else (match_operator 0 "comparison_operator"
14486                         [(match_operator 1 "float_operator"
14487                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14488                            (match_operand 3 "register_operand" "")])
14489           (match_operand 4 "" "")
14490           (match_operand 5 "" "")))
14491    (clobber (reg:CCFP FPSR_REG))
14492    (clobber (reg:CCFP FLAGS_REG))
14493    (clobber (match_scratch:HI 6 "=a"))]
14494   "reload_completed"
14495   [(const_int 0)]
14497   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14498   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14499                         operands[3], operands[7],
14500                         operands[4], operands[5], operands[6], NULL_RTX);
14501   DONE;
14504 ;; %%% Kill this when reload knows how to do it.
14505 (define_split
14506   [(set (pc)
14507         (if_then_else (match_operator 0 "comparison_operator"
14508                         [(match_operator 1 "float_operator"
14509                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14510                            (match_operand 3 "register_operand" "")])
14511           (match_operand 4 "" "")
14512           (match_operand 5 "" "")))
14513    (clobber (reg:CCFP FPSR_REG))
14514    (clobber (reg:CCFP FLAGS_REG))
14515    (clobber (match_scratch:HI 6 "=a"))]
14516   "reload_completed"
14517   [(const_int 0)]
14519   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14520   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14521   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14522                         operands[3], operands[7],
14523                         operands[4], operands[5], operands[6], operands[2]);
14524   DONE;
14527 ;; Unconditional and other jump instructions
14529 (define_insn "jump"
14530   [(set (pc)
14531         (label_ref (match_operand 0 "" "")))]
14532   ""
14533   "jmp\t%l0"
14534   [(set_attr "type" "ibr")
14535    (set (attr "length")
14536            (if_then_else (and (ge (minus (match_dup 0) (pc))
14537                                   (const_int -126))
14538                               (lt (minus (match_dup 0) (pc))
14539                                   (const_int 128)))
14540              (const_int 2)
14541              (const_int 5)))
14542    (set_attr "modrm" "0")])
14544 (define_expand "indirect_jump"
14545   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14546   ""
14547   "")
14549 (define_insn "*indirect_jump"
14550   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14551   ""
14552   "jmp\t%A0"
14553   [(set_attr "type" "ibr")
14554    (set_attr "length_immediate" "0")])
14556 (define_expand "tablejump"
14557   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14558               (use (label_ref (match_operand 1 "" "")))])]
14559   ""
14561   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14562      relative.  Convert the relative address to an absolute address.  */
14563   if (flag_pic)
14564     {
14565       rtx op0, op1;
14566       enum rtx_code code;
14568       /* We can't use @GOTOFF for text labels on VxWorks;
14569          see gotoff_operand.  */
14570       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14571         {
14572           code = PLUS;
14573           op0 = operands[0];
14574           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14575         }
14576       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14577         {
14578           code = PLUS;
14579           op0 = operands[0];
14580           op1 = pic_offset_table_rtx;
14581         }
14582       else
14583         {
14584           code = MINUS;
14585           op0 = pic_offset_table_rtx;
14586           op1 = operands[0];
14587         }
14589       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14590                                          OPTAB_DIRECT);
14591     }
14594 (define_insn "*tablejump_1"
14595   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14596    (use (label_ref (match_operand 1 "" "")))]
14597   ""
14598   "jmp\t%A0"
14599   [(set_attr "type" "ibr")
14600    (set_attr "length_immediate" "0")])
14602 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14604 (define_peephole2
14605   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14606    (set (match_operand:QI 1 "register_operand" "")
14607         (match_operator:QI 2 "ix86_comparison_operator"
14608           [(reg FLAGS_REG) (const_int 0)]))
14609    (set (match_operand 3 "q_regs_operand" "")
14610         (zero_extend (match_dup 1)))]
14611   "(peep2_reg_dead_p (3, operands[1])
14612     || operands_match_p (operands[1], operands[3]))
14613    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14614   [(set (match_dup 4) (match_dup 0))
14615    (set (strict_low_part (match_dup 5))
14616         (match_dup 2))]
14618   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14619   operands[5] = gen_lowpart (QImode, operands[3]);
14620   ix86_expand_clear (operands[3]);
14623 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14625 (define_peephole2
14626   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14627    (set (match_operand:QI 1 "register_operand" "")
14628         (match_operator:QI 2 "ix86_comparison_operator"
14629           [(reg FLAGS_REG) (const_int 0)]))
14630    (parallel [(set (match_operand 3 "q_regs_operand" "")
14631                    (zero_extend (match_dup 1)))
14632               (clobber (reg:CC FLAGS_REG))])]
14633   "(peep2_reg_dead_p (3, operands[1])
14634     || operands_match_p (operands[1], operands[3]))
14635    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14636   [(set (match_dup 4) (match_dup 0))
14637    (set (strict_low_part (match_dup 5))
14638         (match_dup 2))]
14640   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14641   operands[5] = gen_lowpart (QImode, operands[3]);
14642   ix86_expand_clear (operands[3]);
14645 ;; Call instructions.
14647 ;; The predicates normally associated with named expanders are not properly
14648 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14649 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14651 ;; Call subroutine returning no value.
14653 (define_expand "call_pop"
14654   [(parallel [(call (match_operand:QI 0 "" "")
14655                     (match_operand:SI 1 "" ""))
14656               (set (reg:SI SP_REG)
14657                    (plus:SI (reg:SI SP_REG)
14658                             (match_operand:SI 3 "" "")))])]
14659   "!TARGET_64BIT"
14661   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14662   DONE;
14665 (define_insn "*call_pop_0"
14666   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14667          (match_operand:SI 1 "" ""))
14668    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14669                             (match_operand:SI 2 "immediate_operand" "")))]
14670   "!TARGET_64BIT"
14672   if (SIBLING_CALL_P (insn))
14673     return "jmp\t%P0";
14674   else
14675     return "call\t%P0";
14677   [(set_attr "type" "call")])
14679 (define_insn "*call_pop_1"
14680   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14681          (match_operand:SI 1 "" ""))
14682    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14683                             (match_operand:SI 2 "immediate_operand" "i")))]
14684   "!TARGET_64BIT"
14686   if (constant_call_address_operand (operands[0], Pmode))
14687     {
14688       if (SIBLING_CALL_P (insn))
14689         return "jmp\t%P0";
14690       else
14691         return "call\t%P0";
14692     }
14693   if (SIBLING_CALL_P (insn))
14694     return "jmp\t%A0";
14695   else
14696     return "call\t%A0";
14698   [(set_attr "type" "call")])
14700 (define_expand "call"
14701   [(call (match_operand:QI 0 "" "")
14702          (match_operand 1 "" ""))
14703    (use (match_operand 2 "" ""))]
14704   ""
14706   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14707   DONE;
14710 (define_expand "sibcall"
14711   [(call (match_operand:QI 0 "" "")
14712          (match_operand 1 "" ""))
14713    (use (match_operand 2 "" ""))]
14714   ""
14716   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14717   DONE;
14720 (define_insn "*call_0"
14721   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14722          (match_operand 1 "" ""))]
14723   ""
14725   if (SIBLING_CALL_P (insn))
14726     return "jmp\t%P0";
14727   else
14728     return "call\t%P0";
14730   [(set_attr "type" "call")])
14732 (define_insn "*call_1"
14733   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14734          (match_operand 1 "" ""))]
14735   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14737   if (constant_call_address_operand (operands[0], Pmode))
14738     return "call\t%P0";
14739   return "call\t%A0";
14741   [(set_attr "type" "call")])
14743 (define_insn "*sibcall_1"
14744   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14745          (match_operand 1 "" ""))]
14746   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14748   if (constant_call_address_operand (operands[0], Pmode))
14749     return "jmp\t%P0";
14750   return "jmp\t%A0";
14752   [(set_attr "type" "call")])
14754 (define_insn "*call_1_rex64"
14755   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14756          (match_operand 1 "" ""))]
14757   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14758    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14760   if (constant_call_address_operand (operands[0], Pmode))
14761     return "call\t%P0";
14762   return "call\t%A0";
14764   [(set_attr "type" "call")])
14766 (define_insn "*call_1_rex64_large"
14767   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14768          (match_operand 1 "" ""))]
14769   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14770   "call\t%A0"
14771   [(set_attr "type" "call")])
14773 (define_insn "*sibcall_1_rex64"
14774   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14775          (match_operand 1 "" ""))]
14776   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14777   "jmp\t%P0"
14778   [(set_attr "type" "call")])
14780 (define_insn "*sibcall_1_rex64_v"
14781   [(call (mem:QI (reg:DI R11_REG))
14782          (match_operand 0 "" ""))]
14783   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14784   "jmp\t{*%%}r11"
14785   [(set_attr "type" "call")])
14788 ;; Call subroutine, returning value in operand 0
14790 (define_expand "call_value_pop"
14791   [(parallel [(set (match_operand 0 "" "")
14792                    (call (match_operand:QI 1 "" "")
14793                          (match_operand:SI 2 "" "")))
14794               (set (reg:SI SP_REG)
14795                    (plus:SI (reg:SI SP_REG)
14796                             (match_operand:SI 4 "" "")))])]
14797   "!TARGET_64BIT"
14799   ix86_expand_call (operands[0], operands[1], operands[2],
14800                     operands[3], operands[4], 0);
14801   DONE;
14804 (define_expand "call_value"
14805   [(set (match_operand 0 "" "")
14806         (call (match_operand:QI 1 "" "")
14807               (match_operand:SI 2 "" "")))
14808    (use (match_operand:SI 3 "" ""))]
14809   ;; Operand 2 not used on the i386.
14810   ""
14812   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14813   DONE;
14816 (define_expand "sibcall_value"
14817   [(set (match_operand 0 "" "")
14818         (call (match_operand:QI 1 "" "")
14819               (match_operand:SI 2 "" "")))
14820    (use (match_operand:SI 3 "" ""))]
14821   ;; Operand 2 not used on the i386.
14822   ""
14824   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14825   DONE;
14828 ;; Call subroutine returning any type.
14830 (define_expand "untyped_call"
14831   [(parallel [(call (match_operand 0 "" "")
14832                     (const_int 0))
14833               (match_operand 1 "" "")
14834               (match_operand 2 "" "")])]
14835   ""
14837   int i;
14839   /* In order to give reg-stack an easier job in validating two
14840      coprocessor registers as containing a possible return value,
14841      simply pretend the untyped call returns a complex long double
14842      value.  */
14844   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14845                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14846                     operands[0], const0_rtx,
14847                     GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
14848                                                       : X64_SSE_REGPARM_MAX)
14849                              - 1),
14850                     NULL, 0);
14852   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14853     {
14854       rtx set = XVECEXP (operands[2], 0, i);
14855       emit_move_insn (SET_DEST (set), SET_SRC (set));
14856     }
14858   /* The optimizer does not know that the call sets the function value
14859      registers we stored in the result block.  We avoid problems by
14860      claiming that all hard registers are used and clobbered at this
14861      point.  */
14862   emit_insn (gen_blockage ());
14864   DONE;
14867 ;; Prologue and epilogue instructions
14869 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14870 ;; all of memory.  This blocks insns from being moved across this point.
14872 (define_insn "blockage"
14873   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14874   ""
14875   ""
14876   [(set_attr "length" "0")])
14878 ;; As USE insns aren't meaningful after reload, this is used instead
14879 ;; to prevent deleting instructions setting registers for PIC code
14880 (define_insn "prologue_use"
14881   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14882   ""
14883   ""
14884   [(set_attr "length" "0")])
14886 ;; Insn emitted into the body of a function to return from a function.
14887 ;; This is only done if the function's epilogue is known to be simple.
14888 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14890 (define_expand "return"
14891   [(return)]
14892   "ix86_can_use_return_insn_p ()"
14894   if (crtl->args.pops_args)
14895     {
14896       rtx popc = GEN_INT (crtl->args.pops_args);
14897       emit_jump_insn (gen_return_pop_internal (popc));
14898       DONE;
14899     }
14902 (define_insn "return_internal"
14903   [(return)]
14904   "reload_completed"
14905   "ret"
14906   [(set_attr "length" "1")
14907    (set_attr "length_immediate" "0")
14908    (set_attr "modrm" "0")])
14910 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14911 ;; instruction Athlon and K8 have.
14913 (define_insn "return_internal_long"
14914   [(return)
14915    (unspec [(const_int 0)] UNSPEC_REP)]
14916   "reload_completed"
14917   "rep\;ret"
14918   [(set_attr "length" "1")
14919    (set_attr "length_immediate" "0")
14920    (set_attr "prefix_rep" "1")
14921    (set_attr "modrm" "0")])
14923 (define_insn "return_pop_internal"
14924   [(return)
14925    (use (match_operand:SI 0 "const_int_operand" ""))]
14926   "reload_completed"
14927   "ret\t%0"
14928   [(set_attr "length" "3")
14929    (set_attr "length_immediate" "2")
14930    (set_attr "modrm" "0")])
14932 (define_insn "return_indirect_internal"
14933   [(return)
14934    (use (match_operand:SI 0 "register_operand" "r"))]
14935   "reload_completed"
14936   "jmp\t%A0"
14937   [(set_attr "type" "ibr")
14938    (set_attr "length_immediate" "0")])
14940 (define_insn "nop"
14941   [(const_int 0)]
14942   ""
14943   "nop"
14944   [(set_attr "length" "1")
14945    (set_attr "length_immediate" "0")
14946    (set_attr "modrm" "0")])
14948 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14949 ;; branch prediction penalty for the third jump in a 16-byte
14950 ;; block on K8.
14952 (define_insn "align"
14953   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14954   ""
14956 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14957   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14958 #else
14959   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14960      The align insn is used to avoid 3 jump instructions in the row to improve
14961      branch prediction and the benefits hardly outweigh the cost of extra 8
14962      nops on the average inserted by full alignment pseudo operation.  */
14963 #endif
14964   return "";
14966   [(set_attr "length" "16")])
14968 (define_expand "prologue"
14969   [(const_int 0)]
14970   ""
14971   "ix86_expand_prologue (); DONE;")
14973 (define_insn "set_got"
14974   [(set (match_operand:SI 0 "register_operand" "=r")
14975         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14976    (clobber (reg:CC FLAGS_REG))]
14977   "!TARGET_64BIT"
14978   { return output_set_got (operands[0], NULL_RTX); }
14979   [(set_attr "type" "multi")
14980    (set_attr "length" "12")])
14982 (define_insn "set_got_labelled"
14983   [(set (match_operand:SI 0 "register_operand" "=r")
14984         (unspec:SI [(label_ref (match_operand 1 "" ""))]
14985          UNSPEC_SET_GOT))
14986    (clobber (reg:CC FLAGS_REG))]
14987   "!TARGET_64BIT"
14988   { return output_set_got (operands[0], operands[1]); }
14989   [(set_attr "type" "multi")
14990    (set_attr "length" "12")])
14992 (define_insn "set_got_rex64"
14993   [(set (match_operand:DI 0 "register_operand" "=r")
14994         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14995   "TARGET_64BIT"
14996   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14997   [(set_attr "type" "lea")
14998    (set_attr "length" "6")])
15000 (define_insn "set_rip_rex64"
15001   [(set (match_operand:DI 0 "register_operand" "=r")
15002         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15003   "TARGET_64BIT"
15004   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15005   [(set_attr "type" "lea")
15006    (set_attr "length" "6")])
15008 (define_insn "set_got_offset_rex64"
15009   [(set (match_operand:DI 0 "register_operand" "=r")
15010         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15011   "TARGET_64BIT"
15012   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15013   [(set_attr "type" "imov")
15014    (set_attr "length" "11")])
15016 (define_expand "epilogue"
15017   [(const_int 0)]
15018   ""
15019   "ix86_expand_epilogue (1); DONE;")
15021 (define_expand "sibcall_epilogue"
15022   [(const_int 0)]
15023   ""
15024   "ix86_expand_epilogue (0); DONE;")
15026 (define_expand "eh_return"
15027   [(use (match_operand 0 "register_operand" ""))]
15028   ""
15030   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15032   /* Tricky bit: we write the address of the handler to which we will
15033      be returning into someone else's stack frame, one word below the
15034      stack address we wish to restore.  */
15035   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15036   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15037   tmp = gen_rtx_MEM (Pmode, tmp);
15038   emit_move_insn (tmp, ra);
15040   if (Pmode == SImode)
15041     emit_jump_insn (gen_eh_return_si (sa));
15042   else
15043     emit_jump_insn (gen_eh_return_di (sa));
15044   emit_barrier ();
15045   DONE;
15048 (define_insn_and_split "eh_return_<mode>"
15049   [(set (pc)
15050         (unspec [(match_operand:P 0 "register_operand" "c")]
15051                  UNSPEC_EH_RETURN))]
15052   ""
15053   "#"
15054   "reload_completed"
15055   [(const_int 0)]
15056   "ix86_expand_epilogue (2); DONE;")
15058 (define_insn "leave"
15059   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15060    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15061    (clobber (mem:BLK (scratch)))]
15062   "!TARGET_64BIT"
15063   "leave"
15064   [(set_attr "type" "leave")])
15066 (define_insn "leave_rex64"
15067   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15068    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15069    (clobber (mem:BLK (scratch)))]
15070   "TARGET_64BIT"
15071   "leave"
15072   [(set_attr "type" "leave")])
15074 (define_expand "ffssi2"
15075   [(parallel
15076      [(set (match_operand:SI 0 "register_operand" "")
15077            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15078       (clobber (match_scratch:SI 2 ""))
15079       (clobber (reg:CC FLAGS_REG))])]
15080   ""
15082   if (TARGET_CMOVE)
15083     {
15084       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15085       DONE;
15086     }
15089 (define_expand "ffs_cmove"
15090   [(set (match_dup 2) (const_int -1))
15091    (parallel [(set (reg:CCZ FLAGS_REG)
15092                    (compare:CCZ (match_operand:SI 1 "register_operand" "")
15093                                 (const_int 0)))
15094               (set (match_operand:SI 0 "nonimmediate_operand" "")
15095                    (ctz:SI (match_dup 1)))])
15096    (set (match_dup 0) (if_then_else:SI
15097                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15098                         (match_dup 2)
15099                         (match_dup 0)))
15100    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15101               (clobber (reg:CC FLAGS_REG))])]
15102   "TARGET_CMOVE"
15103   "operands[2] = gen_reg_rtx (SImode);")
15105 (define_insn_and_split "*ffs_no_cmove"
15106   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15107         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15108    (clobber (match_scratch:SI 2 "=&q"))
15109    (clobber (reg:CC FLAGS_REG))]
15110   "!TARGET_CMOVE"
15111   "#"
15112   "&& reload_completed"
15113   [(parallel [(set (reg:CCZ FLAGS_REG)
15114                    (compare:CCZ (match_dup 1) (const_int 0)))
15115               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15116    (set (strict_low_part (match_dup 3))
15117         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15118    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15119               (clobber (reg:CC FLAGS_REG))])
15120    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15121               (clobber (reg:CC FLAGS_REG))])
15122    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15123               (clobber (reg:CC FLAGS_REG))])]
15125   operands[3] = gen_lowpart (QImode, operands[2]);
15126   ix86_expand_clear (operands[2]);
15129 (define_insn "*ffssi_1"
15130   [(set (reg:CCZ FLAGS_REG)
15131         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15132                      (const_int 0)))
15133    (set (match_operand:SI 0 "register_operand" "=r")
15134         (ctz:SI (match_dup 1)))]
15135   ""
15136   "bsf{l}\t{%1, %0|%0, %1}"
15137   [(set_attr "prefix_0f" "1")])
15139 (define_expand "ffsdi2"
15140   [(set (match_dup 2) (const_int -1))
15141    (parallel [(set (reg:CCZ FLAGS_REG)
15142                    (compare:CCZ (match_operand:DI 1 "register_operand" "")
15143                                 (const_int 0)))
15144               (set (match_operand:DI 0 "nonimmediate_operand" "")
15145                    (ctz:DI (match_dup 1)))])
15146    (set (match_dup 0) (if_then_else:DI
15147                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15148                         (match_dup 2)
15149                         (match_dup 0)))
15150    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15151               (clobber (reg:CC FLAGS_REG))])]
15152   "TARGET_64BIT"
15153   "operands[2] = gen_reg_rtx (DImode);")
15155 (define_insn "*ffsdi_1"
15156   [(set (reg:CCZ FLAGS_REG)
15157         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15158                      (const_int 0)))
15159    (set (match_operand:DI 0 "register_operand" "=r")
15160         (ctz:DI (match_dup 1)))]
15161   "TARGET_64BIT"
15162   "bsf{q}\t{%1, %0|%0, %1}"
15163   [(set_attr "prefix_0f" "1")])
15165 (define_insn "ctzsi2"
15166   [(set (match_operand:SI 0 "register_operand" "=r")
15167         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15168    (clobber (reg:CC FLAGS_REG))]
15169   ""
15170   "bsf{l}\t{%1, %0|%0, %1}"
15171   [(set_attr "prefix_0f" "1")])
15173 (define_insn "ctzdi2"
15174   [(set (match_operand:DI 0 "register_operand" "=r")
15175         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15176    (clobber (reg:CC FLAGS_REG))]
15177   "TARGET_64BIT"
15178   "bsf{q}\t{%1, %0|%0, %1}"
15179   [(set_attr "prefix_0f" "1")])
15181 (define_expand "clzsi2"
15182   [(parallel
15183      [(set (match_operand:SI 0 "register_operand" "")
15184            (minus:SI (const_int 31)
15185                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15186       (clobber (reg:CC FLAGS_REG))])
15187    (parallel
15188      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15189       (clobber (reg:CC FLAGS_REG))])]
15190   ""
15192   if (TARGET_ABM)
15193     {
15194       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15195       DONE;
15196     }
15199 (define_insn "clzsi2_abm"
15200   [(set (match_operand:SI 0 "register_operand" "=r")
15201         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15202    (clobber (reg:CC FLAGS_REG))]
15203   "TARGET_ABM"
15204   "lzcnt{l}\t{%1, %0|%0, %1}"
15205   [(set_attr "prefix_rep" "1")
15206    (set_attr "type" "bitmanip")
15207    (set_attr "mode" "SI")])
15209 (define_insn "*bsr"
15210   [(set (match_operand:SI 0 "register_operand" "=r")
15211         (minus:SI (const_int 31)
15212                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15213    (clobber (reg:CC FLAGS_REG))]
15214   ""
15215   "bsr{l}\t{%1, %0|%0, %1}"
15216   [(set_attr "prefix_0f" "1")
15217    (set_attr "mode" "SI")])
15219 (define_insn "popcountsi2"
15220   [(set (match_operand:SI 0 "register_operand" "=r")
15221         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15222    (clobber (reg:CC FLAGS_REG))]
15223   "TARGET_POPCNT"
15224   "popcnt{l}\t{%1, %0|%0, %1}"
15225   [(set_attr "prefix_rep" "1")
15226    (set_attr "type" "bitmanip")
15227    (set_attr "mode" "SI")])
15229 (define_insn "*popcountsi2_cmp"
15230   [(set (reg FLAGS_REG)
15231         (compare
15232           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15233           (const_int 0)))
15234    (set (match_operand:SI 0 "register_operand" "=r")
15235         (popcount:SI (match_dup 1)))]
15236   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15237   "popcnt{l}\t{%1, %0|%0, %1}"
15238   [(set_attr "prefix_rep" "1")
15239    (set_attr "type" "bitmanip")
15240    (set_attr "mode" "SI")])
15242 (define_insn "*popcountsi2_cmp_zext"
15243   [(set (reg FLAGS_REG)
15244         (compare
15245           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15246           (const_int 0)))
15247    (set (match_operand:DI 0 "register_operand" "=r")
15248         (zero_extend:DI(popcount:SI (match_dup 1))))]
15249   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15250   "popcnt{l}\t{%1, %0|%0, %1}"
15251   [(set_attr "prefix_rep" "1")
15252    (set_attr "type" "bitmanip")
15253    (set_attr "mode" "SI")])
15255 (define_expand "bswapsi2"
15256   [(set (match_operand:SI 0 "register_operand" "")
15257         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15258   ""
15260   if (!TARGET_BSWAP)
15261     {
15262       rtx x = operands[0];
15264       emit_move_insn (x, operands[1]);
15265       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15266       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15267       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15268       DONE;
15269     }
15272 (define_insn "*bswapsi_1"
15273   [(set (match_operand:SI 0 "register_operand" "=r")
15274         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15275   "TARGET_BSWAP"
15276   "bswap\t%0"
15277   [(set_attr "prefix_0f" "1")
15278    (set_attr "length" "2")])
15280 (define_insn "*bswaphi_lowpart_1"
15281   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15282         (bswap:HI (match_dup 0)))
15283    (clobber (reg:CC FLAGS_REG))]
15284   "TARGET_USE_XCHGB || optimize_size"
15285   "@
15286     xchg{b}\t{%h0, %b0|%b0, %h0}
15287     rol{w}\t{$8, %0|%0, 8}"
15288   [(set_attr "length" "2,4")
15289    (set_attr "mode" "QI,HI")])
15291 (define_insn "bswaphi_lowpart"
15292   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15293         (bswap:HI (match_dup 0)))
15294    (clobber (reg:CC FLAGS_REG))]
15295   ""
15296   "rol{w}\t{$8, %0|%0, 8}"
15297   [(set_attr "length" "4")
15298    (set_attr "mode" "HI")])
15300 (define_insn "bswapdi2"
15301   [(set (match_operand:DI 0 "register_operand" "=r")
15302         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15303   "TARGET_64BIT"
15304   "bswap\t%0"
15305   [(set_attr "prefix_0f" "1")
15306    (set_attr "length" "3")])
15308 (define_expand "clzdi2"
15309   [(parallel
15310      [(set (match_operand:DI 0 "register_operand" "")
15311            (minus:DI (const_int 63)
15312                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15313       (clobber (reg:CC FLAGS_REG))])
15314    (parallel
15315      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15316       (clobber (reg:CC FLAGS_REG))])]
15317   "TARGET_64BIT"
15319   if (TARGET_ABM)
15320     {
15321       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15322       DONE;
15323     }
15326 (define_insn "clzdi2_abm"
15327   [(set (match_operand:DI 0 "register_operand" "=r")
15328         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15329    (clobber (reg:CC FLAGS_REG))]
15330   "TARGET_64BIT && TARGET_ABM"
15331   "lzcnt{q}\t{%1, %0|%0, %1}"
15332   [(set_attr "prefix_rep" "1")
15333    (set_attr "type" "bitmanip")
15334    (set_attr "mode" "DI")])
15336 (define_insn "*bsr_rex64"
15337   [(set (match_operand:DI 0 "register_operand" "=r")
15338         (minus:DI (const_int 63)
15339                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15340    (clobber (reg:CC FLAGS_REG))]
15341   "TARGET_64BIT"
15342   "bsr{q}\t{%1, %0|%0, %1}"
15343   [(set_attr "prefix_0f" "1")
15344    (set_attr "mode" "DI")])
15346 (define_insn "popcountdi2"
15347   [(set (match_operand:DI 0 "register_operand" "=r")
15348         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15349    (clobber (reg:CC FLAGS_REG))]
15350   "TARGET_64BIT && TARGET_POPCNT"
15351   "popcnt{q}\t{%1, %0|%0, %1}"
15352   [(set_attr "prefix_rep" "1")
15353    (set_attr "type" "bitmanip")
15354    (set_attr "mode" "DI")])
15356 (define_insn "*popcountdi2_cmp"
15357   [(set (reg FLAGS_REG)
15358         (compare
15359           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15360           (const_int 0)))
15361    (set (match_operand:DI 0 "register_operand" "=r")
15362         (popcount:DI (match_dup 1)))]
15363   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15364   "popcnt{q}\t{%1, %0|%0, %1}"
15365   [(set_attr "prefix_rep" "1")
15366    (set_attr "type" "bitmanip")
15367    (set_attr "mode" "DI")])
15369 (define_expand "clzhi2"
15370   [(parallel
15371      [(set (match_operand:HI 0 "register_operand" "")
15372            (minus:HI (const_int 15)
15373                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15374       (clobber (reg:CC FLAGS_REG))])
15375    (parallel
15376      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15377       (clobber (reg:CC FLAGS_REG))])]
15378   ""
15380   if (TARGET_ABM)
15381     {
15382       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15383       DONE;
15384     }
15387 (define_insn "clzhi2_abm"
15388   [(set (match_operand:HI 0 "register_operand" "=r")
15389         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15390    (clobber (reg:CC FLAGS_REG))]
15391   "TARGET_ABM"
15392   "lzcnt{w}\t{%1, %0|%0, %1}"
15393   [(set_attr "prefix_rep" "1")
15394    (set_attr "type" "bitmanip")
15395    (set_attr "mode" "HI")])
15397 (define_insn "*bsrhi"
15398   [(set (match_operand:HI 0 "register_operand" "=r")
15399         (minus:HI (const_int 15)
15400                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15401    (clobber (reg:CC FLAGS_REG))]
15402   ""
15403   "bsr{w}\t{%1, %0|%0, %1}"
15404   [(set_attr "prefix_0f" "1")
15405    (set_attr "mode" "HI")])
15407 (define_insn "popcounthi2"
15408   [(set (match_operand:HI 0 "register_operand" "=r")
15409         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15410    (clobber (reg:CC FLAGS_REG))]
15411   "TARGET_POPCNT"
15412   "popcnt{w}\t{%1, %0|%0, %1}"
15413   [(set_attr "prefix_rep" "1")
15414    (set_attr "type" "bitmanip")
15415    (set_attr "mode" "HI")])
15417 (define_insn "*popcounthi2_cmp"
15418   [(set (reg FLAGS_REG)
15419         (compare
15420           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15421           (const_int 0)))
15422    (set (match_operand:HI 0 "register_operand" "=r")
15423         (popcount:HI (match_dup 1)))]
15424   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15425   "popcnt{w}\t{%1, %0|%0, %1}"
15426   [(set_attr "prefix_rep" "1")
15427    (set_attr "type" "bitmanip")
15428    (set_attr "mode" "HI")])
15430 (define_expand "paritydi2"
15431   [(set (match_operand:DI 0 "register_operand" "")
15432         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15433   "! TARGET_POPCNT"
15435   rtx scratch = gen_reg_rtx (QImode);
15436   rtx cond;
15438   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15439                                 NULL_RTX, operands[1]));
15441   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15442                          gen_rtx_REG (CCmode, FLAGS_REG),
15443                          const0_rtx);
15444   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15446   if (TARGET_64BIT)
15447     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15448   else
15449     {
15450       rtx tmp = gen_reg_rtx (SImode);
15452       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15453       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15454     }
15455   DONE;
15458 (define_insn_and_split "paritydi2_cmp"
15459   [(set (reg:CC FLAGS_REG)
15460         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15461    (clobber (match_scratch:DI 0 "=r"))
15462    (clobber (match_scratch:SI 1 "=&r"))
15463    (clobber (match_scratch:HI 2 "=Q"))]
15464   "! TARGET_POPCNT"
15465   "#"
15466   "&& reload_completed"
15467   [(parallel
15468      [(set (match_dup 1)
15469            (xor:SI (match_dup 1) (match_dup 4)))
15470       (clobber (reg:CC FLAGS_REG))])
15471    (parallel
15472      [(set (reg:CC FLAGS_REG)
15473            (parity:CC (match_dup 1)))
15474       (clobber (match_dup 1))
15475       (clobber (match_dup 2))])]
15477   operands[4] = gen_lowpart (SImode, operands[3]);
15479   if (TARGET_64BIT)
15480     {
15481       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15482       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15483     }
15484   else
15485     operands[1] = gen_highpart (SImode, operands[3]);
15488 (define_expand "paritysi2"
15489   [(set (match_operand:SI 0 "register_operand" "")
15490         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15491   "! TARGET_POPCNT"
15493   rtx scratch = gen_reg_rtx (QImode);
15494   rtx cond;
15496   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15498   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15499                          gen_rtx_REG (CCmode, FLAGS_REG),
15500                          const0_rtx);
15501   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15503   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15504   DONE;
15507 (define_insn_and_split "paritysi2_cmp"
15508   [(set (reg:CC FLAGS_REG)
15509         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15510    (clobber (match_scratch:SI 0 "=r"))
15511    (clobber (match_scratch:HI 1 "=&Q"))]
15512   "! TARGET_POPCNT"
15513   "#"
15514   "&& reload_completed"
15515   [(parallel
15516      [(set (match_dup 1)
15517            (xor:HI (match_dup 1) (match_dup 3)))
15518       (clobber (reg:CC FLAGS_REG))])
15519    (parallel
15520      [(set (reg:CC FLAGS_REG)
15521            (parity:CC (match_dup 1)))
15522       (clobber (match_dup 1))])]
15524   operands[3] = gen_lowpart (HImode, operands[2]);
15526   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15527   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15530 (define_insn "*parityhi2_cmp"
15531   [(set (reg:CC FLAGS_REG)
15532         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15533    (clobber (match_scratch:HI 0 "=Q"))]
15534   "! TARGET_POPCNT"
15535   "xor{b}\t{%h0, %b0|%b0, %h0}"
15536   [(set_attr "length" "2")
15537    (set_attr "mode" "HI")])
15539 (define_insn "*parityqi2_cmp"
15540   [(set (reg:CC FLAGS_REG)
15541         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15542   "! TARGET_POPCNT"
15543   "test{b}\t%0, %0"
15544   [(set_attr "length" "2")
15545    (set_attr "mode" "QI")])
15547 ;; Thread-local storage patterns for ELF.
15549 ;; Note that these code sequences must appear exactly as shown
15550 ;; in order to allow linker relaxation.
15552 (define_insn "*tls_global_dynamic_32_gnu"
15553   [(set (match_operand:SI 0 "register_operand" "=a")
15554         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15555                     (match_operand:SI 2 "tls_symbolic_operand" "")
15556                     (match_operand:SI 3 "call_insn_operand" "")]
15557                     UNSPEC_TLS_GD))
15558    (clobber (match_scratch:SI 4 "=d"))
15559    (clobber (match_scratch:SI 5 "=c"))
15560    (clobber (reg:CC FLAGS_REG))]
15561   "!TARGET_64BIT && TARGET_GNU_TLS"
15562   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15563   [(set_attr "type" "multi")
15564    (set_attr "length" "12")])
15566 (define_insn "*tls_global_dynamic_32_sun"
15567   [(set (match_operand:SI 0 "register_operand" "=a")
15568         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15569                     (match_operand:SI 2 "tls_symbolic_operand" "")
15570                     (match_operand:SI 3 "call_insn_operand" "")]
15571                     UNSPEC_TLS_GD))
15572    (clobber (match_scratch:SI 4 "=d"))
15573    (clobber (match_scratch:SI 5 "=c"))
15574    (clobber (reg:CC FLAGS_REG))]
15575   "!TARGET_64BIT && TARGET_SUN_TLS"
15576   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15577         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15578   [(set_attr "type" "multi")
15579    (set_attr "length" "14")])
15581 (define_expand "tls_global_dynamic_32"
15582   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15583                    (unspec:SI
15584                     [(match_dup 2)
15585                      (match_operand:SI 1 "tls_symbolic_operand" "")
15586                      (match_dup 3)]
15587                     UNSPEC_TLS_GD))
15588               (clobber (match_scratch:SI 4 ""))
15589               (clobber (match_scratch:SI 5 ""))
15590               (clobber (reg:CC FLAGS_REG))])]
15591   ""
15593   if (flag_pic)
15594     operands[2] = pic_offset_table_rtx;
15595   else
15596     {
15597       operands[2] = gen_reg_rtx (Pmode);
15598       emit_insn (gen_set_got (operands[2]));
15599     }
15600   if (TARGET_GNU2_TLS)
15601     {
15602        emit_insn (gen_tls_dynamic_gnu2_32
15603                   (operands[0], operands[1], operands[2]));
15604        DONE;
15605     }
15606   operands[3] = ix86_tls_get_addr ();
15609 (define_insn "*tls_global_dynamic_64"
15610   [(set (match_operand:DI 0 "register_operand" "=a")
15611         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15612                  (match_operand:DI 3 "" "")))
15613    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15614               UNSPEC_TLS_GD)]
15615   "TARGET_64BIT"
15616   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15617   [(set_attr "type" "multi")
15618    (set_attr "length" "16")])
15620 (define_expand "tls_global_dynamic_64"
15621   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15622                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15623               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15624                          UNSPEC_TLS_GD)])]
15625   ""
15627   if (TARGET_GNU2_TLS)
15628     {
15629        emit_insn (gen_tls_dynamic_gnu2_64
15630                   (operands[0], operands[1]));
15631        DONE;
15632     }
15633   operands[2] = ix86_tls_get_addr ();
15636 (define_insn "*tls_local_dynamic_base_32_gnu"
15637   [(set (match_operand:SI 0 "register_operand" "=a")
15638         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15639                     (match_operand:SI 2 "call_insn_operand" "")]
15640                    UNSPEC_TLS_LD_BASE))
15641    (clobber (match_scratch:SI 3 "=d"))
15642    (clobber (match_scratch:SI 4 "=c"))
15643    (clobber (reg:CC FLAGS_REG))]
15644   "!TARGET_64BIT && TARGET_GNU_TLS"
15645   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15646   [(set_attr "type" "multi")
15647    (set_attr "length" "11")])
15649 (define_insn "*tls_local_dynamic_base_32_sun"
15650   [(set (match_operand:SI 0 "register_operand" "=a")
15651         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15652                     (match_operand:SI 2 "call_insn_operand" "")]
15653                    UNSPEC_TLS_LD_BASE))
15654    (clobber (match_scratch:SI 3 "=d"))
15655    (clobber (match_scratch:SI 4 "=c"))
15656    (clobber (reg:CC FLAGS_REG))]
15657   "!TARGET_64BIT && TARGET_SUN_TLS"
15658   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15659         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15660   [(set_attr "type" "multi")
15661    (set_attr "length" "13")])
15663 (define_expand "tls_local_dynamic_base_32"
15664   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15665                    (unspec:SI [(match_dup 1) (match_dup 2)]
15666                               UNSPEC_TLS_LD_BASE))
15667               (clobber (match_scratch:SI 3 ""))
15668               (clobber (match_scratch:SI 4 ""))
15669               (clobber (reg:CC FLAGS_REG))])]
15670   ""
15672   if (flag_pic)
15673     operands[1] = pic_offset_table_rtx;
15674   else
15675     {
15676       operands[1] = gen_reg_rtx (Pmode);
15677       emit_insn (gen_set_got (operands[1]));
15678     }
15679   if (TARGET_GNU2_TLS)
15680     {
15681        emit_insn (gen_tls_dynamic_gnu2_32
15682                   (operands[0], ix86_tls_module_base (), operands[1]));
15683        DONE;
15684     }
15685   operands[2] = ix86_tls_get_addr ();
15688 (define_insn "*tls_local_dynamic_base_64"
15689   [(set (match_operand:DI 0 "register_operand" "=a")
15690         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15691                  (match_operand:DI 2 "" "")))
15692    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15693   "TARGET_64BIT"
15694   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15695   [(set_attr "type" "multi")
15696    (set_attr "length" "12")])
15698 (define_expand "tls_local_dynamic_base_64"
15699   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15700                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15701               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15702   ""
15704   if (TARGET_GNU2_TLS)
15705     {
15706        emit_insn (gen_tls_dynamic_gnu2_64
15707                   (operands[0], ix86_tls_module_base ()));
15708        DONE;
15709     }
15710   operands[1] = ix86_tls_get_addr ();
15713 ;; Local dynamic of a single variable is a lose.  Show combine how
15714 ;; to convert that back to global dynamic.
15716 (define_insn_and_split "*tls_local_dynamic_32_once"
15717   [(set (match_operand:SI 0 "register_operand" "=a")
15718         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15719                              (match_operand:SI 2 "call_insn_operand" "")]
15720                             UNSPEC_TLS_LD_BASE)
15721                  (const:SI (unspec:SI
15722                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15723                             UNSPEC_DTPOFF))))
15724    (clobber (match_scratch:SI 4 "=d"))
15725    (clobber (match_scratch:SI 5 "=c"))
15726    (clobber (reg:CC FLAGS_REG))]
15727   ""
15728   "#"
15729   ""
15730   [(parallel [(set (match_dup 0)
15731                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15732                               UNSPEC_TLS_GD))
15733               (clobber (match_dup 4))
15734               (clobber (match_dup 5))
15735               (clobber (reg:CC FLAGS_REG))])]
15736   "")
15738 ;; Load and add the thread base pointer from %gs:0.
15740 (define_insn "*load_tp_si"
15741   [(set (match_operand:SI 0 "register_operand" "=r")
15742         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15743   "!TARGET_64BIT"
15744   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15745   [(set_attr "type" "imov")
15746    (set_attr "modrm" "0")
15747    (set_attr "length" "7")
15748    (set_attr "memory" "load")
15749    (set_attr "imm_disp" "false")])
15751 (define_insn "*add_tp_si"
15752   [(set (match_operand:SI 0 "register_operand" "=r")
15753         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15754                  (match_operand:SI 1 "register_operand" "0")))
15755    (clobber (reg:CC FLAGS_REG))]
15756   "!TARGET_64BIT"
15757   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15758   [(set_attr "type" "alu")
15759    (set_attr "modrm" "0")
15760    (set_attr "length" "7")
15761    (set_attr "memory" "load")
15762    (set_attr "imm_disp" "false")])
15764 (define_insn "*load_tp_di"
15765   [(set (match_operand:DI 0 "register_operand" "=r")
15766         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15767   "TARGET_64BIT"
15768   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15769   [(set_attr "type" "imov")
15770    (set_attr "modrm" "0")
15771    (set_attr "length" "7")
15772    (set_attr "memory" "load")
15773    (set_attr "imm_disp" "false")])
15775 (define_insn "*add_tp_di"
15776   [(set (match_operand:DI 0 "register_operand" "=r")
15777         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15778                  (match_operand:DI 1 "register_operand" "0")))
15779    (clobber (reg:CC FLAGS_REG))]
15780   "TARGET_64BIT"
15781   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15782   [(set_attr "type" "alu")
15783    (set_attr "modrm" "0")
15784    (set_attr "length" "7")
15785    (set_attr "memory" "load")
15786    (set_attr "imm_disp" "false")])
15788 ;; GNU2 TLS patterns can be split.
15790 (define_expand "tls_dynamic_gnu2_32"
15791   [(set (match_dup 3)
15792         (plus:SI (match_operand:SI 2 "register_operand" "")
15793                  (const:SI
15794                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15795                              UNSPEC_TLSDESC))))
15796    (parallel
15797     [(set (match_operand:SI 0 "register_operand" "")
15798           (unspec:SI [(match_dup 1) (match_dup 3)
15799                       (match_dup 2) (reg:SI SP_REG)]
15800                       UNSPEC_TLSDESC))
15801      (clobber (reg:CC FLAGS_REG))])]
15802   "!TARGET_64BIT && TARGET_GNU2_TLS"
15804   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15805   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15808 (define_insn "*tls_dynamic_lea_32"
15809   [(set (match_operand:SI 0 "register_operand" "=r")
15810         (plus:SI (match_operand:SI 1 "register_operand" "b")
15811                  (const:SI
15812                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15813                               UNSPEC_TLSDESC))))]
15814   "!TARGET_64BIT && TARGET_GNU2_TLS"
15815   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15816   [(set_attr "type" "lea")
15817    (set_attr "mode" "SI")
15818    (set_attr "length" "6")
15819    (set_attr "length_address" "4")])
15821 (define_insn "*tls_dynamic_call_32"
15822   [(set (match_operand:SI 0 "register_operand" "=a")
15823         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15824                     (match_operand:SI 2 "register_operand" "0")
15825                     ;; we have to make sure %ebx still points to the GOT
15826                     (match_operand:SI 3 "register_operand" "b")
15827                     (reg:SI SP_REG)]
15828                    UNSPEC_TLSDESC))
15829    (clobber (reg:CC FLAGS_REG))]
15830   "!TARGET_64BIT && TARGET_GNU2_TLS"
15831   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15832   [(set_attr "type" "call")
15833    (set_attr "length" "2")
15834    (set_attr "length_address" "0")])
15836 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15837   [(set (match_operand:SI 0 "register_operand" "=&a")
15838         (plus:SI
15839          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15840                      (match_operand:SI 4 "" "")
15841                      (match_operand:SI 2 "register_operand" "b")
15842                      (reg:SI SP_REG)]
15843                     UNSPEC_TLSDESC)
15844          (const:SI (unspec:SI
15845                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15846                     UNSPEC_DTPOFF))))
15847    (clobber (reg:CC FLAGS_REG))]
15848   "!TARGET_64BIT && TARGET_GNU2_TLS"
15849   "#"
15850   ""
15851   [(set (match_dup 0) (match_dup 5))]
15853   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15854   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15857 (define_expand "tls_dynamic_gnu2_64"
15858   [(set (match_dup 2)
15859         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15860                    UNSPEC_TLSDESC))
15861    (parallel
15862     [(set (match_operand:DI 0 "register_operand" "")
15863           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15864                      UNSPEC_TLSDESC))
15865      (clobber (reg:CC FLAGS_REG))])]
15866   "TARGET_64BIT && TARGET_GNU2_TLS"
15868   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15869   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15872 (define_insn "*tls_dynamic_lea_64"
15873   [(set (match_operand:DI 0 "register_operand" "=r")
15874         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15875                    UNSPEC_TLSDESC))]
15876   "TARGET_64BIT && TARGET_GNU2_TLS"
15877   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15878   [(set_attr "type" "lea")
15879    (set_attr "mode" "DI")
15880    (set_attr "length" "7")
15881    (set_attr "length_address" "4")])
15883 (define_insn "*tls_dynamic_call_64"
15884   [(set (match_operand:DI 0 "register_operand" "=a")
15885         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15886                     (match_operand:DI 2 "register_operand" "0")
15887                     (reg:DI SP_REG)]
15888                    UNSPEC_TLSDESC))
15889    (clobber (reg:CC FLAGS_REG))]
15890   "TARGET_64BIT && TARGET_GNU2_TLS"
15891   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15892   [(set_attr "type" "call")
15893    (set_attr "length" "2")
15894    (set_attr "length_address" "0")])
15896 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15897   [(set (match_operand:DI 0 "register_operand" "=&a")
15898         (plus:DI
15899          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15900                      (match_operand:DI 3 "" "")
15901                      (reg:DI SP_REG)]
15902                     UNSPEC_TLSDESC)
15903          (const:DI (unspec:DI
15904                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15905                     UNSPEC_DTPOFF))))
15906    (clobber (reg:CC FLAGS_REG))]
15907   "TARGET_64BIT && TARGET_GNU2_TLS"
15908   "#"
15909   ""
15910   [(set (match_dup 0) (match_dup 4))]
15912   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15913   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15918 ;; These patterns match the binary 387 instructions for addM3, subM3,
15919 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15920 ;; SFmode.  The first is the normal insn, the second the same insn but
15921 ;; with one operand a conversion, and the third the same insn but with
15922 ;; the other operand a conversion.  The conversion may be SFmode or
15923 ;; SImode if the target mode DFmode, but only SImode if the target mode
15924 ;; is SFmode.
15926 ;; Gcc is slightly more smart about handling normal two address instructions
15927 ;; so use special patterns for add and mull.
15929 (define_insn "*fop_<mode>_comm_mixed"
15930   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15931         (match_operator:MODEF 3 "binary_fp_operator"
15932           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
15933            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15934   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15935    && COMMUTATIVE_ARITH_P (operands[3])
15936    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15937   "* return output_387_binary_op (insn, operands);"
15938   [(set (attr "type")
15939         (if_then_else (eq_attr "alternative" "1")
15940            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15941               (const_string "ssemul")
15942               (const_string "sseadd"))
15943            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15944               (const_string "fmul")
15945               (const_string "fop"))))
15946    (set_attr "mode" "<MODE>")])
15948 (define_insn "*fop_<mode>_comm_sse"
15949   [(set (match_operand:MODEF 0 "register_operand" "=x")
15950         (match_operator:MODEF 3 "binary_fp_operator"
15951           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15952            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15953   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15954    && COMMUTATIVE_ARITH_P (operands[3])
15955    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15956   "* return output_387_binary_op (insn, operands);"
15957   [(set (attr "type")
15958         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15959            (const_string "ssemul")
15960            (const_string "sseadd")))
15961    (set_attr "mode" "<MODE>")])
15963 (define_insn "*fop_<mode>_comm_i387"
15964   [(set (match_operand:MODEF 0 "register_operand" "=f")
15965         (match_operator:MODEF 3 "binary_fp_operator"
15966           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15967            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
15968   "TARGET_80387
15969    && COMMUTATIVE_ARITH_P (operands[3])
15970    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15971   "* return output_387_binary_op (insn, operands);"
15972   [(set (attr "type")
15973         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15974            (const_string "fmul")
15975            (const_string "fop")))
15976    (set_attr "mode" "<MODE>")])
15978 (define_insn "*fop_<mode>_1_mixed"
15979   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15980         (match_operator:MODEF 3 "binary_fp_operator"
15981           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
15982            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15983   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15984    && !COMMUTATIVE_ARITH_P (operands[3])
15985    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15986   "* return output_387_binary_op (insn, operands);"
15987   [(set (attr "type")
15988         (cond [(and (eq_attr "alternative" "2")
15989                     (match_operand:MODEF 3 "mult_operator" ""))
15990                  (const_string "ssemul")
15991                (and (eq_attr "alternative" "2")
15992                     (match_operand:MODEF 3 "div_operator" ""))
15993                  (const_string "ssediv")
15994                (eq_attr "alternative" "2")
15995                  (const_string "sseadd")
15996                (match_operand:MODEF 3 "mult_operator" "")
15997                  (const_string "fmul")
15998                (match_operand:MODEF 3 "div_operator" "")
15999                  (const_string "fdiv")
16000               ]
16001               (const_string "fop")))
16002    (set_attr "mode" "<MODE>")])
16004 (define_insn "*rcpsf2_sse"
16005   [(set (match_operand:SF 0 "register_operand" "=x")
16006         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16007                    UNSPEC_RCP))]
16008   "TARGET_SSE_MATH"
16009   "rcpss\t{%1, %0|%0, %1}"
16010   [(set_attr "type" "sse")
16011    (set_attr "mode" "SF")])
16013 (define_insn "*fop_<mode>_1_sse"
16014   [(set (match_operand:MODEF 0 "register_operand" "=x")
16015         (match_operator:MODEF 3 "binary_fp_operator"
16016           [(match_operand:MODEF 1 "register_operand" "0")
16017            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16018   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16019    && !COMMUTATIVE_ARITH_P (operands[3])"
16020   "* return output_387_binary_op (insn, operands);"
16021   [(set (attr "type")
16022         (cond [(match_operand:MODEF 3 "mult_operator" "")
16023                  (const_string "ssemul")
16024                (match_operand:MODEF 3 "div_operator" "")
16025                  (const_string "ssediv")
16026               ]
16027               (const_string "sseadd")))
16028    (set_attr "mode" "<MODE>")])
16030 ;; This pattern is not fully shadowed by the pattern above.
16031 (define_insn "*fop_<mode>_1_i387"
16032   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16033         (match_operator:MODEF 3 "binary_fp_operator"
16034           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16035            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16036   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16037    && !COMMUTATIVE_ARITH_P (operands[3])
16038    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16039   "* return output_387_binary_op (insn, operands);"
16040   [(set (attr "type")
16041         (cond [(match_operand:MODEF 3 "mult_operator" "")
16042                  (const_string "fmul")
16043                (match_operand:MODEF 3 "div_operator" "")
16044                  (const_string "fdiv")
16045               ]
16046               (const_string "fop")))
16047    (set_attr "mode" "<MODE>")])
16049 ;; ??? Add SSE splitters for these!
16050 (define_insn "*fop_<MODEF:mode>_2_i387"
16051   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16052         (match_operator:MODEF 3 "binary_fp_operator"
16053           [(float:MODEF
16054              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16055            (match_operand:MODEF 2 "register_operand" "0,0")]))]
16056   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16057    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_size)"
16058   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16059   [(set (attr "type")
16060         (cond [(match_operand:MODEF 3 "mult_operator" "")
16061                  (const_string "fmul")
16062                (match_operand:MODEF 3 "div_operator" "")
16063                  (const_string "fdiv")
16064               ]
16065               (const_string "fop")))
16066    (set_attr "fp_int_src" "true")
16067    (set_attr "mode" "<X87MODEI12:MODE>")])
16069 (define_insn "*fop_<MODEF:mode>_3_i387"
16070   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16071         (match_operator:MODEF 3 "binary_fp_operator"
16072           [(match_operand:MODEF 1 "register_operand" "0,0")
16073            (float:MODEF
16074              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16075   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
16076    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_size)"
16077   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16078   [(set (attr "type")
16079         (cond [(match_operand:MODEF 3 "mult_operator" "")
16080                  (const_string "fmul")
16081                (match_operand:MODEF 3 "div_operator" "")
16082                  (const_string "fdiv")
16083               ]
16084               (const_string "fop")))
16085    (set_attr "fp_int_src" "true")
16086    (set_attr "mode" "<MODE>")])
16088 (define_insn "*fop_df_4_i387"
16089   [(set (match_operand:DF 0 "register_operand" "=f,f")
16090         (match_operator:DF 3 "binary_fp_operator"
16091            [(float_extend:DF
16092              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16093             (match_operand:DF 2 "register_operand" "0,f")]))]
16094   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16095    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16096   "* return output_387_binary_op (insn, operands);"
16097   [(set (attr "type")
16098         (cond [(match_operand:DF 3 "mult_operator" "")
16099                  (const_string "fmul")
16100                (match_operand:DF 3 "div_operator" "")
16101                  (const_string "fdiv")
16102               ]
16103               (const_string "fop")))
16104    (set_attr "mode" "SF")])
16106 (define_insn "*fop_df_5_i387"
16107   [(set (match_operand:DF 0 "register_operand" "=f,f")
16108         (match_operator:DF 3 "binary_fp_operator"
16109           [(match_operand:DF 1 "register_operand" "0,f")
16110            (float_extend:DF
16111             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16112   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16113   "* return output_387_binary_op (insn, operands);"
16114   [(set (attr "type")
16115         (cond [(match_operand:DF 3 "mult_operator" "")
16116                  (const_string "fmul")
16117                (match_operand:DF 3 "div_operator" "")
16118                  (const_string "fdiv")
16119               ]
16120               (const_string "fop")))
16121    (set_attr "mode" "SF")])
16123 (define_insn "*fop_df_6_i387"
16124   [(set (match_operand:DF 0 "register_operand" "=f,f")
16125         (match_operator:DF 3 "binary_fp_operator"
16126           [(float_extend:DF
16127             (match_operand:SF 1 "register_operand" "0,f"))
16128            (float_extend:DF
16129             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16130   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16131   "* return output_387_binary_op (insn, operands);"
16132   [(set (attr "type")
16133         (cond [(match_operand:DF 3 "mult_operator" "")
16134                  (const_string "fmul")
16135                (match_operand:DF 3 "div_operator" "")
16136                  (const_string "fdiv")
16137               ]
16138               (const_string "fop")))
16139    (set_attr "mode" "SF")])
16141 (define_insn "*fop_xf_comm_i387"
16142   [(set (match_operand:XF 0 "register_operand" "=f")
16143         (match_operator:XF 3 "binary_fp_operator"
16144                         [(match_operand:XF 1 "register_operand" "%0")
16145                          (match_operand:XF 2 "register_operand" "f")]))]
16146   "TARGET_80387
16147    && COMMUTATIVE_ARITH_P (operands[3])"
16148   "* return output_387_binary_op (insn, operands);"
16149   [(set (attr "type")
16150         (if_then_else (match_operand:XF 3 "mult_operator" "")
16151            (const_string "fmul")
16152            (const_string "fop")))
16153    (set_attr "mode" "XF")])
16155 (define_insn "*fop_xf_1_i387"
16156   [(set (match_operand:XF 0 "register_operand" "=f,f")
16157         (match_operator:XF 3 "binary_fp_operator"
16158                         [(match_operand:XF 1 "register_operand" "0,f")
16159                          (match_operand:XF 2 "register_operand" "f,0")]))]
16160   "TARGET_80387
16161    && !COMMUTATIVE_ARITH_P (operands[3])"
16162   "* return output_387_binary_op (insn, operands);"
16163   [(set (attr "type")
16164         (cond [(match_operand:XF 3 "mult_operator" "")
16165                  (const_string "fmul")
16166                (match_operand:XF 3 "div_operator" "")
16167                  (const_string "fdiv")
16168               ]
16169               (const_string "fop")))
16170    (set_attr "mode" "XF")])
16172 (define_insn "*fop_xf_2_i387"
16173   [(set (match_operand:XF 0 "register_operand" "=f,f")
16174         (match_operator:XF 3 "binary_fp_operator"
16175           [(float:XF
16176              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16177            (match_operand:XF 2 "register_operand" "0,0")]))]
16178   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)"
16179   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16180   [(set (attr "type")
16181         (cond [(match_operand:XF 3 "mult_operator" "")
16182                  (const_string "fmul")
16183                (match_operand:XF 3 "div_operator" "")
16184                  (const_string "fdiv")
16185               ]
16186               (const_string "fop")))
16187    (set_attr "fp_int_src" "true")
16188    (set_attr "mode" "<MODE>")])
16190 (define_insn "*fop_xf_3_i387"
16191   [(set (match_operand:XF 0 "register_operand" "=f,f")
16192         (match_operator:XF 3 "binary_fp_operator"
16193           [(match_operand:XF 1 "register_operand" "0,0")
16194            (float:XF
16195              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16196   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)"
16197   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16198   [(set (attr "type")
16199         (cond [(match_operand:XF 3 "mult_operator" "")
16200                  (const_string "fmul")
16201                (match_operand:XF 3 "div_operator" "")
16202                  (const_string "fdiv")
16203               ]
16204               (const_string "fop")))
16205    (set_attr "fp_int_src" "true")
16206    (set_attr "mode" "<MODE>")])
16208 (define_insn "*fop_xf_4_i387"
16209   [(set (match_operand:XF 0 "register_operand" "=f,f")
16210         (match_operator:XF 3 "binary_fp_operator"
16211            [(float_extend:XF
16212               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16213             (match_operand:XF 2 "register_operand" "0,f")]))]
16214   "TARGET_80387"
16215   "* return output_387_binary_op (insn, operands);"
16216   [(set (attr "type")
16217         (cond [(match_operand:XF 3 "mult_operator" "")
16218                  (const_string "fmul")
16219                (match_operand:XF 3 "div_operator" "")
16220                  (const_string "fdiv")
16221               ]
16222               (const_string "fop")))
16223    (set_attr "mode" "<MODE>")])
16225 (define_insn "*fop_xf_5_i387"
16226   [(set (match_operand:XF 0 "register_operand" "=f,f")
16227         (match_operator:XF 3 "binary_fp_operator"
16228           [(match_operand:XF 1 "register_operand" "0,f")
16229            (float_extend:XF
16230              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16231   "TARGET_80387"
16232   "* return output_387_binary_op (insn, operands);"
16233   [(set (attr "type")
16234         (cond [(match_operand:XF 3 "mult_operator" "")
16235                  (const_string "fmul")
16236                (match_operand:XF 3 "div_operator" "")
16237                  (const_string "fdiv")
16238               ]
16239               (const_string "fop")))
16240    (set_attr "mode" "<MODE>")])
16242 (define_insn "*fop_xf_6_i387"
16243   [(set (match_operand:XF 0 "register_operand" "=f,f")
16244         (match_operator:XF 3 "binary_fp_operator"
16245           [(float_extend:XF
16246              (match_operand:MODEF 1 "register_operand" "0,f"))
16247            (float_extend:XF
16248              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16249   "TARGET_80387"
16250   "* return output_387_binary_op (insn, operands);"
16251   [(set (attr "type")
16252         (cond [(match_operand:XF 3 "mult_operator" "")
16253                  (const_string "fmul")
16254                (match_operand:XF 3 "div_operator" "")
16255                  (const_string "fdiv")
16256               ]
16257               (const_string "fop")))
16258    (set_attr "mode" "<MODE>")])
16260 (define_split
16261   [(set (match_operand 0 "register_operand" "")
16262         (match_operator 3 "binary_fp_operator"
16263            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16264             (match_operand 2 "register_operand" "")]))]
16265   "reload_completed
16266    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16267   [(const_int 0)]
16269   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16270   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16271   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16272                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16273                                           GET_MODE (operands[3]),
16274                                           operands[4],
16275                                           operands[2])));
16276   ix86_free_from_memory (GET_MODE (operands[1]));
16277   DONE;
16280 (define_split
16281   [(set (match_operand 0 "register_operand" "")
16282         (match_operator 3 "binary_fp_operator"
16283            [(match_operand 1 "register_operand" "")
16284             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16285   "reload_completed
16286    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16287   [(const_int 0)]
16289   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16290   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16291   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16292                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16293                                           GET_MODE (operands[3]),
16294                                           operands[1],
16295                                           operands[4])));
16296   ix86_free_from_memory (GET_MODE (operands[2]));
16297   DONE;
16300 ;; FPU special functions.
16302 ;; This pattern implements a no-op XFmode truncation for
16303 ;; all fancy i386 XFmode math functions.
16305 (define_insn "truncxf<mode>2_i387_noop_unspec"
16306   [(set (match_operand:MODEF 0 "register_operand" "=f")
16307         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16308         UNSPEC_TRUNC_NOOP))]
16309   "TARGET_USE_FANCY_MATH_387"
16310   "* return output_387_reg_move (insn, operands);"
16311   [(set_attr "type" "fmov")
16312    (set_attr "mode" "<MODE>")])
16314 (define_insn "sqrtxf2"
16315   [(set (match_operand:XF 0 "register_operand" "=f")
16316         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16317   "TARGET_USE_FANCY_MATH_387"
16318   "fsqrt"
16319   [(set_attr "type" "fpspc")
16320    (set_attr "mode" "XF")
16321    (set_attr "athlon_decode" "direct")
16322    (set_attr "amdfam10_decode" "direct")])
16324 (define_insn "sqrt_extend<mode>xf2_i387"
16325   [(set (match_operand:XF 0 "register_operand" "=f")
16326         (sqrt:XF
16327           (float_extend:XF
16328             (match_operand:MODEF 1 "register_operand" "0"))))]
16329   "TARGET_USE_FANCY_MATH_387"
16330   "fsqrt"
16331   [(set_attr "type" "fpspc")
16332    (set_attr "mode" "XF")
16333    (set_attr "athlon_decode" "direct")
16334    (set_attr "amdfam10_decode" "direct")])
16336 (define_insn "*rsqrtsf2_sse"
16337   [(set (match_operand:SF 0 "register_operand" "=x")
16338         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16339                    UNSPEC_RSQRT))]
16340   "TARGET_SSE_MATH"
16341   "rsqrtss\t{%1, %0|%0, %1}"
16342   [(set_attr "type" "sse")
16343    (set_attr "mode" "SF")])
16345 (define_expand "rsqrtsf2"
16346   [(set (match_operand:SF 0 "register_operand" "")
16347         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16348                    UNSPEC_RSQRT))]
16349   "TARGET_SSE_MATH"
16351   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16352   DONE;
16355 (define_insn "*sqrt<mode>2_sse"
16356   [(set (match_operand:MODEF 0 "register_operand" "=x")
16357         (sqrt:MODEF
16358           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16359   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16360   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16361   [(set_attr "type" "sse")
16362    (set_attr "mode" "<MODE>")
16363    (set_attr "athlon_decode" "*")
16364    (set_attr "amdfam10_decode" "*")])
16366 (define_expand "sqrt<mode>2"
16367   [(set (match_operand:MODEF 0 "register_operand" "")
16368         (sqrt:MODEF
16369           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16370   "TARGET_USE_FANCY_MATH_387
16371    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16373   if (<MODE>mode == SFmode
16374       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16375       && flag_finite_math_only && !flag_trapping_math
16376       && flag_unsafe_math_optimizations)
16377     {
16378       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16379       DONE;
16380     }
16382   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16383     {
16384       rtx op0 = gen_reg_rtx (XFmode);
16385       rtx op1 = force_reg (<MODE>mode, operands[1]);
16387       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16388       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16389       DONE;
16390    }
16393 (define_insn "fpremxf4_i387"
16394   [(set (match_operand:XF 0 "register_operand" "=f")
16395         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16396                     (match_operand:XF 3 "register_operand" "1")]
16397                    UNSPEC_FPREM_F))
16398    (set (match_operand:XF 1 "register_operand" "=u")
16399         (unspec:XF [(match_dup 2) (match_dup 3)]
16400                    UNSPEC_FPREM_U))
16401    (set (reg:CCFP FPSR_REG)
16402         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16403                      UNSPEC_C2_FLAG))]
16404   "TARGET_USE_FANCY_MATH_387"
16405   "fprem"
16406   [(set_attr "type" "fpspc")
16407    (set_attr "mode" "XF")])
16409 (define_expand "fmodxf3"
16410   [(use (match_operand:XF 0 "register_operand" ""))
16411    (use (match_operand:XF 1 "general_operand" ""))
16412    (use (match_operand:XF 2 "general_operand" ""))]
16413   "TARGET_USE_FANCY_MATH_387"
16415   rtx label = gen_label_rtx ();
16417   rtx op1 = gen_reg_rtx (XFmode);
16418   rtx op2 = gen_reg_rtx (XFmode);
16420   emit_move_insn (op2, operands[2]);
16421   emit_move_insn (op1, operands[1]);
16423   emit_label (label);
16424   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16425   ix86_emit_fp_unordered_jump (label);
16426   LABEL_NUSES (label) = 1;
16428   emit_move_insn (operands[0], op1);
16429   DONE;
16432 (define_expand "fmod<mode>3"
16433   [(use (match_operand:MODEF 0 "register_operand" ""))
16434    (use (match_operand:MODEF 1 "general_operand" ""))
16435    (use (match_operand:MODEF 2 "general_operand" ""))]
16436   "TARGET_USE_FANCY_MATH_387"
16438   rtx label = gen_label_rtx ();
16440   rtx op1 = gen_reg_rtx (XFmode);
16441   rtx op2 = gen_reg_rtx (XFmode);
16443   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16444   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16446   emit_label (label);
16447   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16448   ix86_emit_fp_unordered_jump (label);
16449   LABEL_NUSES (label) = 1;
16451   /* Truncate the result properly for strict SSE math.  */
16452   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16453       && !TARGET_MIX_SSE_I387)
16454     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16455   else
16456     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16458   DONE;
16461 (define_insn "fprem1xf4_i387"
16462   [(set (match_operand:XF 0 "register_operand" "=f")
16463         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16464                     (match_operand:XF 3 "register_operand" "1")]
16465                    UNSPEC_FPREM1_F))
16466    (set (match_operand:XF 1 "register_operand" "=u")
16467         (unspec:XF [(match_dup 2) (match_dup 3)]
16468                    UNSPEC_FPREM1_U))
16469    (set (reg:CCFP FPSR_REG)
16470         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16471                      UNSPEC_C2_FLAG))]
16472   "TARGET_USE_FANCY_MATH_387"
16473   "fprem1"
16474   [(set_attr "type" "fpspc")
16475    (set_attr "mode" "XF")])
16477 (define_expand "remainderxf3"
16478   [(use (match_operand:XF 0 "register_operand" ""))
16479    (use (match_operand:XF 1 "general_operand" ""))
16480    (use (match_operand:XF 2 "general_operand" ""))]
16481   "TARGET_USE_FANCY_MATH_387"
16483   rtx label = gen_label_rtx ();
16485   rtx op1 = gen_reg_rtx (XFmode);
16486   rtx op2 = gen_reg_rtx (XFmode);
16488   emit_move_insn (op2, operands[2]);
16489   emit_move_insn (op1, operands[1]);
16491   emit_label (label);
16492   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16493   ix86_emit_fp_unordered_jump (label);
16494   LABEL_NUSES (label) = 1;
16496   emit_move_insn (operands[0], op1);
16497   DONE;
16500 (define_expand "remainder<mode>3"
16501   [(use (match_operand:MODEF 0 "register_operand" ""))
16502    (use (match_operand:MODEF 1 "general_operand" ""))
16503    (use (match_operand:MODEF 2 "general_operand" ""))]
16504   "TARGET_USE_FANCY_MATH_387"
16506   rtx label = gen_label_rtx ();
16508   rtx op1 = gen_reg_rtx (XFmode);
16509   rtx op2 = gen_reg_rtx (XFmode);
16511   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16512   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16514   emit_label (label);
16516   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16517   ix86_emit_fp_unordered_jump (label);
16518   LABEL_NUSES (label) = 1;
16520   /* Truncate the result properly for strict SSE math.  */
16521   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16522       && !TARGET_MIX_SSE_I387)
16523     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16524   else
16525     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16527   DONE;
16530 (define_insn "*sinxf2_i387"
16531   [(set (match_operand:XF 0 "register_operand" "=f")
16532         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16533   "TARGET_USE_FANCY_MATH_387
16534    && flag_unsafe_math_optimizations"
16535   "fsin"
16536   [(set_attr "type" "fpspc")
16537    (set_attr "mode" "XF")])
16539 (define_insn "*sin_extend<mode>xf2_i387"
16540   [(set (match_operand:XF 0 "register_operand" "=f")
16541         (unspec:XF [(float_extend:XF
16542                       (match_operand:MODEF 1 "register_operand" "0"))]
16543                    UNSPEC_SIN))]
16544   "TARGET_USE_FANCY_MATH_387
16545    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16546        || TARGET_MIX_SSE_I387)
16547    && flag_unsafe_math_optimizations"
16548   "fsin"
16549   [(set_attr "type" "fpspc")
16550    (set_attr "mode" "XF")])
16552 (define_insn "*cosxf2_i387"
16553   [(set (match_operand:XF 0 "register_operand" "=f")
16554         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16555   "TARGET_USE_FANCY_MATH_387
16556    && flag_unsafe_math_optimizations"
16557   "fcos"
16558   [(set_attr "type" "fpspc")
16559    (set_attr "mode" "XF")])
16561 (define_insn "*cos_extend<mode>xf2_i387"
16562   [(set (match_operand:XF 0 "register_operand" "=f")
16563         (unspec:XF [(float_extend:XF
16564                       (match_operand:MODEF 1 "register_operand" "0"))]
16565                    UNSPEC_COS))]
16566   "TARGET_USE_FANCY_MATH_387
16567    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16568        || TARGET_MIX_SSE_I387)
16569    && flag_unsafe_math_optimizations"
16570   "fcos"
16571   [(set_attr "type" "fpspc")
16572    (set_attr "mode" "XF")])
16574 ;; When sincos pattern is defined, sin and cos builtin functions will be
16575 ;; expanded to sincos pattern with one of its outputs left unused.
16576 ;; CSE pass will figure out if two sincos patterns can be combined,
16577 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16578 ;; depending on the unused output.
16580 (define_insn "sincosxf3"
16581   [(set (match_operand:XF 0 "register_operand" "=f")
16582         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16583                    UNSPEC_SINCOS_COS))
16584    (set (match_operand:XF 1 "register_operand" "=u")
16585         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16586   "TARGET_USE_FANCY_MATH_387
16587    && flag_unsafe_math_optimizations"
16588   "fsincos"
16589   [(set_attr "type" "fpspc")
16590    (set_attr "mode" "XF")])
16592 (define_split
16593   [(set (match_operand:XF 0 "register_operand" "")
16594         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16595                    UNSPEC_SINCOS_COS))
16596    (set (match_operand:XF 1 "register_operand" "")
16597         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16598   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16599    && !(reload_completed || reload_in_progress)"
16600   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16601   "")
16603 (define_split
16604   [(set (match_operand:XF 0 "register_operand" "")
16605         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16606                    UNSPEC_SINCOS_COS))
16607    (set (match_operand:XF 1 "register_operand" "")
16608         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16609   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16610    && !(reload_completed || reload_in_progress)"
16611   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16612   "")
16614 (define_insn "sincos_extend<mode>xf3_i387"
16615   [(set (match_operand:XF 0 "register_operand" "=f")
16616         (unspec:XF [(float_extend:XF
16617                       (match_operand:MODEF 2 "register_operand" "0"))]
16618                    UNSPEC_SINCOS_COS))
16619    (set (match_operand:XF 1 "register_operand" "=u")
16620         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16621   "TARGET_USE_FANCY_MATH_387
16622    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16623        || TARGET_MIX_SSE_I387)
16624    && flag_unsafe_math_optimizations"
16625   "fsincos"
16626   [(set_attr "type" "fpspc")
16627    (set_attr "mode" "XF")])
16629 (define_split
16630   [(set (match_operand:XF 0 "register_operand" "")
16631         (unspec:XF [(float_extend:XF
16632                       (match_operand:MODEF 2 "register_operand" ""))]
16633                    UNSPEC_SINCOS_COS))
16634    (set (match_operand:XF 1 "register_operand" "")
16635         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16636   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16637    && !(reload_completed || reload_in_progress)"
16638   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16639   "")
16641 (define_split
16642   [(set (match_operand:XF 0 "register_operand" "")
16643         (unspec:XF [(float_extend:XF
16644                       (match_operand:MODEF 2 "register_operand" ""))]
16645                    UNSPEC_SINCOS_COS))
16646    (set (match_operand:XF 1 "register_operand" "")
16647         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16648   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16649    && !(reload_completed || reload_in_progress)"
16650   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16651   "")
16653 (define_expand "sincos<mode>3"
16654   [(use (match_operand:MODEF 0 "register_operand" ""))
16655    (use (match_operand:MODEF 1 "register_operand" ""))
16656    (use (match_operand:MODEF 2 "register_operand" ""))]
16657   "TARGET_USE_FANCY_MATH_387
16658    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16659        || TARGET_MIX_SSE_I387)
16660    && flag_unsafe_math_optimizations"
16662   rtx op0 = gen_reg_rtx (XFmode);
16663   rtx op1 = gen_reg_rtx (XFmode);
16665   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16666   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16667   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16668   DONE;
16671 (define_insn "fptanxf4_i387"
16672   [(set (match_operand:XF 0 "register_operand" "=f")
16673         (match_operand:XF 3 "const_double_operand" "F"))
16674    (set (match_operand:XF 1 "register_operand" "=u")
16675         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16676                    UNSPEC_TAN))]
16677   "TARGET_USE_FANCY_MATH_387
16678    && flag_unsafe_math_optimizations
16679    && standard_80387_constant_p (operands[3]) == 2"
16680   "fptan"
16681   [(set_attr "type" "fpspc")
16682    (set_attr "mode" "XF")])
16684 (define_insn "fptan_extend<mode>xf4_i387"
16685   [(set (match_operand:MODEF 0 "register_operand" "=f")
16686         (match_operand:MODEF 3 "const_double_operand" "F"))
16687    (set (match_operand:XF 1 "register_operand" "=u")
16688         (unspec:XF [(float_extend:XF
16689                       (match_operand:MODEF 2 "register_operand" "0"))]
16690                    UNSPEC_TAN))]
16691   "TARGET_USE_FANCY_MATH_387
16692    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16693        || TARGET_MIX_SSE_I387)
16694    && flag_unsafe_math_optimizations
16695    && standard_80387_constant_p (operands[3]) == 2"
16696   "fptan"
16697   [(set_attr "type" "fpspc")
16698    (set_attr "mode" "XF")])
16700 (define_expand "tanxf2"
16701   [(use (match_operand:XF 0 "register_operand" ""))
16702    (use (match_operand:XF 1 "register_operand" ""))]
16703   "TARGET_USE_FANCY_MATH_387
16704    && flag_unsafe_math_optimizations"
16706   rtx one = gen_reg_rtx (XFmode);
16707   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16709   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16710   DONE;
16713 (define_expand "tan<mode>2"
16714   [(use (match_operand:MODEF 0 "register_operand" ""))
16715    (use (match_operand:MODEF 1 "register_operand" ""))]
16716   "TARGET_USE_FANCY_MATH_387
16717    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16718        || TARGET_MIX_SSE_I387)
16719    && flag_unsafe_math_optimizations"
16721   rtx op0 = gen_reg_rtx (XFmode);
16723   rtx one = gen_reg_rtx (<MODE>mode);
16724   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16726   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16727                                              operands[1], op2));
16728   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16729   DONE;
16732 (define_insn "*fpatanxf3_i387"
16733   [(set (match_operand:XF 0 "register_operand" "=f")
16734         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16735                     (match_operand:XF 2 "register_operand" "u")]
16736                    UNSPEC_FPATAN))
16737    (clobber (match_scratch:XF 3 "=2"))]
16738   "TARGET_USE_FANCY_MATH_387
16739    && flag_unsafe_math_optimizations"
16740   "fpatan"
16741   [(set_attr "type" "fpspc")
16742    (set_attr "mode" "XF")])
16744 (define_insn "fpatan_extend<mode>xf3_i387"
16745   [(set (match_operand:XF 0 "register_operand" "=f")
16746         (unspec:XF [(float_extend:XF
16747                       (match_operand:MODEF 1 "register_operand" "0"))
16748                     (float_extend:XF
16749                       (match_operand:MODEF 2 "register_operand" "u"))]
16750                    UNSPEC_FPATAN))
16751    (clobber (match_scratch:XF 3 "=2"))]
16752   "TARGET_USE_FANCY_MATH_387
16753    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16754        || TARGET_MIX_SSE_I387)
16755    && flag_unsafe_math_optimizations"
16756   "fpatan"
16757   [(set_attr "type" "fpspc")
16758    (set_attr "mode" "XF")])
16760 (define_expand "atan2xf3"
16761   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16762                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16763                                (match_operand:XF 1 "register_operand" "")]
16764                               UNSPEC_FPATAN))
16765               (clobber (match_scratch:XF 3 ""))])]
16766   "TARGET_USE_FANCY_MATH_387
16767    && flag_unsafe_math_optimizations"
16768   "")
16770 (define_expand "atan2<mode>3"
16771   [(use (match_operand:MODEF 0 "register_operand" ""))
16772    (use (match_operand:MODEF 1 "register_operand" ""))
16773    (use (match_operand:MODEF 2 "register_operand" ""))]
16774   "TARGET_USE_FANCY_MATH_387
16775    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16776        || TARGET_MIX_SSE_I387)
16777    && flag_unsafe_math_optimizations"
16779   rtx op0 = gen_reg_rtx (XFmode);
16781   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16782   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16783   DONE;
16786 (define_expand "atanxf2"
16787   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16788                    (unspec:XF [(match_dup 2)
16789                                (match_operand:XF 1 "register_operand" "")]
16790                               UNSPEC_FPATAN))
16791               (clobber (match_scratch:XF 3 ""))])]
16792   "TARGET_USE_FANCY_MATH_387
16793    && flag_unsafe_math_optimizations"
16795   operands[2] = gen_reg_rtx (XFmode);
16796   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16799 (define_expand "atan<mode>2"
16800   [(use (match_operand:MODEF 0 "register_operand" ""))
16801    (use (match_operand:MODEF 1 "register_operand" ""))]
16802   "TARGET_USE_FANCY_MATH_387
16803    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16804        || TARGET_MIX_SSE_I387)
16805    && flag_unsafe_math_optimizations"
16807   rtx op0 = gen_reg_rtx (XFmode);
16809   rtx op2 = gen_reg_rtx (<MODE>mode);
16810   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16812   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16813   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16814   DONE;
16817 (define_expand "asinxf2"
16818   [(set (match_dup 2)
16819         (mult:XF (match_operand:XF 1 "register_operand" "")
16820                  (match_dup 1)))
16821    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16822    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16823    (parallel [(set (match_operand:XF 0 "register_operand" "")
16824                    (unspec:XF [(match_dup 5) (match_dup 1)]
16825                               UNSPEC_FPATAN))
16826               (clobber (match_scratch:XF 6 ""))])]
16827   "TARGET_USE_FANCY_MATH_387
16828    && flag_unsafe_math_optimizations && !optimize_size"
16830   int i;
16832   for (i = 2; i < 6; i++)
16833     operands[i] = gen_reg_rtx (XFmode);
16835   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16838 (define_expand "asin<mode>2"
16839   [(use (match_operand:MODEF 0 "register_operand" ""))
16840    (use (match_operand:MODEF 1 "general_operand" ""))]
16841  "TARGET_USE_FANCY_MATH_387
16842    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16843        || TARGET_MIX_SSE_I387)
16844    && flag_unsafe_math_optimizations && !optimize_size"
16846   rtx op0 = gen_reg_rtx (XFmode);
16847   rtx op1 = gen_reg_rtx (XFmode);
16849   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16850   emit_insn (gen_asinxf2 (op0, op1));
16851   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16852   DONE;
16855 (define_expand "acosxf2"
16856   [(set (match_dup 2)
16857         (mult:XF (match_operand:XF 1 "register_operand" "")
16858                  (match_dup 1)))
16859    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16860    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16861    (parallel [(set (match_operand:XF 0 "register_operand" "")
16862                    (unspec:XF [(match_dup 1) (match_dup 5)]
16863                               UNSPEC_FPATAN))
16864               (clobber (match_scratch:XF 6 ""))])]
16865   "TARGET_USE_FANCY_MATH_387
16866    && flag_unsafe_math_optimizations && !optimize_size"
16868   int i;
16870   for (i = 2; i < 6; i++)
16871     operands[i] = gen_reg_rtx (XFmode);
16873   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16876 (define_expand "acos<mode>2"
16877   [(use (match_operand:MODEF 0 "register_operand" ""))
16878    (use (match_operand:MODEF 1 "general_operand" ""))]
16879  "TARGET_USE_FANCY_MATH_387
16880    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16881        || TARGET_MIX_SSE_I387)
16882    && flag_unsafe_math_optimizations && !optimize_size"
16884   rtx op0 = gen_reg_rtx (XFmode);
16885   rtx op1 = gen_reg_rtx (XFmode);
16887   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16888   emit_insn (gen_acosxf2 (op0, op1));
16889   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16890   DONE;
16893 (define_insn "fyl2xxf3_i387"
16894   [(set (match_operand:XF 0 "register_operand" "=f")
16895         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16896                     (match_operand:XF 2 "register_operand" "u")]
16897                    UNSPEC_FYL2X))
16898    (clobber (match_scratch:XF 3 "=2"))]
16899   "TARGET_USE_FANCY_MATH_387
16900    && flag_unsafe_math_optimizations"
16901   "fyl2x"
16902   [(set_attr "type" "fpspc")
16903    (set_attr "mode" "XF")])
16905 (define_insn "fyl2x_extend<mode>xf3_i387"
16906   [(set (match_operand:XF 0 "register_operand" "=f")
16907         (unspec:XF [(float_extend:XF
16908                       (match_operand:MODEF 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    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16914        || TARGET_MIX_SSE_I387)
16915    && flag_unsafe_math_optimizations"
16916   "fyl2x"
16917   [(set_attr "type" "fpspc")
16918    (set_attr "mode" "XF")])
16920 (define_expand "logxf2"
16921   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16922                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16923                                (match_dup 2)] UNSPEC_FYL2X))
16924               (clobber (match_scratch:XF 3 ""))])]
16925   "TARGET_USE_FANCY_MATH_387
16926    && flag_unsafe_math_optimizations"
16928   operands[2] = gen_reg_rtx (XFmode);
16929   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16932 (define_expand "log<mode>2"
16933   [(use (match_operand:MODEF 0 "register_operand" ""))
16934    (use (match_operand:MODEF 1 "register_operand" ""))]
16935   "TARGET_USE_FANCY_MATH_387
16936    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16937        || TARGET_MIX_SSE_I387)
16938    && flag_unsafe_math_optimizations"
16940   rtx op0 = gen_reg_rtx (XFmode);
16942   rtx op2 = gen_reg_rtx (XFmode);
16943   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16945   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16946   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16947   DONE;
16950 (define_expand "log10xf2"
16951   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16952                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16953                                (match_dup 2)] UNSPEC_FYL2X))
16954               (clobber (match_scratch:XF 3 ""))])]
16955   "TARGET_USE_FANCY_MATH_387
16956    && flag_unsafe_math_optimizations"
16958   operands[2] = gen_reg_rtx (XFmode);
16959   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16962 (define_expand "log10<mode>2"
16963   [(use (match_operand:MODEF 0 "register_operand" ""))
16964    (use (match_operand:MODEF 1 "register_operand" ""))]
16965   "TARGET_USE_FANCY_MATH_387
16966    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16967        || TARGET_MIX_SSE_I387)
16968    && flag_unsafe_math_optimizations"
16970   rtx op0 = gen_reg_rtx (XFmode);
16972   rtx op2 = gen_reg_rtx (XFmode);
16973   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16975   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16976   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16977   DONE;
16980 (define_expand "log2xf2"
16981   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16982                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16983                                (match_dup 2)] UNSPEC_FYL2X))
16984               (clobber (match_scratch:XF 3 ""))])]
16985   "TARGET_USE_FANCY_MATH_387
16986    && flag_unsafe_math_optimizations"
16988   operands[2] = gen_reg_rtx (XFmode);
16989   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16992 (define_expand "log2<mode>2"
16993   [(use (match_operand:MODEF 0 "register_operand" ""))
16994    (use (match_operand:MODEF 1 "register_operand" ""))]
16995   "TARGET_USE_FANCY_MATH_387
16996    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16997        || TARGET_MIX_SSE_I387)
16998    && flag_unsafe_math_optimizations"
17000   rtx op0 = gen_reg_rtx (XFmode);
17002   rtx op2 = gen_reg_rtx (XFmode);
17003   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17005   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17006   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17007   DONE;
17010 (define_insn "fyl2xp1xf3_i387"
17011   [(set (match_operand:XF 0 "register_operand" "=f")
17012         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17013                     (match_operand:XF 2 "register_operand" "u")]
17014                    UNSPEC_FYL2XP1))
17015    (clobber (match_scratch:XF 3 "=2"))]
17016   "TARGET_USE_FANCY_MATH_387
17017    && flag_unsafe_math_optimizations"
17018   "fyl2xp1"
17019   [(set_attr "type" "fpspc")
17020    (set_attr "mode" "XF")])
17022 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17023   [(set (match_operand:XF 0 "register_operand" "=f")
17024         (unspec:XF [(float_extend:XF
17025                       (match_operand:MODEF 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    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17031        || TARGET_MIX_SSE_I387)
17032    && flag_unsafe_math_optimizations"
17033   "fyl2xp1"
17034   [(set_attr "type" "fpspc")
17035    (set_attr "mode" "XF")])
17037 (define_expand "log1pxf2"
17038   [(use (match_operand:XF 0 "register_operand" ""))
17039    (use (match_operand:XF 1 "register_operand" ""))]
17040   "TARGET_USE_FANCY_MATH_387
17041    && flag_unsafe_math_optimizations && !optimize_size"
17043   ix86_emit_i387_log1p (operands[0], operands[1]);
17044   DONE;
17047 (define_expand "log1p<mode>2"
17048   [(use (match_operand:MODEF 0 "register_operand" ""))
17049    (use (match_operand:MODEF 1 "register_operand" ""))]
17050   "TARGET_USE_FANCY_MATH_387
17051    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17052        || TARGET_MIX_SSE_I387)
17053    && flag_unsafe_math_optimizations && !optimize_size"
17055   rtx op0 = gen_reg_rtx (XFmode);
17057   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17059   ix86_emit_i387_log1p (op0, operands[1]);
17060   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17061   DONE;
17064 (define_insn "fxtractxf3_i387"
17065   [(set (match_operand:XF 0 "register_operand" "=f")
17066         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17067                    UNSPEC_XTRACT_FRACT))
17068    (set (match_operand:XF 1 "register_operand" "=u")
17069         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17070   "TARGET_USE_FANCY_MATH_387
17071    && flag_unsafe_math_optimizations"
17072   "fxtract"
17073   [(set_attr "type" "fpspc")
17074    (set_attr "mode" "XF")])
17076 (define_insn "fxtract_extend<mode>xf3_i387"
17077   [(set (match_operand:XF 0 "register_operand" "=f")
17078         (unspec:XF [(float_extend:XF
17079                       (match_operand:MODEF 2 "register_operand" "0"))]
17080                    UNSPEC_XTRACT_FRACT))
17081    (set (match_operand:XF 1 "register_operand" "=u")
17082         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17083   "TARGET_USE_FANCY_MATH_387
17084    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17085        || TARGET_MIX_SSE_I387)
17086    && flag_unsafe_math_optimizations"
17087   "fxtract"
17088   [(set_attr "type" "fpspc")
17089    (set_attr "mode" "XF")])
17091 (define_expand "logbxf2"
17092   [(parallel [(set (match_dup 2)
17093                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17094                               UNSPEC_XTRACT_FRACT))
17095               (set (match_operand:XF 0 "register_operand" "")
17096                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17097   "TARGET_USE_FANCY_MATH_387
17098    && flag_unsafe_math_optimizations"
17100   operands[2] = gen_reg_rtx (XFmode);
17103 (define_expand "logb<mode>2"
17104   [(use (match_operand:MODEF 0 "register_operand" ""))
17105    (use (match_operand:MODEF 1 "register_operand" ""))]
17106   "TARGET_USE_FANCY_MATH_387
17107    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17108        || TARGET_MIX_SSE_I387)
17109    && flag_unsafe_math_optimizations"
17111   rtx op0 = gen_reg_rtx (XFmode);
17112   rtx op1 = gen_reg_rtx (XFmode);
17114   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17115   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17116   DONE;
17119 (define_expand "ilogbxf2"
17120   [(use (match_operand:SI 0 "register_operand" ""))
17121    (use (match_operand:XF 1 "register_operand" ""))]
17122   "TARGET_USE_FANCY_MATH_387
17123    && flag_unsafe_math_optimizations && !optimize_size"
17125   rtx op0 = gen_reg_rtx (XFmode);
17126   rtx op1 = gen_reg_rtx (XFmode);
17128   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17129   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17130   DONE;
17133 (define_expand "ilogb<mode>2"
17134   [(use (match_operand:SI 0 "register_operand" ""))
17135    (use (match_operand:MODEF 1 "register_operand" ""))]
17136   "TARGET_USE_FANCY_MATH_387
17137    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17138        || TARGET_MIX_SSE_I387)
17139    && flag_unsafe_math_optimizations && !optimize_size"
17141   rtx op0 = gen_reg_rtx (XFmode);
17142   rtx op1 = gen_reg_rtx (XFmode);
17144   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17145   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17146   DONE;
17149 (define_insn "*f2xm1xf2_i387"
17150   [(set (match_operand:XF 0 "register_operand" "=f")
17151         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17152                    UNSPEC_F2XM1))]
17153   "TARGET_USE_FANCY_MATH_387
17154    && flag_unsafe_math_optimizations"
17155   "f2xm1"
17156   [(set_attr "type" "fpspc")
17157    (set_attr "mode" "XF")])
17159 (define_insn "*fscalexf4_i387"
17160   [(set (match_operand:XF 0 "register_operand" "=f")
17161         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17162                     (match_operand:XF 3 "register_operand" "1")]
17163                    UNSPEC_FSCALE_FRACT))
17164    (set (match_operand:XF 1 "register_operand" "=u")
17165         (unspec:XF [(match_dup 2) (match_dup 3)]
17166                    UNSPEC_FSCALE_EXP))]
17167   "TARGET_USE_FANCY_MATH_387
17168    && flag_unsafe_math_optimizations"
17169   "fscale"
17170   [(set_attr "type" "fpspc")
17171    (set_attr "mode" "XF")])
17173 (define_expand "expNcorexf3"
17174   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17175                                (match_operand:XF 2 "register_operand" "")))
17176    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17177    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17178    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17179    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17180    (parallel [(set (match_operand:XF 0 "register_operand" "")
17181                    (unspec:XF [(match_dup 8) (match_dup 4)]
17182                               UNSPEC_FSCALE_FRACT))
17183               (set (match_dup 9)
17184                    (unspec:XF [(match_dup 8) (match_dup 4)]
17185                               UNSPEC_FSCALE_EXP))])]
17186   "TARGET_USE_FANCY_MATH_387
17187    && flag_unsafe_math_optimizations && !optimize_size"
17189   int i;
17191   for (i = 3; i < 10; i++)
17192     operands[i] = gen_reg_rtx (XFmode);
17194   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17197 (define_expand "expxf2"
17198   [(use (match_operand:XF 0 "register_operand" ""))
17199    (use (match_operand:XF 1 "register_operand" ""))]
17200   "TARGET_USE_FANCY_MATH_387
17201    && flag_unsafe_math_optimizations && !optimize_size"
17203   rtx op2 = gen_reg_rtx (XFmode);
17204   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17206   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17207   DONE;
17210 (define_expand "exp<mode>2"
17211   [(use (match_operand:MODEF 0 "register_operand" ""))
17212    (use (match_operand:MODEF 1 "general_operand" ""))]
17213  "TARGET_USE_FANCY_MATH_387
17214    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17215        || TARGET_MIX_SSE_I387)
17216    && flag_unsafe_math_optimizations && !optimize_size"
17218   rtx op0 = gen_reg_rtx (XFmode);
17219   rtx op1 = gen_reg_rtx (XFmode);
17221   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17222   emit_insn (gen_expxf2 (op0, op1));
17223   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17224   DONE;
17227 (define_expand "exp10xf2"
17228   [(use (match_operand:XF 0 "register_operand" ""))
17229    (use (match_operand:XF 1 "register_operand" ""))]
17230   "TARGET_USE_FANCY_MATH_387
17231    && flag_unsafe_math_optimizations && !optimize_size"
17233   rtx op2 = gen_reg_rtx (XFmode);
17234   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17236   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17237   DONE;
17240 (define_expand "exp10<mode>2"
17241   [(use (match_operand:MODEF 0 "register_operand" ""))
17242    (use (match_operand:MODEF 1 "general_operand" ""))]
17243  "TARGET_USE_FANCY_MATH_387
17244    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17245        || TARGET_MIX_SSE_I387)
17246    && flag_unsafe_math_optimizations && !optimize_size"
17248   rtx op0 = gen_reg_rtx (XFmode);
17249   rtx op1 = gen_reg_rtx (XFmode);
17251   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17252   emit_insn (gen_exp10xf2 (op0, op1));
17253   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17254   DONE;
17257 (define_expand "exp2xf2"
17258   [(use (match_operand:XF 0 "register_operand" ""))
17259    (use (match_operand:XF 1 "register_operand" ""))]
17260   "TARGET_USE_FANCY_MATH_387
17261    && flag_unsafe_math_optimizations && !optimize_size"
17263   rtx op2 = gen_reg_rtx (XFmode);
17264   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17266   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17267   DONE;
17270 (define_expand "exp2<mode>2"
17271   [(use (match_operand:MODEF 0 "register_operand" ""))
17272    (use (match_operand:MODEF 1 "general_operand" ""))]
17273  "TARGET_USE_FANCY_MATH_387
17274    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17275        || TARGET_MIX_SSE_I387)
17276    && flag_unsafe_math_optimizations && !optimize_size"
17278   rtx op0 = gen_reg_rtx (XFmode);
17279   rtx op1 = gen_reg_rtx (XFmode);
17281   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17282   emit_insn (gen_exp2xf2 (op0, op1));
17283   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17284   DONE;
17287 (define_expand "expm1xf2"
17288   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17289                                (match_dup 2)))
17290    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17291    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17292    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17293    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17294    (parallel [(set (match_dup 7)
17295                    (unspec:XF [(match_dup 6) (match_dup 4)]
17296                               UNSPEC_FSCALE_FRACT))
17297               (set (match_dup 8)
17298                    (unspec:XF [(match_dup 6) (match_dup 4)]
17299                               UNSPEC_FSCALE_EXP))])
17300    (parallel [(set (match_dup 10)
17301                    (unspec:XF [(match_dup 9) (match_dup 8)]
17302                               UNSPEC_FSCALE_FRACT))
17303               (set (match_dup 11)
17304                    (unspec:XF [(match_dup 9) (match_dup 8)]
17305                               UNSPEC_FSCALE_EXP))])
17306    (set (match_dup 12) (minus:XF (match_dup 10)
17307                                  (float_extend:XF (match_dup 13))))
17308    (set (match_operand:XF 0 "register_operand" "")
17309         (plus:XF (match_dup 12) (match_dup 7)))]
17310   "TARGET_USE_FANCY_MATH_387
17311    && flag_unsafe_math_optimizations && !optimize_size"
17313   int i;
17315   for (i = 2; i < 13; i++)
17316     operands[i] = gen_reg_rtx (XFmode);
17318   operands[13]
17319     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17321   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17324 (define_expand "expm1<mode>2"
17325   [(use (match_operand:MODEF 0 "register_operand" ""))
17326    (use (match_operand:MODEF 1 "general_operand" ""))]
17327  "TARGET_USE_FANCY_MATH_387
17328    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17329        || TARGET_MIX_SSE_I387)
17330    && flag_unsafe_math_optimizations && !optimize_size"
17332   rtx op0 = gen_reg_rtx (XFmode);
17333   rtx op1 = gen_reg_rtx (XFmode);
17335   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17336   emit_insn (gen_expm1xf2 (op0, op1));
17337   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17338   DONE;
17341 (define_expand "ldexpxf3"
17342   [(set (match_dup 3)
17343         (float:XF (match_operand:SI 2 "register_operand" "")))
17344    (parallel [(set (match_operand:XF 0 " register_operand" "")
17345                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17346                                (match_dup 3)]
17347                               UNSPEC_FSCALE_FRACT))
17348               (set (match_dup 4)
17349                    (unspec:XF [(match_dup 1) (match_dup 3)]
17350                               UNSPEC_FSCALE_EXP))])]
17351   "TARGET_USE_FANCY_MATH_387
17352    && flag_unsafe_math_optimizations && !optimize_size"
17354   operands[3] = gen_reg_rtx (XFmode);
17355   operands[4] = gen_reg_rtx (XFmode);
17358 (define_expand "ldexp<mode>3"
17359   [(use (match_operand:MODEF 0 "register_operand" ""))
17360    (use (match_operand:MODEF 1 "general_operand" ""))
17361    (use (match_operand:SI 2 "register_operand" ""))]
17362  "TARGET_USE_FANCY_MATH_387
17363    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17364        || TARGET_MIX_SSE_I387)
17365    && flag_unsafe_math_optimizations && !optimize_size"
17367   rtx op0 = gen_reg_rtx (XFmode);
17368   rtx op1 = gen_reg_rtx (XFmode);
17370   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17371   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17372   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17373   DONE;
17376 (define_expand "scalbxf3"
17377   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17378                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17379                                (match_operand:XF 2 "register_operand" "")]
17380                               UNSPEC_FSCALE_FRACT))
17381               (set (match_dup 3)
17382                    (unspec:XF [(match_dup 1) (match_dup 2)]
17383                               UNSPEC_FSCALE_EXP))])]
17384   "TARGET_USE_FANCY_MATH_387
17385    && flag_unsafe_math_optimizations && !optimize_size"
17387   operands[3] = gen_reg_rtx (XFmode);
17390 (define_expand "scalb<mode>3"
17391   [(use (match_operand:MODEF 0 "register_operand" ""))
17392    (use (match_operand:MODEF 1 "general_operand" ""))
17393    (use (match_operand:MODEF 2 "register_operand" ""))]
17394  "TARGET_USE_FANCY_MATH_387
17395    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17396        || TARGET_MIX_SSE_I387)
17397    && flag_unsafe_math_optimizations && !optimize_size"
17399   rtx op0 = gen_reg_rtx (XFmode);
17400   rtx op1 = gen_reg_rtx (XFmode);
17401   rtx op2 = gen_reg_rtx (XFmode);
17403   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17404   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17405   emit_insn (gen_scalbxf3 (op0, op1, op2));
17406   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17407   DONE;
17411 (define_insn "sse4_1_round<mode>2"
17412   [(set (match_operand:MODEF 0 "register_operand" "=x")
17413         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17414                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17415                       UNSPEC_ROUND))]
17416   "TARGET_ROUND"
17417   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17418   [(set_attr "type" "ssecvt")
17419    (set_attr "prefix_extra" "1")
17420    (set_attr "mode" "<MODE>")])
17422 (define_insn "rintxf2"
17423   [(set (match_operand:XF 0 "register_operand" "=f")
17424         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17425                    UNSPEC_FRNDINT))]
17426   "TARGET_USE_FANCY_MATH_387
17427    && flag_unsafe_math_optimizations"
17428   "frndint"
17429   [(set_attr "type" "fpspc")
17430    (set_attr "mode" "XF")])
17432 (define_expand "rint<mode>2"
17433   [(use (match_operand:MODEF 0 "register_operand" ""))
17434    (use (match_operand:MODEF 1 "register_operand" ""))]
17435   "(TARGET_USE_FANCY_MATH_387
17436     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17437         || TARGET_MIX_SSE_I387)
17438     && flag_unsafe_math_optimizations)
17439    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17440        && !flag_trapping_math
17441        && (TARGET_ROUND || !optimize_size))"
17443   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17444       && !flag_trapping_math
17445       && (TARGET_ROUND || !optimize_size))
17446     {
17447       if (TARGET_ROUND)
17448         emit_insn (gen_sse4_1_round<mode>2
17449                    (operands[0], operands[1], GEN_INT (0x04)));
17450       else
17451         ix86_expand_rint (operand0, operand1);
17452     }
17453   else
17454     {
17455       rtx op0 = gen_reg_rtx (XFmode);
17456       rtx op1 = gen_reg_rtx (XFmode);
17458       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17459       emit_insn (gen_rintxf2 (op0, op1));
17461       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17462     }
17463   DONE;
17466 (define_expand "round<mode>2"
17467   [(match_operand:MODEF 0 "register_operand" "")
17468    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17469   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17470    && !flag_trapping_math && !flag_rounding_math
17471    && !optimize_size"
17473   if (TARGET_64BIT || (<MODE>mode != DFmode))
17474     ix86_expand_round (operand0, operand1);
17475   else
17476     ix86_expand_rounddf_32 (operand0, operand1);
17477   DONE;
17480 (define_insn_and_split "*fistdi2_1"
17481   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17482         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17483                    UNSPEC_FIST))]
17484   "TARGET_USE_FANCY_MATH_387
17485    && !(reload_completed || reload_in_progress)"
17486   "#"
17487   "&& 1"
17488   [(const_int 0)]
17490   if (memory_operand (operands[0], VOIDmode))
17491     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17492   else
17493     {
17494       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17495       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17496                                          operands[2]));
17497     }
17498   DONE;
17500   [(set_attr "type" "fpspc")
17501    (set_attr "mode" "DI")])
17503 (define_insn "fistdi2"
17504   [(set (match_operand:DI 0 "memory_operand" "=m")
17505         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17506                    UNSPEC_FIST))
17507    (clobber (match_scratch:XF 2 "=&1f"))]
17508   "TARGET_USE_FANCY_MATH_387"
17509   "* return output_fix_trunc (insn, operands, 0);"
17510   [(set_attr "type" "fpspc")
17511    (set_attr "mode" "DI")])
17513 (define_insn "fistdi2_with_temp"
17514   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17515         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17516                    UNSPEC_FIST))
17517    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17518    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17519   "TARGET_USE_FANCY_MATH_387"
17520   "#"
17521   [(set_attr "type" "fpspc")
17522    (set_attr "mode" "DI")])
17524 (define_split
17525   [(set (match_operand:DI 0 "register_operand" "")
17526         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17527                    UNSPEC_FIST))
17528    (clobber (match_operand:DI 2 "memory_operand" ""))
17529    (clobber (match_scratch 3 ""))]
17530   "reload_completed"
17531   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17532               (clobber (match_dup 3))])
17533    (set (match_dup 0) (match_dup 2))]
17534   "")
17536 (define_split
17537   [(set (match_operand:DI 0 "memory_operand" "")
17538         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17539                    UNSPEC_FIST))
17540    (clobber (match_operand:DI 2 "memory_operand" ""))
17541    (clobber (match_scratch 3 ""))]
17542   "reload_completed"
17543   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17544               (clobber (match_dup 3))])]
17545   "")
17547 (define_insn_and_split "*fist<mode>2_1"
17548   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17549         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17550                            UNSPEC_FIST))]
17551   "TARGET_USE_FANCY_MATH_387
17552    && !(reload_completed || reload_in_progress)"
17553   "#"
17554   "&& 1"
17555   [(const_int 0)]
17557   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17558   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17559                                         operands[2]));
17560   DONE;
17562   [(set_attr "type" "fpspc")
17563    (set_attr "mode" "<MODE>")])
17565 (define_insn "fist<mode>2"
17566   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17567         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17568                            UNSPEC_FIST))]
17569   "TARGET_USE_FANCY_MATH_387"
17570   "* return output_fix_trunc (insn, operands, 0);"
17571   [(set_attr "type" "fpspc")
17572    (set_attr "mode" "<MODE>")])
17574 (define_insn "fist<mode>2_with_temp"
17575   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17576         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17577                            UNSPEC_FIST))
17578    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17579   "TARGET_USE_FANCY_MATH_387"
17580   "#"
17581   [(set_attr "type" "fpspc")
17582    (set_attr "mode" "<MODE>")])
17584 (define_split
17585   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17586         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17587                            UNSPEC_FIST))
17588    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17589   "reload_completed"
17590   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17591    (set (match_dup 0) (match_dup 2))]
17592   "")
17594 (define_split
17595   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17596         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17597                            UNSPEC_FIST))
17598    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17599   "reload_completed"
17600   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17601   "")
17603 (define_expand "lrintxf<mode>2"
17604   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17605      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17606                       UNSPEC_FIST))]
17607   "TARGET_USE_FANCY_MATH_387"
17608   "")
17610 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17611   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17612      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17613                         UNSPEC_FIX_NOTRUNC))]
17614   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17615    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17616   "")
17618 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17619   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17620    (match_operand:MODEF 1 "register_operand" "")]
17621   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17622    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17623    && !flag_trapping_math && !flag_rounding_math
17624    && !optimize_size"
17626   ix86_expand_lround (operand0, operand1);
17627   DONE;
17630 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17631 (define_insn_and_split "frndintxf2_floor"
17632   [(set (match_operand:XF 0 "register_operand" "")
17633         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17634          UNSPEC_FRNDINT_FLOOR))
17635    (clobber (reg:CC FLAGS_REG))]
17636   "TARGET_USE_FANCY_MATH_387
17637    && flag_unsafe_math_optimizations
17638    && !(reload_completed || reload_in_progress)"
17639   "#"
17640   "&& 1"
17641   [(const_int 0)]
17643   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17645   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17646   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17648   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17649                                         operands[2], operands[3]));
17650   DONE;
17652   [(set_attr "type" "frndint")
17653    (set_attr "i387_cw" "floor")
17654    (set_attr "mode" "XF")])
17656 (define_insn "frndintxf2_floor_i387"
17657   [(set (match_operand:XF 0 "register_operand" "=f")
17658         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17659          UNSPEC_FRNDINT_FLOOR))
17660    (use (match_operand:HI 2 "memory_operand" "m"))
17661    (use (match_operand:HI 3 "memory_operand" "m"))]
17662   "TARGET_USE_FANCY_MATH_387
17663    && flag_unsafe_math_optimizations"
17664   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17665   [(set_attr "type" "frndint")
17666    (set_attr "i387_cw" "floor")
17667    (set_attr "mode" "XF")])
17669 (define_expand "floorxf2"
17670   [(use (match_operand:XF 0 "register_operand" ""))
17671    (use (match_operand:XF 1 "register_operand" ""))]
17672   "TARGET_USE_FANCY_MATH_387
17673    && flag_unsafe_math_optimizations && !optimize_size"
17675   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17676   DONE;
17679 (define_expand "floor<mode>2"
17680   [(use (match_operand:MODEF 0 "register_operand" ""))
17681    (use (match_operand:MODEF 1 "register_operand" ""))]
17682   "(TARGET_USE_FANCY_MATH_387
17683     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17684         || TARGET_MIX_SSE_I387)
17685     && flag_unsafe_math_optimizations && !optimize_size)
17686    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17687        && !flag_trapping_math
17688        && (TARGET_ROUND || !optimize_size))"
17690   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17691       && !flag_trapping_math
17692       && (TARGET_ROUND || !optimize_size))
17693     {
17694       if (TARGET_ROUND)
17695         emit_insn (gen_sse4_1_round<mode>2
17696                    (operands[0], operands[1], GEN_INT (0x01)));
17697       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17698         ix86_expand_floorceil (operand0, operand1, true);
17699       else
17700         ix86_expand_floorceildf_32 (operand0, operand1, true);
17701     }
17702   else
17703     {
17704       rtx op0 = gen_reg_rtx (XFmode);
17705       rtx op1 = gen_reg_rtx (XFmode);
17707       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17708       emit_insn (gen_frndintxf2_floor (op0, op1));
17710       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17711     }
17712   DONE;
17715 (define_insn_and_split "*fist<mode>2_floor_1"
17716   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17717         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17718          UNSPEC_FIST_FLOOR))
17719    (clobber (reg:CC FLAGS_REG))]
17720   "TARGET_USE_FANCY_MATH_387
17721    && flag_unsafe_math_optimizations
17722    && !(reload_completed || reload_in_progress)"
17723   "#"
17724   "&& 1"
17725   [(const_int 0)]
17727   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17729   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17730   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17731   if (memory_operand (operands[0], VOIDmode))
17732     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17733                                       operands[2], operands[3]));
17734   else
17735     {
17736       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17737       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17738                                                   operands[2], operands[3],
17739                                                   operands[4]));
17740     }
17741   DONE;
17743   [(set_attr "type" "fistp")
17744    (set_attr "i387_cw" "floor")
17745    (set_attr "mode" "<MODE>")])
17747 (define_insn "fistdi2_floor"
17748   [(set (match_operand:DI 0 "memory_operand" "=m")
17749         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17750          UNSPEC_FIST_FLOOR))
17751    (use (match_operand:HI 2 "memory_operand" "m"))
17752    (use (match_operand:HI 3 "memory_operand" "m"))
17753    (clobber (match_scratch:XF 4 "=&1f"))]
17754   "TARGET_USE_FANCY_MATH_387
17755    && flag_unsafe_math_optimizations"
17756   "* return output_fix_trunc (insn, operands, 0);"
17757   [(set_attr "type" "fistp")
17758    (set_attr "i387_cw" "floor")
17759    (set_attr "mode" "DI")])
17761 (define_insn "fistdi2_floor_with_temp"
17762   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17763         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17764          UNSPEC_FIST_FLOOR))
17765    (use (match_operand:HI 2 "memory_operand" "m,m"))
17766    (use (match_operand:HI 3 "memory_operand" "m,m"))
17767    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17768    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17769   "TARGET_USE_FANCY_MATH_387
17770    && flag_unsafe_math_optimizations"
17771   "#"
17772   [(set_attr "type" "fistp")
17773    (set_attr "i387_cw" "floor")
17774    (set_attr "mode" "DI")])
17776 (define_split
17777   [(set (match_operand:DI 0 "register_operand" "")
17778         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17779          UNSPEC_FIST_FLOOR))
17780    (use (match_operand:HI 2 "memory_operand" ""))
17781    (use (match_operand:HI 3 "memory_operand" ""))
17782    (clobber (match_operand:DI 4 "memory_operand" ""))
17783    (clobber (match_scratch 5 ""))]
17784   "reload_completed"
17785   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17786               (use (match_dup 2))
17787               (use (match_dup 3))
17788               (clobber (match_dup 5))])
17789    (set (match_dup 0) (match_dup 4))]
17790   "")
17792 (define_split
17793   [(set (match_operand:DI 0 "memory_operand" "")
17794         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17795          UNSPEC_FIST_FLOOR))
17796    (use (match_operand:HI 2 "memory_operand" ""))
17797    (use (match_operand:HI 3 "memory_operand" ""))
17798    (clobber (match_operand:DI 4 "memory_operand" ""))
17799    (clobber (match_scratch 5 ""))]
17800   "reload_completed"
17801   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17802               (use (match_dup 2))
17803               (use (match_dup 3))
17804               (clobber (match_dup 5))])]
17805   "")
17807 (define_insn "fist<mode>2_floor"
17808   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17809         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17810          UNSPEC_FIST_FLOOR))
17811    (use (match_operand:HI 2 "memory_operand" "m"))
17812    (use (match_operand:HI 3 "memory_operand" "m"))]
17813   "TARGET_USE_FANCY_MATH_387
17814    && flag_unsafe_math_optimizations"
17815   "* return output_fix_trunc (insn, operands, 0);"
17816   [(set_attr "type" "fistp")
17817    (set_attr "i387_cw" "floor")
17818    (set_attr "mode" "<MODE>")])
17820 (define_insn "fist<mode>2_floor_with_temp"
17821   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17822         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17823          UNSPEC_FIST_FLOOR))
17824    (use (match_operand:HI 2 "memory_operand" "m,m"))
17825    (use (match_operand:HI 3 "memory_operand" "m,m"))
17826    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17827   "TARGET_USE_FANCY_MATH_387
17828    && flag_unsafe_math_optimizations"
17829   "#"
17830   [(set_attr "type" "fistp")
17831    (set_attr "i387_cw" "floor")
17832    (set_attr "mode" "<MODE>")])
17834 (define_split
17835   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17836         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17837          UNSPEC_FIST_FLOOR))
17838    (use (match_operand:HI 2 "memory_operand" ""))
17839    (use (match_operand:HI 3 "memory_operand" ""))
17840    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17841   "reload_completed"
17842   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17843                                   UNSPEC_FIST_FLOOR))
17844               (use (match_dup 2))
17845               (use (match_dup 3))])
17846    (set (match_dup 0) (match_dup 4))]
17847   "")
17849 (define_split
17850   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17851         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17852          UNSPEC_FIST_FLOOR))
17853    (use (match_operand:HI 2 "memory_operand" ""))
17854    (use (match_operand:HI 3 "memory_operand" ""))
17855    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17856   "reload_completed"
17857   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17858                                   UNSPEC_FIST_FLOOR))
17859               (use (match_dup 2))
17860               (use (match_dup 3))])]
17861   "")
17863 (define_expand "lfloorxf<mode>2"
17864   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17865                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17866                     UNSPEC_FIST_FLOOR))
17867               (clobber (reg:CC FLAGS_REG))])]
17868   "TARGET_USE_FANCY_MATH_387
17869    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17870    && flag_unsafe_math_optimizations"
17871   "")
17873 (define_expand "lfloor<mode>di2"
17874   [(match_operand:DI 0 "nonimmediate_operand" "")
17875    (match_operand:MODEF 1 "register_operand" "")]
17876   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17877    && !flag_trapping_math
17878    && !optimize_size"
17880   ix86_expand_lfloorceil (operand0, operand1, true);
17881   DONE;
17884 (define_expand "lfloor<mode>si2"
17885   [(match_operand:SI 0 "nonimmediate_operand" "")
17886    (match_operand:MODEF 1 "register_operand" "")]
17887   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17888    && !flag_trapping_math
17889    && (!optimize_size || !TARGET_64BIT)"
17891   ix86_expand_lfloorceil (operand0, operand1, true);
17892   DONE;
17895 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17896 (define_insn_and_split "frndintxf2_ceil"
17897   [(set (match_operand:XF 0 "register_operand" "")
17898         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17899          UNSPEC_FRNDINT_CEIL))
17900    (clobber (reg:CC FLAGS_REG))]
17901   "TARGET_USE_FANCY_MATH_387
17902    && flag_unsafe_math_optimizations
17903    && !(reload_completed || reload_in_progress)"
17904   "#"
17905   "&& 1"
17906   [(const_int 0)]
17908   ix86_optimize_mode_switching[I387_CEIL] = 1;
17910   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17911   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17913   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17914                                        operands[2], operands[3]));
17915   DONE;
17917   [(set_attr "type" "frndint")
17918    (set_attr "i387_cw" "ceil")
17919    (set_attr "mode" "XF")])
17921 (define_insn "frndintxf2_ceil_i387"
17922   [(set (match_operand:XF 0 "register_operand" "=f")
17923         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17924          UNSPEC_FRNDINT_CEIL))
17925    (use (match_operand:HI 2 "memory_operand" "m"))
17926    (use (match_operand:HI 3 "memory_operand" "m"))]
17927   "TARGET_USE_FANCY_MATH_387
17928    && flag_unsafe_math_optimizations"
17929   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17930   [(set_attr "type" "frndint")
17931    (set_attr "i387_cw" "ceil")
17932    (set_attr "mode" "XF")])
17934 (define_expand "ceilxf2"
17935   [(use (match_operand:XF 0 "register_operand" ""))
17936    (use (match_operand:XF 1 "register_operand" ""))]
17937   "TARGET_USE_FANCY_MATH_387
17938    && flag_unsafe_math_optimizations && !optimize_size"
17940   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17941   DONE;
17944 (define_expand "ceil<mode>2"
17945   [(use (match_operand:MODEF 0 "register_operand" ""))
17946    (use (match_operand:MODEF 1 "register_operand" ""))]
17947   "(TARGET_USE_FANCY_MATH_387
17948     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17949         || TARGET_MIX_SSE_I387)
17950     && flag_unsafe_math_optimizations && !optimize_size)
17951    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17952        && !flag_trapping_math
17953        && (TARGET_ROUND || !optimize_size))"
17955   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17956       && !flag_trapping_math
17957       && (TARGET_ROUND || !optimize_size))
17958     {
17959       if (TARGET_ROUND)
17960         emit_insn (gen_sse4_1_round<mode>2
17961                    (operands[0], operands[1], GEN_INT (0x02)));
17962       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17963         ix86_expand_floorceil (operand0, operand1, false);
17964       else
17965         ix86_expand_floorceildf_32 (operand0, operand1, false);
17966     }
17967   else
17968     {
17969       rtx op0 = gen_reg_rtx (XFmode);
17970       rtx op1 = gen_reg_rtx (XFmode);
17972       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17973       emit_insn (gen_frndintxf2_ceil (op0, op1));
17975       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17976     }
17977   DONE;
17980 (define_insn_and_split "*fist<mode>2_ceil_1"
17981   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17982         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17983          UNSPEC_FIST_CEIL))
17984    (clobber (reg:CC FLAGS_REG))]
17985   "TARGET_USE_FANCY_MATH_387
17986    && flag_unsafe_math_optimizations
17987    && !(reload_completed || reload_in_progress)"
17988   "#"
17989   "&& 1"
17990   [(const_int 0)]
17992   ix86_optimize_mode_switching[I387_CEIL] = 1;
17994   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17995   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17996   if (memory_operand (operands[0], VOIDmode))
17997     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17998                                      operands[2], operands[3]));
17999   else
18000     {
18001       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18002       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18003                                                  operands[2], operands[3],
18004                                                  operands[4]));
18005     }
18006   DONE;
18008   [(set_attr "type" "fistp")
18009    (set_attr "i387_cw" "ceil")
18010    (set_attr "mode" "<MODE>")])
18012 (define_insn "fistdi2_ceil"
18013   [(set (match_operand:DI 0 "memory_operand" "=m")
18014         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18015          UNSPEC_FIST_CEIL))
18016    (use (match_operand:HI 2 "memory_operand" "m"))
18017    (use (match_operand:HI 3 "memory_operand" "m"))
18018    (clobber (match_scratch:XF 4 "=&1f"))]
18019   "TARGET_USE_FANCY_MATH_387
18020    && flag_unsafe_math_optimizations"
18021   "* return output_fix_trunc (insn, operands, 0);"
18022   [(set_attr "type" "fistp")
18023    (set_attr "i387_cw" "ceil")
18024    (set_attr "mode" "DI")])
18026 (define_insn "fistdi2_ceil_with_temp"
18027   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18028         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18029          UNSPEC_FIST_CEIL))
18030    (use (match_operand:HI 2 "memory_operand" "m,m"))
18031    (use (match_operand:HI 3 "memory_operand" "m,m"))
18032    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18033    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18034   "TARGET_USE_FANCY_MATH_387
18035    && flag_unsafe_math_optimizations"
18036   "#"
18037   [(set_attr "type" "fistp")
18038    (set_attr "i387_cw" "ceil")
18039    (set_attr "mode" "DI")])
18041 (define_split
18042   [(set (match_operand:DI 0 "register_operand" "")
18043         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18044          UNSPEC_FIST_CEIL))
18045    (use (match_operand:HI 2 "memory_operand" ""))
18046    (use (match_operand:HI 3 "memory_operand" ""))
18047    (clobber (match_operand:DI 4 "memory_operand" ""))
18048    (clobber (match_scratch 5 ""))]
18049   "reload_completed"
18050   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18051               (use (match_dup 2))
18052               (use (match_dup 3))
18053               (clobber (match_dup 5))])
18054    (set (match_dup 0) (match_dup 4))]
18055   "")
18057 (define_split
18058   [(set (match_operand:DI 0 "memory_operand" "")
18059         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18060          UNSPEC_FIST_CEIL))
18061    (use (match_operand:HI 2 "memory_operand" ""))
18062    (use (match_operand:HI 3 "memory_operand" ""))
18063    (clobber (match_operand:DI 4 "memory_operand" ""))
18064    (clobber (match_scratch 5 ""))]
18065   "reload_completed"
18066   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18067               (use (match_dup 2))
18068               (use (match_dup 3))
18069               (clobber (match_dup 5))])]
18070   "")
18072 (define_insn "fist<mode>2_ceil"
18073   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18074         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18075          UNSPEC_FIST_CEIL))
18076    (use (match_operand:HI 2 "memory_operand" "m"))
18077    (use (match_operand:HI 3 "memory_operand" "m"))]
18078   "TARGET_USE_FANCY_MATH_387
18079    && flag_unsafe_math_optimizations"
18080   "* return output_fix_trunc (insn, operands, 0);"
18081   [(set_attr "type" "fistp")
18082    (set_attr "i387_cw" "ceil")
18083    (set_attr "mode" "<MODE>")])
18085 (define_insn "fist<mode>2_ceil_with_temp"
18086   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18087         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18088          UNSPEC_FIST_CEIL))
18089    (use (match_operand:HI 2 "memory_operand" "m,m"))
18090    (use (match_operand:HI 3 "memory_operand" "m,m"))
18091    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18092   "TARGET_USE_FANCY_MATH_387
18093    && flag_unsafe_math_optimizations"
18094   "#"
18095   [(set_attr "type" "fistp")
18096    (set_attr "i387_cw" "ceil")
18097    (set_attr "mode" "<MODE>")])
18099 (define_split
18100   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18101         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18102          UNSPEC_FIST_CEIL))
18103    (use (match_operand:HI 2 "memory_operand" ""))
18104    (use (match_operand:HI 3 "memory_operand" ""))
18105    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18106   "reload_completed"
18107   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18108                                   UNSPEC_FIST_CEIL))
18109               (use (match_dup 2))
18110               (use (match_dup 3))])
18111    (set (match_dup 0) (match_dup 4))]
18112   "")
18114 (define_split
18115   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18116         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18117          UNSPEC_FIST_CEIL))
18118    (use (match_operand:HI 2 "memory_operand" ""))
18119    (use (match_operand:HI 3 "memory_operand" ""))
18120    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18121   "reload_completed"
18122   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18123                                   UNSPEC_FIST_CEIL))
18124               (use (match_dup 2))
18125               (use (match_dup 3))])]
18126   "")
18128 (define_expand "lceilxf<mode>2"
18129   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18130                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18131                     UNSPEC_FIST_CEIL))
18132               (clobber (reg:CC FLAGS_REG))])]
18133   "TARGET_USE_FANCY_MATH_387
18134    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18135    && flag_unsafe_math_optimizations"
18136   "")
18138 (define_expand "lceil<mode>di2"
18139   [(match_operand:DI 0 "nonimmediate_operand" "")
18140    (match_operand:MODEF 1 "register_operand" "")]
18141   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18142    && !flag_trapping_math"
18144   ix86_expand_lfloorceil (operand0, operand1, false);
18145   DONE;
18148 (define_expand "lceil<mode>si2"
18149   [(match_operand:SI 0 "nonimmediate_operand" "")
18150    (match_operand:MODEF 1 "register_operand" "")]
18151   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18152    && !flag_trapping_math"
18154   ix86_expand_lfloorceil (operand0, operand1, false);
18155   DONE;
18158 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18159 (define_insn_and_split "frndintxf2_trunc"
18160   [(set (match_operand:XF 0 "register_operand" "")
18161         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18162          UNSPEC_FRNDINT_TRUNC))
18163    (clobber (reg:CC FLAGS_REG))]
18164   "TARGET_USE_FANCY_MATH_387
18165    && flag_unsafe_math_optimizations
18166    && !(reload_completed || reload_in_progress)"
18167   "#"
18168   "&& 1"
18169   [(const_int 0)]
18171   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18173   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18174   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18176   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18177                                         operands[2], operands[3]));
18178   DONE;
18180   [(set_attr "type" "frndint")
18181    (set_attr "i387_cw" "trunc")
18182    (set_attr "mode" "XF")])
18184 (define_insn "frndintxf2_trunc_i387"
18185   [(set (match_operand:XF 0 "register_operand" "=f")
18186         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18187          UNSPEC_FRNDINT_TRUNC))
18188    (use (match_operand:HI 2 "memory_operand" "m"))
18189    (use (match_operand:HI 3 "memory_operand" "m"))]
18190   "TARGET_USE_FANCY_MATH_387
18191    && flag_unsafe_math_optimizations"
18192   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18193   [(set_attr "type" "frndint")
18194    (set_attr "i387_cw" "trunc")
18195    (set_attr "mode" "XF")])
18197 (define_expand "btruncxf2"
18198   [(use (match_operand:XF 0 "register_operand" ""))
18199    (use (match_operand:XF 1 "register_operand" ""))]
18200   "TARGET_USE_FANCY_MATH_387
18201    && flag_unsafe_math_optimizations && !optimize_size"
18203   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18204   DONE;
18207 (define_expand "btrunc<mode>2"
18208   [(use (match_operand:MODEF 0 "register_operand" ""))
18209    (use (match_operand:MODEF 1 "register_operand" ""))]
18210   "(TARGET_USE_FANCY_MATH_387
18211     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18212         || TARGET_MIX_SSE_I387)
18213     && flag_unsafe_math_optimizations && !optimize_size)
18214    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18215        && !flag_trapping_math
18216        && (TARGET_ROUND || !optimize_size))"
18218   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18219       && !flag_trapping_math
18220       && (TARGET_ROUND || !optimize_size))
18221     {
18222       if (TARGET_ROUND)
18223         emit_insn (gen_sse4_1_round<mode>2
18224                    (operands[0], operands[1], GEN_INT (0x03)));
18225       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18226         ix86_expand_trunc (operand0, operand1);
18227       else
18228         ix86_expand_truncdf_32 (operand0, operand1);
18229     }
18230   else
18231     {
18232       rtx op0 = gen_reg_rtx (XFmode);
18233       rtx op1 = gen_reg_rtx (XFmode);
18235       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18236       emit_insn (gen_frndintxf2_trunc (op0, op1));
18238       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18239     }
18240   DONE;
18243 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18244 (define_insn_and_split "frndintxf2_mask_pm"
18245   [(set (match_operand:XF 0 "register_operand" "")
18246         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18247          UNSPEC_FRNDINT_MASK_PM))
18248    (clobber (reg:CC FLAGS_REG))]
18249   "TARGET_USE_FANCY_MATH_387
18250    && flag_unsafe_math_optimizations
18251    && !(reload_completed || reload_in_progress)"
18252   "#"
18253   "&& 1"
18254   [(const_int 0)]
18256   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18258   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18259   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18261   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18262                                           operands[2], operands[3]));
18263   DONE;
18265   [(set_attr "type" "frndint")
18266    (set_attr "i387_cw" "mask_pm")
18267    (set_attr "mode" "XF")])
18269 (define_insn "frndintxf2_mask_pm_i387"
18270   [(set (match_operand:XF 0 "register_operand" "=f")
18271         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18272          UNSPEC_FRNDINT_MASK_PM))
18273    (use (match_operand:HI 2 "memory_operand" "m"))
18274    (use (match_operand:HI 3 "memory_operand" "m"))]
18275   "TARGET_USE_FANCY_MATH_387
18276    && flag_unsafe_math_optimizations"
18277   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18278   [(set_attr "type" "frndint")
18279    (set_attr "i387_cw" "mask_pm")
18280    (set_attr "mode" "XF")])
18282 (define_expand "nearbyintxf2"
18283   [(use (match_operand:XF 0 "register_operand" ""))
18284    (use (match_operand:XF 1 "register_operand" ""))]
18285   "TARGET_USE_FANCY_MATH_387
18286    && flag_unsafe_math_optimizations"
18288   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18290   DONE;
18293 (define_expand "nearbyint<mode>2"
18294   [(use (match_operand:MODEF 0 "register_operand" ""))
18295    (use (match_operand:MODEF 1 "register_operand" ""))]
18296   "TARGET_USE_FANCY_MATH_387
18297    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18298        || TARGET_MIX_SSE_I387)
18299    && flag_unsafe_math_optimizations"
18301   rtx op0 = gen_reg_rtx (XFmode);
18302   rtx op1 = gen_reg_rtx (XFmode);
18304   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18305   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18307   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18308   DONE;
18311 (define_insn "fxam<mode>2_i387"
18312   [(set (match_operand:HI 0 "register_operand" "=a")
18313         (unspec:HI
18314           [(match_operand:X87MODEF 1 "register_operand" "f")]
18315           UNSPEC_FXAM))]
18316   "TARGET_USE_FANCY_MATH_387"
18317   "fxam\n\tfnstsw\t%0"
18318   [(set_attr "type" "multi")
18319    (set_attr "unit" "i387")
18320    (set_attr "mode" "<MODE>")])
18322 (define_expand "isinf<mode>2"
18323   [(use (match_operand:SI 0 "register_operand" ""))
18324    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18325   "TARGET_USE_FANCY_MATH_387
18326    && TARGET_C99_FUNCTIONS
18327    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18329   rtx mask = GEN_INT (0x45);
18330   rtx val = GEN_INT (0x05);
18332   rtx cond;
18334   rtx scratch = gen_reg_rtx (HImode);
18335   rtx res = gen_reg_rtx (QImode);
18337   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18338   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18339   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18340   cond = gen_rtx_fmt_ee (EQ, QImode,
18341                          gen_rtx_REG (CCmode, FLAGS_REG),
18342                          const0_rtx);
18343   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18344   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18345   DONE;
18348 (define_expand "signbit<mode>2"
18349   [(use (match_operand:SI 0 "register_operand" ""))
18350    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18351   "TARGET_USE_FANCY_MATH_387
18352    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18354   rtx mask = GEN_INT (0x0200);
18356   rtx scratch = gen_reg_rtx (HImode);
18358   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18359   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18360   DONE;
18363 ;; Block operation instructions
18365 (define_insn "cld"
18366   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18367   ""
18368   "cld"
18369   [(set_attr "length" "1")
18370    (set_attr "length_immediate" "0")
18371    (set_attr "modrm" "0")])
18373 (define_expand "movmemsi"
18374   [(use (match_operand:BLK 0 "memory_operand" ""))
18375    (use (match_operand:BLK 1 "memory_operand" ""))
18376    (use (match_operand:SI 2 "nonmemory_operand" ""))
18377    (use (match_operand:SI 3 "const_int_operand" ""))
18378    (use (match_operand:SI 4 "const_int_operand" ""))
18379    (use (match_operand:SI 5 "const_int_operand" ""))]
18380   ""
18382  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18383                          operands[4], operands[5]))
18384    DONE;
18385  else
18386    FAIL;
18389 (define_expand "movmemdi"
18390   [(use (match_operand:BLK 0 "memory_operand" ""))
18391    (use (match_operand:BLK 1 "memory_operand" ""))
18392    (use (match_operand:DI 2 "nonmemory_operand" ""))
18393    (use (match_operand:DI 3 "const_int_operand" ""))
18394    (use (match_operand:SI 4 "const_int_operand" ""))
18395    (use (match_operand:SI 5 "const_int_operand" ""))]
18396   "TARGET_64BIT"
18398  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18399                          operands[4], operands[5]))
18400    DONE;
18401  else
18402    FAIL;
18405 ;; Most CPUs don't like single string operations
18406 ;; Handle this case here to simplify previous expander.
18408 (define_expand "strmov"
18409   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18410    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18411    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18412               (clobber (reg:CC FLAGS_REG))])
18413    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18414               (clobber (reg:CC FLAGS_REG))])]
18415   ""
18417   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18419   /* If .md ever supports :P for Pmode, these can be directly
18420      in the pattern above.  */
18421   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18422   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18424   /* Can't use this if the user has appropriated esi or edi.  */
18425   if ((TARGET_SINGLE_STRINGOP || optimize_size)
18426       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18427     {
18428       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18429                                       operands[2], operands[3],
18430                                       operands[5], operands[6]));
18431       DONE;
18432     }
18434   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18437 (define_expand "strmov_singleop"
18438   [(parallel [(set (match_operand 1 "memory_operand" "")
18439                    (match_operand 3 "memory_operand" ""))
18440               (set (match_operand 0 "register_operand" "")
18441                    (match_operand 4 "" ""))
18442               (set (match_operand 2 "register_operand" "")
18443                    (match_operand 5 "" ""))])]
18444   "TARGET_SINGLE_STRINGOP || optimize_size"
18445   "ix86_current_function_needs_cld = 1;")
18447 (define_insn "*strmovdi_rex_1"
18448   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18449         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18450    (set (match_operand:DI 0 "register_operand" "=D")
18451         (plus:DI (match_dup 2)
18452                  (const_int 8)))
18453    (set (match_operand:DI 1 "register_operand" "=S")
18454         (plus:DI (match_dup 3)
18455                  (const_int 8)))]
18456   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18457   "movsq"
18458   [(set_attr "type" "str")
18459    (set_attr "mode" "DI")
18460    (set_attr "memory" "both")])
18462 (define_insn "*strmovsi_1"
18463   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18464         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18465    (set (match_operand:SI 0 "register_operand" "=D")
18466         (plus:SI (match_dup 2)
18467                  (const_int 4)))
18468    (set (match_operand:SI 1 "register_operand" "=S")
18469         (plus:SI (match_dup 3)
18470                  (const_int 4)))]
18471   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18472   "movs{l|d}"
18473   [(set_attr "type" "str")
18474    (set_attr "mode" "SI")
18475    (set_attr "memory" "both")])
18477 (define_insn "*strmovsi_rex_1"
18478   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18479         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18480    (set (match_operand:DI 0 "register_operand" "=D")
18481         (plus:DI (match_dup 2)
18482                  (const_int 4)))
18483    (set (match_operand:DI 1 "register_operand" "=S")
18484         (plus:DI (match_dup 3)
18485                  (const_int 4)))]
18486   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18487   "movs{l|d}"
18488   [(set_attr "type" "str")
18489    (set_attr "mode" "SI")
18490    (set_attr "memory" "both")])
18492 (define_insn "*strmovhi_1"
18493   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18494         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18495    (set (match_operand:SI 0 "register_operand" "=D")
18496         (plus:SI (match_dup 2)
18497                  (const_int 2)))
18498    (set (match_operand:SI 1 "register_operand" "=S")
18499         (plus:SI (match_dup 3)
18500                  (const_int 2)))]
18501   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18502   "movsw"
18503   [(set_attr "type" "str")
18504    (set_attr "memory" "both")
18505    (set_attr "mode" "HI")])
18507 (define_insn "*strmovhi_rex_1"
18508   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18509         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18510    (set (match_operand:DI 0 "register_operand" "=D")
18511         (plus:DI (match_dup 2)
18512                  (const_int 2)))
18513    (set (match_operand:DI 1 "register_operand" "=S")
18514         (plus:DI (match_dup 3)
18515                  (const_int 2)))]
18516   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18517   "movsw"
18518   [(set_attr "type" "str")
18519    (set_attr "memory" "both")
18520    (set_attr "mode" "HI")])
18522 (define_insn "*strmovqi_1"
18523   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18524         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18525    (set (match_operand:SI 0 "register_operand" "=D")
18526         (plus:SI (match_dup 2)
18527                  (const_int 1)))
18528    (set (match_operand:SI 1 "register_operand" "=S")
18529         (plus:SI (match_dup 3)
18530                  (const_int 1)))]
18531   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18532   "movsb"
18533   [(set_attr "type" "str")
18534    (set_attr "memory" "both")
18535    (set_attr "mode" "QI")])
18537 (define_insn "*strmovqi_rex_1"
18538   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18539         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18540    (set (match_operand:DI 0 "register_operand" "=D")
18541         (plus:DI (match_dup 2)
18542                  (const_int 1)))
18543    (set (match_operand:DI 1 "register_operand" "=S")
18544         (plus:DI (match_dup 3)
18545                  (const_int 1)))]
18546   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18547   "movsb"
18548   [(set_attr "type" "str")
18549    (set_attr "memory" "both")
18550    (set_attr "mode" "QI")])
18552 (define_expand "rep_mov"
18553   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18554               (set (match_operand 0 "register_operand" "")
18555                    (match_operand 5 "" ""))
18556               (set (match_operand 2 "register_operand" "")
18557                    (match_operand 6 "" ""))
18558               (set (match_operand 1 "memory_operand" "")
18559                    (match_operand 3 "memory_operand" ""))
18560               (use (match_dup 4))])]
18561   ""
18562   "ix86_current_function_needs_cld = 1;")
18564 (define_insn "*rep_movdi_rex64"
18565   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18566    (set (match_operand:DI 0 "register_operand" "=D")
18567         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18568                             (const_int 3))
18569                  (match_operand:DI 3 "register_operand" "0")))
18570    (set (match_operand:DI 1 "register_operand" "=S")
18571         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18572                  (match_operand:DI 4 "register_operand" "1")))
18573    (set (mem:BLK (match_dup 3))
18574         (mem:BLK (match_dup 4)))
18575    (use (match_dup 5))]
18576   "TARGET_64BIT"
18577   "rep movsq"
18578   [(set_attr "type" "str")
18579    (set_attr "prefix_rep" "1")
18580    (set_attr "memory" "both")
18581    (set_attr "mode" "DI")])
18583 (define_insn "*rep_movsi"
18584   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18585    (set (match_operand:SI 0 "register_operand" "=D")
18586         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18587                             (const_int 2))
18588                  (match_operand:SI 3 "register_operand" "0")))
18589    (set (match_operand:SI 1 "register_operand" "=S")
18590         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18591                  (match_operand:SI 4 "register_operand" "1")))
18592    (set (mem:BLK (match_dup 3))
18593         (mem:BLK (match_dup 4)))
18594    (use (match_dup 5))]
18595   "!TARGET_64BIT"
18596   "rep movs{l|d}"
18597   [(set_attr "type" "str")
18598    (set_attr "prefix_rep" "1")
18599    (set_attr "memory" "both")
18600    (set_attr "mode" "SI")])
18602 (define_insn "*rep_movsi_rex64"
18603   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18604    (set (match_operand:DI 0 "register_operand" "=D")
18605         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18606                             (const_int 2))
18607                  (match_operand:DI 3 "register_operand" "0")))
18608    (set (match_operand:DI 1 "register_operand" "=S")
18609         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18610                  (match_operand:DI 4 "register_operand" "1")))
18611    (set (mem:BLK (match_dup 3))
18612         (mem:BLK (match_dup 4)))
18613    (use (match_dup 5))]
18614   "TARGET_64BIT"
18615   "rep movs{l|d}"
18616   [(set_attr "type" "str")
18617    (set_attr "prefix_rep" "1")
18618    (set_attr "memory" "both")
18619    (set_attr "mode" "SI")])
18621 (define_insn "*rep_movqi"
18622   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18623    (set (match_operand:SI 0 "register_operand" "=D")
18624         (plus:SI (match_operand:SI 3 "register_operand" "0")
18625                  (match_operand:SI 5 "register_operand" "2")))
18626    (set (match_operand:SI 1 "register_operand" "=S")
18627         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18628    (set (mem:BLK (match_dup 3))
18629         (mem:BLK (match_dup 4)))
18630    (use (match_dup 5))]
18631   "!TARGET_64BIT"
18632   "rep movsb"
18633   [(set_attr "type" "str")
18634    (set_attr "prefix_rep" "1")
18635    (set_attr "memory" "both")
18636    (set_attr "mode" "SI")])
18638 (define_insn "*rep_movqi_rex64"
18639   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18640    (set (match_operand:DI 0 "register_operand" "=D")
18641         (plus:DI (match_operand:DI 3 "register_operand" "0")
18642                  (match_operand:DI 5 "register_operand" "2")))
18643    (set (match_operand:DI 1 "register_operand" "=S")
18644         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18645    (set (mem:BLK (match_dup 3))
18646         (mem:BLK (match_dup 4)))
18647    (use (match_dup 5))]
18648   "TARGET_64BIT"
18649   "rep movsb"
18650   [(set_attr "type" "str")
18651    (set_attr "prefix_rep" "1")
18652    (set_attr "memory" "both")
18653    (set_attr "mode" "SI")])
18655 (define_expand "setmemsi"
18656    [(use (match_operand:BLK 0 "memory_operand" ""))
18657     (use (match_operand:SI 1 "nonmemory_operand" ""))
18658     (use (match_operand 2 "const_int_operand" ""))
18659     (use (match_operand 3 "const_int_operand" ""))
18660     (use (match_operand:SI 4 "const_int_operand" ""))
18661     (use (match_operand:SI 5 "const_int_operand" ""))]
18662   ""
18664  if (ix86_expand_setmem (operands[0], operands[1],
18665                          operands[2], operands[3],
18666                          operands[4], operands[5]))
18667    DONE;
18668  else
18669    FAIL;
18672 (define_expand "setmemdi"
18673    [(use (match_operand:BLK 0 "memory_operand" ""))
18674     (use (match_operand:DI 1 "nonmemory_operand" ""))
18675     (use (match_operand 2 "const_int_operand" ""))
18676     (use (match_operand 3 "const_int_operand" ""))
18677     (use (match_operand 4 "const_int_operand" ""))
18678     (use (match_operand 5 "const_int_operand" ""))]
18679   "TARGET_64BIT"
18681  if (ix86_expand_setmem (operands[0], operands[1],
18682                          operands[2], operands[3],
18683                          operands[4], operands[5]))
18684    DONE;
18685  else
18686    FAIL;
18689 ;; Most CPUs don't like single string operations
18690 ;; Handle this case here to simplify previous expander.
18692 (define_expand "strset"
18693   [(set (match_operand 1 "memory_operand" "")
18694         (match_operand 2 "register_operand" ""))
18695    (parallel [(set (match_operand 0 "register_operand" "")
18696                    (match_dup 3))
18697               (clobber (reg:CC FLAGS_REG))])]
18698   ""
18700   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18701     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18703   /* If .md ever supports :P for Pmode, this can be directly
18704      in the pattern above.  */
18705   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18706                               GEN_INT (GET_MODE_SIZE (GET_MODE
18707                                                       (operands[2]))));
18708   if (TARGET_SINGLE_STRINGOP || optimize_size)
18709     {
18710       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18711                                       operands[3]));
18712       DONE;
18713     }
18716 (define_expand "strset_singleop"
18717   [(parallel [(set (match_operand 1 "memory_operand" "")
18718                    (match_operand 2 "register_operand" ""))
18719               (set (match_operand 0 "register_operand" "")
18720                    (match_operand 3 "" ""))])]
18721   "TARGET_SINGLE_STRINGOP || optimize_size"
18722   "ix86_current_function_needs_cld = 1;")
18724 (define_insn "*strsetdi_rex_1"
18725   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18726         (match_operand:DI 2 "register_operand" "a"))
18727    (set (match_operand:DI 0 "register_operand" "=D")
18728         (plus:DI (match_dup 1)
18729                  (const_int 8)))]
18730   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18731   "stosq"
18732   [(set_attr "type" "str")
18733    (set_attr "memory" "store")
18734    (set_attr "mode" "DI")])
18736 (define_insn "*strsetsi_1"
18737   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18738         (match_operand:SI 2 "register_operand" "a"))
18739    (set (match_operand:SI 0 "register_operand" "=D")
18740         (plus:SI (match_dup 1)
18741                  (const_int 4)))]
18742   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18743   "stos{l|d}"
18744   [(set_attr "type" "str")
18745    (set_attr "memory" "store")
18746    (set_attr "mode" "SI")])
18748 (define_insn "*strsetsi_rex_1"
18749   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18750         (match_operand:SI 2 "register_operand" "a"))
18751    (set (match_operand:DI 0 "register_operand" "=D")
18752         (plus:DI (match_dup 1)
18753                  (const_int 4)))]
18754   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18755   "stos{l|d}"
18756   [(set_attr "type" "str")
18757    (set_attr "memory" "store")
18758    (set_attr "mode" "SI")])
18760 (define_insn "*strsethi_1"
18761   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18762         (match_operand:HI 2 "register_operand" "a"))
18763    (set (match_operand:SI 0 "register_operand" "=D")
18764         (plus:SI (match_dup 1)
18765                  (const_int 2)))]
18766   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18767   "stosw"
18768   [(set_attr "type" "str")
18769    (set_attr "memory" "store")
18770    (set_attr "mode" "HI")])
18772 (define_insn "*strsethi_rex_1"
18773   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18774         (match_operand:HI 2 "register_operand" "a"))
18775    (set (match_operand:DI 0 "register_operand" "=D")
18776         (plus:DI (match_dup 1)
18777                  (const_int 2)))]
18778   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18779   "stosw"
18780   [(set_attr "type" "str")
18781    (set_attr "memory" "store")
18782    (set_attr "mode" "HI")])
18784 (define_insn "*strsetqi_1"
18785   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18786         (match_operand:QI 2 "register_operand" "a"))
18787    (set (match_operand:SI 0 "register_operand" "=D")
18788         (plus:SI (match_dup 1)
18789                  (const_int 1)))]
18790   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18791   "stosb"
18792   [(set_attr "type" "str")
18793    (set_attr "memory" "store")
18794    (set_attr "mode" "QI")])
18796 (define_insn "*strsetqi_rex_1"
18797   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18798         (match_operand:QI 2 "register_operand" "a"))
18799    (set (match_operand:DI 0 "register_operand" "=D")
18800         (plus:DI (match_dup 1)
18801                  (const_int 1)))]
18802   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18803   "stosb"
18804   [(set_attr "type" "str")
18805    (set_attr "memory" "store")
18806    (set_attr "mode" "QI")])
18808 (define_expand "rep_stos"
18809   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18810               (set (match_operand 0 "register_operand" "")
18811                    (match_operand 4 "" ""))
18812               (set (match_operand 2 "memory_operand" "") (const_int 0))
18813               (use (match_operand 3 "register_operand" ""))
18814               (use (match_dup 1))])]
18815   ""
18816   "ix86_current_function_needs_cld = 1;")
18818 (define_insn "*rep_stosdi_rex64"
18819   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18820    (set (match_operand:DI 0 "register_operand" "=D")
18821         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18822                             (const_int 3))
18823                  (match_operand:DI 3 "register_operand" "0")))
18824    (set (mem:BLK (match_dup 3))
18825         (const_int 0))
18826    (use (match_operand:DI 2 "register_operand" "a"))
18827    (use (match_dup 4))]
18828   "TARGET_64BIT"
18829   "rep stosq"
18830   [(set_attr "type" "str")
18831    (set_attr "prefix_rep" "1")
18832    (set_attr "memory" "store")
18833    (set_attr "mode" "DI")])
18835 (define_insn "*rep_stossi"
18836   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18837    (set (match_operand:SI 0 "register_operand" "=D")
18838         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18839                             (const_int 2))
18840                  (match_operand:SI 3 "register_operand" "0")))
18841    (set (mem:BLK (match_dup 3))
18842         (const_int 0))
18843    (use (match_operand:SI 2 "register_operand" "a"))
18844    (use (match_dup 4))]
18845   "!TARGET_64BIT"
18846   "rep stos{l|d}"
18847   [(set_attr "type" "str")
18848    (set_attr "prefix_rep" "1")
18849    (set_attr "memory" "store")
18850    (set_attr "mode" "SI")])
18852 (define_insn "*rep_stossi_rex64"
18853   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18854    (set (match_operand:DI 0 "register_operand" "=D")
18855         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18856                             (const_int 2))
18857                  (match_operand:DI 3 "register_operand" "0")))
18858    (set (mem:BLK (match_dup 3))
18859         (const_int 0))
18860    (use (match_operand:SI 2 "register_operand" "a"))
18861    (use (match_dup 4))]
18862   "TARGET_64BIT"
18863   "rep stos{l|d}"
18864   [(set_attr "type" "str")
18865    (set_attr "prefix_rep" "1")
18866    (set_attr "memory" "store")
18867    (set_attr "mode" "SI")])
18869 (define_insn "*rep_stosqi"
18870   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18871    (set (match_operand:SI 0 "register_operand" "=D")
18872         (plus:SI (match_operand:SI 3 "register_operand" "0")
18873                  (match_operand:SI 4 "register_operand" "1")))
18874    (set (mem:BLK (match_dup 3))
18875         (const_int 0))
18876    (use (match_operand:QI 2 "register_operand" "a"))
18877    (use (match_dup 4))]
18878   "!TARGET_64BIT"
18879   "rep stosb"
18880   [(set_attr "type" "str")
18881    (set_attr "prefix_rep" "1")
18882    (set_attr "memory" "store")
18883    (set_attr "mode" "QI")])
18885 (define_insn "*rep_stosqi_rex64"
18886   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18887    (set (match_operand:DI 0 "register_operand" "=D")
18888         (plus:DI (match_operand:DI 3 "register_operand" "0")
18889                  (match_operand:DI 4 "register_operand" "1")))
18890    (set (mem:BLK (match_dup 3))
18891         (const_int 0))
18892    (use (match_operand:QI 2 "register_operand" "a"))
18893    (use (match_dup 4))]
18894   "TARGET_64BIT"
18895   "rep stosb"
18896   [(set_attr "type" "str")
18897    (set_attr "prefix_rep" "1")
18898    (set_attr "memory" "store")
18899    (set_attr "mode" "QI")])
18901 (define_expand "cmpstrnsi"
18902   [(set (match_operand:SI 0 "register_operand" "")
18903         (compare:SI (match_operand:BLK 1 "general_operand" "")
18904                     (match_operand:BLK 2 "general_operand" "")))
18905    (use (match_operand 3 "general_operand" ""))
18906    (use (match_operand 4 "immediate_operand" ""))]
18907   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18909   rtx addr1, addr2, out, outlow, count, countreg, align;
18911   /* Can't use this if the user has appropriated esi or edi.  */
18912   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18913     FAIL;
18915   out = operands[0];
18916   if (!REG_P (out))
18917     out = gen_reg_rtx (SImode);
18919   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18920   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18921   if (addr1 != XEXP (operands[1], 0))
18922     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18923   if (addr2 != XEXP (operands[2], 0))
18924     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18926   count = operands[3];
18927   countreg = ix86_zero_extend_to_Pmode (count);
18929   /* %%% Iff we are testing strict equality, we can use known alignment
18930      to good advantage.  This may be possible with combine, particularly
18931      once cc0 is dead.  */
18932   align = operands[4];
18934   if (CONST_INT_P (count))
18935     {
18936       if (INTVAL (count) == 0)
18937         {
18938           emit_move_insn (operands[0], const0_rtx);
18939           DONE;
18940         }
18941       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18942                                      operands[1], operands[2]));
18943     }
18944   else
18945     {
18946       if (TARGET_64BIT)
18947         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18948       else
18949         emit_insn (gen_cmpsi_1 (countreg, countreg));
18950       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18951                                   operands[1], operands[2]));
18952     }
18954   outlow = gen_lowpart (QImode, out);
18955   emit_insn (gen_cmpintqi (outlow));
18956   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18958   if (operands[0] != out)
18959     emit_move_insn (operands[0], out);
18961   DONE;
18964 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18966 (define_expand "cmpintqi"
18967   [(set (match_dup 1)
18968         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18969    (set (match_dup 2)
18970         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18971    (parallel [(set (match_operand:QI 0 "register_operand" "")
18972                    (minus:QI (match_dup 1)
18973                              (match_dup 2)))
18974               (clobber (reg:CC FLAGS_REG))])]
18975   ""
18976   "operands[1] = gen_reg_rtx (QImode);
18977    operands[2] = gen_reg_rtx (QImode);")
18979 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
18980 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
18982 (define_expand "cmpstrnqi_nz_1"
18983   [(parallel [(set (reg:CC FLAGS_REG)
18984                    (compare:CC (match_operand 4 "memory_operand" "")
18985                                (match_operand 5 "memory_operand" "")))
18986               (use (match_operand 2 "register_operand" ""))
18987               (use (match_operand:SI 3 "immediate_operand" ""))
18988               (clobber (match_operand 0 "register_operand" ""))
18989               (clobber (match_operand 1 "register_operand" ""))
18990               (clobber (match_dup 2))])]
18991   ""
18992   "ix86_current_function_needs_cld = 1;")
18994 (define_insn "*cmpstrnqi_nz_1"
18995   [(set (reg:CC FLAGS_REG)
18996         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18997                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18998    (use (match_operand:SI 6 "register_operand" "2"))
18999    (use (match_operand:SI 3 "immediate_operand" "i"))
19000    (clobber (match_operand:SI 0 "register_operand" "=S"))
19001    (clobber (match_operand:SI 1 "register_operand" "=D"))
19002    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19003   "!TARGET_64BIT"
19004   "repz cmpsb"
19005   [(set_attr "type" "str")
19006    (set_attr "mode" "QI")
19007    (set_attr "prefix_rep" "1")])
19009 (define_insn "*cmpstrnqi_nz_rex_1"
19010   [(set (reg:CC FLAGS_REG)
19011         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19012                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19013    (use (match_operand:DI 6 "register_operand" "2"))
19014    (use (match_operand:SI 3 "immediate_operand" "i"))
19015    (clobber (match_operand:DI 0 "register_operand" "=S"))
19016    (clobber (match_operand:DI 1 "register_operand" "=D"))
19017    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19018   "TARGET_64BIT"
19019   "repz cmpsb"
19020   [(set_attr "type" "str")
19021    (set_attr "mode" "QI")
19022    (set_attr "prefix_rep" "1")])
19024 ;; The same, but the count is not known to not be zero.
19026 (define_expand "cmpstrnqi_1"
19027   [(parallel [(set (reg:CC FLAGS_REG)
19028                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19029                                      (const_int 0))
19030                   (compare:CC (match_operand 4 "memory_operand" "")
19031                               (match_operand 5 "memory_operand" ""))
19032                   (const_int 0)))
19033               (use (match_operand:SI 3 "immediate_operand" ""))
19034               (use (reg:CC FLAGS_REG))
19035               (clobber (match_operand 0 "register_operand" ""))
19036               (clobber (match_operand 1 "register_operand" ""))
19037               (clobber (match_dup 2))])]
19038   ""
19039   "ix86_current_function_needs_cld = 1;")
19041 (define_insn "*cmpstrnqi_1"
19042   [(set (reg:CC FLAGS_REG)
19043         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19044                              (const_int 0))
19045           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19046                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19047           (const_int 0)))
19048    (use (match_operand:SI 3 "immediate_operand" "i"))
19049    (use (reg:CC FLAGS_REG))
19050    (clobber (match_operand:SI 0 "register_operand" "=S"))
19051    (clobber (match_operand:SI 1 "register_operand" "=D"))
19052    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19053   "!TARGET_64BIT"
19054   "repz cmpsb"
19055   [(set_attr "type" "str")
19056    (set_attr "mode" "QI")
19057    (set_attr "prefix_rep" "1")])
19059 (define_insn "*cmpstrnqi_rex_1"
19060   [(set (reg:CC FLAGS_REG)
19061         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19062                              (const_int 0))
19063           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19064                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19065           (const_int 0)))
19066    (use (match_operand:SI 3 "immediate_operand" "i"))
19067    (use (reg:CC FLAGS_REG))
19068    (clobber (match_operand:DI 0 "register_operand" "=S"))
19069    (clobber (match_operand:DI 1 "register_operand" "=D"))
19070    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19071   "TARGET_64BIT"
19072   "repz cmpsb"
19073   [(set_attr "type" "str")
19074    (set_attr "mode" "QI")
19075    (set_attr "prefix_rep" "1")])
19077 (define_expand "strlensi"
19078   [(set (match_operand:SI 0 "register_operand" "")
19079         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19080                     (match_operand:QI 2 "immediate_operand" "")
19081                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19082   ""
19084  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19085    DONE;
19086  else
19087    FAIL;
19090 (define_expand "strlendi"
19091   [(set (match_operand:DI 0 "register_operand" "")
19092         (unspec:DI [(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 "strlenqi_1"
19104   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19105               (clobber (match_operand 1 "register_operand" ""))
19106               (clobber (reg:CC FLAGS_REG))])]
19107   ""
19108   "ix86_current_function_needs_cld = 1;")
19110 (define_insn "*strlenqi_1"
19111   [(set (match_operand:SI 0 "register_operand" "=&c")
19112         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19113                     (match_operand:QI 2 "register_operand" "a")
19114                     (match_operand:SI 3 "immediate_operand" "i")
19115                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19116    (clobber (match_operand:SI 1 "register_operand" "=D"))
19117    (clobber (reg:CC FLAGS_REG))]
19118   "!TARGET_64BIT"
19119   "repnz scasb"
19120   [(set_attr "type" "str")
19121    (set_attr "mode" "QI")
19122    (set_attr "prefix_rep" "1")])
19124 (define_insn "*strlenqi_rex_1"
19125   [(set (match_operand:DI 0 "register_operand" "=&c")
19126         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19127                     (match_operand:QI 2 "register_operand" "a")
19128                     (match_operand:DI 3 "immediate_operand" "i")
19129                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19130    (clobber (match_operand:DI 1 "register_operand" "=D"))
19131    (clobber (reg:CC FLAGS_REG))]
19132   "TARGET_64BIT"
19133   "repnz scasb"
19134   [(set_attr "type" "str")
19135    (set_attr "mode" "QI")
19136    (set_attr "prefix_rep" "1")])
19138 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19139 ;; handled in combine, but it is not currently up to the task.
19140 ;; When used for their truth value, the cmpstrn* expanders generate
19141 ;; code like this:
19143 ;;   repz cmpsb
19144 ;;   seta       %al
19145 ;;   setb       %dl
19146 ;;   cmpb       %al, %dl
19147 ;;   jcc        label
19149 ;; The intermediate three instructions are unnecessary.
19151 ;; This one handles cmpstrn*_nz_1...
19152 (define_peephole2
19153   [(parallel[
19154      (set (reg:CC FLAGS_REG)
19155           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19156                       (mem:BLK (match_operand 5 "register_operand" ""))))
19157      (use (match_operand 6 "register_operand" ""))
19158      (use (match_operand:SI 3 "immediate_operand" ""))
19159      (clobber (match_operand 0 "register_operand" ""))
19160      (clobber (match_operand 1 "register_operand" ""))
19161      (clobber (match_operand 2 "register_operand" ""))])
19162    (set (match_operand:QI 7 "register_operand" "")
19163         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19164    (set (match_operand:QI 8 "register_operand" "")
19165         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19166    (set (reg FLAGS_REG)
19167         (compare (match_dup 7) (match_dup 8)))
19168   ]
19169   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19170   [(parallel[
19171      (set (reg:CC FLAGS_REG)
19172           (compare:CC (mem:BLK (match_dup 4))
19173                       (mem:BLK (match_dup 5))))
19174      (use (match_dup 6))
19175      (use (match_dup 3))
19176      (clobber (match_dup 0))
19177      (clobber (match_dup 1))
19178      (clobber (match_dup 2))])]
19179   "")
19181 ;; ...and this one handles cmpstrn*_1.
19182 (define_peephole2
19183   [(parallel[
19184      (set (reg:CC FLAGS_REG)
19185           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19186                                (const_int 0))
19187             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19188                         (mem:BLK (match_operand 5 "register_operand" "")))
19189             (const_int 0)))
19190      (use (match_operand:SI 3 "immediate_operand" ""))
19191      (use (reg:CC FLAGS_REG))
19192      (clobber (match_operand 0 "register_operand" ""))
19193      (clobber (match_operand 1 "register_operand" ""))
19194      (clobber (match_operand 2 "register_operand" ""))])
19195    (set (match_operand:QI 7 "register_operand" "")
19196         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19197    (set (match_operand:QI 8 "register_operand" "")
19198         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19199    (set (reg FLAGS_REG)
19200         (compare (match_dup 7) (match_dup 8)))
19201   ]
19202   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19203   [(parallel[
19204      (set (reg:CC FLAGS_REG)
19205           (if_then_else:CC (ne (match_dup 6)
19206                                (const_int 0))
19207             (compare:CC (mem:BLK (match_dup 4))
19208                         (mem:BLK (match_dup 5)))
19209             (const_int 0)))
19210      (use (match_dup 3))
19211      (use (reg:CC FLAGS_REG))
19212      (clobber (match_dup 0))
19213      (clobber (match_dup 1))
19214      (clobber (match_dup 2))])]
19215   "")
19219 ;; Conditional move instructions.
19221 (define_expand "movdicc"
19222   [(set (match_operand:DI 0 "register_operand" "")
19223         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19224                          (match_operand:DI 2 "general_operand" "")
19225                          (match_operand:DI 3 "general_operand" "")))]
19226   "TARGET_64BIT"
19227   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19229 (define_insn "x86_movdicc_0_m1_rex64"
19230   [(set (match_operand:DI 0 "register_operand" "=r")
19231         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19232           (const_int -1)
19233           (const_int 0)))
19234    (clobber (reg:CC FLAGS_REG))]
19235   "TARGET_64BIT"
19236   "sbb{q}\t%0, %0"
19237   ; Since we don't have the proper number of operands for an alu insn,
19238   ; fill in all the blanks.
19239   [(set_attr "type" "alu")
19240    (set_attr "pent_pair" "pu")
19241    (set_attr "memory" "none")
19242    (set_attr "imm_disp" "false")
19243    (set_attr "mode" "DI")
19244    (set_attr "length_immediate" "0")])
19246 (define_insn "*x86_movdicc_0_m1_se"
19247   [(set (match_operand:DI 0 "register_operand" "=r")
19248         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19249                          (const_int 1)
19250                          (const_int 0)))
19251    (clobber (reg:CC FLAGS_REG))]
19252   ""
19253   "sbb{q}\t%0, %0"
19254   [(set_attr "type" "alu")
19255    (set_attr "pent_pair" "pu")
19256    (set_attr "memory" "none")
19257    (set_attr "imm_disp" "false")
19258    (set_attr "mode" "DI")
19259    (set_attr "length_immediate" "0")])
19261 (define_insn "*movdicc_c_rex64"
19262   [(set (match_operand:DI 0 "register_operand" "=r,r")
19263         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19264                                 [(reg FLAGS_REG) (const_int 0)])
19265                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19266                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19267   "TARGET_64BIT && TARGET_CMOVE
19268    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19269   "@
19270    cmov%O2%C1\t{%2, %0|%0, %2}
19271    cmov%O2%c1\t{%3, %0|%0, %3}"
19272   [(set_attr "type" "icmov")
19273    (set_attr "mode" "DI")])
19275 (define_expand "movsicc"
19276   [(set (match_operand:SI 0 "register_operand" "")
19277         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19278                          (match_operand:SI 2 "general_operand" "")
19279                          (match_operand:SI 3 "general_operand" "")))]
19280   ""
19281   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19283 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19284 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19285 ;; So just document what we're doing explicitly.
19287 (define_insn "x86_movsicc_0_m1"
19288   [(set (match_operand:SI 0 "register_operand" "=r")
19289         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19290           (const_int -1)
19291           (const_int 0)))
19292    (clobber (reg:CC FLAGS_REG))]
19293   ""
19294   "sbb{l}\t%0, %0"
19295   ; Since we don't have the proper number of operands for an alu insn,
19296   ; fill in all the blanks.
19297   [(set_attr "type" "alu")
19298    (set_attr "pent_pair" "pu")
19299    (set_attr "memory" "none")
19300    (set_attr "imm_disp" "false")
19301    (set_attr "mode" "SI")
19302    (set_attr "length_immediate" "0")])
19304 (define_insn "*x86_movsicc_0_m1_se"
19305   [(set (match_operand:SI 0 "register_operand" "=r")
19306         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19307                          (const_int 1)
19308                          (const_int 0)))
19309    (clobber (reg:CC FLAGS_REG))]
19310   ""
19311   "sbb{l}\t%0, %0"
19312   [(set_attr "type" "alu")
19313    (set_attr "pent_pair" "pu")
19314    (set_attr "memory" "none")
19315    (set_attr "imm_disp" "false")
19316    (set_attr "mode" "SI")
19317    (set_attr "length_immediate" "0")])
19319 (define_insn "*movsicc_noc"
19320   [(set (match_operand:SI 0 "register_operand" "=r,r")
19321         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19322                                 [(reg FLAGS_REG) (const_int 0)])
19323                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19324                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19325   "TARGET_CMOVE
19326    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19327   "@
19328    cmov%O2%C1\t{%2, %0|%0, %2}
19329    cmov%O2%c1\t{%3, %0|%0, %3}"
19330   [(set_attr "type" "icmov")
19331    (set_attr "mode" "SI")])
19333 (define_expand "movhicc"
19334   [(set (match_operand:HI 0 "register_operand" "")
19335         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19336                          (match_operand:HI 2 "general_operand" "")
19337                          (match_operand:HI 3 "general_operand" "")))]
19338   "TARGET_HIMODE_MATH"
19339   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19341 (define_insn "*movhicc_noc"
19342   [(set (match_operand:HI 0 "register_operand" "=r,r")
19343         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19344                                 [(reg FLAGS_REG) (const_int 0)])
19345                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19346                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19347   "TARGET_CMOVE
19348    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19349   "@
19350    cmov%O2%C1\t{%2, %0|%0, %2}
19351    cmov%O2%c1\t{%3, %0|%0, %3}"
19352   [(set_attr "type" "icmov")
19353    (set_attr "mode" "HI")])
19355 (define_expand "movqicc"
19356   [(set (match_operand:QI 0 "register_operand" "")
19357         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19358                          (match_operand:QI 2 "general_operand" "")
19359                          (match_operand:QI 3 "general_operand" "")))]
19360   "TARGET_QIMODE_MATH"
19361   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19363 (define_insn_and_split "*movqicc_noc"
19364   [(set (match_operand:QI 0 "register_operand" "=r,r")
19365         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19366                                 [(match_operand 4 "flags_reg_operand" "")
19367                                  (const_int 0)])
19368                       (match_operand:QI 2 "register_operand" "r,0")
19369                       (match_operand:QI 3 "register_operand" "0,r")))]
19370   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19371   "#"
19372   "&& reload_completed"
19373   [(set (match_dup 0)
19374         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19375                       (match_dup 2)
19376                       (match_dup 3)))]
19377   "operands[0] = gen_lowpart (SImode, operands[0]);
19378    operands[2] = gen_lowpart (SImode, operands[2]);
19379    operands[3] = gen_lowpart (SImode, operands[3]);"
19380   [(set_attr "type" "icmov")
19381    (set_attr "mode" "SI")])
19383 (define_expand "mov<mode>cc"
19384   [(set (match_operand:X87MODEF 0 "register_operand" "")
19385         (if_then_else:X87MODEF
19386           (match_operand 1 "comparison_operator" "")
19387           (match_operand:X87MODEF 2 "register_operand" "")
19388           (match_operand:X87MODEF 3 "register_operand" "")))]
19389   "(TARGET_80387 && TARGET_CMOVE)
19390    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19391   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19393 (define_insn "*movsfcc_1_387"
19394   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19395         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19396                                 [(reg FLAGS_REG) (const_int 0)])
19397                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19398                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19399   "TARGET_80387 && TARGET_CMOVE
19400    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19401   "@
19402    fcmov%F1\t{%2, %0|%0, %2}
19403    fcmov%f1\t{%3, %0|%0, %3}
19404    cmov%O2%C1\t{%2, %0|%0, %2}
19405    cmov%O2%c1\t{%3, %0|%0, %3}"
19406   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19407    (set_attr "mode" "SF,SF,SI,SI")])
19409 (define_insn "*movdfcc_1"
19410   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19411         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19412                                 [(reg FLAGS_REG) (const_int 0)])
19413                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19414                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19415   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19416    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19417   "@
19418    fcmov%F1\t{%2, %0|%0, %2}
19419    fcmov%f1\t{%3, %0|%0, %3}
19420    #
19421    #"
19422   [(set_attr "type" "fcmov,fcmov,multi,multi")
19423    (set_attr "mode" "DF")])
19425 (define_insn "*movdfcc_1_rex64"
19426   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19427         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19428                                 [(reg FLAGS_REG) (const_int 0)])
19429                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19430                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19431   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19432    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19433   "@
19434    fcmov%F1\t{%2, %0|%0, %2}
19435    fcmov%f1\t{%3, %0|%0, %3}
19436    cmov%O2%C1\t{%2, %0|%0, %2}
19437    cmov%O2%c1\t{%3, %0|%0, %3}"
19438   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19439    (set_attr "mode" "DF")])
19441 (define_split
19442   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19443         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19444                                 [(match_operand 4 "flags_reg_operand" "")
19445                                  (const_int 0)])
19446                       (match_operand:DF 2 "nonimmediate_operand" "")
19447                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19448   "!TARGET_64BIT && reload_completed"
19449   [(set (match_dup 2)
19450         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19451                       (match_dup 5)
19452                       (match_dup 6)))
19453    (set (match_dup 3)
19454         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19455                       (match_dup 7)
19456                       (match_dup 8)))]
19457   "split_di (&operands[2], 2, &operands[5], &operands[7]);
19458    split_di (&operands[0], 1, &operands[2], &operands[3]);")
19460 (define_insn "*movxfcc_1"
19461   [(set (match_operand:XF 0 "register_operand" "=f,f")
19462         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19463                                 [(reg FLAGS_REG) (const_int 0)])
19464                       (match_operand:XF 2 "register_operand" "f,0")
19465                       (match_operand:XF 3 "register_operand" "0,f")))]
19466   "TARGET_80387 && TARGET_CMOVE"
19467   "@
19468    fcmov%F1\t{%2, %0|%0, %2}
19469    fcmov%f1\t{%3, %0|%0, %3}"
19470   [(set_attr "type" "fcmov")
19471    (set_attr "mode" "XF")])
19473 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19474 ;; the scalar versions to have only XMM registers as operands.
19476 ;; SSE5 conditional move
19477 (define_insn "*sse5_pcmov_<mode>"
19478   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19479         (if_then_else:MODEF
19480           (match_operand:MODEF 1 "register_operand" "x,0")
19481           (match_operand:MODEF 2 "register_operand" "0,x")
19482           (match_operand:MODEF 3 "register_operand" "x,x")))]
19483   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19484   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19485   [(set_attr "type" "sse4arg")])
19487 ;; These versions of the min/max patterns are intentionally ignorant of
19488 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19489 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19490 ;; are undefined in this condition, we're certain this is correct.
19492 (define_insn "<code><mode>3"
19493   [(set (match_operand:MODEF 0 "register_operand" "=x")
19494         (smaxmin:MODEF
19495           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19496           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19497   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19498   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19499   [(set_attr "type" "sseadd")
19500    (set_attr "mode" "<MODE>")])
19502 ;; These versions of the min/max patterns implement exactly the operations
19503 ;;   min = (op1 < op2 ? op1 : op2)
19504 ;;   max = (!(op1 < op2) ? op1 : op2)
19505 ;; Their operands are not commutative, and thus they may be used in the
19506 ;; presence of -0.0 and NaN.
19508 (define_insn "*ieee_smin<mode>3"
19509   [(set (match_operand:MODEF 0 "register_operand" "=x")
19510         (unspec:MODEF
19511           [(match_operand:MODEF 1 "register_operand" "0")
19512            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19513          UNSPEC_IEEE_MIN))]
19514   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19515   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19516   [(set_attr "type" "sseadd")
19517    (set_attr "mode" "<MODE>")])
19519 (define_insn "*ieee_smax<mode>3"
19520   [(set (match_operand:MODEF 0 "register_operand" "=x")
19521         (unspec:MODEF
19522           [(match_operand:MODEF 1 "register_operand" "0")
19523            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19524          UNSPEC_IEEE_MAX))]
19525   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19526   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19527   [(set_attr "type" "sseadd")
19528    (set_attr "mode" "<MODE>")])
19530 ;; Make two stack loads independent:
19531 ;;   fld aa              fld aa
19532 ;;   fld %st(0)     ->   fld bb
19533 ;;   fmul bb             fmul %st(1), %st
19535 ;; Actually we only match the last two instructions for simplicity.
19536 (define_peephole2
19537   [(set (match_operand 0 "fp_register_operand" "")
19538         (match_operand 1 "fp_register_operand" ""))
19539    (set (match_dup 0)
19540         (match_operator 2 "binary_fp_operator"
19541            [(match_dup 0)
19542             (match_operand 3 "memory_operand" "")]))]
19543   "REGNO (operands[0]) != REGNO (operands[1])"
19544   [(set (match_dup 0) (match_dup 3))
19545    (set (match_dup 0) (match_dup 4))]
19547   ;; The % modifier is not operational anymore in peephole2's, so we have to
19548   ;; swap the operands manually in the case of addition and multiplication.
19549   "if (COMMUTATIVE_ARITH_P (operands[2]))
19550      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19551                                  operands[0], operands[1]);
19552    else
19553      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19554                                  operands[1], operands[0]);")
19556 ;; Conditional addition patterns
19557 (define_expand "add<mode>cc"
19558   [(match_operand:SWI 0 "register_operand" "")
19559    (match_operand 1 "comparison_operator" "")
19560    (match_operand:SWI 2 "register_operand" "")
19561    (match_operand:SWI 3 "const_int_operand" "")]
19562   ""
19563   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19566 ;; Misc patterns (?)
19568 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19569 ;; Otherwise there will be nothing to keep
19571 ;; [(set (reg ebp) (reg esp))]
19572 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19573 ;;  (clobber (eflags)]
19574 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19576 ;; in proper program order.
19577 (define_insn "pro_epilogue_adjust_stack_1"
19578   [(set (match_operand:SI 0 "register_operand" "=r,r")
19579         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19580                  (match_operand:SI 2 "immediate_operand" "i,i")))
19581    (clobber (reg:CC FLAGS_REG))
19582    (clobber (mem:BLK (scratch)))]
19583   "!TARGET_64BIT"
19585   switch (get_attr_type (insn))
19586     {
19587     case TYPE_IMOV:
19588       return "mov{l}\t{%1, %0|%0, %1}";
19590     case TYPE_ALU:
19591       if (CONST_INT_P (operands[2])
19592           && (INTVAL (operands[2]) == 128
19593               || (INTVAL (operands[2]) < 0
19594                   && INTVAL (operands[2]) != -128)))
19595         {
19596           operands[2] = GEN_INT (-INTVAL (operands[2]));
19597           return "sub{l}\t{%2, %0|%0, %2}";
19598         }
19599       return "add{l}\t{%2, %0|%0, %2}";
19601     case TYPE_LEA:
19602       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19603       return "lea{l}\t{%a2, %0|%0, %a2}";
19605     default:
19606       gcc_unreachable ();
19607     }
19609   [(set (attr "type")
19610         (cond [(eq_attr "alternative" "0")
19611                  (const_string "alu")
19612                (match_operand:SI 2 "const0_operand" "")
19613                  (const_string "imov")
19614               ]
19615               (const_string "lea")))
19616    (set_attr "mode" "SI")])
19618 (define_insn "pro_epilogue_adjust_stack_rex64"
19619   [(set (match_operand:DI 0 "register_operand" "=r,r")
19620         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19621                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19622    (clobber (reg:CC FLAGS_REG))
19623    (clobber (mem:BLK (scratch)))]
19624   "TARGET_64BIT"
19626   switch (get_attr_type (insn))
19627     {
19628     case TYPE_IMOV:
19629       return "mov{q}\t{%1, %0|%0, %1}";
19631     case TYPE_ALU:
19632       if (CONST_INT_P (operands[2])
19633           /* Avoid overflows.  */
19634           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19635           && (INTVAL (operands[2]) == 128
19636               || (INTVAL (operands[2]) < 0
19637                   && INTVAL (operands[2]) != -128)))
19638         {
19639           operands[2] = GEN_INT (-INTVAL (operands[2]));
19640           return "sub{q}\t{%2, %0|%0, %2}";
19641         }
19642       return "add{q}\t{%2, %0|%0, %2}";
19644     case TYPE_LEA:
19645       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19646       return "lea{q}\t{%a2, %0|%0, %a2}";
19648     default:
19649       gcc_unreachable ();
19650     }
19652   [(set (attr "type")
19653         (cond [(eq_attr "alternative" "0")
19654                  (const_string "alu")
19655                (match_operand:DI 2 "const0_operand" "")
19656                  (const_string "imov")
19657               ]
19658               (const_string "lea")))
19659    (set_attr "mode" "DI")])
19661 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19662   [(set (match_operand:DI 0 "register_operand" "=r,r")
19663         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19664                  (match_operand:DI 3 "immediate_operand" "i,i")))
19665    (use (match_operand:DI 2 "register_operand" "r,r"))
19666    (clobber (reg:CC FLAGS_REG))
19667    (clobber (mem:BLK (scratch)))]
19668   "TARGET_64BIT"
19670   switch (get_attr_type (insn))
19671     {
19672     case TYPE_ALU:
19673       return "add{q}\t{%2, %0|%0, %2}";
19675     case TYPE_LEA:
19676       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19677       return "lea{q}\t{%a2, %0|%0, %a2}";
19679     default:
19680       gcc_unreachable ();
19681     }
19683   [(set_attr "type" "alu,lea")
19684    (set_attr "mode" "DI")])
19686 (define_insn "allocate_stack_worker_32"
19687   [(set (match_operand:SI 0 "register_operand" "+a")
19688         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19689    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19690    (clobber (reg:CC FLAGS_REG))]
19691   "!TARGET_64BIT && TARGET_STACK_PROBE"
19692   "call\t___chkstk"
19693   [(set_attr "type" "multi")
19694    (set_attr "length" "5")])
19696 (define_insn "allocate_stack_worker_64"
19697   [(set (match_operand:DI 0 "register_operand" "+a")
19698         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19699    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19700    (clobber (reg:DI R10_REG))
19701    (clobber (reg:DI R11_REG))
19702    (clobber (reg:CC FLAGS_REG))]
19703   "TARGET_64BIT && TARGET_STACK_PROBE"
19704   "call\t___chkstk"
19705   [(set_attr "type" "multi")
19706    (set_attr "length" "5")])
19708 (define_expand "allocate_stack"
19709   [(match_operand 0 "register_operand" "")
19710    (match_operand 1 "general_operand" "")]
19711   "TARGET_STACK_PROBE"
19713   rtx x;
19715 #ifndef CHECK_STACK_LIMIT
19716 #define CHECK_STACK_LIMIT 0
19717 #endif
19719   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19720       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19721     {
19722       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19723                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19724       if (x != stack_pointer_rtx)
19725         emit_move_insn (stack_pointer_rtx, x);
19726     }
19727   else
19728     {
19729       x = copy_to_mode_reg (Pmode, operands[1]);
19730       if (TARGET_64BIT)
19731         x = gen_allocate_stack_worker_64 (x);
19732       else
19733         x = gen_allocate_stack_worker_32 (x);
19734       emit_insn (x);
19735     }
19737   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19738   DONE;
19741 (define_expand "builtin_setjmp_receiver"
19742   [(label_ref (match_operand 0 "" ""))]
19743   "!TARGET_64BIT && flag_pic"
19745   if (TARGET_MACHO)
19746     {
19747       rtx xops[3];
19748       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19749       rtx label_rtx = gen_label_rtx ();
19750       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19751       xops[0] = xops[1] = picreg;
19752       xops[2] = gen_rtx_CONST (SImode,
19753                   gen_rtx_MINUS (SImode,
19754                     gen_rtx_LABEL_REF (SImode, label_rtx),
19755                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19756       ix86_expand_binary_operator (MINUS, SImode, xops);
19757     }
19758   else
19759     emit_insn (gen_set_got (pic_offset_table_rtx));
19760   DONE;
19763 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19765 (define_split
19766   [(set (match_operand 0 "register_operand" "")
19767         (match_operator 3 "promotable_binary_operator"
19768            [(match_operand 1 "register_operand" "")
19769             (match_operand 2 "aligned_operand" "")]))
19770    (clobber (reg:CC FLAGS_REG))]
19771   "! TARGET_PARTIAL_REG_STALL && reload_completed
19772    && ((GET_MODE (operands[0]) == HImode
19773         && ((!optimize_size && !TARGET_FAST_PREFIX)
19774             /* ??? next two lines just !satisfies_constraint_K (...) */
19775             || !CONST_INT_P (operands[2])
19776             || satisfies_constraint_K (operands[2])))
19777        || (GET_MODE (operands[0]) == QImode
19778            && (TARGET_PROMOTE_QImode || optimize_size)))"
19779   [(parallel [(set (match_dup 0)
19780                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19781               (clobber (reg:CC FLAGS_REG))])]
19782   "operands[0] = gen_lowpart (SImode, operands[0]);
19783    operands[1] = gen_lowpart (SImode, operands[1]);
19784    if (GET_CODE (operands[3]) != ASHIFT)
19785      operands[2] = gen_lowpart (SImode, operands[2]);
19786    PUT_MODE (operands[3], SImode);")
19788 ; Promote the QImode tests, as i386 has encoding of the AND
19789 ; instruction with 32-bit sign-extended immediate and thus the
19790 ; instruction size is unchanged, except in the %eax case for
19791 ; which it is increased by one byte, hence the ! optimize_size.
19792 (define_split
19793   [(set (match_operand 0 "flags_reg_operand" "")
19794         (match_operator 2 "compare_operator"
19795           [(and (match_operand 3 "aligned_operand" "")
19796                 (match_operand 4 "const_int_operand" ""))
19797            (const_int 0)]))
19798    (set (match_operand 1 "register_operand" "")
19799         (and (match_dup 3) (match_dup 4)))]
19800   "! TARGET_PARTIAL_REG_STALL && reload_completed
19801    && ! optimize_size
19802    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19803        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19804    /* Ensure that the operand will remain sign-extended immediate.  */
19805    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19806   [(parallel [(set (match_dup 0)
19807                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19808                                     (const_int 0)]))
19809               (set (match_dup 1)
19810                    (and:SI (match_dup 3) (match_dup 4)))])]
19812   operands[4]
19813     = gen_int_mode (INTVAL (operands[4])
19814                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19815   operands[1] = gen_lowpart (SImode, operands[1]);
19816   operands[3] = gen_lowpart (SImode, operands[3]);
19819 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19820 ; the TEST instruction with 32-bit sign-extended immediate and thus
19821 ; the instruction size would at least double, which is not what we
19822 ; want even with ! optimize_size.
19823 (define_split
19824   [(set (match_operand 0 "flags_reg_operand" "")
19825         (match_operator 1 "compare_operator"
19826           [(and (match_operand:HI 2 "aligned_operand" "")
19827                 (match_operand:HI 3 "const_int_operand" ""))
19828            (const_int 0)]))]
19829   "! TARGET_PARTIAL_REG_STALL && reload_completed
19830    && ! TARGET_FAST_PREFIX
19831    && ! optimize_size
19832    /* Ensure that the operand will remain sign-extended immediate.  */
19833    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19834   [(set (match_dup 0)
19835         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19836                          (const_int 0)]))]
19838   operands[3]
19839     = gen_int_mode (INTVAL (operands[3])
19840                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19841   operands[2] = gen_lowpart (SImode, operands[2]);
19844 (define_split
19845   [(set (match_operand 0 "register_operand" "")
19846         (neg (match_operand 1 "register_operand" "")))
19847    (clobber (reg:CC FLAGS_REG))]
19848   "! TARGET_PARTIAL_REG_STALL && reload_completed
19849    && (GET_MODE (operands[0]) == HImode
19850        || (GET_MODE (operands[0]) == QImode
19851            && (TARGET_PROMOTE_QImode || optimize_size)))"
19852   [(parallel [(set (match_dup 0)
19853                    (neg:SI (match_dup 1)))
19854               (clobber (reg:CC FLAGS_REG))])]
19855   "operands[0] = gen_lowpart (SImode, operands[0]);
19856    operands[1] = gen_lowpart (SImode, operands[1]);")
19858 (define_split
19859   [(set (match_operand 0 "register_operand" "")
19860         (not (match_operand 1 "register_operand" "")))]
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   [(set (match_dup 0)
19866         (not:SI (match_dup 1)))]
19867   "operands[0] = gen_lowpart (SImode, operands[0]);
19868    operands[1] = gen_lowpart (SImode, operands[1]);")
19870 (define_split
19871   [(set (match_operand 0 "register_operand" "")
19872         (if_then_else (match_operator 1 "comparison_operator"
19873                                 [(reg FLAGS_REG) (const_int 0)])
19874                       (match_operand 2 "register_operand" "")
19875                       (match_operand 3 "register_operand" "")))]
19876   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19877    && (GET_MODE (operands[0]) == HImode
19878        || (GET_MODE (operands[0]) == QImode
19879            && (TARGET_PROMOTE_QImode || optimize_size)))"
19880   [(set (match_dup 0)
19881         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19882   "operands[0] = gen_lowpart (SImode, operands[0]);
19883    operands[2] = gen_lowpart (SImode, operands[2]);
19884    operands[3] = gen_lowpart (SImode, operands[3]);")
19887 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19888 ;; transform a complex memory operation into two memory to register operations.
19890 ;; Don't push memory operands
19891 (define_peephole2
19892   [(set (match_operand:SI 0 "push_operand" "")
19893         (match_operand:SI 1 "memory_operand" ""))
19894    (match_scratch:SI 2 "r")]
19895   "!optimize_size && !TARGET_PUSH_MEMORY
19896    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19897   [(set (match_dup 2) (match_dup 1))
19898    (set (match_dup 0) (match_dup 2))]
19899   "")
19901 (define_peephole2
19902   [(set (match_operand:DI 0 "push_operand" "")
19903         (match_operand:DI 1 "memory_operand" ""))
19904    (match_scratch:DI 2 "r")]
19905   "!optimize_size && !TARGET_PUSH_MEMORY
19906    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19907   [(set (match_dup 2) (match_dup 1))
19908    (set (match_dup 0) (match_dup 2))]
19909   "")
19911 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19912 ;; SImode pushes.
19913 (define_peephole2
19914   [(set (match_operand:SF 0 "push_operand" "")
19915         (match_operand:SF 1 "memory_operand" ""))
19916    (match_scratch:SF 2 "r")]
19917   "!optimize_size && !TARGET_PUSH_MEMORY
19918    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19919   [(set (match_dup 2) (match_dup 1))
19920    (set (match_dup 0) (match_dup 2))]
19921   "")
19923 (define_peephole2
19924   [(set (match_operand:HI 0 "push_operand" "")
19925         (match_operand:HI 1 "memory_operand" ""))
19926    (match_scratch:HI 2 "r")]
19927   "!optimize_size && !TARGET_PUSH_MEMORY
19928    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19929   [(set (match_dup 2) (match_dup 1))
19930    (set (match_dup 0) (match_dup 2))]
19931   "")
19933 (define_peephole2
19934   [(set (match_operand:QI 0 "push_operand" "")
19935         (match_operand:QI 1 "memory_operand" ""))
19936    (match_scratch:QI 2 "q")]
19937   "!optimize_size && !TARGET_PUSH_MEMORY
19938    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19939   [(set (match_dup 2) (match_dup 1))
19940    (set (match_dup 0) (match_dup 2))]
19941   "")
19943 ;; Don't move an immediate directly to memory when the instruction
19944 ;; gets too big.
19945 (define_peephole2
19946   [(match_scratch:SI 1 "r")
19947    (set (match_operand:SI 0 "memory_operand" "")
19948         (const_int 0))]
19949   "! optimize_size
19950    && ! TARGET_USE_MOV0
19951    && TARGET_SPLIT_LONG_MOVES
19952    && get_attr_length (insn) >= ix86_cost->large_insn
19953    && peep2_regno_dead_p (0, FLAGS_REG)"
19954   [(parallel [(set (match_dup 1) (const_int 0))
19955               (clobber (reg:CC FLAGS_REG))])
19956    (set (match_dup 0) (match_dup 1))]
19957   "")
19959 (define_peephole2
19960   [(match_scratch:HI 1 "r")
19961    (set (match_operand:HI 0 "memory_operand" "")
19962         (const_int 0))]
19963   "! optimize_size
19964    && ! TARGET_USE_MOV0
19965    && TARGET_SPLIT_LONG_MOVES
19966    && get_attr_length (insn) >= ix86_cost->large_insn
19967    && peep2_regno_dead_p (0, FLAGS_REG)"
19968   [(parallel [(set (match_dup 2) (const_int 0))
19969               (clobber (reg:CC FLAGS_REG))])
19970    (set (match_dup 0) (match_dup 1))]
19971   "operands[2] = gen_lowpart (SImode, operands[1]);")
19973 (define_peephole2
19974   [(match_scratch:QI 1 "q")
19975    (set (match_operand:QI 0 "memory_operand" "")
19976         (const_int 0))]
19977   "! optimize_size
19978    && ! TARGET_USE_MOV0
19979    && TARGET_SPLIT_LONG_MOVES
19980    && get_attr_length (insn) >= ix86_cost->large_insn
19981    && peep2_regno_dead_p (0, FLAGS_REG)"
19982   [(parallel [(set (match_dup 2) (const_int 0))
19983               (clobber (reg:CC FLAGS_REG))])
19984    (set (match_dup 0) (match_dup 1))]
19985   "operands[2] = gen_lowpart (SImode, operands[1]);")
19987 (define_peephole2
19988   [(match_scratch:SI 2 "r")
19989    (set (match_operand:SI 0 "memory_operand" "")
19990         (match_operand:SI 1 "immediate_operand" ""))]
19991   "! optimize_size
19992    && TARGET_SPLIT_LONG_MOVES
19993    && get_attr_length (insn) >= ix86_cost->large_insn"
19994   [(set (match_dup 2) (match_dup 1))
19995    (set (match_dup 0) (match_dup 2))]
19996   "")
19998 (define_peephole2
19999   [(match_scratch:HI 2 "r")
20000    (set (match_operand:HI 0 "memory_operand" "")
20001         (match_operand:HI 1 "immediate_operand" ""))]
20002   "! optimize_size
20003    && TARGET_SPLIT_LONG_MOVES
20004    && get_attr_length (insn) >= ix86_cost->large_insn"
20005   [(set (match_dup 2) (match_dup 1))
20006    (set (match_dup 0) (match_dup 2))]
20007   "")
20009 (define_peephole2
20010   [(match_scratch:QI 2 "q")
20011    (set (match_operand:QI 0 "memory_operand" "")
20012         (match_operand:QI 1 "immediate_operand" ""))]
20013   "! optimize_size
20014    && TARGET_SPLIT_LONG_MOVES
20015    && get_attr_length (insn) >= ix86_cost->large_insn"
20016   [(set (match_dup 2) (match_dup 1))
20017    (set (match_dup 0) (match_dup 2))]
20018   "")
20020 ;; Don't compare memory with zero, load and use a test instead.
20021 (define_peephole2
20022   [(set (match_operand 0 "flags_reg_operand" "")
20023         (match_operator 1 "compare_operator"
20024           [(match_operand:SI 2 "memory_operand" "")
20025            (const_int 0)]))
20026    (match_scratch:SI 3 "r")]
20027   " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20028   [(set (match_dup 3) (match_dup 2))
20029    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20030   "")
20032 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20033 ;; Don't split NOTs with a displacement operand, because resulting XOR
20034 ;; will not be pairable anyway.
20036 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20037 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20038 ;; so this split helps here as well.
20040 ;; Note: Can't do this as a regular split because we can't get proper
20041 ;; lifetime information then.
20043 (define_peephole2
20044   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20045         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20046   "!optimize_size
20047    && ((TARGET_NOT_UNPAIRABLE
20048         && (!MEM_P (operands[0])
20049             || !memory_displacement_operand (operands[0], SImode)))
20050        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20051    && peep2_regno_dead_p (0, FLAGS_REG)"
20052   [(parallel [(set (match_dup 0)
20053                    (xor:SI (match_dup 1) (const_int -1)))
20054               (clobber (reg:CC FLAGS_REG))])]
20055   "")
20057 (define_peephole2
20058   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20059         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20060   "!optimize_size
20061    && ((TARGET_NOT_UNPAIRABLE
20062         && (!MEM_P (operands[0])
20063             || !memory_displacement_operand (operands[0], HImode)))
20064        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20065    && peep2_regno_dead_p (0, FLAGS_REG)"
20066   [(parallel [(set (match_dup 0)
20067                    (xor:HI (match_dup 1) (const_int -1)))
20068               (clobber (reg:CC FLAGS_REG))])]
20069   "")
20071 (define_peephole2
20072   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20073         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20074   "!optimize_size
20075    && ((TARGET_NOT_UNPAIRABLE
20076         && (!MEM_P (operands[0])
20077             || !memory_displacement_operand (operands[0], QImode)))
20078        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20079    && peep2_regno_dead_p (0, FLAGS_REG)"
20080   [(parallel [(set (match_dup 0)
20081                    (xor:QI (match_dup 1) (const_int -1)))
20082               (clobber (reg:CC FLAGS_REG))])]
20083   "")
20085 ;; Non pairable "test imm, reg" instructions can be translated to
20086 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20087 ;; byte opcode instead of two, have a short form for byte operands),
20088 ;; so do it for other CPUs as well.  Given that the value was dead,
20089 ;; this should not create any new dependencies.  Pass on the sub-word
20090 ;; versions if we're concerned about partial register stalls.
20092 (define_peephole2
20093   [(set (match_operand 0 "flags_reg_operand" "")
20094         (match_operator 1 "compare_operator"
20095           [(and:SI (match_operand:SI 2 "register_operand" "")
20096                    (match_operand:SI 3 "immediate_operand" ""))
20097            (const_int 0)]))]
20098   "ix86_match_ccmode (insn, CCNOmode)
20099    && (true_regnum (operands[2]) != AX_REG
20100        || satisfies_constraint_K (operands[3]))
20101    && peep2_reg_dead_p (1, operands[2])"
20102   [(parallel
20103      [(set (match_dup 0)
20104            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20105                             (const_int 0)]))
20106       (set (match_dup 2)
20107            (and:SI (match_dup 2) (match_dup 3)))])]
20108   "")
20110 ;; We don't need to handle HImode case, because it will be promoted to SImode
20111 ;; on ! TARGET_PARTIAL_REG_STALL
20113 (define_peephole2
20114   [(set (match_operand 0 "flags_reg_operand" "")
20115         (match_operator 1 "compare_operator"
20116           [(and:QI (match_operand:QI 2 "register_operand" "")
20117                    (match_operand:QI 3 "immediate_operand" ""))
20118            (const_int 0)]))]
20119   "! TARGET_PARTIAL_REG_STALL
20120    && ix86_match_ccmode (insn, CCNOmode)
20121    && true_regnum (operands[2]) != AX_REG
20122    && peep2_reg_dead_p (1, operands[2])"
20123   [(parallel
20124      [(set (match_dup 0)
20125            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20126                             (const_int 0)]))
20127       (set (match_dup 2)
20128            (and:QI (match_dup 2) (match_dup 3)))])]
20129   "")
20131 (define_peephole2
20132   [(set (match_operand 0 "flags_reg_operand" "")
20133         (match_operator 1 "compare_operator"
20134           [(and:SI
20135              (zero_extract:SI
20136                (match_operand 2 "ext_register_operand" "")
20137                (const_int 8)
20138                (const_int 8))
20139              (match_operand 3 "const_int_operand" ""))
20140            (const_int 0)]))]
20141   "! TARGET_PARTIAL_REG_STALL
20142    && ix86_match_ccmode (insn, CCNOmode)
20143    && true_regnum (operands[2]) != AX_REG
20144    && peep2_reg_dead_p (1, operands[2])"
20145   [(parallel [(set (match_dup 0)
20146                    (match_op_dup 1
20147                      [(and:SI
20148                         (zero_extract:SI
20149                           (match_dup 2)
20150                           (const_int 8)
20151                           (const_int 8))
20152                         (match_dup 3))
20153                       (const_int 0)]))
20154               (set (zero_extract:SI (match_dup 2)
20155                                     (const_int 8)
20156                                     (const_int 8))
20157                    (and:SI
20158                      (zero_extract:SI
20159                        (match_dup 2)
20160                        (const_int 8)
20161                        (const_int 8))
20162                      (match_dup 3)))])]
20163   "")
20165 ;; Don't do logical operations with memory inputs.
20166 (define_peephole2
20167   [(match_scratch:SI 2 "r")
20168    (parallel [(set (match_operand:SI 0 "register_operand" "")
20169                    (match_operator:SI 3 "arith_or_logical_operator"
20170                      [(match_dup 0)
20171                       (match_operand:SI 1 "memory_operand" "")]))
20172               (clobber (reg:CC FLAGS_REG))])]
20173   "! optimize_size && ! TARGET_READ_MODIFY"
20174   [(set (match_dup 2) (match_dup 1))
20175    (parallel [(set (match_dup 0)
20176                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20177               (clobber (reg:CC FLAGS_REG))])]
20178   "")
20180 (define_peephole2
20181   [(match_scratch:SI 2 "r")
20182    (parallel [(set (match_operand:SI 0 "register_operand" "")
20183                    (match_operator:SI 3 "arith_or_logical_operator"
20184                      [(match_operand:SI 1 "memory_operand" "")
20185                       (match_dup 0)]))
20186               (clobber (reg:CC FLAGS_REG))])]
20187   "! optimize_size && ! TARGET_READ_MODIFY"
20188   [(set (match_dup 2) (match_dup 1))
20189    (parallel [(set (match_dup 0)
20190                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20191               (clobber (reg:CC FLAGS_REG))])]
20192   "")
20194 ; Don't do logical operations with memory outputs
20196 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20197 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20198 ; the same decoder scheduling characteristics as the original.
20200 (define_peephole2
20201   [(match_scratch:SI 2 "r")
20202    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20203                    (match_operator:SI 3 "arith_or_logical_operator"
20204                      [(match_dup 0)
20205                       (match_operand:SI 1 "nonmemory_operand" "")]))
20206               (clobber (reg:CC FLAGS_REG))])]
20207   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20208   [(set (match_dup 2) (match_dup 0))
20209    (parallel [(set (match_dup 2)
20210                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20211               (clobber (reg:CC FLAGS_REG))])
20212    (set (match_dup 0) (match_dup 2))]
20213   "")
20215 (define_peephole2
20216   [(match_scratch:SI 2 "r")
20217    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20218                    (match_operator:SI 3 "arith_or_logical_operator"
20219                      [(match_operand:SI 1 "nonmemory_operand" "")
20220                       (match_dup 0)]))
20221               (clobber (reg:CC FLAGS_REG))])]
20222   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20223   [(set (match_dup 2) (match_dup 0))
20224    (parallel [(set (match_dup 2)
20225                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20226               (clobber (reg:CC FLAGS_REG))])
20227    (set (match_dup 0) (match_dup 2))]
20228   "")
20230 ;; Attempt to always use XOR for zeroing registers.
20231 (define_peephole2
20232   [(set (match_operand 0 "register_operand" "")
20233         (match_operand 1 "const0_operand" ""))]
20234   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20235    && (! TARGET_USE_MOV0 || optimize_size)
20236    && GENERAL_REG_P (operands[0])
20237    && peep2_regno_dead_p (0, FLAGS_REG)"
20238   [(parallel [(set (match_dup 0) (const_int 0))
20239               (clobber (reg:CC FLAGS_REG))])]
20241   operands[0] = gen_lowpart (word_mode, operands[0]);
20244 (define_peephole2
20245   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20246         (const_int 0))]
20247   "(GET_MODE (operands[0]) == QImode
20248     || GET_MODE (operands[0]) == HImode)
20249    && (! TARGET_USE_MOV0 || optimize_size)
20250    && peep2_regno_dead_p (0, FLAGS_REG)"
20251   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20252               (clobber (reg:CC FLAGS_REG))])])
20254 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20255 (define_peephole2
20256   [(set (match_operand 0 "register_operand" "")
20257         (const_int -1))]
20258   "(GET_MODE (operands[0]) == HImode
20259     || GET_MODE (operands[0]) == SImode
20260     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20261    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20262    && peep2_regno_dead_p (0, FLAGS_REG)"
20263   [(parallel [(set (match_dup 0) (const_int -1))
20264               (clobber (reg:CC FLAGS_REG))])]
20265   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20266                               operands[0]);")
20268 ;; Attempt to convert simple leas to adds. These can be created by
20269 ;; move expanders.
20270 (define_peephole2
20271   [(set (match_operand:SI 0 "register_operand" "")
20272         (plus:SI (match_dup 0)
20273                  (match_operand:SI 1 "nonmemory_operand" "")))]
20274   "peep2_regno_dead_p (0, FLAGS_REG)"
20275   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20276               (clobber (reg:CC FLAGS_REG))])]
20277   "")
20279 (define_peephole2
20280   [(set (match_operand:SI 0 "register_operand" "")
20281         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20282                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20283   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20284   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20285               (clobber (reg:CC FLAGS_REG))])]
20286   "operands[2] = gen_lowpart (SImode, operands[2]);")
20288 (define_peephole2
20289   [(set (match_operand:DI 0 "register_operand" "")
20290         (plus:DI (match_dup 0)
20291                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20292   "peep2_regno_dead_p (0, FLAGS_REG)"
20293   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20294               (clobber (reg:CC FLAGS_REG))])]
20295   "")
20297 (define_peephole2
20298   [(set (match_operand:SI 0 "register_operand" "")
20299         (mult:SI (match_dup 0)
20300                  (match_operand:SI 1 "const_int_operand" "")))]
20301   "exact_log2 (INTVAL (operands[1])) >= 0
20302    && peep2_regno_dead_p (0, FLAGS_REG)"
20303   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20304               (clobber (reg:CC FLAGS_REG))])]
20305   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20307 (define_peephole2
20308   [(set (match_operand:DI 0 "register_operand" "")
20309         (mult:DI (match_dup 0)
20310                  (match_operand:DI 1 "const_int_operand" "")))]
20311   "exact_log2 (INTVAL (operands[1])) >= 0
20312    && peep2_regno_dead_p (0, FLAGS_REG)"
20313   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20314               (clobber (reg:CC FLAGS_REG))])]
20315   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20317 (define_peephole2
20318   [(set (match_operand:SI 0 "register_operand" "")
20319         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20320                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20321   "exact_log2 (INTVAL (operands[2])) >= 0
20322    && REGNO (operands[0]) == REGNO (operands[1])
20323    && peep2_regno_dead_p (0, FLAGS_REG)"
20324   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20325               (clobber (reg:CC FLAGS_REG))])]
20326   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20328 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20329 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20330 ;; many CPUs it is also faster, since special hardware to avoid esp
20331 ;; dependencies is present.
20333 ;; While some of these conversions may be done using splitters, we use peepholes
20334 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20336 ;; Convert prologue esp subtractions to push.
20337 ;; We need register to push.  In order to keep verify_flow_info happy we have
20338 ;; two choices
20339 ;; - use scratch and clobber it in order to avoid dependencies
20340 ;; - use already live register
20341 ;; We can't use the second way right now, since there is no reliable way how to
20342 ;; verify that given register is live.  First choice will also most likely in
20343 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20344 ;; call clobbered registers are dead.  We may want to use base pointer as an
20345 ;; alternative when no register is available later.
20347 (define_peephole2
20348   [(match_scratch:SI 0 "r")
20349    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20350               (clobber (reg:CC FLAGS_REG))
20351               (clobber (mem:BLK (scratch)))])]
20352   "optimize_size || !TARGET_SUB_ESP_4"
20353   [(clobber (match_dup 0))
20354    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20355               (clobber (mem:BLK (scratch)))])])
20357 (define_peephole2
20358   [(match_scratch:SI 0 "r")
20359    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20360               (clobber (reg:CC FLAGS_REG))
20361               (clobber (mem:BLK (scratch)))])]
20362   "optimize_size || !TARGET_SUB_ESP_8"
20363   [(clobber (match_dup 0))
20364    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20365    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20366               (clobber (mem:BLK (scratch)))])])
20368 ;; Convert esp subtractions to push.
20369 (define_peephole2
20370   [(match_scratch:SI 0 "r")
20371    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20372               (clobber (reg:CC FLAGS_REG))])]
20373   "optimize_size || !TARGET_SUB_ESP_4"
20374   [(clobber (match_dup 0))
20375    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20377 (define_peephole2
20378   [(match_scratch:SI 0 "r")
20379    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20380               (clobber (reg:CC FLAGS_REG))])]
20381   "optimize_size || !TARGET_SUB_ESP_8"
20382   [(clobber (match_dup 0))
20383    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20384    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20386 ;; Convert epilogue deallocator to pop.
20387 (define_peephole2
20388   [(match_scratch:SI 0 "r")
20389    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20390               (clobber (reg:CC FLAGS_REG))
20391               (clobber (mem:BLK (scratch)))])]
20392   "optimize_size || !TARGET_ADD_ESP_4"
20393   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20394               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20395               (clobber (mem:BLK (scratch)))])]
20396   "")
20398 ;; Two pops case is tricky, since pop causes dependency on destination register.
20399 ;; We use two registers if available.
20400 (define_peephole2
20401   [(match_scratch:SI 0 "r")
20402    (match_scratch:SI 1 "r")
20403    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20404               (clobber (reg:CC FLAGS_REG))
20405               (clobber (mem:BLK (scratch)))])]
20406   "optimize_size || !TARGET_ADD_ESP_8"
20407   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20408               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20409               (clobber (mem:BLK (scratch)))])
20410    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20411               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20412   "")
20414 (define_peephole2
20415   [(match_scratch:SI 0 "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"
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 0) (mem:SI (reg:SI SP_REG)))
20424               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20425   "")
20427 ;; Convert esp additions to pop.
20428 (define_peephole2
20429   [(match_scratch:SI 0 "r")
20430    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20431               (clobber (reg:CC FLAGS_REG))])]
20432   ""
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   "")
20437 ;; Two pops case is tricky, since pop causes dependency on destination register.
20438 ;; We use two registers if available.
20439 (define_peephole2
20440   [(match_scratch:SI 0 "r")
20441    (match_scratch:SI 1 "r")
20442    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20443               (clobber (reg:CC FLAGS_REG))])]
20444   ""
20445   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20446               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20447    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20448               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20449   "")
20451 (define_peephole2
20452   [(match_scratch:SI 0 "r")
20453    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20454               (clobber (reg:CC FLAGS_REG))])]
20455   "optimize_size"
20456   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20457               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
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   "")
20462 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20463 ;; required and register dies.  Similarly for 128 to plus -128.
20464 (define_peephole2
20465   [(set (match_operand 0 "flags_reg_operand" "")
20466         (match_operator 1 "compare_operator"
20467           [(match_operand 2 "register_operand" "")
20468            (match_operand 3 "const_int_operand" "")]))]
20469   "(INTVAL (operands[3]) == -1
20470     || INTVAL (operands[3]) == 1
20471     || INTVAL (operands[3]) == 128)
20472    && ix86_match_ccmode (insn, CCGCmode)
20473    && peep2_reg_dead_p (1, operands[2])"
20474   [(parallel [(set (match_dup 0)
20475                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20476               (clobber (match_dup 2))])]
20477   "")
20479 (define_peephole2
20480   [(match_scratch:DI 0 "r")
20481    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20482               (clobber (reg:CC FLAGS_REG))
20483               (clobber (mem:BLK (scratch)))])]
20484   "optimize_size || !TARGET_SUB_ESP_4"
20485   [(clobber (match_dup 0))
20486    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20487               (clobber (mem:BLK (scratch)))])])
20489 (define_peephole2
20490   [(match_scratch:DI 0 "r")
20491    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20492               (clobber (reg:CC FLAGS_REG))
20493               (clobber (mem:BLK (scratch)))])]
20494   "optimize_size || !TARGET_SUB_ESP_8"
20495   [(clobber (match_dup 0))
20496    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20497    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20498               (clobber (mem:BLK (scratch)))])])
20500 ;; Convert esp subtractions to push.
20501 (define_peephole2
20502   [(match_scratch:DI 0 "r")
20503    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20504               (clobber (reg:CC FLAGS_REG))])]
20505   "optimize_size || !TARGET_SUB_ESP_4"
20506   [(clobber (match_dup 0))
20507    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20509 (define_peephole2
20510   [(match_scratch:DI 0 "r")
20511    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20512               (clobber (reg:CC FLAGS_REG))])]
20513   "optimize_size || !TARGET_SUB_ESP_8"
20514   [(clobber (match_dup 0))
20515    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20516    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20518 ;; Convert epilogue deallocator to pop.
20519 (define_peephole2
20520   [(match_scratch:DI 0 "r")
20521    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20522               (clobber (reg:CC FLAGS_REG))
20523               (clobber (mem:BLK (scratch)))])]
20524   "optimize_size || !TARGET_ADD_ESP_4"
20525   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20526               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20527               (clobber (mem:BLK (scratch)))])]
20528   "")
20530 ;; Two pops case is tricky, since pop causes dependency on destination register.
20531 ;; We use two registers if available.
20532 (define_peephole2
20533   [(match_scratch:DI 0 "r")
20534    (match_scratch:DI 1 "r")
20535    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20536               (clobber (reg:CC FLAGS_REG))
20537               (clobber (mem:BLK (scratch)))])]
20538   "optimize_size || !TARGET_ADD_ESP_8"
20539   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20540               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20541               (clobber (mem:BLK (scratch)))])
20542    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20543               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20544   "")
20546 (define_peephole2
20547   [(match_scratch:DI 0 "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"
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 0) (mem:DI (reg:DI SP_REG)))
20556               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20557   "")
20559 ;; Convert esp additions to pop.
20560 (define_peephole2
20561   [(match_scratch:DI 0 "r")
20562    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20563               (clobber (reg:CC FLAGS_REG))])]
20564   ""
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   "")
20569 ;; Two pops case is tricky, since pop causes dependency on destination register.
20570 ;; We use two registers if available.
20571 (define_peephole2
20572   [(match_scratch:DI 0 "r")
20573    (match_scratch:DI 1 "r")
20574    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20575               (clobber (reg:CC FLAGS_REG))])]
20576   ""
20577   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20578               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20579    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20580               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20581   "")
20583 (define_peephole2
20584   [(match_scratch:DI 0 "r")
20585    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20586               (clobber (reg:CC FLAGS_REG))])]
20587   "optimize_size"
20588   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20589               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
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   "")
20594 ;; Convert imul by three, five and nine into lea
20595 (define_peephole2
20596   [(parallel
20597     [(set (match_operand:SI 0 "register_operand" "")
20598           (mult:SI (match_operand:SI 1 "register_operand" "")
20599                    (match_operand:SI 2 "const_int_operand" "")))
20600      (clobber (reg:CC FLAGS_REG))])]
20601   "INTVAL (operands[2]) == 3
20602    || INTVAL (operands[2]) == 5
20603    || INTVAL (operands[2]) == 9"
20604   [(set (match_dup 0)
20605         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20606                  (match_dup 1)))]
20607   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20609 (define_peephole2
20610   [(parallel
20611     [(set (match_operand:SI 0 "register_operand" "")
20612           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20613                    (match_operand:SI 2 "const_int_operand" "")))
20614      (clobber (reg:CC FLAGS_REG))])]
20615   "!optimize_size
20616    && (INTVAL (operands[2]) == 3
20617        || INTVAL (operands[2]) == 5
20618        || INTVAL (operands[2]) == 9)"
20619   [(set (match_dup 0) (match_dup 1))
20620    (set (match_dup 0)
20621         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20622                  (match_dup 0)))]
20623   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20625 (define_peephole2
20626   [(parallel
20627     [(set (match_operand:DI 0 "register_operand" "")
20628           (mult:DI (match_operand:DI 1 "register_operand" "")
20629                    (match_operand:DI 2 "const_int_operand" "")))
20630      (clobber (reg:CC FLAGS_REG))])]
20631   "TARGET_64BIT
20632    && (INTVAL (operands[2]) == 3
20633        || INTVAL (operands[2]) == 5
20634        || INTVAL (operands[2]) == 9)"
20635   [(set (match_dup 0)
20636         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20637                  (match_dup 1)))]
20638   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20640 (define_peephole2
20641   [(parallel
20642     [(set (match_operand:DI 0 "register_operand" "")
20643           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20644                    (match_operand:DI 2 "const_int_operand" "")))
20645      (clobber (reg:CC FLAGS_REG))])]
20646   "TARGET_64BIT
20647    && !optimize_size
20648    && (INTVAL (operands[2]) == 3
20649        || INTVAL (operands[2]) == 5
20650        || INTVAL (operands[2]) == 9)"
20651   [(set (match_dup 0) (match_dup 1))
20652    (set (match_dup 0)
20653         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20654                  (match_dup 0)))]
20655   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20657 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20658 ;; imul $32bit_imm, reg, reg is direct decoded.
20659 (define_peephole2
20660   [(match_scratch:DI 3 "r")
20661    (parallel [(set (match_operand:DI 0 "register_operand" "")
20662                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20663                             (match_operand:DI 2 "immediate_operand" "")))
20664               (clobber (reg:CC FLAGS_REG))])]
20665   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20666    && !satisfies_constraint_K (operands[2])"
20667   [(set (match_dup 3) (match_dup 1))
20668    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20669               (clobber (reg:CC FLAGS_REG))])]
20672 (define_peephole2
20673   [(match_scratch:SI 3 "r")
20674    (parallel [(set (match_operand:SI 0 "register_operand" "")
20675                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20676                             (match_operand:SI 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:SI (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:DI 0 "register_operand" "")
20688                    (zero_extend:DI
20689                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20690                               (match_operand:SI 2 "immediate_operand" ""))))
20691               (clobber (reg:CC FLAGS_REG))])]
20692   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20693    && !satisfies_constraint_K (operands[2])"
20694   [(set (match_dup 3) (match_dup 1))
20695    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20696               (clobber (reg:CC FLAGS_REG))])]
20699 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20700 ;; Convert it into imul reg, reg
20701 ;; It would be better to force assembler to encode instruction using long
20702 ;; immediate, but there is apparently no way to do so.
20703 (define_peephole2
20704   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20705                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20706                             (match_operand:DI 2 "const_int_operand" "")))
20707               (clobber (reg:CC FLAGS_REG))])
20708    (match_scratch:DI 3 "r")]
20709   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20710    && satisfies_constraint_K (operands[2])"
20711   [(set (match_dup 3) (match_dup 2))
20712    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20713               (clobber (reg:CC FLAGS_REG))])]
20715   if (!rtx_equal_p (operands[0], operands[1]))
20716     emit_move_insn (operands[0], operands[1]);
20719 (define_peephole2
20720   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20721                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20722                             (match_operand:SI 2 "const_int_operand" "")))
20723               (clobber (reg:CC FLAGS_REG))])
20724    (match_scratch:SI 3 "r")]
20725   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20726    && satisfies_constraint_K (operands[2])"
20727   [(set (match_dup 3) (match_dup 2))
20728    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20729               (clobber (reg:CC FLAGS_REG))])]
20731   if (!rtx_equal_p (operands[0], operands[1]))
20732     emit_move_insn (operands[0], operands[1]);
20735 (define_peephole2
20736   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20737                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20738                             (match_operand:HI 2 "immediate_operand" "")))
20739               (clobber (reg:CC FLAGS_REG))])
20740    (match_scratch:HI 3 "r")]
20741   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20742   [(set (match_dup 3) (match_dup 2))
20743    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20744               (clobber (reg:CC FLAGS_REG))])]
20746   if (!rtx_equal_p (operands[0], operands[1]))
20747     emit_move_insn (operands[0], operands[1]);
20750 ;; After splitting up read-modify operations, array accesses with memory
20751 ;; operands might end up in form:
20752 ;;  sall    $2, %eax
20753 ;;  movl    4(%esp), %edx
20754 ;;  addl    %edx, %eax
20755 ;; instead of pre-splitting:
20756 ;;  sall    $2, %eax
20757 ;;  addl    4(%esp), %eax
20758 ;; Turn it into:
20759 ;;  movl    4(%esp), %edx
20760 ;;  leal    (%edx,%eax,4), %eax
20762 (define_peephole2
20763   [(parallel [(set (match_operand 0 "register_operand" "")
20764                    (ashift (match_operand 1 "register_operand" "")
20765                            (match_operand 2 "const_int_operand" "")))
20766                (clobber (reg:CC FLAGS_REG))])
20767    (set (match_operand 3 "register_operand")
20768         (match_operand 4 "x86_64_general_operand" ""))
20769    (parallel [(set (match_operand 5 "register_operand" "")
20770                    (plus (match_operand 6 "register_operand" "")
20771                          (match_operand 7 "register_operand" "")))
20772                    (clobber (reg:CC FLAGS_REG))])]
20773   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20774    /* Validate MODE for lea.  */
20775    && ((!TARGET_PARTIAL_REG_STALL
20776         && (GET_MODE (operands[0]) == QImode
20777             || GET_MODE (operands[0]) == HImode))
20778        || GET_MODE (operands[0]) == SImode
20779        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20780    /* We reorder load and the shift.  */
20781    && !rtx_equal_p (operands[1], operands[3])
20782    && !reg_overlap_mentioned_p (operands[0], operands[4])
20783    /* Last PLUS must consist of operand 0 and 3.  */
20784    && !rtx_equal_p (operands[0], operands[3])
20785    && (rtx_equal_p (operands[3], operands[6])
20786        || rtx_equal_p (operands[3], operands[7]))
20787    && (rtx_equal_p (operands[0], operands[6])
20788        || rtx_equal_p (operands[0], operands[7]))
20789    /* The intermediate operand 0 must die or be same as output.  */
20790    && (rtx_equal_p (operands[0], operands[5])
20791        || peep2_reg_dead_p (3, operands[0]))"
20792   [(set (match_dup 3) (match_dup 4))
20793    (set (match_dup 0) (match_dup 1))]
20795   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20796   int scale = 1 << INTVAL (operands[2]);
20797   rtx index = gen_lowpart (Pmode, operands[1]);
20798   rtx base = gen_lowpart (Pmode, operands[3]);
20799   rtx dest = gen_lowpart (mode, operands[5]);
20801   operands[1] = gen_rtx_PLUS (Pmode, base,
20802                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20803   if (mode != Pmode)
20804     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20805   operands[0] = dest;
20808 ;; Call-value patterns last so that the wildcard operand does not
20809 ;; disrupt insn-recog's switch tables.
20811 (define_insn "*call_value_pop_0"
20812   [(set (match_operand 0 "" "")
20813         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20814               (match_operand:SI 2 "" "")))
20815    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20816                             (match_operand:SI 3 "immediate_operand" "")))]
20817   "!TARGET_64BIT"
20819   if (SIBLING_CALL_P (insn))
20820     return "jmp\t%P1";
20821   else
20822     return "call\t%P1";
20824   [(set_attr "type" "callv")])
20826 (define_insn "*call_value_pop_1"
20827   [(set (match_operand 0 "" "")
20828         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20829               (match_operand:SI 2 "" "")))
20830    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20831                             (match_operand:SI 3 "immediate_operand" "i")))]
20832   "!TARGET_64BIT"
20834   if (constant_call_address_operand (operands[1], Pmode))
20835     {
20836       if (SIBLING_CALL_P (insn))
20837         return "jmp\t%P1";
20838       else
20839         return "call\t%P1";
20840     }
20841   if (SIBLING_CALL_P (insn))
20842     return "jmp\t%A1";
20843   else
20844     return "call\t%A1";
20846   [(set_attr "type" "callv")])
20848 (define_insn "*call_value_0"
20849   [(set (match_operand 0 "" "")
20850         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20851               (match_operand:SI 2 "" "")))]
20852   "!TARGET_64BIT"
20854   if (SIBLING_CALL_P (insn))
20855     return "jmp\t%P1";
20856   else
20857     return "call\t%P1";
20859   [(set_attr "type" "callv")])
20861 (define_insn "*call_value_0_rex64"
20862   [(set (match_operand 0 "" "")
20863         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20864               (match_operand:DI 2 "const_int_operand" "")))]
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_1"
20875   [(set (match_operand 0 "" "")
20876         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20877               (match_operand:SI 2 "" "")))]
20878   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20880   if (constant_call_address_operand (operands[1], Pmode))
20881     return "call\t%P1";
20882   return "call\t%A1";
20884   [(set_attr "type" "callv")])
20886 (define_insn "*sibcall_value_1"
20887   [(set (match_operand 0 "" "")
20888         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20889               (match_operand:SI 2 "" "")))]
20890   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20892   if (constant_call_address_operand (operands[1], Pmode))
20893     return "jmp\t%P1";
20894   return "jmp\t%A1";
20896   [(set_attr "type" "callv")])
20898 (define_insn "*call_value_1_rex64"
20899   [(set (match_operand 0 "" "")
20900         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20901               (match_operand:DI 2 "" "")))]
20902   "!SIBLING_CALL_P (insn) && TARGET_64BIT
20903    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20905   if (constant_call_address_operand (operands[1], Pmode))
20906     return "call\t%P1";
20907   return "call\t%A1";
20909   [(set_attr "type" "callv")])
20911 (define_insn "*call_value_1_rex64_large"
20912   [(set (match_operand 0 "" "")
20913         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20914               (match_operand:DI 2 "" "")))]
20915   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20916   "call\t%A1"
20917   [(set_attr "type" "callv")])
20919 (define_insn "*sibcall_value_1_rex64"
20920   [(set (match_operand 0 "" "")
20921         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20922               (match_operand:DI 2 "" "")))]
20923   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20924   "jmp\t%P1"
20925   [(set_attr "type" "callv")])
20927 (define_insn "*sibcall_value_1_rex64_v"
20928   [(set (match_operand 0 "" "")
20929         (call (mem:QI (reg:DI R11_REG))
20930               (match_operand:DI 1 "" "")))]
20931   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20932   "jmp\t{*%%}r11"
20933   [(set_attr "type" "callv")])
20935 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20936 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20937 ;; caught for use by garbage collectors and the like.  Using an insn that
20938 ;; maps to SIGILL makes it more likely the program will rightfully die.
20939 ;; Keeping with tradition, "6" is in honor of #UD.
20940 (define_insn "trap"
20941   [(trap_if (const_int 1) (const_int 6))]
20942   ""
20943   { return ASM_SHORT "0x0b0f"; }
20944   [(set_attr "length" "2")])
20946 (define_expand "sse_prologue_save"
20947   [(parallel [(set (match_operand:BLK 0 "" "")
20948                    (unspec:BLK [(reg:DI 21)
20949                                 (reg:DI 22)
20950                                 (reg:DI 23)
20951                                 (reg:DI 24)
20952                                 (reg:DI 25)
20953                                 (reg:DI 26)
20954                                 (reg:DI 27)
20955                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20956               (use (match_operand:DI 1 "register_operand" ""))
20957               (use (match_operand:DI 2 "immediate_operand" ""))
20958               (use (label_ref:DI (match_operand 3 "" "")))])]
20959   "TARGET_64BIT"
20960   "")
20962 (define_insn "*sse_prologue_save_insn"
20963   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20964                           (match_operand:DI 4 "const_int_operand" "n")))
20965         (unspec:BLK [(reg:DI 21)
20966                      (reg:DI 22)
20967                      (reg:DI 23)
20968                      (reg:DI 24)
20969                      (reg:DI 25)
20970                      (reg:DI 26)
20971                      (reg:DI 27)
20972                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20973    (use (match_operand:DI 1 "register_operand" "r"))
20974    (use (match_operand:DI 2 "const_int_operand" "i"))
20975    (use (label_ref:DI (match_operand 3 "" "X")))]
20976   "TARGET_64BIT
20977    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
20978    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20980   int i;
20981   operands[0] = gen_rtx_MEM (Pmode,
20982                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20983   output_asm_insn ("jmp\t%A1", operands);
20984   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20985     {
20986       operands[4] = adjust_address (operands[0], DImode, i*16);
20987       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20988       PUT_MODE (operands[4], TImode);
20989       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20990         output_asm_insn ("rex", operands);
20991       output_asm_insn ("movaps\t{%5, %4|%4, %5}", operands);
20992     }
20993   (*targetm.asm_out.internal_label) (asm_out_file, "L",
20994                                      CODE_LABEL_NUMBER (operands[3]));
20995   return "";
20997   [(set_attr "type" "other")
20998    (set_attr "length_immediate" "0")
20999    (set_attr "length_address" "0")
21000    (set_attr "length" "34")
21001    (set_attr "memory" "store")
21002    (set_attr "modrm" "0")
21003    (set_attr "mode" "DI")])
21005 (define_expand "prefetch"
21006   [(prefetch (match_operand 0 "address_operand" "")
21007              (match_operand:SI 1 "const_int_operand" "")
21008              (match_operand:SI 2 "const_int_operand" ""))]
21009   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21011   int rw = INTVAL (operands[1]);
21012   int locality = INTVAL (operands[2]);
21014   gcc_assert (rw == 0 || rw == 1);
21015   gcc_assert (locality >= 0 && locality <= 3);
21016   gcc_assert (GET_MODE (operands[0]) == Pmode
21017               || GET_MODE (operands[0]) == VOIDmode);
21019   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21020      supported by SSE counterpart or the SSE prefetch is not available
21021      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21022      of locality.  */
21023   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21024     operands[2] = GEN_INT (3);
21025   else
21026     operands[1] = const0_rtx;
21029 (define_insn "*prefetch_sse"
21030   [(prefetch (match_operand:SI 0 "address_operand" "p")
21031              (const_int 0)
21032              (match_operand:SI 1 "const_int_operand" ""))]
21033   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21035   static const char * const patterns[4] = {
21036    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21037   };
21039   int locality = INTVAL (operands[1]);
21040   gcc_assert (locality >= 0 && locality <= 3);
21042   return patterns[locality];
21044   [(set_attr "type" "sse")
21045    (set_attr "memory" "none")])
21047 (define_insn "*prefetch_sse_rex"
21048   [(prefetch (match_operand:DI 0 "address_operand" "p")
21049              (const_int 0)
21050              (match_operand:SI 1 "const_int_operand" ""))]
21051   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21053   static const char * const patterns[4] = {
21054    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21055   };
21057   int locality = INTVAL (operands[1]);
21058   gcc_assert (locality >= 0 && locality <= 3);
21060   return patterns[locality];
21062   [(set_attr "type" "sse")
21063    (set_attr "memory" "none")])
21065 (define_insn "*prefetch_3dnow"
21066   [(prefetch (match_operand:SI 0 "address_operand" "p")
21067              (match_operand:SI 1 "const_int_operand" "n")
21068              (const_int 3))]
21069   "TARGET_3DNOW && !TARGET_64BIT"
21071   if (INTVAL (operands[1]) == 0)
21072     return "prefetch\t%a0";
21073   else
21074     return "prefetchw\t%a0";
21076   [(set_attr "type" "mmx")
21077    (set_attr "memory" "none")])
21079 (define_insn "*prefetch_3dnow_rex"
21080   [(prefetch (match_operand:DI 0 "address_operand" "p")
21081              (match_operand:SI 1 "const_int_operand" "n")
21082              (const_int 3))]
21083   "TARGET_3DNOW && TARGET_64BIT"
21085   if (INTVAL (operands[1]) == 0)
21086     return "prefetch\t%a0";
21087   else
21088     return "prefetchw\t%a0";
21090   [(set_attr "type" "mmx")
21091    (set_attr "memory" "none")])
21093 (define_expand "stack_protect_set"
21094   [(match_operand 0 "memory_operand" "")
21095    (match_operand 1 "memory_operand" "")]
21096   ""
21098 #ifdef TARGET_THREAD_SSP_OFFSET
21099   if (TARGET_64BIT)
21100     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21101                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21102   else
21103     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21104                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21105 #else
21106   if (TARGET_64BIT)
21107     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21108   else
21109     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21110 #endif
21111   DONE;
21114 (define_insn "stack_protect_set_si"
21115   [(set (match_operand:SI 0 "memory_operand" "=m")
21116         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21117    (set (match_scratch:SI 2 "=&r") (const_int 0))
21118    (clobber (reg:CC FLAGS_REG))]
21119   ""
21120   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21121   [(set_attr "type" "multi")])
21123 (define_insn "stack_protect_set_di"
21124   [(set (match_operand:DI 0 "memory_operand" "=m")
21125         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21126    (set (match_scratch:DI 2 "=&r") (const_int 0))
21127    (clobber (reg:CC FLAGS_REG))]
21128   "TARGET_64BIT"
21129   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21130   [(set_attr "type" "multi")])
21132 (define_insn "stack_tls_protect_set_si"
21133   [(set (match_operand:SI 0 "memory_operand" "=m")
21134         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21135    (set (match_scratch:SI 2 "=&r") (const_int 0))
21136    (clobber (reg:CC FLAGS_REG))]
21137   ""
21138   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21139   [(set_attr "type" "multi")])
21141 (define_insn "stack_tls_protect_set_di"
21142   [(set (match_operand:DI 0 "memory_operand" "=m")
21143         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21144    (set (match_scratch:DI 2 "=&r") (const_int 0))
21145    (clobber (reg:CC FLAGS_REG))]
21146   "TARGET_64BIT"
21147   {
21148      /* The kernel uses a different segment register for performance reasons; a
21149         system call would not have to trash the userspace segment register,
21150         which would be expensive */
21151      if (ix86_cmodel != CM_KERNEL)
21152         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21153      else
21154         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21155   }
21156   [(set_attr "type" "multi")])
21158 (define_expand "stack_protect_test"
21159   [(match_operand 0 "memory_operand" "")
21160    (match_operand 1 "memory_operand" "")
21161    (match_operand 2 "" "")]
21162   ""
21164   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21165   ix86_compare_op0 = operands[0];
21166   ix86_compare_op1 = operands[1];
21167   ix86_compare_emitted = flags;
21169 #ifdef TARGET_THREAD_SSP_OFFSET
21170   if (TARGET_64BIT)
21171     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21172                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21173   else
21174     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21175                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21176 #else
21177   if (TARGET_64BIT)
21178     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21179   else
21180     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21181 #endif
21182   emit_jump_insn (gen_beq (operands[2]));
21183   DONE;
21186 (define_insn "stack_protect_test_si"
21187   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21188         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21189                      (match_operand:SI 2 "memory_operand" "m")]
21190                     UNSPEC_SP_TEST))
21191    (clobber (match_scratch:SI 3 "=&r"))]
21192   ""
21193   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21194   [(set_attr "type" "multi")])
21196 (define_insn "stack_protect_test_di"
21197   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21198         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21199                      (match_operand:DI 2 "memory_operand" "m")]
21200                     UNSPEC_SP_TEST))
21201    (clobber (match_scratch:DI 3 "=&r"))]
21202   "TARGET_64BIT"
21203   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21204   [(set_attr "type" "multi")])
21206 (define_insn "stack_tls_protect_test_si"
21207   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21208         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21209                      (match_operand:SI 2 "const_int_operand" "i")]
21210                     UNSPEC_SP_TLS_TEST))
21211    (clobber (match_scratch:SI 3 "=r"))]
21212   ""
21213   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21214   [(set_attr "type" "multi")])
21216 (define_insn "stack_tls_protect_test_di"
21217   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21218         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21219                      (match_operand:DI 2 "const_int_operand" "i")]
21220                     UNSPEC_SP_TLS_TEST))
21221    (clobber (match_scratch:DI 3 "=r"))]
21222   "TARGET_64BIT"
21223   {
21224      /* The kernel uses a different segment register for performance reasons; a
21225         system call would not have to trash the userspace segment register,
21226         which would be expensive */
21227      if (ix86_cmodel != CM_KERNEL)
21228         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21229      else
21230         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21231   }
21232   [(set_attr "type" "multi")])
21234 (define_mode_iterator CRC32MODE [QI HI SI])
21235 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21236 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21238 (define_insn "sse4_2_crc32<mode>"
21239   [(set (match_operand:SI 0 "register_operand" "=r")
21240         (unspec:SI
21241           [(match_operand:SI 1 "register_operand" "0")
21242            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21243           UNSPEC_CRC32))]
21244   "TARGET_SSE4_2"
21245   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21246   [(set_attr "type" "sselog1")
21247    (set_attr "prefix_rep" "1")
21248    (set_attr "prefix_extra" "1")
21249    (set_attr "mode" "SI")])
21251 (define_insn "sse4_2_crc32di"
21252   [(set (match_operand:DI 0 "register_operand" "=r")
21253         (unspec:DI
21254           [(match_operand:DI 1 "register_operand" "0")
21255            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21256           UNSPEC_CRC32))]
21257   "TARGET_SSE4_2 && TARGET_64BIT"
21258   "crc32q\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" "DI")])
21264 (include "mmx.md")
21265 (include "sse.md")
21266 (include "sync.md")