Update concepts branch to revision 131834
[official-gcc.git] / gcc / config / i386 / i386.md
blobca01494871f22450e3ca5f5dc5e8417dfc6a352e
1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
7 ;;
8 ;; This file is part of GCC.
9 ;;
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; any later version.
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3.  If not see
22 ;; <http://www.gnu.org/licenses/>.  */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; 'z' mov%z1 would be movl, movw, or movb depending on the mode of
31 ;;     operands[1].
32 ;; 'L' Print the opcode suffix for a 32-bit integer opcode.
33 ;; 'W' Print the opcode suffix for a 16-bit integer opcode.
34 ;; 'B' Print the opcode suffix for an 8-bit integer opcode.
35 ;; 'Q' Print the opcode suffix for a 64-bit float opcode.
36 ;; 'S' Print the opcode suffix for a 32-bit float opcode.
37 ;; 'T' Print the opcode suffix for an 80-bit extended real XFmode float opcode.
38 ;; 'J' Print the appropriate jump operand.
40 ;; 'b' Print the QImode name of the register for the indicated operand.
41 ;;     %b0 would print %al if operands[0] is reg 0.
42 ;; 'w' Likewise, print the HImode name of the register.
43 ;; 'k' Likewise, print the SImode name of the register.
44 ;; 'h' Print the QImode name for a "high" register, either ah, bh, ch or dh.
45 ;; 'y' Print "st(0)" instead of "st" as a register.
47 ;; UNSPEC usage:
49 (define_constants
50   [; Relocation specifiers
51    (UNSPEC_GOT                  0)
52    (UNSPEC_GOTOFF               1)
53    (UNSPEC_GOTPCREL             2)
54    (UNSPEC_GOTTPOFF             3)
55    (UNSPEC_TPOFF                4)
56    (UNSPEC_NTPOFF               5)
57    (UNSPEC_DTPOFF               6)
58    (UNSPEC_GOTNTPOFF            7)
59    (UNSPEC_INDNTPOFF            8)
60    (UNSPEC_PLTOFF               9)
62    ; Prologue support
63    (UNSPEC_STACK_ALLOC          11)
64    (UNSPEC_SET_GOT              12)
65    (UNSPEC_SSE_PROLOGUE_SAVE    13)
66    (UNSPEC_REG_SAVE             14)
67    (UNSPEC_DEF_CFA              15)
68    (UNSPEC_SET_RIP              16)
69    (UNSPEC_SET_GOT_OFFSET       17)
71    ; TLS support
72    (UNSPEC_TP                   18)
73    (UNSPEC_TLS_GD               19)
74    (UNSPEC_TLS_LD_BASE          20)
75    (UNSPEC_TLSDESC              21)
77    ; Other random patterns
78    (UNSPEC_SCAS                 30)
79    (UNSPEC_FNSTSW               31)
80    (UNSPEC_SAHF                 32)
81    (UNSPEC_FSTCW                33)
82    (UNSPEC_ADD_CARRY            34)
83    (UNSPEC_FLDCW                35)
84    (UNSPEC_REP                  36)
85    (UNSPEC_EH_RETURN            37)
86    (UNSPEC_LD_MPIC              38)     ; load_macho_picbase
87    (UNSPEC_TRUNC_NOOP           39)
89    ; For SSE/MMX support:
90    (UNSPEC_FIX_NOTRUNC          40)
91    (UNSPEC_MASKMOV              41)
92    (UNSPEC_MOVMSK               42)
93    (UNSPEC_MOVNT                43)
94    (UNSPEC_MOVU                 44)
95    (UNSPEC_RCP                  45)
96    (UNSPEC_RSQRT                46)
97    (UNSPEC_SFENCE               47)
98    (UNSPEC_PFRCP                49)
99    (UNSPEC_PFRCPIT1             40)
100    (UNSPEC_PFRCPIT2             41)
101    (UNSPEC_PFRSQRT              42)
102    (UNSPEC_PFRSQIT1             43)
103    (UNSPEC_MFENCE               44)
104    (UNSPEC_LFENCE               45)
105    (UNSPEC_PSADBW               46)
106    (UNSPEC_LDDQU                47)
108    ; Generic math support
109    (UNSPEC_COPYSIGN             50)
110    (UNSPEC_IEEE_MIN             51)     ; not commutative
111    (UNSPEC_IEEE_MAX             52)     ; not commutative
113    ; x87 Floating point
114    (UNSPEC_SIN                  60)
115    (UNSPEC_COS                  61)
116    (UNSPEC_FPATAN               62)
117    (UNSPEC_FYL2X                63)
118    (UNSPEC_FYL2XP1              64)
119    (UNSPEC_FRNDINT              65)
120    (UNSPEC_FIST                 66)
121    (UNSPEC_F2XM1                67)
122    (UNSPEC_TAN                  68)
123    (UNSPEC_FXAM                 69)
125    ; x87 Rounding
126    (UNSPEC_FRNDINT_FLOOR        70)
127    (UNSPEC_FRNDINT_CEIL         71)
128    (UNSPEC_FRNDINT_TRUNC        72)
129    (UNSPEC_FRNDINT_MASK_PM      73)
130    (UNSPEC_FIST_FLOOR           74)
131    (UNSPEC_FIST_CEIL            75)
133    ; x87 Double output FP
134    (UNSPEC_SINCOS_COS           80)
135    (UNSPEC_SINCOS_SIN           81)
136    (UNSPEC_XTRACT_FRACT         84)
137    (UNSPEC_XTRACT_EXP           85)
138    (UNSPEC_FSCALE_FRACT         86)
139    (UNSPEC_FSCALE_EXP           87)
140    (UNSPEC_FPREM_F              88)
141    (UNSPEC_FPREM_U              89)
142    (UNSPEC_FPREM1_F             90)
143    (UNSPEC_FPREM1_U             91)
145    (UNSPEC_C2_FLAG              95)
147    ; SSP patterns
148    (UNSPEC_SP_SET               100)
149    (UNSPEC_SP_TEST              101)
150    (UNSPEC_SP_TLS_SET           102)
151    (UNSPEC_SP_TLS_TEST          103)
153    ; SSSE3
154    (UNSPEC_PSHUFB               120)
155    (UNSPEC_PSIGN                121)
156    (UNSPEC_PALIGNR              122)
158    ; For SSE4A support
159    (UNSPEC_EXTRQI               130)
160    (UNSPEC_EXTRQ                131)
161    (UNSPEC_INSERTQI             132)
162    (UNSPEC_INSERTQ              133)
164    ; For SSE4.1 support
165    (UNSPEC_BLENDV               134)
166    (UNSPEC_INSERTPS             135)
167    (UNSPEC_DP                   136)
168    (UNSPEC_MOVNTDQA             137)
169    (UNSPEC_MPSADBW              138)
170    (UNSPEC_PHMINPOSUW           139)
171    (UNSPEC_PTEST                140)
172    (UNSPEC_ROUND                141)
174    ; For SSE4.2 support
175    (UNSPEC_CRC32                143)
176    (UNSPEC_PCMPESTR             144)
177    (UNSPEC_PCMPISTR             145)
179    ;; For SSE5
180    (UNSPEC_SSE5_INTRINSIC       150)
181    (UNSPEC_SSE5_UNSIGNED_CMP    151)
182    (UNSPEC_SSE5_TRUEFALSE       152)
183    (UNSPEC_SSE5_PERMUTE         153)
184    (UNSPEC_FRCZ                 154)
185    (UNSPEC_CVTPH2PS             155)
186    (UNSPEC_CVTPS2PH             156)
188    ; For AES support
189    (UNSPEC_AESENC               159)
190    (UNSPEC_AESENCLAST           160)
191    (UNSPEC_AESDEC               161)
192    (UNSPEC_AESDECLAST           162)
193    (UNSPEC_AESIMC               163)
194    (UNSPEC_AESKEYGENASSIST      164)
196    ; For PCLMUL support
197    (UNSPEC_PCLMUL               165)
198   ])
200 (define_constants
201   [(UNSPECV_BLOCKAGE            0)
202    (UNSPECV_STACK_PROBE         1)
203    (UNSPECV_EMMS                2)
204    (UNSPECV_LDMXCSR             3)
205    (UNSPECV_STMXCSR             4)
206    (UNSPECV_FEMMS               5)
207    (UNSPECV_CLFLUSH             6)
208    (UNSPECV_ALIGN               7)
209    (UNSPECV_MONITOR             8)
210    (UNSPECV_MWAIT               9)
211    (UNSPECV_CMPXCHG_1           10)
212    (UNSPECV_CMPXCHG_2           11)
213    (UNSPECV_XCHG                12)
214    (UNSPECV_LOCK                13)
215    (UNSPECV_PROLOGUE_USE        14)
216    (UNSPECV_CLD                 15)
217   ])
219 ;; Constants to represent pcomtrue/pcomfalse variants
220 (define_constants
221   [(PCOM_FALSE                  0)
222    (PCOM_TRUE                   1)
223    (COM_FALSE_S                 2)
224    (COM_FALSE_P                 3)
225    (COM_TRUE_S                  4)
226    (COM_TRUE_P                  5)
227   ])
229 ;; Constants used in the SSE5 pperm instruction
230 (define_constants
231   [(PPERM_SRC                   0x00)   /* copy source */
232    (PPERM_INVERT                0x20)   /* invert source */
233    (PPERM_REVERSE               0x40)   /* bit reverse source */
234    (PPERM_REV_INV               0x60)   /* bit reverse & invert src */
235    (PPERM_ZERO                  0x80)   /* all 0's */
236    (PPERM_ONES                  0xa0)   /* all 1's */
237    (PPERM_SIGN                  0xc0)   /* propagate sign bit */
238    (PPERM_INV_SIGN              0xe0)   /* invert & propagate sign */
239    (PPERM_SRC1                  0x00)   /* use first source byte */
240    (PPERM_SRC2                  0x10)   /* use second source byte */
241    ])
243 ;; Registers by name.
244 (define_constants
245   [(AX_REG                       0)
246    (DX_REG                       1)
247    (CX_REG                       2)
248    (SI_REG                       4)
249    (DI_REG                       5)
250    (BP_REG                       6)
251    (SP_REG                       7)
252    (FLAGS_REG                   17)
253    (FPSR_REG                    18)
254    (FPCR_REG                    19)
255    (R10_REG                     39)
256    (R11_REG                     40)
257   ])
259 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
260 ;; from i386.c.
262 ;; In C guard expressions, put expressions which may be compile-time
263 ;; constants first.  This allows for better optimization.  For
264 ;; example, write "TARGET_64BIT && reload_completed", not
265 ;; "reload_completed && TARGET_64BIT".
268 ;; Processor type.  This attribute must exactly match the processor_type
269 ;; enumeration in i386.h.
270 (define_attr "cpu" "i386,i486,pentium,pentiumpro,geode,k6,athlon,pentium4,k8,
271                     nocona,core2,generic32,generic64,amdfam10"
272   (const (symbol_ref "ix86_tune")))
274 ;; A basic instruction type.  Refinements due to arguments to be
275 ;; provided in other attributes.
276 (define_attr "type"
277   "other,multi,
278    alu,alu1,negnot,imov,imovx,lea,
279    incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
280    icmp,test,ibr,setcc,icmov,
281    push,pop,call,callv,leave,
282    str,bitmanip,
283    fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
284    sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
285    sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
286    ssemuladd,sse4arg,
287    mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
288   (const_string "other"))
290 ;; Main data type used by the insn
291 (define_attr "mode"
292   "unknown,none,QI,HI,SI,DI,SF,DF,XF,TI,V4SF,V2DF,V2SF,V1DF"
293   (const_string "unknown"))
295 ;; The CPU unit operations uses.
296 (define_attr "unit" "integer,i387,sse,mmx,unknown"
297   (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
298            (const_string "i387")
299          (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
300                           sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
301                           ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
302            (const_string "sse")
303          (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
304            (const_string "mmx")
305          (eq_attr "type" "other")
306            (const_string "unknown")]
307          (const_string "integer")))
309 ;; The (bounding maximum) length of an instruction immediate.
310 (define_attr "length_immediate" ""
311   (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
312                           bitmanip")
313            (const_int 0)
314          (eq_attr "unit" "i387,sse,mmx")
315            (const_int 0)
316          (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
317                           imul,icmp,push,pop")
318            (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
319          (eq_attr "type" "imov,test")
320            (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
321          (eq_attr "type" "call")
322            (if_then_else (match_operand 0 "constant_call_address_operand" "")
323              (const_int 4)
324              (const_int 0))
325          (eq_attr "type" "callv")
326            (if_then_else (match_operand 1 "constant_call_address_operand" "")
327              (const_int 4)
328              (const_int 0))
329          ;; We don't know the size before shorten_branches.  Expect
330          ;; the instruction to fit for better scheduling.
331          (eq_attr "type" "ibr")
332            (const_int 1)
333          ]
334          (symbol_ref "/* Update immediate_length and other attributes! */
335                       gcc_unreachable (),1")))
337 ;; The (bounding maximum) length of an instruction address.
338 (define_attr "length_address" ""
339   (cond [(eq_attr "type" "str,other,multi,fxch")
340            (const_int 0)
341          (and (eq_attr "type" "call")
342               (match_operand 0 "constant_call_address_operand" ""))
343              (const_int 0)
344          (and (eq_attr "type" "callv")
345               (match_operand 1 "constant_call_address_operand" ""))
346              (const_int 0)
347          ]
348          (symbol_ref "ix86_attr_length_address_default (insn)")))
350 ;; Set when length prefix is used.
351 (define_attr "prefix_data16" ""
352   (if_then_else (ior (eq_attr "mode" "HI")
353                      (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF")))
354     (const_int 1)
355     (const_int 0)))
357 ;; Set when string REP prefix is used.
358 (define_attr "prefix_rep" ""
359   (if_then_else (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
360     (const_int 1)
361     (const_int 0)))
363 ;; Set when 0f opcode prefix is used.
364 (define_attr "prefix_0f" ""
365   (if_then_else
366     (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
367          (eq_attr "unit" "sse,mmx"))
368     (const_int 1)
369     (const_int 0)))
371 ;; Set when REX opcode prefix is used.
372 (define_attr "prefix_rex" ""
373   (cond [(and (eq_attr "mode" "DI")
374               (eq_attr "type" "!push,pop,call,callv,leave,ibr"))
375            (const_int 1)
376          (and (eq_attr "mode" "QI")
377               (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
378                   (const_int 0)))
379            (const_int 1)
380          (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
381              (const_int 0))
382            (const_int 1)
383         ]
384         (const_int 0)))
386 ;; There are also additional prefixes in SSSE3.
387 (define_attr "prefix_extra" "" (const_int 0))
389 ;; Set when modrm byte is used.
390 (define_attr "modrm" ""
391   (cond [(eq_attr "type" "str,leave")
392            (const_int 0)
393          (eq_attr "unit" "i387")
394            (const_int 0)
395          (and (eq_attr "type" "incdec")
396               (ior (match_operand:SI 1 "register_operand" "")
397                    (match_operand:HI 1 "register_operand" "")))
398            (const_int 0)
399          (and (eq_attr "type" "push")
400               (not (match_operand 1 "memory_operand" "")))
401            (const_int 0)
402          (and (eq_attr "type" "pop")
403               (not (match_operand 0 "memory_operand" "")))
404            (const_int 0)
405          (and (eq_attr "type" "imov")
406               (ior (and (match_operand 0 "register_operand" "")
407                         (match_operand 1 "immediate_operand" ""))
408                    (ior (and (match_operand 0 "ax_reg_operand" "")
409                              (match_operand 1 "memory_displacement_only_operand" ""))
410                         (and (match_operand 0 "memory_displacement_only_operand" "")
411                              (match_operand 1 "ax_reg_operand" "")))))
412            (const_int 0)
413          (and (eq_attr "type" "call")
414               (match_operand 0 "constant_call_address_operand" ""))
415              (const_int 0)
416          (and (eq_attr "type" "callv")
417               (match_operand 1 "constant_call_address_operand" ""))
418              (const_int 0)
419          ]
420          (const_int 1)))
422 ;; The (bounding maximum) length of an instruction in bytes.
423 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
424 ;; Later we may want to split them and compute proper length as for
425 ;; other insns.
426 (define_attr "length" ""
427   (cond [(eq_attr "type" "other,multi,fistp,frndint")
428            (const_int 16)
429          (eq_attr "type" "fcmp")
430            (const_int 4)
431          (eq_attr "unit" "i387")
432            (plus (const_int 2)
433                  (plus (attr "prefix_data16")
434                        (attr "length_address")))]
435          (plus (plus (attr "modrm")
436                      (plus (attr "prefix_0f")
437                            (plus (attr "prefix_rex")
438                                  (plus (attr "prefix_extra")
439                                        (const_int 1)))))
440                (plus (attr "prefix_rep")
441                      (plus (attr "prefix_data16")
442                            (plus (attr "length_immediate")
443                                  (attr "length_address")))))))
445 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
446 ;; `store' if there is a simple memory reference therein, or `unknown'
447 ;; if the instruction is complex.
449 (define_attr "memory" "none,load,store,both,unknown"
450   (cond [(eq_attr "type" "other,multi,str")
451            (const_string "unknown")
452          (eq_attr "type" "lea,fcmov,fpspc")
453            (const_string "none")
454          (eq_attr "type" "fistp,leave")
455            (const_string "both")
456          (eq_attr "type" "frndint")
457            (const_string "load")
458          (eq_attr "type" "push")
459            (if_then_else (match_operand 1 "memory_operand" "")
460              (const_string "both")
461              (const_string "store"))
462          (eq_attr "type" "pop")
463            (if_then_else (match_operand 0 "memory_operand" "")
464              (const_string "both")
465              (const_string "load"))
466          (eq_attr "type" "setcc")
467            (if_then_else (match_operand 0 "memory_operand" "")
468              (const_string "store")
469              (const_string "none"))
470          (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
471            (if_then_else (ior (match_operand 0 "memory_operand" "")
472                               (match_operand 1 "memory_operand" ""))
473              (const_string "load")
474              (const_string "none"))
475          (eq_attr "type" "ibr")
476            (if_then_else (match_operand 0 "memory_operand" "")
477              (const_string "load")
478              (const_string "none"))
479          (eq_attr "type" "call")
480            (if_then_else (match_operand 0 "constant_call_address_operand" "")
481              (const_string "none")
482              (const_string "load"))
483          (eq_attr "type" "callv")
484            (if_then_else (match_operand 1 "constant_call_address_operand" "")
485              (const_string "none")
486              (const_string "load"))
487          (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
488               (match_operand 1 "memory_operand" ""))
489            (const_string "both")
490          (and (match_operand 0 "memory_operand" "")
491               (match_operand 1 "memory_operand" ""))
492            (const_string "both")
493          (match_operand 0 "memory_operand" "")
494            (const_string "store")
495          (match_operand 1 "memory_operand" "")
496            (const_string "load")
497          (and (eq_attr "type"
498                  "!alu1,negnot,ishift1,
499                    imov,imovx,icmp,test,bitmanip,
500                    fmov,fcmp,fsgn,
501                    sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
502                    sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
503               (match_operand 2 "memory_operand" ""))
504            (const_string "load")
505          (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
506               (match_operand 3 "memory_operand" ""))
507            (const_string "load")
508         ]
509         (const_string "none")))
511 ;; Indicates if an instruction has both an immediate and a displacement.
513 (define_attr "imm_disp" "false,true,unknown"
514   (cond [(eq_attr "type" "other,multi")
515            (const_string "unknown")
516          (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
517               (and (match_operand 0 "memory_displacement_operand" "")
518                    (match_operand 1 "immediate_operand" "")))
519            (const_string "true")
520          (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
521               (and (match_operand 0 "memory_displacement_operand" "")
522                    (match_operand 2 "immediate_operand" "")))
523            (const_string "true")
524         ]
525         (const_string "false")))
527 ;; Indicates if an FP operation has an integer source.
529 (define_attr "fp_int_src" "false,true"
530   (const_string "false"))
532 ;; Defines rounding mode of an FP operation.
534 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
535   (const_string "any"))
537 ;; Describe a user's asm statement.
538 (define_asm_attributes
539   [(set_attr "length" "128")
540    (set_attr "type" "multi")])
542 ;; All integer comparison codes.
543 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
545 ;; All floating-point comparison codes.
546 (define_code_iterator fp_cond [unordered ordered
547                                uneq unge ungt unle unlt ltgt ])
549 (define_code_iterator plusminus [plus minus])
551 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
553 ;; Base name for define_insn
554 (define_code_attr plusminus_insn
555   [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
556    (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
558 ;; Base name for insn mnemonic.
559 (define_code_attr plusminus_mnemonic
560   [(plus "add") (ss_plus "adds") (us_plus "addus")
561    (minus "sub") (ss_minus "subs") (us_minus "subus")])
563 ;; Mark commutative operators as such in constraints.
564 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
565                         (minus "") (ss_minus "") (us_minus "")])
567 ;; Mapping of signed max and min
568 (define_code_iterator smaxmin [smax smin])
570 ;; Mapping of unsigned max and min
571 (define_code_iterator umaxmin [umax umin])
573 ;; Base name for integer and FP insn mnemonic
574 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
575                                  (umax "maxu") (umin "minu")])
576 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
578 ;; Mapping of parallel logic operators
579 (define_code_iterator plogic [and ior xor])
581 ;; Base name for insn mnemonic.
582 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
584 ;; Mapping of abs neg operators
585 (define_code_iterator absneg [abs neg])
587 ;; Base name for x87 insn mnemonic.
588 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
590 ;; All single word integer modes.
591 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
593 ;; Instruction suffix for integer modes.
594 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
596 ;; Register class for integer modes.
597 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
599 ;; Immediate operand constraint for integer modes.
600 (define_mode_attr i [(QI "i") (HI "i") (SI "i") (DI "e")])
602 ;; General operand predicate for integer modes.
603 (define_mode_attr general_operand
604         [(QI "general_operand")
605          (HI "general_operand")
606          (SI "general_operand")
607          (DI "x86_64_general_operand")])
609 ;; SSE and x87 SFmode and DFmode floating point modes
610 (define_mode_iterator MODEF [SF DF])
612 ;; All x87 floating point modes
613 (define_mode_iterator X87MODEF [SF DF XF])
615 ;; All integer modes handled by x87 fisttp operator.
616 (define_mode_iterator X87MODEI [HI SI DI])
618 ;; All integer modes handled by integer x87 operators.
619 (define_mode_iterator X87MODEI12 [HI SI])
621 ;; All integer modes handled by SSE cvtts?2si* operators.
622 (define_mode_iterator SSEMODEI24 [SI DI])
624 ;; SSE asm suffix for floating point modes
625 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
627 ;; SSE vector mode corresponding to a scalar mode
628 (define_mode_attr ssevecmode
629   [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
631 ;; Instruction suffix for REX 64bit operators.
632 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
634 ;; 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" "n,n")))]
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" "n,n")))]
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" "n,n")))]
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" "ri,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" "ri,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" "n,n")))]
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" "qi,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" "qi,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" "n")))]
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" "X"))]
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" "X")))
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" "i"))
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                         "rinm,rin,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" "ri"))]
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" "i"))
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" "qi"))]
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" "i"))
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" "i"))
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_64BIT"
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_64BIT
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    (clobber (reg:CC FLAGS_REG))]
5467   "TARGET_64BIT"
5468   "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
5470 (define_insn "*addti3_1"
5471   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
5472         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
5473                  (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
5474    (clobber (reg:CC FLAGS_REG))]
5475   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
5476   "#")
5478 (define_split
5479   [(set (match_operand:TI 0 "nonimmediate_operand" "")
5480         (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
5481                  (match_operand:TI 2 "x86_64_general_operand" "")))
5482    (clobber (reg:CC FLAGS_REG))]
5483   "TARGET_64BIT && reload_completed"
5484   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5485                                           UNSPEC_ADD_CARRY))
5486               (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
5487    (parallel [(set (match_dup 3)
5488                    (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
5489                                      (match_dup 4))
5490                             (match_dup 5)))
5491               (clobber (reg:CC FLAGS_REG))])]
5492   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
5494 ;; %%% splits for addsidi3
5495 ;  [(set (match_operand:DI 0 "nonimmediate_operand" "")
5496 ;       (plus:DI (match_operand:DI 1 "general_operand" "")
5497 ;                (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
5499 (define_expand "adddi3"
5500   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5501         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5502                  (match_operand:DI 2 "x86_64_general_operand" "")))
5503    (clobber (reg:CC FLAGS_REG))]
5504   ""
5505   "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
5507 (define_insn "*adddi3_1"
5508   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
5509         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5510                  (match_operand:DI 2 "general_operand" "roiF,riF")))
5511    (clobber (reg:CC FLAGS_REG))]
5512   "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5513   "#")
5515 (define_split
5516   [(set (match_operand:DI 0 "nonimmediate_operand" "")
5517         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
5518                  (match_operand:DI 2 "general_operand" "")))
5519    (clobber (reg:CC FLAGS_REG))]
5520   "!TARGET_64BIT && reload_completed"
5521   [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
5522                                           UNSPEC_ADD_CARRY))
5523               (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
5524    (parallel [(set (match_dup 3)
5525                    (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
5526                                      (match_dup 4))
5527                             (match_dup 5)))
5528               (clobber (reg:CC FLAGS_REG))])]
5529   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
5531 (define_insn "adddi3_carry_rex64"
5532   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5533           (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
5534                             (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
5535                    (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
5536    (clobber (reg:CC FLAGS_REG))]
5537   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5538   "adc{q}\t{%2, %0|%0, %2}"
5539   [(set_attr "type" "alu")
5540    (set_attr "pent_pair" "pu")
5541    (set_attr "mode" "DI")])
5543 (define_insn "*adddi3_cc_rex64"
5544   [(set (reg:CC FLAGS_REG)
5545         (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
5546                     (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
5547                    UNSPEC_ADD_CARRY))
5548    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
5549         (plus:DI (match_dup 1) (match_dup 2)))]
5550   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5551   "add{q}\t{%2, %0|%0, %2}"
5552   [(set_attr "type" "alu")
5553    (set_attr "mode" "DI")])
5555 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
5556   [(set (reg:CCC FLAGS_REG)
5557         (compare:CCC
5558             (plusminus:SWI
5559                 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
5560                 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
5561             (match_dup 1)))
5562    (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5563         (plusminus:SWI (match_dup 1) (match_dup 2)))]
5564   "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
5565   "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
5566   [(set_attr "type" "alu")
5567    (set_attr "mode" "<MODE>")])
5569 (define_insn "*add<mode>3_cconly_overflow"
5570   [(set (reg:CCC FLAGS_REG)
5571         (compare:CCC
5572                 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
5573                           (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5574                 (match_dup 1)))
5575    (clobber (match_scratch:SWI 0 "=<r>"))]
5576   "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5577   "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5578   [(set_attr "type" "alu")
5579    (set_attr "mode" "<MODE>")])
5581 (define_insn "*sub<mode>3_cconly_overflow"
5582   [(set (reg:CCC FLAGS_REG)
5583         (compare:CCC
5584              (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
5585                         (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
5586              (match_dup 0)))]
5587   ""
5588   "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
5589   [(set_attr "type" "icmp")
5590    (set_attr "mode" "<MODE>")])
5592 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
5593   [(set (reg:CCC FLAGS_REG)
5594         (compare:CCC
5595             (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
5596                           (match_operand:SI 2 "general_operand" "g"))
5597             (match_dup 1)))
5598    (set (match_operand:DI 0 "register_operand" "=r")
5599         (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
5600   "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
5601   "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
5602   [(set_attr "type" "alu")
5603    (set_attr "mode" "SI")])
5605 (define_insn "addqi3_carry"
5606   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5607           (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
5608                             (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
5609                    (match_operand:QI 2 "general_operand" "qi,qm")))
5610    (clobber (reg:CC FLAGS_REG))]
5611   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5612   "adc{b}\t{%2, %0|%0, %2}"
5613   [(set_attr "type" "alu")
5614    (set_attr "pent_pair" "pu")
5615    (set_attr "mode" "QI")])
5617 (define_insn "addhi3_carry"
5618   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5619           (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
5620                             (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
5621                    (match_operand:HI 2 "general_operand" "ri,rm")))
5622    (clobber (reg:CC FLAGS_REG))]
5623   "ix86_binary_operator_ok (PLUS, HImode, operands)"
5624   "adc{w}\t{%2, %0|%0, %2}"
5625   [(set_attr "type" "alu")
5626    (set_attr "pent_pair" "pu")
5627    (set_attr "mode" "HI")])
5629 (define_insn "addsi3_carry"
5630   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5631           (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5632                             (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
5633                    (match_operand:SI 2 "general_operand" "ri,rm")))
5634    (clobber (reg:CC FLAGS_REG))]
5635   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5636   "adc{l}\t{%2, %0|%0, %2}"
5637   [(set_attr "type" "alu")
5638    (set_attr "pent_pair" "pu")
5639    (set_attr "mode" "SI")])
5641 (define_insn "*addsi3_carry_zext"
5642   [(set (match_operand:DI 0 "register_operand" "=r")
5643           (zero_extend:DI
5644             (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5645                               (match_operand:SI 1 "nonimmediate_operand" "%0"))
5646                      (match_operand:SI 2 "general_operand" "g"))))
5647    (clobber (reg:CC FLAGS_REG))]
5648   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5649   "adc{l}\t{%2, %k0|%k0, %2}"
5650   [(set_attr "type" "alu")
5651    (set_attr "pent_pair" "pu")
5652    (set_attr "mode" "SI")])
5654 (define_insn "*addsi3_cc"
5655   [(set (reg:CC FLAGS_REG)
5656         (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
5657                     (match_operand:SI 2 "general_operand" "ri,rm")]
5658                    UNSPEC_ADD_CARRY))
5659    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
5660         (plus:SI (match_dup 1) (match_dup 2)))]
5661   "ix86_binary_operator_ok (PLUS, SImode, operands)"
5662   "add{l}\t{%2, %0|%0, %2}"
5663   [(set_attr "type" "alu")
5664    (set_attr "mode" "SI")])
5666 (define_insn "addqi3_cc"
5667   [(set (reg:CC FLAGS_REG)
5668         (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5669                     (match_operand:QI 2 "general_operand" "qi,qm")]
5670                    UNSPEC_ADD_CARRY))
5671    (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5672         (plus:QI (match_dup 1) (match_dup 2)))]
5673   "ix86_binary_operator_ok (PLUS, QImode, operands)"
5674   "add{b}\t{%2, %0|%0, %2}"
5675   [(set_attr "type" "alu")
5676    (set_attr "mode" "QI")])
5678 (define_expand "addsi3"
5679   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
5680                    (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
5681                             (match_operand:SI 2 "general_operand" "")))
5682               (clobber (reg:CC FLAGS_REG))])]
5683   ""
5684   "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
5686 (define_insn "*lea_1"
5687   [(set (match_operand:SI 0 "register_operand" "=r")
5688         (match_operand:SI 1 "no_seg_address_operand" "p"))]
5689   "!TARGET_64BIT"
5690   "lea{l}\t{%a1, %0|%0, %a1}"
5691   [(set_attr "type" "lea")
5692    (set_attr "mode" "SI")])
5694 (define_insn "*lea_1_rex64"
5695   [(set (match_operand:SI 0 "register_operand" "=r")
5696         (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5697   "TARGET_64BIT"
5698   "lea{l}\t{%a1, %0|%0, %a1}"
5699   [(set_attr "type" "lea")
5700    (set_attr "mode" "SI")])
5702 (define_insn "*lea_1_zext"
5703   [(set (match_operand:DI 0 "register_operand" "=r")
5704         (zero_extend:DI
5705          (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5706   "TARGET_64BIT"
5707   "lea{l}\t{%a1, %k0|%k0, %a1}"
5708   [(set_attr "type" "lea")
5709    (set_attr "mode" "SI")])
5711 (define_insn "*lea_2_rex64"
5712   [(set (match_operand:DI 0 "register_operand" "=r")
5713         (match_operand:DI 1 "no_seg_address_operand" "p"))]
5714   "TARGET_64BIT"
5715   "lea{q}\t{%a1, %0|%0, %a1}"
5716   [(set_attr "type" "lea")
5717    (set_attr "mode" "DI")])
5719 ;; The lea patterns for non-Pmodes needs to be matched by several
5720 ;; insns converted to real lea by splitters.
5722 (define_insn_and_split "*lea_general_1"
5723   [(set (match_operand 0 "register_operand" "=r")
5724         (plus (plus (match_operand 1 "index_register_operand" "l")
5725                     (match_operand 2 "register_operand" "r"))
5726               (match_operand 3 "immediate_operand" "i")))]
5727   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5728     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5729    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5730    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5731    && GET_MODE (operands[0]) == GET_MODE (operands[2])
5732    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5733        || GET_MODE (operands[3]) == VOIDmode)"
5734   "#"
5735   "&& reload_completed"
5736   [(const_int 0)]
5738   rtx pat;
5739   operands[0] = gen_lowpart (SImode, operands[0]);
5740   operands[1] = gen_lowpart (Pmode, operands[1]);
5741   operands[2] = gen_lowpart (Pmode, operands[2]);
5742   operands[3] = gen_lowpart (Pmode, operands[3]);
5743   pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
5744                       operands[3]);
5745   if (Pmode != SImode)
5746     pat = gen_rtx_SUBREG (SImode, pat, 0);
5747   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5748   DONE;
5750   [(set_attr "type" "lea")
5751    (set_attr "mode" "SI")])
5753 (define_insn_and_split "*lea_general_1_zext"
5754   [(set (match_operand:DI 0 "register_operand" "=r")
5755         (zero_extend:DI
5756           (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
5757                             (match_operand:SI 2 "register_operand" "r"))
5758                    (match_operand:SI 3 "immediate_operand" "i"))))]
5759   "TARGET_64BIT"
5760   "#"
5761   "&& reload_completed"
5762   [(set (match_dup 0)
5763         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
5764                                                      (match_dup 2))
5765                                             (match_dup 3)) 0)))]
5767   operands[1] = gen_lowpart (Pmode, operands[1]);
5768   operands[2] = gen_lowpart (Pmode, operands[2]);
5769   operands[3] = gen_lowpart (Pmode, operands[3]);
5771   [(set_attr "type" "lea")
5772    (set_attr "mode" "SI")])
5774 (define_insn_and_split "*lea_general_2"
5775   [(set (match_operand 0 "register_operand" "=r")
5776         (plus (mult (match_operand 1 "index_register_operand" "l")
5777                     (match_operand 2 "const248_operand" "i"))
5778               (match_operand 3 "nonmemory_operand" "ri")))]
5779   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5780     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5781    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5782    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5783    && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5784        || GET_MODE (operands[3]) == VOIDmode)"
5785   "#"
5786   "&& reload_completed"
5787   [(const_int 0)]
5789   rtx pat;
5790   operands[0] = gen_lowpart (SImode, operands[0]);
5791   operands[1] = gen_lowpart (Pmode, operands[1]);
5792   operands[3] = gen_lowpart (Pmode, operands[3]);
5793   pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
5794                       operands[3]);
5795   if (Pmode != SImode)
5796     pat = gen_rtx_SUBREG (SImode, pat, 0);
5797   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5798   DONE;
5800   [(set_attr "type" "lea")
5801    (set_attr "mode" "SI")])
5803 (define_insn_and_split "*lea_general_2_zext"
5804   [(set (match_operand:DI 0 "register_operand" "=r")
5805         (zero_extend:DI
5806           (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
5807                             (match_operand:SI 2 "const248_operand" "n"))
5808                    (match_operand:SI 3 "nonmemory_operand" "ri"))))]
5809   "TARGET_64BIT"
5810   "#"
5811   "&& reload_completed"
5812   [(set (match_dup 0)
5813         (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
5814                                                      (match_dup 2))
5815                                             (match_dup 3)) 0)))]
5817   operands[1] = gen_lowpart (Pmode, operands[1]);
5818   operands[3] = gen_lowpart (Pmode, operands[3]);
5820   [(set_attr "type" "lea")
5821    (set_attr "mode" "SI")])
5823 (define_insn_and_split "*lea_general_3"
5824   [(set (match_operand 0 "register_operand" "=r")
5825         (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5826                           (match_operand 2 "const248_operand" "i"))
5827                     (match_operand 3 "register_operand" "r"))
5828               (match_operand 4 "immediate_operand" "i")))]
5829   "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
5830     || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
5831    && (!TARGET_PARTIAL_REG_STALL || optimize_size)
5832    && GET_MODE (operands[0]) == GET_MODE (operands[1])
5833    && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5834   "#"
5835   "&& reload_completed"
5836   [(const_int 0)]
5838   rtx pat;
5839   operands[0] = gen_lowpart (SImode, operands[0]);
5840   operands[1] = gen_lowpart (Pmode, operands[1]);
5841   operands[3] = gen_lowpart (Pmode, operands[3]);
5842   operands[4] = gen_lowpart (Pmode, operands[4]);
5843   pat = gen_rtx_PLUS (Pmode,
5844                       gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
5845                                                          operands[2]),
5846                                     operands[3]),
5847                       operands[4]);
5848   if (Pmode != SImode)
5849     pat = gen_rtx_SUBREG (SImode, pat, 0);
5850   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5851   DONE;
5853   [(set_attr "type" "lea")
5854    (set_attr "mode" "SI")])
5856 (define_insn_and_split "*lea_general_3_zext"
5857   [(set (match_operand:DI 0 "register_operand" "=r")
5858         (zero_extend:DI
5859           (plus:SI (plus:SI (mult:SI
5860                               (match_operand:SI 1 "index_register_operand" "l")
5861                               (match_operand:SI 2 "const248_operand" "n"))
5862                             (match_operand:SI 3 "register_operand" "r"))
5863                    (match_operand:SI 4 "immediate_operand" "i"))))]
5864   "TARGET_64BIT"
5865   "#"
5866   "&& reload_completed"
5867   [(set (match_dup 0)
5868         (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
5869                                                               (match_dup 2))
5870                                                      (match_dup 3))
5871                                             (match_dup 4)) 0)))]
5873   operands[1] = gen_lowpart (Pmode, operands[1]);
5874   operands[3] = gen_lowpart (Pmode, operands[3]);
5875   operands[4] = gen_lowpart (Pmode, operands[4]);
5877   [(set_attr "type" "lea")
5878    (set_attr "mode" "SI")])
5880 (define_insn "*adddi_1_rex64"
5881   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r")
5882         (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r")
5883                  (match_operand:DI 2 "x86_64_general_operand" "rme,re,le")))
5884    (clobber (reg:CC FLAGS_REG))]
5885   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
5887   switch (get_attr_type (insn))
5888     {
5889     case TYPE_LEA:
5890       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5891       return "lea{q}\t{%a2, %0|%0, %a2}";
5893     case TYPE_INCDEC:
5894       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5895       if (operands[2] == const1_rtx)
5896         return "inc{q}\t%0";
5897       else
5898         {
5899           gcc_assert (operands[2] == constm1_rtx);
5900           return "dec{q}\t%0";
5901         }
5903     default:
5904       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5906       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5907          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5908       if (CONST_INT_P (operands[2])
5909           /* Avoid overflows.  */
5910           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5911           && (INTVAL (operands[2]) == 128
5912               || (INTVAL (operands[2]) < 0
5913                   && INTVAL (operands[2]) != -128)))
5914         {
5915           operands[2] = GEN_INT (-INTVAL (operands[2]));
5916           return "sub{q}\t{%2, %0|%0, %2}";
5917         }
5918       return "add{q}\t{%2, %0|%0, %2}";
5919     }
5921   [(set (attr "type")
5922      (cond [(eq_attr "alternative" "2")
5923               (const_string "lea")
5924             ; Current assemblers are broken and do not allow @GOTOFF in
5925             ; ought but a memory context.
5926             (match_operand:DI 2 "pic_symbolic_operand" "")
5927               (const_string "lea")
5928             (match_operand:DI 2 "incdec_operand" "")
5929               (const_string "incdec")
5930            ]
5931            (const_string "alu")))
5932    (set_attr "mode" "DI")])
5934 ;; Convert lea to the lea pattern to avoid flags dependency.
5935 (define_split
5936   [(set (match_operand:DI 0 "register_operand" "")
5937         (plus:DI (match_operand:DI 1 "register_operand" "")
5938                  (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
5939    (clobber (reg:CC FLAGS_REG))]
5940   "TARGET_64BIT && reload_completed
5941    && true_regnum (operands[0]) != true_regnum (operands[1])"
5942   [(set (match_dup 0)
5943         (plus:DI (match_dup 1)
5944                  (match_dup 2)))]
5945   "")
5947 (define_insn "*adddi_2_rex64"
5948   [(set (reg FLAGS_REG)
5949         (compare
5950           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
5951                    (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
5952           (const_int 0)))
5953    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
5954         (plus:DI (match_dup 1) (match_dup 2)))]
5955   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5956    && ix86_binary_operator_ok (PLUS, DImode, operands)
5957    /* Current assemblers are broken and do not allow @GOTOFF in
5958       ought but a memory context.  */
5959    && ! pic_symbolic_operand (operands[2], VOIDmode)"
5961   switch (get_attr_type (insn))
5962     {
5963     case TYPE_INCDEC:
5964       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5965       if (operands[2] == const1_rtx)
5966         return "inc{q}\t%0";
5967       else
5968         {
5969           gcc_assert (operands[2] == constm1_rtx);
5970           return "dec{q}\t%0";
5971         }
5973     default:
5974       gcc_assert (rtx_equal_p (operands[0], operands[1]));
5975       /* ???? We ought to handle there the 32bit case too
5976          - do we need new constraint?  */
5977       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
5978          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
5979       if (CONST_INT_P (operands[2])
5980           /* Avoid overflows.  */
5981           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
5982           && (INTVAL (operands[2]) == 128
5983               || (INTVAL (operands[2]) < 0
5984                   && INTVAL (operands[2]) != -128)))
5985         {
5986           operands[2] = GEN_INT (-INTVAL (operands[2]));
5987           return "sub{q}\t{%2, %0|%0, %2}";
5988         }
5989       return "add{q}\t{%2, %0|%0, %2}";
5990     }
5992   [(set (attr "type")
5993      (if_then_else (match_operand:DI 2 "incdec_operand" "")
5994         (const_string "incdec")
5995         (const_string "alu")))
5996    (set_attr "mode" "DI")])
5998 (define_insn "*adddi_3_rex64"
5999   [(set (reg FLAGS_REG)
6000         (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6001                  (match_operand:DI 1 "x86_64_general_operand" "%0")))
6002    (clobber (match_scratch:DI 0 "=r"))]
6003   "TARGET_64BIT
6004    && ix86_match_ccmode (insn, CCZmode)
6005    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6006    /* Current assemblers are broken and do not allow @GOTOFF in
6007       ought but a memory context.  */
6008    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6010   switch (get_attr_type (insn))
6011     {
6012     case TYPE_INCDEC:
6013       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6014       if (operands[2] == const1_rtx)
6015         return "inc{q}\t%0";
6016       else
6017         {
6018           gcc_assert (operands[2] == constm1_rtx);
6019           return "dec{q}\t%0";
6020         }
6022     default:
6023       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6024       /* ???? We ought to handle there the 32bit case too
6025          - do we need new constraint?  */
6026       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6027          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6028       if (CONST_INT_P (operands[2])
6029           /* Avoid overflows.  */
6030           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6031           && (INTVAL (operands[2]) == 128
6032               || (INTVAL (operands[2]) < 0
6033                   && INTVAL (operands[2]) != -128)))
6034         {
6035           operands[2] = GEN_INT (-INTVAL (operands[2]));
6036           return "sub{q}\t{%2, %0|%0, %2}";
6037         }
6038       return "add{q}\t{%2, %0|%0, %2}";
6039     }
6041   [(set (attr "type")
6042      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6043         (const_string "incdec")
6044         (const_string "alu")))
6045    (set_attr "mode" "DI")])
6047 ; For comparisons against 1, -1 and 128, we may generate better code
6048 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6049 ; is matched then.  We can't accept general immediate, because for
6050 ; case of overflows,  the result is messed up.
6051 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6052 ; when negated.
6053 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6054 ; only for comparisons not depending on it.
6055 (define_insn "*adddi_4_rex64"
6056   [(set (reg FLAGS_REG)
6057         (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6058                  (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6059    (clobber (match_scratch:DI 0 "=rm"))]
6060   "TARGET_64BIT
6061    &&  ix86_match_ccmode (insn, CCGCmode)"
6063   switch (get_attr_type (insn))
6064     {
6065     case TYPE_INCDEC:
6066       if (operands[2] == constm1_rtx)
6067         return "inc{q}\t%0";
6068       else
6069         {
6070           gcc_assert (operands[2] == const1_rtx);
6071           return "dec{q}\t%0";
6072         }
6074     default:
6075       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6076       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6077          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6078       if ((INTVAL (operands[2]) == -128
6079            || (INTVAL (operands[2]) > 0
6080                && INTVAL (operands[2]) != 128))
6081           /* Avoid overflows.  */
6082           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6083         return "sub{q}\t{%2, %0|%0, %2}";
6084       operands[2] = GEN_INT (-INTVAL (operands[2]));
6085       return "add{q}\t{%2, %0|%0, %2}";
6086     }
6088   [(set (attr "type")
6089      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6090         (const_string "incdec")
6091         (const_string "alu")))
6092    (set_attr "mode" "DI")])
6094 (define_insn "*adddi_5_rex64"
6095   [(set (reg FLAGS_REG)
6096         (compare
6097           (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6098                    (match_operand:DI 2 "x86_64_general_operand" "rme"))
6099           (const_int 0)))
6100    (clobber (match_scratch:DI 0 "=r"))]
6101   "TARGET_64BIT
6102    && ix86_match_ccmode (insn, CCGOCmode)
6103    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6104    /* Current assemblers are broken and do not allow @GOTOFF in
6105       ought but a memory context.  */
6106    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6108   switch (get_attr_type (insn))
6109     {
6110     case TYPE_INCDEC:
6111       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6112       if (operands[2] == const1_rtx)
6113         return "inc{q}\t%0";
6114       else
6115         {
6116           gcc_assert (operands[2] == constm1_rtx);
6117           return "dec{q}\t%0";
6118         }
6120     default:
6121       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6122       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6123          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6124       if (CONST_INT_P (operands[2])
6125           /* Avoid overflows.  */
6126           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6127           && (INTVAL (operands[2]) == 128
6128               || (INTVAL (operands[2]) < 0
6129                   && INTVAL (operands[2]) != -128)))
6130         {
6131           operands[2] = GEN_INT (-INTVAL (operands[2]));
6132           return "sub{q}\t{%2, %0|%0, %2}";
6133         }
6134       return "add{q}\t{%2, %0|%0, %2}";
6135     }
6137   [(set (attr "type")
6138      (if_then_else (match_operand:DI 2 "incdec_operand" "")
6139         (const_string "incdec")
6140         (const_string "alu")))
6141    (set_attr "mode" "DI")])
6144 (define_insn "*addsi_1"
6145   [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r")
6146         (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r")
6147                  (match_operand:SI 2 "general_operand" "rmni,rni,lni")))
6148    (clobber (reg:CC FLAGS_REG))]
6149   "ix86_binary_operator_ok (PLUS, SImode, operands)"
6151   switch (get_attr_type (insn))
6152     {
6153     case TYPE_LEA:
6154       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6155       return "lea{l}\t{%a2, %0|%0, %a2}";
6157     case TYPE_INCDEC:
6158       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6159       if (operands[2] == const1_rtx)
6160         return "inc{l}\t%0";
6161       else
6162         {
6163           gcc_assert (operands[2] == constm1_rtx);
6164           return "dec{l}\t%0";
6165         }
6167     default:
6168       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6170       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6171          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6172       if (CONST_INT_P (operands[2])
6173           && (INTVAL (operands[2]) == 128
6174               || (INTVAL (operands[2]) < 0
6175                   && INTVAL (operands[2]) != -128)))
6176         {
6177           operands[2] = GEN_INT (-INTVAL (operands[2]));
6178           return "sub{l}\t{%2, %0|%0, %2}";
6179         }
6180       return "add{l}\t{%2, %0|%0, %2}";
6181     }
6183   [(set (attr "type")
6184      (cond [(eq_attr "alternative" "2")
6185               (const_string "lea")
6186             ; Current assemblers are broken and do not allow @GOTOFF in
6187             ; ought but a memory context.
6188             (match_operand:SI 2 "pic_symbolic_operand" "")
6189               (const_string "lea")
6190             (match_operand:SI 2 "incdec_operand" "")
6191               (const_string "incdec")
6192            ]
6193            (const_string "alu")))
6194    (set_attr "mode" "SI")])
6196 ;; Convert lea to the lea pattern to avoid flags dependency.
6197 (define_split
6198   [(set (match_operand 0 "register_operand" "")
6199         (plus (match_operand 1 "register_operand" "")
6200               (match_operand 2 "nonmemory_operand" "")))
6201    (clobber (reg:CC FLAGS_REG))]
6202   "reload_completed
6203    && true_regnum (operands[0]) != true_regnum (operands[1])"
6204   [(const_int 0)]
6206   rtx pat;
6207   /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6208      may confuse gen_lowpart.  */
6209   if (GET_MODE (operands[0]) != Pmode)
6210     {
6211       operands[1] = gen_lowpart (Pmode, operands[1]);
6212       operands[2] = gen_lowpart (Pmode, operands[2]);
6213     }
6214   operands[0] = gen_lowpart (SImode, operands[0]);
6215   pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6216   if (Pmode != SImode)
6217     pat = gen_rtx_SUBREG (SImode, pat, 0);
6218   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6219   DONE;
6222 ;; It may seem that nonimmediate operand is proper one for operand 1.
6223 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6224 ;; we take care in ix86_binary_operator_ok to not allow two memory
6225 ;; operands so proper swapping will be done in reload.  This allow
6226 ;; patterns constructed from addsi_1 to match.
6227 (define_insn "addsi_1_zext"
6228   [(set (match_operand:DI 0 "register_operand" "=r,r")
6229         (zero_extend:DI
6230           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6231                    (match_operand:SI 2 "general_operand" "rmni,lni"))))
6232    (clobber (reg:CC FLAGS_REG))]
6233   "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6235   switch (get_attr_type (insn))
6236     {
6237     case TYPE_LEA:
6238       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6239       return "lea{l}\t{%a2, %k0|%k0, %a2}";
6241     case TYPE_INCDEC:
6242       if (operands[2] == const1_rtx)
6243         return "inc{l}\t%k0";
6244       else
6245         {
6246           gcc_assert (operands[2] == constm1_rtx);
6247           return "dec{l}\t%k0";
6248         }
6250     default:
6251       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6252          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6253       if (CONST_INT_P (operands[2])
6254           && (INTVAL (operands[2]) == 128
6255               || (INTVAL (operands[2]) < 0
6256                   && INTVAL (operands[2]) != -128)))
6257         {
6258           operands[2] = GEN_INT (-INTVAL (operands[2]));
6259           return "sub{l}\t{%2, %k0|%k0, %2}";
6260         }
6261       return "add{l}\t{%2, %k0|%k0, %2}";
6262     }
6264   [(set (attr "type")
6265      (cond [(eq_attr "alternative" "1")
6266               (const_string "lea")
6267             ; Current assemblers are broken and do not allow @GOTOFF in
6268             ; ought but a memory context.
6269             (match_operand:SI 2 "pic_symbolic_operand" "")
6270               (const_string "lea")
6271             (match_operand:SI 2 "incdec_operand" "")
6272               (const_string "incdec")
6273            ]
6274            (const_string "alu")))
6275    (set_attr "mode" "SI")])
6277 ;; Convert lea to the lea pattern to avoid flags dependency.
6278 (define_split
6279   [(set (match_operand:DI 0 "register_operand" "")
6280         (zero_extend:DI
6281           (plus:SI (match_operand:SI 1 "register_operand" "")
6282                    (match_operand:SI 2 "nonmemory_operand" ""))))
6283    (clobber (reg:CC FLAGS_REG))]
6284   "TARGET_64BIT && reload_completed
6285    && true_regnum (operands[0]) != true_regnum (operands[1])"
6286   [(set (match_dup 0)
6287         (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6289   operands[1] = gen_lowpart (Pmode, operands[1]);
6290   operands[2] = gen_lowpart (Pmode, operands[2]);
6293 (define_insn "*addsi_2"
6294   [(set (reg FLAGS_REG)
6295         (compare
6296           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6297                    (match_operand:SI 2 "general_operand" "rmni,rni"))
6298           (const_int 0)))
6299    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6300         (plus:SI (match_dup 1) (match_dup 2)))]
6301   "ix86_match_ccmode (insn, CCGOCmode)
6302    && ix86_binary_operator_ok (PLUS, SImode, operands)
6303    /* Current assemblers are broken and do not allow @GOTOFF in
6304       ought but a memory context.  */
6305    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6307   switch (get_attr_type (insn))
6308     {
6309     case TYPE_INCDEC:
6310       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6311       if (operands[2] == const1_rtx)
6312         return "inc{l}\t%0";
6313       else
6314         {
6315           gcc_assert (operands[2] == constm1_rtx);
6316           return "dec{l}\t%0";
6317         }
6319     default:
6320       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6321       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6322          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6323       if (CONST_INT_P (operands[2])
6324           && (INTVAL (operands[2]) == 128
6325               || (INTVAL (operands[2]) < 0
6326                   && INTVAL (operands[2]) != -128)))
6327         {
6328           operands[2] = GEN_INT (-INTVAL (operands[2]));
6329           return "sub{l}\t{%2, %0|%0, %2}";
6330         }
6331       return "add{l}\t{%2, %0|%0, %2}";
6332     }
6334   [(set (attr "type")
6335      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6336         (const_string "incdec")
6337         (const_string "alu")))
6338    (set_attr "mode" "SI")])
6340 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6341 (define_insn "*addsi_2_zext"
6342   [(set (reg FLAGS_REG)
6343         (compare
6344           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6345                    (match_operand:SI 2 "general_operand" "rmni"))
6346           (const_int 0)))
6347    (set (match_operand:DI 0 "register_operand" "=r")
6348         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6349   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6350    && ix86_binary_operator_ok (PLUS, SImode, operands)
6351    /* Current assemblers are broken and do not allow @GOTOFF in
6352       ought but a memory context.  */
6353    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6355   switch (get_attr_type (insn))
6356     {
6357     case TYPE_INCDEC:
6358       if (operands[2] == const1_rtx)
6359         return "inc{l}\t%k0";
6360       else
6361         {
6362           gcc_assert (operands[2] == constm1_rtx);
6363           return "dec{l}\t%k0";
6364         }
6366     default:
6367       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6368          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6369       if (CONST_INT_P (operands[2])
6370           && (INTVAL (operands[2]) == 128
6371               || (INTVAL (operands[2]) < 0
6372                   && INTVAL (operands[2]) != -128)))
6373         {
6374           operands[2] = GEN_INT (-INTVAL (operands[2]));
6375           return "sub{l}\t{%2, %k0|%k0, %2}";
6376         }
6377       return "add{l}\t{%2, %k0|%k0, %2}";
6378     }
6380   [(set (attr "type")
6381      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6382         (const_string "incdec")
6383         (const_string "alu")))
6384    (set_attr "mode" "SI")])
6386 (define_insn "*addsi_3"
6387   [(set (reg FLAGS_REG)
6388         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6389                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6390    (clobber (match_scratch:SI 0 "=r"))]
6391   "ix86_match_ccmode (insn, CCZmode)
6392    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6393    /* Current assemblers are broken and do not allow @GOTOFF in
6394       ought but a memory context.  */
6395    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6397   switch (get_attr_type (insn))
6398     {
6399     case TYPE_INCDEC:
6400       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6401       if (operands[2] == const1_rtx)
6402         return "inc{l}\t%0";
6403       else
6404         {
6405           gcc_assert (operands[2] == constm1_rtx);
6406           return "dec{l}\t%0";
6407         }
6409     default:
6410       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6411       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6412          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6413       if (CONST_INT_P (operands[2])
6414           && (INTVAL (operands[2]) == 128
6415               || (INTVAL (operands[2]) < 0
6416                   && INTVAL (operands[2]) != -128)))
6417         {
6418           operands[2] = GEN_INT (-INTVAL (operands[2]));
6419           return "sub{l}\t{%2, %0|%0, %2}";
6420         }
6421       return "add{l}\t{%2, %0|%0, %2}";
6422     }
6424   [(set (attr "type")
6425      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6426         (const_string "incdec")
6427         (const_string "alu")))
6428    (set_attr "mode" "SI")])
6430 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6431 (define_insn "*addsi_3_zext"
6432   [(set (reg FLAGS_REG)
6433         (compare (neg:SI (match_operand:SI 2 "general_operand" "rmni"))
6434                  (match_operand:SI 1 "nonimmediate_operand" "%0")))
6435    (set (match_operand:DI 0 "register_operand" "=r")
6436         (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6437   "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6438    && ix86_binary_operator_ok (PLUS, SImode, operands)
6439    /* Current assemblers are broken and do not allow @GOTOFF in
6440       ought but a memory context.  */
6441    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6443   switch (get_attr_type (insn))
6444     {
6445     case TYPE_INCDEC:
6446       if (operands[2] == const1_rtx)
6447         return "inc{l}\t%k0";
6448       else
6449         {
6450           gcc_assert (operands[2] == constm1_rtx);
6451           return "dec{l}\t%k0";
6452         }
6454     default:
6455       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6456          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6457       if (CONST_INT_P (operands[2])
6458           && (INTVAL (operands[2]) == 128
6459               || (INTVAL (operands[2]) < 0
6460                   && INTVAL (operands[2]) != -128)))
6461         {
6462           operands[2] = GEN_INT (-INTVAL (operands[2]));
6463           return "sub{l}\t{%2, %k0|%k0, %2}";
6464         }
6465       return "add{l}\t{%2, %k0|%k0, %2}";
6466     }
6468   [(set (attr "type")
6469      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6470         (const_string "incdec")
6471         (const_string "alu")))
6472    (set_attr "mode" "SI")])
6474 ; For comparisons against 1, -1 and 128, we may generate better code
6475 ; by converting cmp to add, inc or dec as done by peephole2.  This pattern
6476 ; is matched then.  We can't accept general immediate, because for
6477 ; case of overflows,  the result is messed up.
6478 ; This pattern also don't hold of 0x80000000, since the value overflows
6479 ; when negated.
6480 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6481 ; only for comparisons not depending on it.
6482 (define_insn "*addsi_4"
6483   [(set (reg FLAGS_REG)
6484         (compare (match_operand:SI 1 "nonimmediate_operand" "0")
6485                  (match_operand:SI 2 "const_int_operand" "n")))
6486    (clobber (match_scratch:SI 0 "=rm"))]
6487   "ix86_match_ccmode (insn, CCGCmode)
6488    && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6490   switch (get_attr_type (insn))
6491     {
6492     case TYPE_INCDEC:
6493       if (operands[2] == constm1_rtx)
6494         return "inc{l}\t%0";
6495       else
6496         {
6497           gcc_assert (operands[2] == const1_rtx);
6498           return "dec{l}\t%0";
6499         }
6501     default:
6502       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6503       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6504          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6505       if ((INTVAL (operands[2]) == -128
6506            || (INTVAL (operands[2]) > 0
6507                && INTVAL (operands[2]) != 128)))
6508         return "sub{l}\t{%2, %0|%0, %2}";
6509       operands[2] = GEN_INT (-INTVAL (operands[2]));
6510       return "add{l}\t{%2, %0|%0, %2}";
6511     }
6513   [(set (attr "type")
6514      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6515         (const_string "incdec")
6516         (const_string "alu")))
6517    (set_attr "mode" "SI")])
6519 (define_insn "*addsi_5"
6520   [(set (reg FLAGS_REG)
6521         (compare
6522           (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6523                    (match_operand:SI 2 "general_operand" "rmni"))
6524           (const_int 0)))
6525    (clobber (match_scratch:SI 0 "=r"))]
6526   "ix86_match_ccmode (insn, CCGOCmode)
6527    && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6528    /* Current assemblers are broken and do not allow @GOTOFF in
6529       ought but a memory context.  */
6530    && ! pic_symbolic_operand (operands[2], VOIDmode)"
6532   switch (get_attr_type (insn))
6533     {
6534     case TYPE_INCDEC:
6535       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6536       if (operands[2] == const1_rtx)
6537         return "inc{l}\t%0";
6538       else
6539         {
6540           gcc_assert (operands[2] == constm1_rtx);
6541           return "dec{l}\t%0";
6542         }
6544     default:
6545       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6546       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6547          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6548       if (CONST_INT_P (operands[2])
6549           && (INTVAL (operands[2]) == 128
6550               || (INTVAL (operands[2]) < 0
6551                   && INTVAL (operands[2]) != -128)))
6552         {
6553           operands[2] = GEN_INT (-INTVAL (operands[2]));
6554           return "sub{l}\t{%2, %0|%0, %2}";
6555         }
6556       return "add{l}\t{%2, %0|%0, %2}";
6557     }
6559   [(set (attr "type")
6560      (if_then_else (match_operand:SI 2 "incdec_operand" "")
6561         (const_string "incdec")
6562         (const_string "alu")))
6563    (set_attr "mode" "SI")])
6565 (define_expand "addhi3"
6566   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
6567                    (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
6568                             (match_operand:HI 2 "general_operand" "")))
6569               (clobber (reg:CC FLAGS_REG))])]
6570   "TARGET_HIMODE_MATH"
6571   "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
6573 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6574 ;; type optimizations enabled by define-splits.  This is not important
6575 ;; for PII, and in fact harmful because of partial register stalls.
6577 (define_insn "*addhi_1_lea"
6578   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6579         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6580                  (match_operand:HI 2 "general_operand" "ri,rm,lni")))
6581    (clobber (reg:CC FLAGS_REG))]
6582   "!TARGET_PARTIAL_REG_STALL
6583    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6585   switch (get_attr_type (insn))
6586     {
6587     case TYPE_LEA:
6588       return "#";
6589     case TYPE_INCDEC:
6590       if (operands[2] == const1_rtx)
6591         return "inc{w}\t%0";
6592       else
6593         {
6594           gcc_assert (operands[2] == constm1_rtx);
6595           return "dec{w}\t%0";
6596         }
6598     default:
6599       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6600          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6601       if (CONST_INT_P (operands[2])
6602           && (INTVAL (operands[2]) == 128
6603               || (INTVAL (operands[2]) < 0
6604                   && INTVAL (operands[2]) != -128)))
6605         {
6606           operands[2] = GEN_INT (-INTVAL (operands[2]));
6607           return "sub{w}\t{%2, %0|%0, %2}";
6608         }
6609       return "add{w}\t{%2, %0|%0, %2}";
6610     }
6612   [(set (attr "type")
6613      (if_then_else (eq_attr "alternative" "2")
6614         (const_string "lea")
6615         (if_then_else (match_operand:HI 2 "incdec_operand" "")
6616            (const_string "incdec")
6617            (const_string "alu"))))
6618    (set_attr "mode" "HI,HI,SI")])
6620 (define_insn "*addhi_1"
6621   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6622         (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6623                  (match_operand:HI 2 "general_operand" "ri,rm")))
6624    (clobber (reg:CC FLAGS_REG))]
6625   "TARGET_PARTIAL_REG_STALL
6626    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6628   switch (get_attr_type (insn))
6629     {
6630     case TYPE_INCDEC:
6631       if (operands[2] == const1_rtx)
6632         return "inc{w}\t%0";
6633       else
6634         {
6635           gcc_assert (operands[2] == constm1_rtx);
6636           return "dec{w}\t%0";
6637         }
6639     default:
6640       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6641          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6642       if (CONST_INT_P (operands[2])
6643           && (INTVAL (operands[2]) == 128
6644               || (INTVAL (operands[2]) < 0
6645                   && INTVAL (operands[2]) != -128)))
6646         {
6647           operands[2] = GEN_INT (-INTVAL (operands[2]));
6648           return "sub{w}\t{%2, %0|%0, %2}";
6649         }
6650       return "add{w}\t{%2, %0|%0, %2}";
6651     }
6653   [(set (attr "type")
6654      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6655         (const_string "incdec")
6656         (const_string "alu")))
6657    (set_attr "mode" "HI")])
6659 (define_insn "*addhi_2"
6660   [(set (reg FLAGS_REG)
6661         (compare
6662           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6663                    (match_operand:HI 2 "general_operand" "rmni,rni"))
6664           (const_int 0)))
6665    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6666         (plus:HI (match_dup 1) (match_dup 2)))]
6667   "ix86_match_ccmode (insn, CCGOCmode)
6668    && ix86_binary_operator_ok (PLUS, HImode, operands)"
6670   switch (get_attr_type (insn))
6671     {
6672     case TYPE_INCDEC:
6673       if (operands[2] == const1_rtx)
6674         return "inc{w}\t%0";
6675       else
6676         {
6677           gcc_assert (operands[2] == constm1_rtx);
6678           return "dec{w}\t%0";
6679         }
6681     default:
6682       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6683          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6684       if (CONST_INT_P (operands[2])
6685           && (INTVAL (operands[2]) == 128
6686               || (INTVAL (operands[2]) < 0
6687                   && INTVAL (operands[2]) != -128)))
6688         {
6689           operands[2] = GEN_INT (-INTVAL (operands[2]));
6690           return "sub{w}\t{%2, %0|%0, %2}";
6691         }
6692       return "add{w}\t{%2, %0|%0, %2}";
6693     }
6695   [(set (attr "type")
6696      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6697         (const_string "incdec")
6698         (const_string "alu")))
6699    (set_attr "mode" "HI")])
6701 (define_insn "*addhi_3"
6702   [(set (reg FLAGS_REG)
6703         (compare (neg:HI (match_operand:HI 2 "general_operand" "rmni"))
6704                  (match_operand:HI 1 "nonimmediate_operand" "%0")))
6705    (clobber (match_scratch:HI 0 "=r"))]
6706   "ix86_match_ccmode (insn, CCZmode)
6707    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6709   switch (get_attr_type (insn))
6710     {
6711     case TYPE_INCDEC:
6712       if (operands[2] == const1_rtx)
6713         return "inc{w}\t%0";
6714       else
6715         {
6716           gcc_assert (operands[2] == constm1_rtx);
6717           return "dec{w}\t%0";
6718         }
6720     default:
6721       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6722          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6723       if (CONST_INT_P (operands[2])
6724           && (INTVAL (operands[2]) == 128
6725               || (INTVAL (operands[2]) < 0
6726                   && INTVAL (operands[2]) != -128)))
6727         {
6728           operands[2] = GEN_INT (-INTVAL (operands[2]));
6729           return "sub{w}\t{%2, %0|%0, %2}";
6730         }
6731       return "add{w}\t{%2, %0|%0, %2}";
6732     }
6734   [(set (attr "type")
6735      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6736         (const_string "incdec")
6737         (const_string "alu")))
6738    (set_attr "mode" "HI")])
6740 ; See comments above addsi_4 for details.
6741 (define_insn "*addhi_4"
6742   [(set (reg FLAGS_REG)
6743         (compare (match_operand:HI 1 "nonimmediate_operand" "0")
6744                  (match_operand:HI 2 "const_int_operand" "n")))
6745    (clobber (match_scratch:HI 0 "=rm"))]
6746   "ix86_match_ccmode (insn, CCGCmode)
6747    && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6749   switch (get_attr_type (insn))
6750     {
6751     case TYPE_INCDEC:
6752       if (operands[2] == constm1_rtx)
6753         return "inc{w}\t%0";
6754       else
6755         {
6756           gcc_assert (operands[2] == const1_rtx);
6757           return "dec{w}\t%0";
6758         }
6760     default:
6761       gcc_assert (rtx_equal_p (operands[0], operands[1]));
6762       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6763          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6764       if ((INTVAL (operands[2]) == -128
6765            || (INTVAL (operands[2]) > 0
6766                && INTVAL (operands[2]) != 128)))
6767         return "sub{w}\t{%2, %0|%0, %2}";
6768       operands[2] = GEN_INT (-INTVAL (operands[2]));
6769       return "add{w}\t{%2, %0|%0, %2}";
6770     }
6772   [(set (attr "type")
6773      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6774         (const_string "incdec")
6775         (const_string "alu")))
6776    (set_attr "mode" "SI")])
6779 (define_insn "*addhi_5"
6780   [(set (reg FLAGS_REG)
6781         (compare
6782           (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6783                    (match_operand:HI 2 "general_operand" "rmni"))
6784           (const_int 0)))
6785    (clobber (match_scratch:HI 0 "=r"))]
6786   "ix86_match_ccmode (insn, CCGOCmode)
6787    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6789   switch (get_attr_type (insn))
6790     {
6791     case TYPE_INCDEC:
6792       if (operands[2] == const1_rtx)
6793         return "inc{w}\t%0";
6794       else
6795         {
6796           gcc_assert (operands[2] == constm1_rtx);
6797           return "dec{w}\t%0";
6798         }
6800     default:
6801       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6802          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6803       if (CONST_INT_P (operands[2])
6804           && (INTVAL (operands[2]) == 128
6805               || (INTVAL (operands[2]) < 0
6806                   && INTVAL (operands[2]) != -128)))
6807         {
6808           operands[2] = GEN_INT (-INTVAL (operands[2]));
6809           return "sub{w}\t{%2, %0|%0, %2}";
6810         }
6811       return "add{w}\t{%2, %0|%0, %2}";
6812     }
6814   [(set (attr "type")
6815      (if_then_else (match_operand:HI 2 "incdec_operand" "")
6816         (const_string "incdec")
6817         (const_string "alu")))
6818    (set_attr "mode" "HI")])
6820 (define_expand "addqi3"
6821   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
6822                    (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
6823                             (match_operand:QI 2 "general_operand" "")))
6824               (clobber (reg:CC FLAGS_REG))])]
6825   "TARGET_QIMODE_MATH"
6826   "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
6828 ;; %%% Potential partial reg stall on alternative 2.  What to do?
6829 (define_insn "*addqi_1_lea"
6830   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6831         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6832                  (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6833    (clobber (reg:CC FLAGS_REG))]
6834   "!TARGET_PARTIAL_REG_STALL
6835    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6837   int widen = (which_alternative == 2);
6838   switch (get_attr_type (insn))
6839     {
6840     case TYPE_LEA:
6841       return "#";
6842     case TYPE_INCDEC:
6843       if (operands[2] == const1_rtx)
6844         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6845       else
6846         {
6847           gcc_assert (operands[2] == constm1_rtx);
6848           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6849         }
6851     default:
6852       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6853          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6854       if (CONST_INT_P (operands[2])
6855           && (INTVAL (operands[2]) == 128
6856               || (INTVAL (operands[2]) < 0
6857                   && INTVAL (operands[2]) != -128)))
6858         {
6859           operands[2] = GEN_INT (-INTVAL (operands[2]));
6860           if (widen)
6861             return "sub{l}\t{%2, %k0|%k0, %2}";
6862           else
6863             return "sub{b}\t{%2, %0|%0, %2}";
6864         }
6865       if (widen)
6866         return "add{l}\t{%k2, %k0|%k0, %k2}";
6867       else
6868         return "add{b}\t{%2, %0|%0, %2}";
6869     }
6871   [(set (attr "type")
6872      (if_then_else (eq_attr "alternative" "3")
6873         (const_string "lea")
6874         (if_then_else (match_operand:QI 2 "incdec_operand" "")
6875            (const_string "incdec")
6876            (const_string "alu"))))
6877    (set_attr "mode" "QI,QI,SI,SI")])
6879 (define_insn "*addqi_1"
6880   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6881         (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6882                  (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6883    (clobber (reg:CC FLAGS_REG))]
6884   "TARGET_PARTIAL_REG_STALL
6885    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6887   int widen = (which_alternative == 2);
6888   switch (get_attr_type (insn))
6889     {
6890     case TYPE_INCDEC:
6891       if (operands[2] == const1_rtx)
6892         return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6893       else
6894         {
6895           gcc_assert (operands[2] == constm1_rtx);
6896           return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6897         }
6899     default:
6900       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6901          Exceptions: -128 encodes smaller than 128, so swap sign and op.  */
6902       if (CONST_INT_P (operands[2])
6903           && (INTVAL (operands[2]) == 128
6904               || (INTVAL (operands[2]) < 0
6905                   && INTVAL (operands[2]) != -128)))
6906         {
6907           operands[2] = GEN_INT (-INTVAL (operands[2]));
6908           if (widen)
6909             return "sub{l}\t{%2, %k0|%k0, %2}";
6910           else
6911             return "sub{b}\t{%2, %0|%0, %2}";
6912         }
6913       if (widen)
6914         return "add{l}\t{%k2, %k0|%k0, %k2}";
6915       else
6916         return "add{b}\t{%2, %0|%0, %2}";
6917     }
6919   [(set (attr "type")
6920      (if_then_else (match_operand:QI 2 "incdec_operand" "")
6921         (const_string "incdec")
6922         (const_string "alu")))
6923    (set_attr "mode" "QI,QI,SI")])
6925 (define_insn "*addqi_1_slp"
6926   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6927         (plus:QI (match_dup 0)
6928                  (match_operand:QI 1 "general_operand" "qn,qnm")))
6929    (clobber (reg:CC FLAGS_REG))]
6930   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
6931    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6933   switch (get_attr_type (insn))
6934     {
6935     case TYPE_INCDEC:
6936       if (operands[1] == const1_rtx)
6937         return "inc{b}\t%0";
6938       else
6939         {
6940           gcc_assert (operands[1] == constm1_rtx);
6941           return "dec{b}\t%0";
6942         }
6944     default:
6945       /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.  */
6946       if (CONST_INT_P (operands[1])
6947           && INTVAL (operands[1]) < 0)
6948         {
6949           operands[1] = GEN_INT (-INTVAL (operands[1]));
6950           return "sub{b}\t{%1, %0|%0, %1}";
6951         }
6952       return "add{b}\t{%1, %0|%0, %1}";
6953     }
6955   [(set (attr "type")
6956      (if_then_else (match_operand:QI 1 "incdec_operand" "")
6957         (const_string "incdec")
6958         (const_string "alu1")))
6959    (set (attr "memory")
6960      (if_then_else (match_operand 1 "memory_operand" "")
6961         (const_string "load")
6962         (const_string "none")))
6963    (set_attr "mode" "QI")])
6965 (define_insn "*addqi_2"
6966   [(set (reg FLAGS_REG)
6967         (compare
6968           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6969                    (match_operand:QI 2 "general_operand" "qmni,qni"))
6970           (const_int 0)))
6971    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6972         (plus:QI (match_dup 1) (match_dup 2)))]
6973   "ix86_match_ccmode (insn, CCGOCmode)
6974    && ix86_binary_operator_ok (PLUS, QImode, operands)"
6976   switch (get_attr_type (insn))
6977     {
6978     case TYPE_INCDEC:
6979       if (operands[2] == const1_rtx)
6980         return "inc{b}\t%0";
6981       else
6982         {
6983           gcc_assert (operands[2] == constm1_rtx
6984                       || (CONST_INT_P (operands[2])
6985                           && INTVAL (operands[2]) == 255));
6986           return "dec{b}\t%0";
6987         }
6989     default:
6990       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
6991       if (CONST_INT_P (operands[2])
6992           && INTVAL (operands[2]) < 0)
6993         {
6994           operands[2] = GEN_INT (-INTVAL (operands[2]));
6995           return "sub{b}\t{%2, %0|%0, %2}";
6996         }
6997       return "add{b}\t{%2, %0|%0, %2}";
6998     }
7000   [(set (attr "type")
7001      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7002         (const_string "incdec")
7003         (const_string "alu")))
7004    (set_attr "mode" "QI")])
7006 (define_insn "*addqi_3"
7007   [(set (reg FLAGS_REG)
7008         (compare (neg:QI (match_operand:QI 2 "general_operand" "qmni"))
7009                  (match_operand:QI 1 "nonimmediate_operand" "%0")))
7010    (clobber (match_scratch:QI 0 "=q"))]
7011   "ix86_match_ccmode (insn, CCZmode)
7012    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7014   switch (get_attr_type (insn))
7015     {
7016     case TYPE_INCDEC:
7017       if (operands[2] == const1_rtx)
7018         return "inc{b}\t%0";
7019       else
7020         {
7021           gcc_assert (operands[2] == constm1_rtx
7022                       || (CONST_INT_P (operands[2])
7023                           && INTVAL (operands[2]) == 255));
7024           return "dec{b}\t%0";
7025         }
7027     default:
7028       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7029       if (CONST_INT_P (operands[2])
7030           && INTVAL (operands[2]) < 0)
7031         {
7032           operands[2] = GEN_INT (-INTVAL (operands[2]));
7033           return "sub{b}\t{%2, %0|%0, %2}";
7034         }
7035       return "add{b}\t{%2, %0|%0, %2}";
7036     }
7038   [(set (attr "type")
7039      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7040         (const_string "incdec")
7041         (const_string "alu")))
7042    (set_attr "mode" "QI")])
7044 ; See comments above addsi_4 for details.
7045 (define_insn "*addqi_4"
7046   [(set (reg FLAGS_REG)
7047         (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7048                  (match_operand:QI 2 "const_int_operand" "n")))
7049    (clobber (match_scratch:QI 0 "=qm"))]
7050   "ix86_match_ccmode (insn, CCGCmode)
7051    && (INTVAL (operands[2]) & 0xff) != 0x80"
7053   switch (get_attr_type (insn))
7054     {
7055     case TYPE_INCDEC:
7056       if (operands[2] == constm1_rtx
7057           || (CONST_INT_P (operands[2])
7058               && INTVAL (operands[2]) == 255))
7059         return "inc{b}\t%0";
7060       else
7061         {
7062           gcc_assert (operands[2] == const1_rtx);
7063           return "dec{b}\t%0";
7064         }
7066     default:
7067       gcc_assert (rtx_equal_p (operands[0], operands[1]));
7068       if (INTVAL (operands[2]) < 0)
7069         {
7070           operands[2] = GEN_INT (-INTVAL (operands[2]));
7071           return "add{b}\t{%2, %0|%0, %2}";
7072         }
7073       return "sub{b}\t{%2, %0|%0, %2}";
7074     }
7076   [(set (attr "type")
7077      (if_then_else (match_operand:HI 2 "incdec_operand" "")
7078         (const_string "incdec")
7079         (const_string "alu")))
7080    (set_attr "mode" "QI")])
7083 (define_insn "*addqi_5"
7084   [(set (reg FLAGS_REG)
7085         (compare
7086           (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7087                    (match_operand:QI 2 "general_operand" "qmni"))
7088           (const_int 0)))
7089    (clobber (match_scratch:QI 0 "=q"))]
7090   "ix86_match_ccmode (insn, CCGOCmode)
7091    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7093   switch (get_attr_type (insn))
7094     {
7095     case TYPE_INCDEC:
7096       if (operands[2] == const1_rtx)
7097         return "inc{b}\t%0";
7098       else
7099         {
7100           gcc_assert (operands[2] == constm1_rtx
7101                       || (CONST_INT_P (operands[2])
7102                           && INTVAL (operands[2]) == 255));
7103           return "dec{b}\t%0";
7104         }
7106     default:
7107       /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'.  */
7108       if (CONST_INT_P (operands[2])
7109           && INTVAL (operands[2]) < 0)
7110         {
7111           operands[2] = GEN_INT (-INTVAL (operands[2]));
7112           return "sub{b}\t{%2, %0|%0, %2}";
7113         }
7114       return "add{b}\t{%2, %0|%0, %2}";
7115     }
7117   [(set (attr "type")
7118      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7119         (const_string "incdec")
7120         (const_string "alu")))
7121    (set_attr "mode" "QI")])
7124 (define_insn "addqi_ext_1"
7125   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7126                          (const_int 8)
7127                          (const_int 8))
7128         (plus:SI
7129           (zero_extract:SI
7130             (match_operand 1 "ext_register_operand" "0")
7131             (const_int 8)
7132             (const_int 8))
7133           (match_operand:QI 2 "general_operand" "Qmn")))
7134    (clobber (reg:CC FLAGS_REG))]
7135   "!TARGET_64BIT"
7137   switch (get_attr_type (insn))
7138     {
7139     case TYPE_INCDEC:
7140       if (operands[2] == const1_rtx)
7141         return "inc{b}\t%h0";
7142       else
7143         {
7144           gcc_assert (operands[2] == constm1_rtx
7145                       || (CONST_INT_P (operands[2])
7146                           && INTVAL (operands[2]) == 255));
7147           return "dec{b}\t%h0";
7148         }
7150     default:
7151       return "add{b}\t{%2, %h0|%h0, %2}";
7152     }
7154   [(set (attr "type")
7155      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7156         (const_string "incdec")
7157         (const_string "alu")))
7158    (set_attr "mode" "QI")])
7160 (define_insn "*addqi_ext_1_rex64"
7161   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7162                          (const_int 8)
7163                          (const_int 8))
7164         (plus:SI
7165           (zero_extract:SI
7166             (match_operand 1 "ext_register_operand" "0")
7167             (const_int 8)
7168             (const_int 8))
7169           (match_operand:QI 2 "nonmemory_operand" "Qn")))
7170    (clobber (reg:CC FLAGS_REG))]
7171   "TARGET_64BIT"
7173   switch (get_attr_type (insn))
7174     {
7175     case TYPE_INCDEC:
7176       if (operands[2] == const1_rtx)
7177         return "inc{b}\t%h0";
7178       else
7179         {
7180           gcc_assert (operands[2] == constm1_rtx
7181                       || (CONST_INT_P (operands[2])
7182                           && INTVAL (operands[2]) == 255));
7183           return "dec{b}\t%h0";
7184         }
7186     default:
7187       return "add{b}\t{%2, %h0|%h0, %2}";
7188     }
7190   [(set (attr "type")
7191      (if_then_else (match_operand:QI 2 "incdec_operand" "")
7192         (const_string "incdec")
7193         (const_string "alu")))
7194    (set_attr "mode" "QI")])
7196 (define_insn "*addqi_ext_2"
7197   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7198                          (const_int 8)
7199                          (const_int 8))
7200         (plus:SI
7201           (zero_extract:SI
7202             (match_operand 1 "ext_register_operand" "%0")
7203             (const_int 8)
7204             (const_int 8))
7205           (zero_extract:SI
7206             (match_operand 2 "ext_register_operand" "Q")
7207             (const_int 8)
7208             (const_int 8))))
7209    (clobber (reg:CC FLAGS_REG))]
7210   ""
7211   "add{b}\t{%h2, %h0|%h0, %h2}"
7212   [(set_attr "type" "alu")
7213    (set_attr "mode" "QI")])
7215 ;; The patterns that match these are at the end of this file.
7217 (define_expand "addxf3"
7218   [(set (match_operand:XF 0 "register_operand" "")
7219         (plus:XF (match_operand:XF 1 "register_operand" "")
7220                  (match_operand:XF 2 "register_operand" "")))]
7221   "TARGET_80387"
7222   "")
7224 (define_expand "add<mode>3"
7225   [(set (match_operand:MODEF 0 "register_operand" "")
7226         (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7227                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7228   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7229   "")
7231 ;; Subtract instructions
7233 ;; %%% splits for subditi3
7235 (define_expand "subti3"
7236   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
7237                    (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7238                              (match_operand:TI 2 "x86_64_general_operand" "")))
7239               (clobber (reg:CC FLAGS_REG))])]
7240   "TARGET_64BIT"
7241   "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7243 (define_insn "*subti3_1"
7244   [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7245         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7246                   (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7247    (clobber (reg:CC FLAGS_REG))]
7248   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7249   "#")
7251 (define_split
7252   [(set (match_operand:TI 0 "nonimmediate_operand" "")
7253         (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7254                   (match_operand:TI 2 "x86_64_general_operand" "")))
7255    (clobber (reg:CC FLAGS_REG))]
7256   "TARGET_64BIT && reload_completed"
7257   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7258               (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7259    (parallel [(set (match_dup 3)
7260                    (minus:DI (match_dup 4)
7261                              (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7262                                       (match_dup 5))))
7263               (clobber (reg:CC FLAGS_REG))])]
7264   "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7266 ;; %%% splits for subsidi3
7268 (define_expand "subdi3"
7269   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
7270                    (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7271                              (match_operand:DI 2 "x86_64_general_operand" "")))
7272               (clobber (reg:CC FLAGS_REG))])]
7273   ""
7274   "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
7276 (define_insn "*subdi3_1"
7277   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
7278         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7279                   (match_operand:DI 2 "general_operand" "roiF,riF")))
7280    (clobber (reg:CC FLAGS_REG))]
7281   "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7282   "#")
7284 (define_split
7285   [(set (match_operand:DI 0 "nonimmediate_operand" "")
7286         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7287                   (match_operand:DI 2 "general_operand" "")))
7288    (clobber (reg:CC FLAGS_REG))]
7289   "!TARGET_64BIT && reload_completed"
7290   [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7291               (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
7292    (parallel [(set (match_dup 3)
7293                    (minus:SI (match_dup 4)
7294                              (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
7295                                       (match_dup 5))))
7296               (clobber (reg:CC FLAGS_REG))])]
7297   "split_di (&operands[0], 3, &operands[0], &operands[3]);")
7299 (define_insn "subdi3_carry_rex64"
7300   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7301           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7302             (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
7303                (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
7304    (clobber (reg:CC FLAGS_REG))]
7305   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7306   "sbb{q}\t{%2, %0|%0, %2}"
7307   [(set_attr "type" "alu")
7308    (set_attr "pent_pair" "pu")
7309    (set_attr "mode" "DI")])
7311 (define_insn "*subdi_1_rex64"
7312   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7313         (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7314                   (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7315    (clobber (reg:CC FLAGS_REG))]
7316   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
7317   "sub{q}\t{%2, %0|%0, %2}"
7318   [(set_attr "type" "alu")
7319    (set_attr "mode" "DI")])
7321 (define_insn "*subdi_2_rex64"
7322   [(set (reg FLAGS_REG)
7323         (compare
7324           (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
7325                     (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
7326           (const_int 0)))
7327    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7328         (minus:DI (match_dup 1) (match_dup 2)))]
7329   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7330    && ix86_binary_operator_ok (MINUS, DImode, operands)"
7331   "sub{q}\t{%2, %0|%0, %2}"
7332   [(set_attr "type" "alu")
7333    (set_attr "mode" "DI")])
7335 (define_insn "*subdi_3_rex63"
7336   [(set (reg FLAGS_REG)
7337         (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
7338                  (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
7339    (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
7340         (minus:DI (match_dup 1) (match_dup 2)))]
7341   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7342    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7343   "sub{q}\t{%2, %0|%0, %2}"
7344   [(set_attr "type" "alu")
7345    (set_attr "mode" "DI")])
7347 (define_insn "subqi3_carry"
7348   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7349           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7350             (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
7351                (match_operand:QI 2 "general_operand" "qi,qm"))))
7352    (clobber (reg:CC FLAGS_REG))]
7353   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7354   "sbb{b}\t{%2, %0|%0, %2}"
7355   [(set_attr "type" "alu")
7356    (set_attr "pent_pair" "pu")
7357    (set_attr "mode" "QI")])
7359 (define_insn "subhi3_carry"
7360   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7361           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7362             (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
7363                (match_operand:HI 2 "general_operand" "ri,rm"))))
7364    (clobber (reg:CC FLAGS_REG))]
7365   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7366   "sbb{w}\t{%2, %0|%0, %2}"
7367   [(set_attr "type" "alu")
7368    (set_attr "pent_pair" "pu")
7369    (set_attr "mode" "HI")])
7371 (define_insn "subsi3_carry"
7372   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7373           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7374             (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7375                (match_operand:SI 2 "general_operand" "ri,rm"))))
7376    (clobber (reg:CC FLAGS_REG))]
7377   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7378   "sbb{l}\t{%2, %0|%0, %2}"
7379   [(set_attr "type" "alu")
7380    (set_attr "pent_pair" "pu")
7381    (set_attr "mode" "SI")])
7383 (define_insn "subsi3_carry_zext"
7384   [(set (match_operand:DI 0 "register_operand" "=r")
7385           (zero_extend:DI
7386             (minus:SI (match_operand:SI 1 "register_operand" "0")
7387               (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7388                  (match_operand:SI 2 "general_operand" "g")))))
7389    (clobber (reg:CC FLAGS_REG))]
7390   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7391   "sbb{l}\t{%2, %k0|%k0, %2}"
7392   [(set_attr "type" "alu")
7393    (set_attr "pent_pair" "pu")
7394    (set_attr "mode" "SI")])
7396 (define_expand "subsi3"
7397   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
7398                    (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
7399                              (match_operand:SI 2 "general_operand" "")))
7400               (clobber (reg:CC FLAGS_REG))])]
7401   ""
7402   "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
7404 (define_insn "*subsi_1"
7405   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7406         (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7407                   (match_operand:SI 2 "general_operand" "ri,rm")))
7408    (clobber (reg:CC FLAGS_REG))]
7409   "ix86_binary_operator_ok (MINUS, SImode, operands)"
7410   "sub{l}\t{%2, %0|%0, %2}"
7411   [(set_attr "type" "alu")
7412    (set_attr "mode" "SI")])
7414 (define_insn "*subsi_1_zext"
7415   [(set (match_operand:DI 0 "register_operand" "=r")
7416         (zero_extend:DI
7417           (minus:SI (match_operand:SI 1 "register_operand" "0")
7418                     (match_operand:SI 2 "general_operand" "g"))))
7419    (clobber (reg:CC FLAGS_REG))]
7420   "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7421   "sub{l}\t{%2, %k0|%k0, %2}"
7422   [(set_attr "type" "alu")
7423    (set_attr "mode" "SI")])
7425 (define_insn "*subsi_2"
7426   [(set (reg FLAGS_REG)
7427         (compare
7428           (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
7429                     (match_operand:SI 2 "general_operand" "ri,rm"))
7430           (const_int 0)))
7431    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7432         (minus:SI (match_dup 1) (match_dup 2)))]
7433   "ix86_match_ccmode (insn, CCGOCmode)
7434    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7435   "sub{l}\t{%2, %0|%0, %2}"
7436   [(set_attr "type" "alu")
7437    (set_attr "mode" "SI")])
7439 (define_insn "*subsi_2_zext"
7440   [(set (reg FLAGS_REG)
7441         (compare
7442           (minus:SI (match_operand:SI 1 "register_operand" "0")
7443                     (match_operand:SI 2 "general_operand" "g"))
7444           (const_int 0)))
7445    (set (match_operand:DI 0 "register_operand" "=r")
7446         (zero_extend:DI
7447           (minus:SI (match_dup 1)
7448                     (match_dup 2))))]
7449   "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7450    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7451   "sub{l}\t{%2, %k0|%k0, %2}"
7452   [(set_attr "type" "alu")
7453    (set_attr "mode" "SI")])
7455 (define_insn "*subsi_3"
7456   [(set (reg FLAGS_REG)
7457         (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
7458                  (match_operand:SI 2 "general_operand" "ri,rm")))
7459    (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
7460         (minus:SI (match_dup 1) (match_dup 2)))]
7461   "ix86_match_ccmode (insn, CCmode)
7462    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7463   "sub{l}\t{%2, %0|%0, %2}"
7464   [(set_attr "type" "alu")
7465    (set_attr "mode" "SI")])
7467 (define_insn "*subsi_3_zext"
7468   [(set (reg FLAGS_REG)
7469         (compare (match_operand:SI 1 "register_operand" "0")
7470                  (match_operand:SI 2 "general_operand" "g")))
7471    (set (match_operand:DI 0 "register_operand" "=r")
7472         (zero_extend:DI
7473           (minus:SI (match_dup 1)
7474                     (match_dup 2))))]
7475   "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7476    && ix86_binary_operator_ok (MINUS, SImode, operands)"
7477   "sub{l}\t{%2, %1|%1, %2}"
7478   [(set_attr "type" "alu")
7479    (set_attr "mode" "DI")])
7481 (define_expand "subhi3"
7482   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
7483                    (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7484                              (match_operand:HI 2 "general_operand" "")))
7485               (clobber (reg:CC FLAGS_REG))])]
7486   "TARGET_HIMODE_MATH"
7487   "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
7489 (define_insn "*subhi_1"
7490   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7491         (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7492                   (match_operand:HI 2 "general_operand" "ri,rm")))
7493    (clobber (reg:CC FLAGS_REG))]
7494   "ix86_binary_operator_ok (MINUS, HImode, operands)"
7495   "sub{w}\t{%2, %0|%0, %2}"
7496   [(set_attr "type" "alu")
7497    (set_attr "mode" "HI")])
7499 (define_insn "*subhi_2"
7500   [(set (reg FLAGS_REG)
7501         (compare
7502           (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
7503                     (match_operand:HI 2 "general_operand" "ri,rm"))
7504           (const_int 0)))
7505    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7506         (minus:HI (match_dup 1) (match_dup 2)))]
7507   "ix86_match_ccmode (insn, CCGOCmode)
7508    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7509   "sub{w}\t{%2, %0|%0, %2}"
7510   [(set_attr "type" "alu")
7511    (set_attr "mode" "HI")])
7513 (define_insn "*subhi_3"
7514   [(set (reg FLAGS_REG)
7515         (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
7516                  (match_operand:HI 2 "general_operand" "ri,rm")))
7517    (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7518         (minus:HI (match_dup 1) (match_dup 2)))]
7519   "ix86_match_ccmode (insn, CCmode)
7520    && ix86_binary_operator_ok (MINUS, HImode, operands)"
7521   "sub{w}\t{%2, %0|%0, %2}"
7522   [(set_attr "type" "alu")
7523    (set_attr "mode" "HI")])
7525 (define_expand "subqi3"
7526   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
7527                    (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7528                              (match_operand:QI 2 "general_operand" "")))
7529               (clobber (reg:CC FLAGS_REG))])]
7530   "TARGET_QIMODE_MATH"
7531   "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
7533 (define_insn "*subqi_1"
7534   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
7535         (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7536                   (match_operand:QI 2 "general_operand" "qn,qmn")))
7537    (clobber (reg:CC FLAGS_REG))]
7538   "ix86_binary_operator_ok (MINUS, QImode, operands)"
7539   "sub{b}\t{%2, %0|%0, %2}"
7540   [(set_attr "type" "alu")
7541    (set_attr "mode" "QI")])
7543 (define_insn "*subqi_1_slp"
7544   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7545         (minus:QI (match_dup 0)
7546                   (match_operand:QI 1 "general_operand" "qn,qmn")))
7547    (clobber (reg:CC FLAGS_REG))]
7548   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
7549    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7550   "sub{b}\t{%1, %0|%0, %1}"
7551   [(set_attr "type" "alu1")
7552    (set_attr "mode" "QI")])
7554 (define_insn "*subqi_2"
7555   [(set (reg FLAGS_REG)
7556         (compare
7557           (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
7558                     (match_operand:QI 2 "general_operand" "qi,qm"))
7559           (const_int 0)))
7560    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7561         (minus:HI (match_dup 1) (match_dup 2)))]
7562   "ix86_match_ccmode (insn, CCGOCmode)
7563    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7564   "sub{b}\t{%2, %0|%0, %2}"
7565   [(set_attr "type" "alu")
7566    (set_attr "mode" "QI")])
7568 (define_insn "*subqi_3"
7569   [(set (reg FLAGS_REG)
7570         (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
7571                  (match_operand:QI 2 "general_operand" "qi,qm")))
7572    (set (match_operand:HI 0 "nonimmediate_operand" "=qm,q")
7573         (minus:HI (match_dup 1) (match_dup 2)))]
7574   "ix86_match_ccmode (insn, CCmode)
7575    && ix86_binary_operator_ok (MINUS, QImode, operands)"
7576   "sub{b}\t{%2, %0|%0, %2}"
7577   [(set_attr "type" "alu")
7578    (set_attr "mode" "QI")])
7580 ;; The patterns that match these are at the end of this file.
7582 (define_expand "subxf3"
7583   [(set (match_operand:XF 0 "register_operand" "")
7584         (minus:XF (match_operand:XF 1 "register_operand" "")
7585                   (match_operand:XF 2 "register_operand" "")))]
7586   "TARGET_80387"
7587   "")
7589 (define_expand "sub<mode>3"
7590   [(set (match_operand:MODEF 0 "register_operand" "")
7591         (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
7592                      (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7593   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7594   "")
7596 ;; Multiply instructions
7598 (define_expand "muldi3"
7599   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7600                    (mult:DI (match_operand:DI 1 "register_operand" "")
7601                             (match_operand:DI 2 "x86_64_general_operand" "")))
7602               (clobber (reg:CC FLAGS_REG))])]
7603   "TARGET_64BIT"
7604   "")
7606 ;; On AMDFAM10
7607 ;; IMUL reg64, reg64, imm8      Direct
7608 ;; IMUL reg64, mem64, imm8      VectorPath
7609 ;; IMUL reg64, reg64, imm32     Direct
7610 ;; IMUL reg64, mem64, imm32     VectorPath
7611 ;; IMUL reg64, reg64            Direct
7612 ;; IMUL reg64, mem64            Direct
7614 (define_insn "*muldi3_1_rex64"
7615   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7616         (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
7617                  (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
7618    (clobber (reg:CC FLAGS_REG))]
7619   "TARGET_64BIT
7620    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7621   "@
7622    imul{q}\t{%2, %1, %0|%0, %1, %2}
7623    imul{q}\t{%2, %1, %0|%0, %1, %2}
7624    imul{q}\t{%2, %0|%0, %2}"
7625   [(set_attr "type" "imul")
7626    (set_attr "prefix_0f" "0,0,1")
7627    (set (attr "athlon_decode")
7628         (cond [(eq_attr "cpu" "athlon")
7629                   (const_string "vector")
7630                (eq_attr "alternative" "1")
7631                   (const_string "vector")
7632                (and (eq_attr "alternative" "2")
7633                     (match_operand 1 "memory_operand" ""))
7634                   (const_string "vector")]
7635               (const_string "direct")))
7636    (set (attr "amdfam10_decode")
7637         (cond [(and (eq_attr "alternative" "0,1")
7638                     (match_operand 1 "memory_operand" ""))
7639                   (const_string "vector")]
7640               (const_string "direct")))
7641    (set_attr "mode" "DI")])
7643 (define_expand "mulsi3"
7644   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7645                    (mult:SI (match_operand:SI 1 "register_operand" "")
7646                             (match_operand:SI 2 "general_operand" "")))
7647               (clobber (reg:CC FLAGS_REG))])]
7648   ""
7649   "")
7651 ;; On AMDFAM10
7652 ;; IMUL reg32, reg32, imm8      Direct
7653 ;; IMUL reg32, mem32, imm8      VectorPath
7654 ;; IMUL reg32, reg32, imm32     Direct
7655 ;; IMUL reg32, mem32, imm32     VectorPath
7656 ;; IMUL reg32, reg32            Direct
7657 ;; IMUL reg32, mem32            Direct
7659 (define_insn "*mulsi3_1"
7660   [(set (match_operand:SI 0 "register_operand" "=r,r,r")
7661         (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7662                  (match_operand:SI 2 "general_operand" "K,i,mr")))
7663    (clobber (reg:CC FLAGS_REG))]
7664   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7665   "@
7666    imul{l}\t{%2, %1, %0|%0, %1, %2}
7667    imul{l}\t{%2, %1, %0|%0, %1, %2}
7668    imul{l}\t{%2, %0|%0, %2}"
7669   [(set_attr "type" "imul")
7670    (set_attr "prefix_0f" "0,0,1")
7671    (set (attr "athlon_decode")
7672         (cond [(eq_attr "cpu" "athlon")
7673                   (const_string "vector")
7674                (eq_attr "alternative" "1")
7675                   (const_string "vector")
7676                (and (eq_attr "alternative" "2")
7677                     (match_operand 1 "memory_operand" ""))
7678                   (const_string "vector")]
7679               (const_string "direct")))
7680    (set (attr "amdfam10_decode")
7681         (cond [(and (eq_attr "alternative" "0,1")
7682                     (match_operand 1 "memory_operand" ""))
7683                   (const_string "vector")]
7684               (const_string "direct")))
7685    (set_attr "mode" "SI")])
7687 (define_insn "*mulsi3_1_zext"
7688   [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7689         (zero_extend:DI
7690           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7691                    (match_operand:SI 2 "general_operand" "K,i,mr"))))
7692    (clobber (reg:CC FLAGS_REG))]
7693   "TARGET_64BIT
7694    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7695   "@
7696    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7697    imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7698    imul{l}\t{%2, %k0|%k0, %2}"
7699   [(set_attr "type" "imul")
7700    (set_attr "prefix_0f" "0,0,1")
7701    (set (attr "athlon_decode")
7702         (cond [(eq_attr "cpu" "athlon")
7703                   (const_string "vector")
7704                (eq_attr "alternative" "1")
7705                   (const_string "vector")
7706                (and (eq_attr "alternative" "2")
7707                     (match_operand 1 "memory_operand" ""))
7708                   (const_string "vector")]
7709               (const_string "direct")))
7710    (set (attr "amdfam10_decode")
7711         (cond [(and (eq_attr "alternative" "0,1")
7712                     (match_operand 1 "memory_operand" ""))
7713                   (const_string "vector")]
7714               (const_string "direct")))
7715    (set_attr "mode" "SI")])
7717 (define_expand "mulhi3"
7718   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7719                    (mult:HI (match_operand:HI 1 "register_operand" "")
7720                             (match_operand:HI 2 "general_operand" "")))
7721               (clobber (reg:CC FLAGS_REG))])]
7722   "TARGET_HIMODE_MATH"
7723   "")
7725 ;; On AMDFAM10
7726 ;; IMUL reg16, reg16, imm8      VectorPath
7727 ;; IMUL reg16, mem16, imm8      VectorPath
7728 ;; IMUL reg16, reg16, imm16     VectorPath
7729 ;; IMUL reg16, mem16, imm16     VectorPath
7730 ;; IMUL reg16, reg16            Direct
7731 ;; IMUL reg16, mem16            Direct
7732 (define_insn "*mulhi3_1"
7733   [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7734         (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7735                  (match_operand:HI 2 "general_operand" "K,i,mr")))
7736    (clobber (reg:CC FLAGS_REG))]
7737   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7738   "@
7739    imul{w}\t{%2, %1, %0|%0, %1, %2}
7740    imul{w}\t{%2, %1, %0|%0, %1, %2}
7741    imul{w}\t{%2, %0|%0, %2}"
7742   [(set_attr "type" "imul")
7743    (set_attr "prefix_0f" "0,0,1")
7744    (set (attr "athlon_decode")
7745         (cond [(eq_attr "cpu" "athlon")
7746                   (const_string "vector")
7747                (eq_attr "alternative" "1,2")
7748                   (const_string "vector")]
7749               (const_string "direct")))
7750    (set (attr "amdfam10_decode")
7751         (cond [(eq_attr "alternative" "0,1")
7752                   (const_string "vector")]
7753               (const_string "direct")))
7754    (set_attr "mode" "HI")])
7756 (define_expand "mulqi3"
7757   [(parallel [(set (match_operand:QI 0 "register_operand" "")
7758                    (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
7759                             (match_operand:QI 2 "register_operand" "")))
7760               (clobber (reg:CC FLAGS_REG))])]
7761   "TARGET_QIMODE_MATH"
7762   "")
7764 ;;On AMDFAM10
7765 ;; MUL reg8     Direct
7766 ;; MUL mem8     Direct
7768 (define_insn "*mulqi3_1"
7769   [(set (match_operand:QI 0 "register_operand" "=a")
7770         (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7771                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
7772    (clobber (reg:CC FLAGS_REG))]
7773   "TARGET_QIMODE_MATH
7774    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7775   "mul{b}\t%2"
7776   [(set_attr "type" "imul")
7777    (set_attr "length_immediate" "0")
7778    (set (attr "athlon_decode")
7779      (if_then_else (eq_attr "cpu" "athlon")
7780         (const_string "vector")
7781         (const_string "direct")))
7782    (set_attr "amdfam10_decode" "direct")
7783    (set_attr "mode" "QI")])
7785 (define_expand "umulqihi3"
7786   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7787                    (mult:HI (zero_extend:HI
7788                               (match_operand:QI 1 "nonimmediate_operand" ""))
7789                             (zero_extend:HI
7790                               (match_operand:QI 2 "register_operand" ""))))
7791               (clobber (reg:CC FLAGS_REG))])]
7792   "TARGET_QIMODE_MATH"
7793   "")
7795 (define_insn "*umulqihi3_1"
7796   [(set (match_operand:HI 0 "register_operand" "=a")
7797         (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7798                  (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7799    (clobber (reg:CC FLAGS_REG))]
7800   "TARGET_QIMODE_MATH
7801    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7802   "mul{b}\t%2"
7803   [(set_attr "type" "imul")
7804    (set_attr "length_immediate" "0")
7805    (set (attr "athlon_decode")
7806      (if_then_else (eq_attr "cpu" "athlon")
7807         (const_string "vector")
7808         (const_string "direct")))
7809    (set_attr "amdfam10_decode" "direct")
7810    (set_attr "mode" "QI")])
7812 (define_expand "mulqihi3"
7813   [(parallel [(set (match_operand:HI 0 "register_operand" "")
7814                    (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
7815                             (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
7816               (clobber (reg:CC FLAGS_REG))])]
7817   "TARGET_QIMODE_MATH"
7818   "")
7820 (define_insn "*mulqihi3_insn"
7821   [(set (match_operand:HI 0 "register_operand" "=a")
7822         (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
7823                  (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7824    (clobber (reg:CC FLAGS_REG))]
7825   "TARGET_QIMODE_MATH
7826    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7827   "imul{b}\t%2"
7828   [(set_attr "type" "imul")
7829    (set_attr "length_immediate" "0")
7830    (set (attr "athlon_decode")
7831      (if_then_else (eq_attr "cpu" "athlon")
7832         (const_string "vector")
7833         (const_string "direct")))
7834    (set_attr "amdfam10_decode" "direct")
7835    (set_attr "mode" "QI")])
7837 (define_expand "umulditi3"
7838   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7839                    (mult:TI (zero_extend:TI
7840                               (match_operand:DI 1 "nonimmediate_operand" ""))
7841                             (zero_extend:TI
7842                               (match_operand:DI 2 "register_operand" ""))))
7843               (clobber (reg:CC FLAGS_REG))])]
7844   "TARGET_64BIT"
7845   "")
7847 (define_insn "*umulditi3_insn"
7848   [(set (match_operand:TI 0 "register_operand" "=A")
7849         (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7850                  (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7851    (clobber (reg:CC FLAGS_REG))]
7852   "TARGET_64BIT
7853    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7854   "mul{q}\t%2"
7855   [(set_attr "type" "imul")
7856    (set_attr "length_immediate" "0")
7857    (set (attr "athlon_decode")
7858      (if_then_else (eq_attr "cpu" "athlon")
7859         (const_string "vector")
7860         (const_string "double")))
7861    (set_attr "amdfam10_decode" "double")
7862    (set_attr "mode" "DI")])
7864 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
7865 (define_expand "umulsidi3"
7866   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7867                    (mult:DI (zero_extend:DI
7868                               (match_operand:SI 1 "nonimmediate_operand" ""))
7869                             (zero_extend:DI
7870                               (match_operand:SI 2 "register_operand" ""))))
7871               (clobber (reg:CC FLAGS_REG))])]
7872   "!TARGET_64BIT"
7873   "")
7875 (define_insn "*umulsidi3_insn"
7876   [(set (match_operand:DI 0 "register_operand" "=A")
7877         (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7878                  (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7879    (clobber (reg:CC FLAGS_REG))]
7880   "!TARGET_64BIT
7881    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7882   "mul{l}\t%2"
7883   [(set_attr "type" "imul")
7884    (set_attr "length_immediate" "0")
7885    (set (attr "athlon_decode")
7886      (if_then_else (eq_attr "cpu" "athlon")
7887         (const_string "vector")
7888         (const_string "double")))
7889    (set_attr "amdfam10_decode" "double")
7890    (set_attr "mode" "SI")])
7892 (define_expand "mulditi3"
7893   [(parallel [(set (match_operand:TI 0 "register_operand" "")
7894                    (mult:TI (sign_extend:TI
7895                               (match_operand:DI 1 "nonimmediate_operand" ""))
7896                             (sign_extend:TI
7897                               (match_operand:DI 2 "register_operand" ""))))
7898               (clobber (reg:CC FLAGS_REG))])]
7899   "TARGET_64BIT"
7900   "")
7902 (define_insn "*mulditi3_insn"
7903   [(set (match_operand:TI 0 "register_operand" "=A")
7904         (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
7905                  (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
7906    (clobber (reg:CC FLAGS_REG))]
7907   "TARGET_64BIT
7908    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7909   "imul{q}\t%2"
7910   [(set_attr "type" "imul")
7911    (set_attr "length_immediate" "0")
7912    (set (attr "athlon_decode")
7913      (if_then_else (eq_attr "cpu" "athlon")
7914         (const_string "vector")
7915         (const_string "double")))
7916    (set_attr "amdfam10_decode" "double")
7917    (set_attr "mode" "DI")])
7919 (define_expand "mulsidi3"
7920   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7921                    (mult:DI (sign_extend:DI
7922                               (match_operand:SI 1 "nonimmediate_operand" ""))
7923                             (sign_extend:DI
7924                               (match_operand:SI 2 "register_operand" ""))))
7925               (clobber (reg:CC FLAGS_REG))])]
7926   "!TARGET_64BIT"
7927   "")
7929 (define_insn "*mulsidi3_insn"
7930   [(set (match_operand:DI 0 "register_operand" "=A")
7931         (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
7932                  (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
7933    (clobber (reg:CC FLAGS_REG))]
7934   "!TARGET_64BIT
7935    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7936   "imul{l}\t%2"
7937   [(set_attr "type" "imul")
7938    (set_attr "length_immediate" "0")
7939    (set (attr "athlon_decode")
7940      (if_then_else (eq_attr "cpu" "athlon")
7941         (const_string "vector")
7942         (const_string "double")))
7943    (set_attr "amdfam10_decode" "double")
7944    (set_attr "mode" "SI")])
7946 (define_expand "umuldi3_highpart"
7947   [(parallel [(set (match_operand:DI 0 "register_operand" "")
7948                    (truncate:DI
7949                      (lshiftrt:TI
7950                        (mult:TI (zero_extend:TI
7951                                   (match_operand:DI 1 "nonimmediate_operand" ""))
7952                                 (zero_extend:TI
7953                                   (match_operand:DI 2 "register_operand" "")))
7954                        (const_int 64))))
7955               (clobber (match_scratch:DI 3 ""))
7956               (clobber (reg:CC FLAGS_REG))])]
7957   "TARGET_64BIT"
7958   "")
7960 (define_insn "*umuldi3_highpart_rex64"
7961   [(set (match_operand:DI 0 "register_operand" "=d")
7962         (truncate:DI
7963           (lshiftrt:TI
7964             (mult:TI (zero_extend:TI
7965                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
7966                      (zero_extend:TI
7967                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
7968             (const_int 64))))
7969    (clobber (match_scratch:DI 3 "=1"))
7970    (clobber (reg:CC FLAGS_REG))]
7971   "TARGET_64BIT
7972    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7973   "mul{q}\t%2"
7974   [(set_attr "type" "imul")
7975    (set_attr "length_immediate" "0")
7976    (set (attr "athlon_decode")
7977      (if_then_else (eq_attr "cpu" "athlon")
7978         (const_string "vector")
7979         (const_string "double")))
7980    (set_attr "amdfam10_decode" "double")
7981    (set_attr "mode" "DI")])
7983 (define_expand "umulsi3_highpart"
7984   [(parallel [(set (match_operand:SI 0 "register_operand" "")
7985                    (truncate:SI
7986                      (lshiftrt:DI
7987                        (mult:DI (zero_extend:DI
7988                                   (match_operand:SI 1 "nonimmediate_operand" ""))
7989                                 (zero_extend:DI
7990                                   (match_operand:SI 2 "register_operand" "")))
7991                        (const_int 32))))
7992               (clobber (match_scratch:SI 3 ""))
7993               (clobber (reg:CC FLAGS_REG))])]
7994   ""
7995   "")
7997 (define_insn "*umulsi3_highpart_insn"
7998   [(set (match_operand:SI 0 "register_operand" "=d")
7999         (truncate:SI
8000           (lshiftrt:DI
8001             (mult:DI (zero_extend:DI
8002                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8003                      (zero_extend:DI
8004                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8005             (const_int 32))))
8006    (clobber (match_scratch:SI 3 "=1"))
8007    (clobber (reg:CC FLAGS_REG))]
8008   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8009   "mul{l}\t%2"
8010   [(set_attr "type" "imul")
8011    (set_attr "length_immediate" "0")
8012    (set (attr "athlon_decode")
8013      (if_then_else (eq_attr "cpu" "athlon")
8014         (const_string "vector")
8015         (const_string "double")))
8016    (set_attr "amdfam10_decode" "double")
8017    (set_attr "mode" "SI")])
8019 (define_insn "*umulsi3_highpart_zext"
8020   [(set (match_operand:DI 0 "register_operand" "=d")
8021         (zero_extend:DI (truncate:SI
8022           (lshiftrt:DI
8023             (mult:DI (zero_extend:DI
8024                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8025                      (zero_extend:DI
8026                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8027             (const_int 32)))))
8028    (clobber (match_scratch:SI 3 "=1"))
8029    (clobber (reg:CC FLAGS_REG))]
8030   "TARGET_64BIT
8031    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8032   "mul{l}\t%2"
8033   [(set_attr "type" "imul")
8034    (set_attr "length_immediate" "0")
8035    (set (attr "athlon_decode")
8036      (if_then_else (eq_attr "cpu" "athlon")
8037         (const_string "vector")
8038         (const_string "double")))
8039    (set_attr "amdfam10_decode" "double")
8040    (set_attr "mode" "SI")])
8042 (define_expand "smuldi3_highpart"
8043   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8044                    (truncate:DI
8045                      (lshiftrt:TI
8046                        (mult:TI (sign_extend:TI
8047                                   (match_operand:DI 1 "nonimmediate_operand" ""))
8048                                 (sign_extend:TI
8049                                   (match_operand:DI 2 "register_operand" "")))
8050                        (const_int 64))))
8051               (clobber (match_scratch:DI 3 ""))
8052               (clobber (reg:CC FLAGS_REG))])]
8053   "TARGET_64BIT"
8054   "")
8056 (define_insn "*smuldi3_highpart_rex64"
8057   [(set (match_operand:DI 0 "register_operand" "=d")
8058         (truncate:DI
8059           (lshiftrt:TI
8060             (mult:TI (sign_extend:TI
8061                        (match_operand:DI 1 "nonimmediate_operand" "%a"))
8062                      (sign_extend:TI
8063                        (match_operand:DI 2 "nonimmediate_operand" "rm")))
8064             (const_int 64))))
8065    (clobber (match_scratch:DI 3 "=1"))
8066    (clobber (reg:CC FLAGS_REG))]
8067   "TARGET_64BIT
8068    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8069   "imul{q}\t%2"
8070   [(set_attr "type" "imul")
8071    (set (attr "athlon_decode")
8072      (if_then_else (eq_attr "cpu" "athlon")
8073         (const_string "vector")
8074         (const_string "double")))
8075    (set_attr "amdfam10_decode" "double")
8076    (set_attr "mode" "DI")])
8078 (define_expand "smulsi3_highpart"
8079   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8080                    (truncate:SI
8081                      (lshiftrt:DI
8082                        (mult:DI (sign_extend:DI
8083                                   (match_operand:SI 1 "nonimmediate_operand" ""))
8084                                 (sign_extend:DI
8085                                   (match_operand:SI 2 "register_operand" "")))
8086                        (const_int 32))))
8087               (clobber (match_scratch:SI 3 ""))
8088               (clobber (reg:CC FLAGS_REG))])]
8089   ""
8090   "")
8092 (define_insn "*smulsi3_highpart_insn"
8093   [(set (match_operand:SI 0 "register_operand" "=d")
8094         (truncate:SI
8095           (lshiftrt:DI
8096             (mult:DI (sign_extend:DI
8097                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8098                      (sign_extend:DI
8099                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8100             (const_int 32))))
8101    (clobber (match_scratch:SI 3 "=1"))
8102    (clobber (reg:CC FLAGS_REG))]
8103   "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8104   "imul{l}\t%2"
8105   [(set_attr "type" "imul")
8106    (set (attr "athlon_decode")
8107      (if_then_else (eq_attr "cpu" "athlon")
8108         (const_string "vector")
8109         (const_string "double")))
8110    (set_attr "amdfam10_decode" "double")
8111    (set_attr "mode" "SI")])
8113 (define_insn "*smulsi3_highpart_zext"
8114   [(set (match_operand:DI 0 "register_operand" "=d")
8115         (zero_extend:DI (truncate:SI
8116           (lshiftrt:DI
8117             (mult:DI (sign_extend:DI
8118                        (match_operand:SI 1 "nonimmediate_operand" "%a"))
8119                      (sign_extend:DI
8120                        (match_operand:SI 2 "nonimmediate_operand" "rm")))
8121             (const_int 32)))))
8122    (clobber (match_scratch:SI 3 "=1"))
8123    (clobber (reg:CC FLAGS_REG))]
8124   "TARGET_64BIT
8125    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8126   "imul{l}\t%2"
8127   [(set_attr "type" "imul")
8128    (set (attr "athlon_decode")
8129      (if_then_else (eq_attr "cpu" "athlon")
8130         (const_string "vector")
8131         (const_string "double")))
8132    (set_attr "amdfam10_decode" "double")
8133    (set_attr "mode" "SI")])
8135 ;; The patterns that match these are at the end of this file.
8137 (define_expand "mulxf3"
8138   [(set (match_operand:XF 0 "register_operand" "")
8139         (mult:XF (match_operand:XF 1 "register_operand" "")
8140                  (match_operand:XF 2 "register_operand" "")))]
8141   "TARGET_80387"
8142   "")
8144 (define_expand "mul<mode>3"
8145   [(set (match_operand:MODEF 0 "register_operand" "")
8146         (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8147                     (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8148   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8149   "")
8151 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8154 ;; Divide instructions
8156 (define_insn "divqi3"
8157   [(set (match_operand:QI 0 "register_operand" "=a")
8158         (div: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   "idiv{b}\t%2"
8163   [(set_attr "type" "idiv")
8164    (set_attr "mode" "QI")])
8166 (define_insn "udivqi3"
8167   [(set (match_operand:QI 0 "register_operand" "=a")
8168         (udiv:QI (match_operand:HI 1 "register_operand" "0")
8169                  (match_operand:QI 2 "nonimmediate_operand" "qm")))
8170    (clobber (reg:CC FLAGS_REG))]
8171   "TARGET_QIMODE_MATH"
8172   "div{b}\t%2"
8173   [(set_attr "type" "idiv")
8174    (set_attr "mode" "QI")])
8176 ;; The patterns that match these are at the end of this file.
8178 (define_expand "divxf3"
8179   [(set (match_operand:XF 0 "register_operand" "")
8180         (div:XF (match_operand:XF 1 "register_operand" "")
8181                 (match_operand:XF 2 "register_operand" "")))]
8182   "TARGET_80387"
8183   "")
8185 (define_expand "divdf3"
8186   [(set (match_operand:DF 0 "register_operand" "")
8187         (div:DF (match_operand:DF 1 "register_operand" "")
8188                 (match_operand:DF 2 "nonimmediate_operand" "")))]
8189    "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8190    "")
8192 (define_expand "divsf3"
8193   [(set (match_operand:SF 0 "register_operand" "")
8194         (div:SF (match_operand:SF 1 "register_operand" "")
8195                 (match_operand:SF 2 "nonimmediate_operand" "")))]
8196   "TARGET_80387 || TARGET_SSE_MATH"
8198   if (TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
8199       && flag_finite_math_only && !flag_trapping_math
8200       && flag_unsafe_math_optimizations)
8201     {
8202       ix86_emit_swdivsf (operands[0], operands[1],
8203                          operands[2], SFmode);
8204       DONE;
8205     }
8208 ;; Remainder instructions.
8210 (define_expand "divmoddi4"
8211   [(parallel [(set (match_operand:DI 0 "register_operand" "")
8212                    (div:DI (match_operand:DI 1 "register_operand" "")
8213                            (match_operand:DI 2 "nonimmediate_operand" "")))
8214               (set (match_operand:DI 3 "register_operand" "")
8215                    (mod:DI (match_dup 1) (match_dup 2)))
8216               (clobber (reg:CC FLAGS_REG))])]
8217   "TARGET_64BIT"
8218   "")
8220 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8221 ;; Penalize eax case slightly because it results in worse scheduling
8222 ;; of code.
8223 (define_insn "*divmoddi4_nocltd_rex64"
8224   [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8225         (div:DI (match_operand:DI 2 "register_operand" "1,0")
8226                 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8227    (set (match_operand:DI 1 "register_operand" "=&d,&d")
8228         (mod:DI (match_dup 2) (match_dup 3)))
8229    (clobber (reg:CC FLAGS_REG))]
8230   "TARGET_64BIT && !optimize_size && !TARGET_USE_CLTD"
8231   "#"
8232   [(set_attr "type" "multi")])
8234 (define_insn "*divmoddi4_cltd_rex64"
8235   [(set (match_operand:DI 0 "register_operand" "=a")
8236         (div:DI (match_operand:DI 2 "register_operand" "a")
8237                 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8238    (set (match_operand:DI 1 "register_operand" "=&d")
8239         (mod:DI (match_dup 2) (match_dup 3)))
8240    (clobber (reg:CC FLAGS_REG))]
8241   "TARGET_64BIT && (optimize_size || TARGET_USE_CLTD)"
8242   "#"
8243   [(set_attr "type" "multi")])
8245 (define_insn "*divmoddi_noext_rex64"
8246   [(set (match_operand:DI 0 "register_operand" "=a")
8247         (div:DI (match_operand:DI 1 "register_operand" "0")
8248                 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8249    (set (match_operand:DI 3 "register_operand" "=d")
8250         (mod:DI (match_dup 1) (match_dup 2)))
8251    (use (match_operand:DI 4 "register_operand" "3"))
8252    (clobber (reg:CC FLAGS_REG))]
8253   "TARGET_64BIT"
8254   "idiv{q}\t%2"
8255   [(set_attr "type" "idiv")
8256    (set_attr "mode" "DI")])
8258 (define_split
8259   [(set (match_operand:DI 0 "register_operand" "")
8260         (div:DI (match_operand:DI 1 "register_operand" "")
8261                 (match_operand:DI 2 "nonimmediate_operand" "")))
8262    (set (match_operand:DI 3 "register_operand" "")
8263         (mod:DI (match_dup 1) (match_dup 2)))
8264    (clobber (reg:CC FLAGS_REG))]
8265   "TARGET_64BIT && reload_completed"
8266   [(parallel [(set (match_dup 3)
8267                    (ashiftrt:DI (match_dup 4) (const_int 63)))
8268               (clobber (reg:CC FLAGS_REG))])
8269    (parallel [(set (match_dup 0)
8270                    (div:DI (reg:DI 0) (match_dup 2)))
8271               (set (match_dup 3)
8272                    (mod:DI (reg:DI 0) (match_dup 2)))
8273               (use (match_dup 3))
8274               (clobber (reg:CC FLAGS_REG))])]
8276   /* Avoid use of cltd in favor of a mov+shift.  */
8277   if (!TARGET_USE_CLTD && !optimize_size)
8278     {
8279       if (true_regnum (operands[1]))
8280         emit_move_insn (operands[0], operands[1]);
8281       else
8282         emit_move_insn (operands[3], operands[1]);
8283       operands[4] = operands[3];
8284     }
8285   else
8286     {
8287       gcc_assert (!true_regnum (operands[1]));
8288       operands[4] = operands[1];
8289     }
8293 (define_expand "divmodsi4"
8294   [(parallel [(set (match_operand:SI 0 "register_operand" "")
8295                    (div:SI (match_operand:SI 1 "register_operand" "")
8296                            (match_operand:SI 2 "nonimmediate_operand" "")))
8297               (set (match_operand:SI 3 "register_operand" "")
8298                    (mod:SI (match_dup 1) (match_dup 2)))
8299               (clobber (reg:CC FLAGS_REG))])]
8300   ""
8301   "")
8303 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8304 ;; Penalize eax case slightly because it results in worse scheduling
8305 ;; of code.
8306 (define_insn "*divmodsi4_nocltd"
8307   [(set (match_operand:SI 0 "register_operand" "=&a,?a")
8308         (div:SI (match_operand:SI 2 "register_operand" "1,0")
8309                 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
8310    (set (match_operand:SI 1 "register_operand" "=&d,&d")
8311         (mod:SI (match_dup 2) (match_dup 3)))
8312    (clobber (reg:CC FLAGS_REG))]
8313   "!optimize_size && !TARGET_USE_CLTD"
8314   "#"
8315   [(set_attr "type" "multi")])
8317 (define_insn "*divmodsi4_cltd"
8318   [(set (match_operand:SI 0 "register_operand" "=a")
8319         (div:SI (match_operand:SI 2 "register_operand" "a")
8320                 (match_operand:SI 3 "nonimmediate_operand" "rm")))
8321    (set (match_operand:SI 1 "register_operand" "=&d")
8322         (mod:SI (match_dup 2) (match_dup 3)))
8323    (clobber (reg:CC FLAGS_REG))]
8324   "optimize_size || TARGET_USE_CLTD"
8325   "#"
8326   [(set_attr "type" "multi")])
8328 (define_insn "*divmodsi_noext"
8329   [(set (match_operand:SI 0 "register_operand" "=a")
8330         (div:SI (match_operand:SI 1 "register_operand" "0")
8331                 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8332    (set (match_operand:SI 3 "register_operand" "=d")
8333         (mod:SI (match_dup 1) (match_dup 2)))
8334    (use (match_operand:SI 4 "register_operand" "3"))
8335    (clobber (reg:CC FLAGS_REG))]
8336   ""
8337   "idiv{l}\t%2"
8338   [(set_attr "type" "idiv")
8339    (set_attr "mode" "SI")])
8341 (define_split
8342   [(set (match_operand:SI 0 "register_operand" "")
8343         (div:SI (match_operand:SI 1 "register_operand" "")
8344                 (match_operand:SI 2 "nonimmediate_operand" "")))
8345    (set (match_operand:SI 3 "register_operand" "")
8346         (mod:SI (match_dup 1) (match_dup 2)))
8347    (clobber (reg:CC FLAGS_REG))]
8348   "reload_completed"
8349   [(parallel [(set (match_dup 3)
8350                    (ashiftrt:SI (match_dup 4) (const_int 31)))
8351               (clobber (reg:CC FLAGS_REG))])
8352    (parallel [(set (match_dup 0)
8353                    (div:SI (reg:SI 0) (match_dup 2)))
8354               (set (match_dup 3)
8355                    (mod:SI (reg:SI 0) (match_dup 2)))
8356               (use (match_dup 3))
8357               (clobber (reg:CC FLAGS_REG))])]
8359   /* Avoid use of cltd in favor of a mov+shift.  */
8360   if (!TARGET_USE_CLTD && !optimize_size)
8361     {
8362       if (true_regnum (operands[1]))
8363         emit_move_insn (operands[0], operands[1]);
8364       else
8365         emit_move_insn (operands[3], operands[1]);
8366       operands[4] = operands[3];
8367     }
8368   else
8369     {
8370       gcc_assert (!true_regnum (operands[1]));
8371       operands[4] = operands[1];
8372     }
8374 ;; %%% Split me.
8375 (define_insn "divmodhi4"
8376   [(set (match_operand:HI 0 "register_operand" "=a")
8377         (div:HI (match_operand:HI 1 "register_operand" "0")
8378                 (match_operand:HI 2 "nonimmediate_operand" "rm")))
8379    (set (match_operand:HI 3 "register_operand" "=&d")
8380         (mod:HI (match_dup 1) (match_dup 2)))
8381    (clobber (reg:CC FLAGS_REG))]
8382   "TARGET_HIMODE_MATH"
8383   "cwtd\;idiv{w}\t%2"
8384   [(set_attr "type" "multi")
8385    (set_attr "length_immediate" "0")
8386    (set_attr "mode" "SI")])
8388 (define_insn "udivmoddi4"
8389   [(set (match_operand:DI 0 "register_operand" "=a")
8390         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8391                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8392    (set (match_operand:DI 3 "register_operand" "=&d")
8393         (umod:DI (match_dup 1) (match_dup 2)))
8394    (clobber (reg:CC FLAGS_REG))]
8395   "TARGET_64BIT"
8396   "xor{q}\t%3, %3\;div{q}\t%2"
8397   [(set_attr "type" "multi")
8398    (set_attr "length_immediate" "0")
8399    (set_attr "mode" "DI")])
8401 (define_insn "*udivmoddi4_noext"
8402   [(set (match_operand:DI 0 "register_operand" "=a")
8403         (udiv:DI (match_operand:DI 1 "register_operand" "0")
8404                  (match_operand:DI 2 "nonimmediate_operand" "rm")))
8405    (set (match_operand:DI 3 "register_operand" "=d")
8406         (umod:DI (match_dup 1) (match_dup 2)))
8407    (use (match_dup 3))
8408    (clobber (reg:CC FLAGS_REG))]
8409   "TARGET_64BIT"
8410   "div{q}\t%2"
8411   [(set_attr "type" "idiv")
8412    (set_attr "mode" "DI")])
8414 (define_split
8415   [(set (match_operand:DI 0 "register_operand" "")
8416         (udiv:DI (match_operand:DI 1 "register_operand" "")
8417                  (match_operand:DI 2 "nonimmediate_operand" "")))
8418    (set (match_operand:DI 3 "register_operand" "")
8419         (umod:DI (match_dup 1) (match_dup 2)))
8420    (clobber (reg:CC FLAGS_REG))]
8421   "TARGET_64BIT && reload_completed"
8422   [(set (match_dup 3) (const_int 0))
8423    (parallel [(set (match_dup 0)
8424                    (udiv:DI (match_dup 1) (match_dup 2)))
8425               (set (match_dup 3)
8426                    (umod:DI (match_dup 1) (match_dup 2)))
8427               (use (match_dup 3))
8428               (clobber (reg:CC FLAGS_REG))])]
8429   "")
8431 (define_insn "udivmodsi4"
8432   [(set (match_operand:SI 0 "register_operand" "=a")
8433         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8434                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8435    (set (match_operand:SI 3 "register_operand" "=&d")
8436         (umod:SI (match_dup 1) (match_dup 2)))
8437    (clobber (reg:CC FLAGS_REG))]
8438   ""
8439   "xor{l}\t%3, %3\;div{l}\t%2"
8440   [(set_attr "type" "multi")
8441    (set_attr "length_immediate" "0")
8442    (set_attr "mode" "SI")])
8444 (define_insn "*udivmodsi4_noext"
8445   [(set (match_operand:SI 0 "register_operand" "=a")
8446         (udiv:SI (match_operand:SI 1 "register_operand" "0")
8447                  (match_operand:SI 2 "nonimmediate_operand" "rm")))
8448    (set (match_operand:SI 3 "register_operand" "=d")
8449         (umod:SI (match_dup 1) (match_dup 2)))
8450    (use (match_dup 3))
8451    (clobber (reg:CC FLAGS_REG))]
8452   ""
8453   "div{l}\t%2"
8454   [(set_attr "type" "idiv")
8455    (set_attr "mode" "SI")])
8457 (define_split
8458   [(set (match_operand:SI 0 "register_operand" "")
8459         (udiv:SI (match_operand:SI 1 "register_operand" "")
8460                  (match_operand:SI 2 "nonimmediate_operand" "")))
8461    (set (match_operand:SI 3 "register_operand" "")
8462         (umod:SI (match_dup 1) (match_dup 2)))
8463    (clobber (reg:CC FLAGS_REG))]
8464   "reload_completed"
8465   [(set (match_dup 3) (const_int 0))
8466    (parallel [(set (match_dup 0)
8467                    (udiv:SI (match_dup 1) (match_dup 2)))
8468               (set (match_dup 3)
8469                    (umod:SI (match_dup 1) (match_dup 2)))
8470               (use (match_dup 3))
8471               (clobber (reg:CC FLAGS_REG))])]
8472   "")
8474 (define_expand "udivmodhi4"
8475   [(set (match_dup 4) (const_int 0))
8476    (parallel [(set (match_operand:HI 0 "register_operand" "")
8477                    (udiv:HI (match_operand:HI 1 "register_operand" "")
8478                             (match_operand:HI 2 "nonimmediate_operand" "")))
8479               (set (match_operand:HI 3 "register_operand" "")
8480                    (umod:HI (match_dup 1) (match_dup 2)))
8481               (use (match_dup 4))
8482               (clobber (reg:CC FLAGS_REG))])]
8483   "TARGET_HIMODE_MATH"
8484   "operands[4] = gen_reg_rtx (HImode);")
8486 (define_insn "*udivmodhi_noext"
8487   [(set (match_operand:HI 0 "register_operand" "=a")
8488         (udiv:HI (match_operand:HI 1 "register_operand" "0")
8489                  (match_operand:HI 2 "nonimmediate_operand" "rm")))
8490    (set (match_operand:HI 3 "register_operand" "=d")
8491         (umod:HI (match_dup 1) (match_dup 2)))
8492    (use (match_operand:HI 4 "register_operand" "3"))
8493    (clobber (reg:CC FLAGS_REG))]
8494   ""
8495   "div{w}\t%2"
8496   [(set_attr "type" "idiv")
8497    (set_attr "mode" "HI")])
8499 ;; We cannot use div/idiv for double division, because it causes
8500 ;; "division by zero" on the overflow and that's not what we expect
8501 ;; from truncate.  Because true (non truncating) double division is
8502 ;; never generated, we can't create this insn anyway.
8504 ;(define_insn ""
8505 ;  [(set (match_operand:SI 0 "register_operand" "=a")
8506 ;       (truncate:SI
8507 ;         (udiv:DI (match_operand:DI 1 "register_operand" "A")
8508 ;                  (zero_extend:DI
8509 ;                    (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8510 ;   (set (match_operand:SI 3 "register_operand" "=d")
8511 ;       (truncate:SI
8512 ;         (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8513 ;   (clobber (reg:CC FLAGS_REG))]
8514 ;  ""
8515 ;  "div{l}\t{%2, %0|%0, %2}"
8516 ;  [(set_attr "type" "idiv")])
8518 ;;- Logical AND instructions
8520 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8521 ;; Note that this excludes ah.
8523 (define_insn "*testdi_1_rex64"
8524   [(set (reg FLAGS_REG)
8525         (compare
8526           (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8527                   (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8528           (const_int 0)))]
8529   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8530    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8531   "@
8532    test{l}\t{%k1, %k0|%k0, %k1}
8533    test{l}\t{%k1, %k0|%k0, %k1}
8534    test{q}\t{%1, %0|%0, %1}
8535    test{q}\t{%1, %0|%0, %1}
8536    test{q}\t{%1, %0|%0, %1}"
8537   [(set_attr "type" "test")
8538    (set_attr "modrm" "0,1,0,1,1")
8539    (set_attr "mode" "SI,SI,DI,DI,DI")
8540    (set_attr "pent_pair" "uv,np,uv,np,uv")])
8542 (define_insn "testsi_1"
8543   [(set (reg FLAGS_REG)
8544         (compare
8545           (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8546                   (match_operand:SI 1 "general_operand" "in,in,rin"))
8547           (const_int 0)))]
8548   "ix86_match_ccmode (insn, CCNOmode)
8549    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8550   "test{l}\t{%1, %0|%0, %1}"
8551   [(set_attr "type" "test")
8552    (set_attr "modrm" "0,1,1")
8553    (set_attr "mode" "SI")
8554    (set_attr "pent_pair" "uv,np,uv")])
8556 (define_expand "testsi_ccno_1"
8557   [(set (reg:CCNO FLAGS_REG)
8558         (compare:CCNO
8559           (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8560                   (match_operand:SI 1 "nonmemory_operand" ""))
8561           (const_int 0)))]
8562   ""
8563   "")
8565 (define_insn "*testhi_1"
8566   [(set (reg FLAGS_REG)
8567         (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8568                          (match_operand:HI 1 "general_operand" "n,n,rn"))
8569                  (const_int 0)))]
8570   "ix86_match_ccmode (insn, CCNOmode)
8571    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8572   "test{w}\t{%1, %0|%0, %1}"
8573   [(set_attr "type" "test")
8574    (set_attr "modrm" "0,1,1")
8575    (set_attr "mode" "HI")
8576    (set_attr "pent_pair" "uv,np,uv")])
8578 (define_expand "testqi_ccz_1"
8579   [(set (reg:CCZ FLAGS_REG)
8580         (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8581                              (match_operand:QI 1 "nonmemory_operand" ""))
8582                  (const_int 0)))]
8583   ""
8584   "")
8586 (define_insn "*testqi_1_maybe_si"
8587   [(set (reg FLAGS_REG)
8588         (compare
8589           (and:QI
8590             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8591             (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8592           (const_int 0)))]
8593    "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8594     && ix86_match_ccmode (insn,
8595                          CONST_INT_P (operands[1])
8596                          && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8598   if (which_alternative == 3)
8599     {
8600       if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8601         operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8602       return "test{l}\t{%1, %k0|%k0, %1}";
8603     }
8604   return "test{b}\t{%1, %0|%0, %1}";
8606   [(set_attr "type" "test")
8607    (set_attr "modrm" "0,1,1,1")
8608    (set_attr "mode" "QI,QI,QI,SI")
8609    (set_attr "pent_pair" "uv,np,uv,np")])
8611 (define_insn "*testqi_1"
8612   [(set (reg FLAGS_REG)
8613         (compare
8614           (and:QI
8615             (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8616             (match_operand:QI 1 "general_operand" "n,n,qn"))
8617           (const_int 0)))]
8618   "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8619    && ix86_match_ccmode (insn, CCNOmode)"
8620   "test{b}\t{%1, %0|%0, %1}"
8621   [(set_attr "type" "test")
8622    (set_attr "modrm" "0,1,1")
8623    (set_attr "mode" "QI")
8624    (set_attr "pent_pair" "uv,np,uv")])
8626 (define_expand "testqi_ext_ccno_0"
8627   [(set (reg:CCNO FLAGS_REG)
8628         (compare:CCNO
8629           (and:SI
8630             (zero_extract:SI
8631               (match_operand 0 "ext_register_operand" "")
8632               (const_int 8)
8633               (const_int 8))
8634             (match_operand 1 "const_int_operand" ""))
8635           (const_int 0)))]
8636   ""
8637   "")
8639 (define_insn "*testqi_ext_0"
8640   [(set (reg FLAGS_REG)
8641         (compare
8642           (and:SI
8643             (zero_extract:SI
8644               (match_operand 0 "ext_register_operand" "Q")
8645               (const_int 8)
8646               (const_int 8))
8647             (match_operand 1 "const_int_operand" "n"))
8648           (const_int 0)))]
8649   "ix86_match_ccmode (insn, CCNOmode)"
8650   "test{b}\t{%1, %h0|%h0, %1}"
8651   [(set_attr "type" "test")
8652    (set_attr "mode" "QI")
8653    (set_attr "length_immediate" "1")
8654    (set_attr "pent_pair" "np")])
8656 (define_insn "*testqi_ext_1"
8657   [(set (reg FLAGS_REG)
8658         (compare
8659           (and:SI
8660             (zero_extract:SI
8661               (match_operand 0 "ext_register_operand" "Q")
8662               (const_int 8)
8663               (const_int 8))
8664             (zero_extend:SI
8665               (match_operand:QI 1 "general_operand" "Qm")))
8666           (const_int 0)))]
8667   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8668    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8669   "test{b}\t{%1, %h0|%h0, %1}"
8670   [(set_attr "type" "test")
8671    (set_attr "mode" "QI")])
8673 (define_insn "*testqi_ext_1_rex64"
8674   [(set (reg FLAGS_REG)
8675         (compare
8676           (and:SI
8677             (zero_extract:SI
8678               (match_operand 0 "ext_register_operand" "Q")
8679               (const_int 8)
8680               (const_int 8))
8681             (zero_extend:SI
8682               (match_operand:QI 1 "register_operand" "Q")))
8683           (const_int 0)))]
8684   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8685   "test{b}\t{%1, %h0|%h0, %1}"
8686   [(set_attr "type" "test")
8687    (set_attr "mode" "QI")])
8689 (define_insn "*testqi_ext_2"
8690   [(set (reg FLAGS_REG)
8691         (compare
8692           (and:SI
8693             (zero_extract:SI
8694               (match_operand 0 "ext_register_operand" "Q")
8695               (const_int 8)
8696               (const_int 8))
8697             (zero_extract:SI
8698               (match_operand 1 "ext_register_operand" "Q")
8699               (const_int 8)
8700               (const_int 8)))
8701           (const_int 0)))]
8702   "ix86_match_ccmode (insn, CCNOmode)"
8703   "test{b}\t{%h1, %h0|%h0, %h1}"
8704   [(set_attr "type" "test")
8705    (set_attr "mode" "QI")])
8707 ;; Combine likes to form bit extractions for some tests.  Humor it.
8708 (define_insn "*testqi_ext_3"
8709   [(set (reg FLAGS_REG)
8710         (compare (zero_extract:SI
8711                    (match_operand 0 "nonimmediate_operand" "rm")
8712                    (match_operand:SI 1 "const_int_operand" "")
8713                    (match_operand:SI 2 "const_int_operand" ""))
8714                  (const_int 0)))]
8715   "ix86_match_ccmode (insn, CCNOmode)
8716    && INTVAL (operands[1]) > 0
8717    && INTVAL (operands[2]) >= 0
8718    && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8719    && (GET_MODE (operands[0]) == SImode
8720        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8721        || GET_MODE (operands[0]) == HImode
8722        || GET_MODE (operands[0]) == QImode)"
8723   "#")
8725 (define_insn "*testqi_ext_3_rex64"
8726   [(set (reg FLAGS_REG)
8727         (compare (zero_extract:DI
8728                    (match_operand 0 "nonimmediate_operand" "rm")
8729                    (match_operand:DI 1 "const_int_operand" "")
8730                    (match_operand:DI 2 "const_int_operand" ""))
8731                  (const_int 0)))]
8732   "TARGET_64BIT
8733    && ix86_match_ccmode (insn, CCNOmode)
8734    && INTVAL (operands[1]) > 0
8735    && INTVAL (operands[2]) >= 0
8736    /* Ensure that resulting mask is zero or sign extended operand.  */
8737    && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8738        || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8739            && INTVAL (operands[1]) > 32))
8740    && (GET_MODE (operands[0]) == SImode
8741        || GET_MODE (operands[0]) == DImode
8742        || GET_MODE (operands[0]) == HImode
8743        || GET_MODE (operands[0]) == QImode)"
8744   "#")
8746 (define_split
8747   [(set (match_operand 0 "flags_reg_operand" "")
8748         (match_operator 1 "compare_operator"
8749           [(zero_extract
8750              (match_operand 2 "nonimmediate_operand" "")
8751              (match_operand 3 "const_int_operand" "")
8752              (match_operand 4 "const_int_operand" ""))
8753            (const_int 0)]))]
8754   "ix86_match_ccmode (insn, CCNOmode)"
8755   [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8757   rtx val = operands[2];
8758   HOST_WIDE_INT len = INTVAL (operands[3]);
8759   HOST_WIDE_INT pos = INTVAL (operands[4]);
8760   HOST_WIDE_INT mask;
8761   enum machine_mode mode, submode;
8763   mode = GET_MODE (val);
8764   if (MEM_P (val))
8765     {
8766       /* ??? Combine likes to put non-volatile mem extractions in QImode
8767          no matter the size of the test.  So find a mode that works.  */
8768       if (! MEM_VOLATILE_P (val))
8769         {
8770           mode = smallest_mode_for_size (pos + len, MODE_INT);
8771           val = adjust_address (val, mode, 0);
8772         }
8773     }
8774   else if (GET_CODE (val) == SUBREG
8775            && (submode = GET_MODE (SUBREG_REG (val)),
8776                GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8777            && pos + len <= GET_MODE_BITSIZE (submode))
8778     {
8779       /* Narrow a paradoxical subreg to prevent partial register stalls.  */
8780       mode = submode;
8781       val = SUBREG_REG (val);
8782     }
8783   else if (mode == HImode && pos + len <= 8)
8784     {
8785       /* Small HImode tests can be converted to QImode.  */
8786       mode = QImode;
8787       val = gen_lowpart (QImode, val);
8788     }
8790   if (len == HOST_BITS_PER_WIDE_INT)
8791     mask = -1;
8792   else
8793     mask = ((HOST_WIDE_INT)1 << len) - 1;
8794   mask <<= pos;
8796   operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8799 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8800 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8801 ;; this is relatively important trick.
8802 ;; Do the conversion only post-reload to avoid limiting of the register class
8803 ;; to QI regs.
8804 (define_split
8805   [(set (match_operand 0 "flags_reg_operand" "")
8806         (match_operator 1 "compare_operator"
8807           [(and (match_operand 2 "register_operand" "")
8808                 (match_operand 3 "const_int_operand" ""))
8809            (const_int 0)]))]
8810    "reload_completed
8811     && QI_REG_P (operands[2])
8812     && GET_MODE (operands[2]) != QImode
8813     && ((ix86_match_ccmode (insn, CCZmode)
8814          && !(INTVAL (operands[3]) & ~(255 << 8)))
8815         || (ix86_match_ccmode (insn, CCNOmode)
8816             && !(INTVAL (operands[3]) & ~(127 << 8))))"
8817   [(set (match_dup 0)
8818         (match_op_dup 1
8819           [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8820                    (match_dup 3))
8821            (const_int 0)]))]
8822   "operands[2] = gen_lowpart (SImode, operands[2]);
8823    operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8825 (define_split
8826   [(set (match_operand 0 "flags_reg_operand" "")
8827         (match_operator 1 "compare_operator"
8828           [(and (match_operand 2 "nonimmediate_operand" "")
8829                 (match_operand 3 "const_int_operand" ""))
8830            (const_int 0)]))]
8831    "reload_completed
8832     && GET_MODE (operands[2]) != QImode
8833     && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8834     && ((ix86_match_ccmode (insn, CCZmode)
8835          && !(INTVAL (operands[3]) & ~255))
8836         || (ix86_match_ccmode (insn, CCNOmode)
8837             && !(INTVAL (operands[3]) & ~127)))"
8838   [(set (match_dup 0)
8839         (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8840                          (const_int 0)]))]
8841   "operands[2] = gen_lowpart (QImode, operands[2]);
8842    operands[3] = gen_lowpart (QImode, operands[3]);")
8845 ;; %%% This used to optimize known byte-wide and operations to memory,
8846 ;; and sometimes to QImode registers.  If this is considered useful,
8847 ;; it should be done with splitters.
8849 (define_expand "anddi3"
8850   [(set (match_operand:DI 0 "nonimmediate_operand" "")
8851         (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8852                 (match_operand:DI 2 "x86_64_szext_general_operand" "")))
8853    (clobber (reg:CC FLAGS_REG))]
8854   "TARGET_64BIT"
8855   "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8857 (define_insn "*anddi_1_rex64"
8858   [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8859         (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8860                 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8861    (clobber (reg:CC FLAGS_REG))]
8862   "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8864   switch (get_attr_type (insn))
8865     {
8866     case TYPE_IMOVX:
8867       {
8868         enum machine_mode mode;
8870         gcc_assert (CONST_INT_P (operands[2]));
8871         if (INTVAL (operands[2]) == 0xff)
8872           mode = QImode;
8873         else
8874           {
8875             gcc_assert (INTVAL (operands[2]) == 0xffff);
8876             mode = HImode;
8877           }
8879         operands[1] = gen_lowpart (mode, operands[1]);
8880         if (mode == QImode)
8881           return "movz{bq|x}\t{%1,%0|%0, %1}";
8882         else
8883           return "movz{wq|x}\t{%1,%0|%0, %1}";
8884       }
8886     default:
8887       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8888       if (get_attr_mode (insn) == MODE_SI)
8889         return "and{l}\t{%k2, %k0|%k0, %k2}";
8890       else
8891         return "and{q}\t{%2, %0|%0, %2}";
8892     }
8894   [(set_attr "type" "alu,alu,alu,imovx")
8895    (set_attr "length_immediate" "*,*,*,0")
8896    (set_attr "mode" "SI,DI,DI,DI")])
8898 (define_insn "*anddi_2"
8899   [(set (reg FLAGS_REG)
8900         (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8901                          (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8902                  (const_int 0)))
8903    (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8904         (and:DI (match_dup 1) (match_dup 2)))]
8905   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8906    && ix86_binary_operator_ok (AND, DImode, operands)"
8907   "@
8908    and{l}\t{%k2, %k0|%k0, %k2}
8909    and{q}\t{%2, %0|%0, %2}
8910    and{q}\t{%2, %0|%0, %2}"
8911   [(set_attr "type" "alu")
8912    (set_attr "mode" "SI,DI,DI")])
8914 (define_expand "andsi3"
8915   [(set (match_operand:SI 0 "nonimmediate_operand" "")
8916         (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8917                 (match_operand:SI 2 "general_operand" "")))
8918    (clobber (reg:CC FLAGS_REG))]
8919   ""
8920   "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8922 (define_insn "*andsi_1"
8923   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8924         (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8925                 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8926    (clobber (reg:CC FLAGS_REG))]
8927   "ix86_binary_operator_ok (AND, SImode, operands)"
8929   switch (get_attr_type (insn))
8930     {
8931     case TYPE_IMOVX:
8932       {
8933         enum machine_mode mode;
8935         gcc_assert (CONST_INT_P (operands[2]));
8936         if (INTVAL (operands[2]) == 0xff)
8937           mode = QImode;
8938         else
8939           {
8940             gcc_assert (INTVAL (operands[2]) == 0xffff);
8941             mode = HImode;
8942           }
8944         operands[1] = gen_lowpart (mode, operands[1]);
8945         if (mode == QImode)
8946           return "movz{bl|x}\t{%1,%0|%0, %1}";
8947         else
8948           return "movz{wl|x}\t{%1,%0|%0, %1}";
8949       }
8951     default:
8952       gcc_assert (rtx_equal_p (operands[0], operands[1]));
8953       return "and{l}\t{%2, %0|%0, %2}";
8954     }
8956   [(set_attr "type" "alu,alu,imovx")
8957    (set_attr "length_immediate" "*,*,0")
8958    (set_attr "mode" "SI")])
8960 (define_split
8961   [(set (match_operand 0 "register_operand" "")
8962         (and (match_dup 0)
8963              (const_int -65536)))
8964    (clobber (reg:CC FLAGS_REG))]
8965   "optimize_size || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8966   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8967   "operands[1] = gen_lowpart (HImode, operands[0]);")
8969 (define_split
8970   [(set (match_operand 0 "ext_register_operand" "")
8971         (and (match_dup 0)
8972              (const_int -256)))
8973    (clobber (reg:CC FLAGS_REG))]
8974   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8975   [(set (strict_low_part (match_dup 1)) (const_int 0))]
8976   "operands[1] = gen_lowpart (QImode, operands[0]);")
8978 (define_split
8979   [(set (match_operand 0 "ext_register_operand" "")
8980         (and (match_dup 0)
8981              (const_int -65281)))
8982    (clobber (reg:CC FLAGS_REG))]
8983   "(optimize_size || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8984   [(parallel [(set (zero_extract:SI (match_dup 0)
8985                                     (const_int 8)
8986                                     (const_int 8))
8987                    (xor:SI
8988                      (zero_extract:SI (match_dup 0)
8989                                       (const_int 8)
8990                                       (const_int 8))
8991                      (zero_extract:SI (match_dup 0)
8992                                       (const_int 8)
8993                                       (const_int 8))))
8994               (clobber (reg:CC FLAGS_REG))])]
8995   "operands[0] = gen_lowpart (SImode, operands[0]);")
8997 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8998 (define_insn "*andsi_1_zext"
8999   [(set (match_operand:DI 0 "register_operand" "=r")
9000         (zero_extend:DI
9001           (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9002                   (match_operand:SI 2 "general_operand" "g"))))
9003    (clobber (reg:CC FLAGS_REG))]
9004   "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9005   "and{l}\t{%2, %k0|%k0, %2}"
9006   [(set_attr "type" "alu")
9007    (set_attr "mode" "SI")])
9009 (define_insn "*andsi_2"
9010   [(set (reg FLAGS_REG)
9011         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9012                          (match_operand:SI 2 "general_operand" "g,ri"))
9013                  (const_int 0)))
9014    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9015         (and:SI (match_dup 1) (match_dup 2)))]
9016   "ix86_match_ccmode (insn, CCNOmode)
9017    && ix86_binary_operator_ok (AND, SImode, operands)"
9018   "and{l}\t{%2, %0|%0, %2}"
9019   [(set_attr "type" "alu")
9020    (set_attr "mode" "SI")])
9022 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9023 (define_insn "*andsi_2_zext"
9024   [(set (reg FLAGS_REG)
9025         (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9026                          (match_operand:SI 2 "general_operand" "g"))
9027                  (const_int 0)))
9028    (set (match_operand:DI 0 "register_operand" "=r")
9029         (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9030   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9031    && ix86_binary_operator_ok (AND, SImode, operands)"
9032   "and{l}\t{%2, %k0|%k0, %2}"
9033   [(set_attr "type" "alu")
9034    (set_attr "mode" "SI")])
9036 (define_expand "andhi3"
9037   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9038         (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9039                 (match_operand:HI 2 "general_operand" "")))
9040    (clobber (reg:CC FLAGS_REG))]
9041   "TARGET_HIMODE_MATH"
9042   "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9044 (define_insn "*andhi_1"
9045   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9046         (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9047                 (match_operand:HI 2 "general_operand" "ri,rm,L")))
9048    (clobber (reg:CC FLAGS_REG))]
9049   "ix86_binary_operator_ok (AND, HImode, operands)"
9051   switch (get_attr_type (insn))
9052     {
9053     case TYPE_IMOVX:
9054       gcc_assert (CONST_INT_P (operands[2]));
9055       gcc_assert (INTVAL (operands[2]) == 0xff);
9056       return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9058     default:
9059       gcc_assert (rtx_equal_p (operands[0], operands[1]));
9061       return "and{w}\t{%2, %0|%0, %2}";
9062     }
9064   [(set_attr "type" "alu,alu,imovx")
9065    (set_attr "length_immediate" "*,*,0")
9066    (set_attr "mode" "HI,HI,SI")])
9068 (define_insn "*andhi_2"
9069   [(set (reg FLAGS_REG)
9070         (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9071                          (match_operand:HI 2 "general_operand" "g,ri"))
9072                  (const_int 0)))
9073    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9074         (and:HI (match_dup 1) (match_dup 2)))]
9075   "ix86_match_ccmode (insn, CCNOmode)
9076    && ix86_binary_operator_ok (AND, HImode, operands)"
9077   "and{w}\t{%2, %0|%0, %2}"
9078   [(set_attr "type" "alu")
9079    (set_attr "mode" "HI")])
9081 (define_expand "andqi3"
9082   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9083         (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9084                 (match_operand:QI 2 "general_operand" "")))
9085    (clobber (reg:CC FLAGS_REG))]
9086   "TARGET_QIMODE_MATH"
9087   "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9089 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9090 (define_insn "*andqi_1"
9091   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9092         (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9093                 (match_operand:QI 2 "general_operand" "qi,qmi,ri")))
9094    (clobber (reg:CC FLAGS_REG))]
9095   "ix86_binary_operator_ok (AND, QImode, operands)"
9096   "@
9097    and{b}\t{%2, %0|%0, %2}
9098    and{b}\t{%2, %0|%0, %2}
9099    and{l}\t{%k2, %k0|%k0, %k2}"
9100   [(set_attr "type" "alu")
9101    (set_attr "mode" "QI,QI,SI")])
9103 (define_insn "*andqi_1_slp"
9104   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9105         (and:QI (match_dup 0)
9106                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9107    (clobber (reg:CC FLAGS_REG))]
9108   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9109    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9110   "and{b}\t{%1, %0|%0, %1}"
9111   [(set_attr "type" "alu1")
9112    (set_attr "mode" "QI")])
9114 (define_insn "*andqi_2_maybe_si"
9115   [(set (reg FLAGS_REG)
9116         (compare (and:QI
9117                       (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9118                       (match_operand:QI 2 "general_operand" "qim,qi,i"))
9119                  (const_int 0)))
9120    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9121         (and:QI (match_dup 1) (match_dup 2)))]
9122   "ix86_binary_operator_ok (AND, QImode, operands)
9123    && ix86_match_ccmode (insn,
9124                          CONST_INT_P (operands[2])
9125                          && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9127   if (which_alternative == 2)
9128     {
9129       if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9130         operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9131       return "and{l}\t{%2, %k0|%k0, %2}";
9132     }
9133   return "and{b}\t{%2, %0|%0, %2}";
9135   [(set_attr "type" "alu")
9136    (set_attr "mode" "QI,QI,SI")])
9138 (define_insn "*andqi_2"
9139   [(set (reg FLAGS_REG)
9140         (compare (and:QI
9141                    (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9142                    (match_operand:QI 2 "general_operand" "qim,qi"))
9143                  (const_int 0)))
9144    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9145         (and:QI (match_dup 1) (match_dup 2)))]
9146   "ix86_match_ccmode (insn, CCNOmode)
9147    && ix86_binary_operator_ok (AND, QImode, operands)"
9148   "and{b}\t{%2, %0|%0, %2}"
9149   [(set_attr "type" "alu")
9150    (set_attr "mode" "QI")])
9152 (define_insn "*andqi_2_slp"
9153   [(set (reg FLAGS_REG)
9154         (compare (and:QI
9155                    (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9156                    (match_operand:QI 1 "nonimmediate_operand" "qmi,qi"))
9157                  (const_int 0)))
9158    (set (strict_low_part (match_dup 0))
9159         (and:QI (match_dup 0) (match_dup 1)))]
9160   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9161    && ix86_match_ccmode (insn, CCNOmode)
9162    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9163   "and{b}\t{%1, %0|%0, %1}"
9164   [(set_attr "type" "alu1")
9165    (set_attr "mode" "QI")])
9167 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9168 ;; operand to zero_extend in andqi_ext_1.  It was checking explicitly
9169 ;; for a QImode operand, which of course failed.
9171 (define_insn "andqi_ext_0"
9172   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9173                          (const_int 8)
9174                          (const_int 8))
9175         (and:SI
9176           (zero_extract:SI
9177             (match_operand 1 "ext_register_operand" "0")
9178             (const_int 8)
9179             (const_int 8))
9180           (match_operand 2 "const_int_operand" "n")))
9181    (clobber (reg:CC FLAGS_REG))]
9182   ""
9183   "and{b}\t{%2, %h0|%h0, %2}"
9184   [(set_attr "type" "alu")
9185    (set_attr "length_immediate" "1")
9186    (set_attr "mode" "QI")])
9188 ;; Generated by peephole translating test to and.  This shows up
9189 ;; often in fp comparisons.
9191 (define_insn "*andqi_ext_0_cc"
9192   [(set (reg FLAGS_REG)
9193         (compare
9194           (and:SI
9195             (zero_extract:SI
9196               (match_operand 1 "ext_register_operand" "0")
9197               (const_int 8)
9198               (const_int 8))
9199             (match_operand 2 "const_int_operand" "n"))
9200           (const_int 0)))
9201    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9202                          (const_int 8)
9203                          (const_int 8))
9204         (and:SI
9205           (zero_extract:SI
9206             (match_dup 1)
9207             (const_int 8)
9208             (const_int 8))
9209           (match_dup 2)))]
9210   "ix86_match_ccmode (insn, CCNOmode)"
9211   "and{b}\t{%2, %h0|%h0, %2}"
9212   [(set_attr "type" "alu")
9213    (set_attr "length_immediate" "1")
9214    (set_attr "mode" "QI")])
9216 (define_insn "*andqi_ext_1"
9217   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9218                          (const_int 8)
9219                          (const_int 8))
9220         (and:SI
9221           (zero_extract:SI
9222             (match_operand 1 "ext_register_operand" "0")
9223             (const_int 8)
9224             (const_int 8))
9225           (zero_extend:SI
9226             (match_operand:QI 2 "general_operand" "Qm"))))
9227    (clobber (reg:CC FLAGS_REG))]
9228   "!TARGET_64BIT"
9229   "and{b}\t{%2, %h0|%h0, %2}"
9230   [(set_attr "type" "alu")
9231    (set_attr "length_immediate" "0")
9232    (set_attr "mode" "QI")])
9234 (define_insn "*andqi_ext_1_rex64"
9235   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9236                          (const_int 8)
9237                          (const_int 8))
9238         (and:SI
9239           (zero_extract:SI
9240             (match_operand 1 "ext_register_operand" "0")
9241             (const_int 8)
9242             (const_int 8))
9243           (zero_extend:SI
9244             (match_operand 2 "ext_register_operand" "Q"))))
9245    (clobber (reg:CC FLAGS_REG))]
9246   "TARGET_64BIT"
9247   "and{b}\t{%2, %h0|%h0, %2}"
9248   [(set_attr "type" "alu")
9249    (set_attr "length_immediate" "0")
9250    (set_attr "mode" "QI")])
9252 (define_insn "*andqi_ext_2"
9253   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9254                          (const_int 8)
9255                          (const_int 8))
9256         (and:SI
9257           (zero_extract:SI
9258             (match_operand 1 "ext_register_operand" "%0")
9259             (const_int 8)
9260             (const_int 8))
9261           (zero_extract:SI
9262             (match_operand 2 "ext_register_operand" "Q")
9263             (const_int 8)
9264             (const_int 8))))
9265    (clobber (reg:CC FLAGS_REG))]
9266   ""
9267   "and{b}\t{%h2, %h0|%h0, %h2}"
9268   [(set_attr "type" "alu")
9269    (set_attr "length_immediate" "0")
9270    (set_attr "mode" "QI")])
9272 ;; Convert wide AND instructions with immediate operand to shorter QImode
9273 ;; equivalents when possible.
9274 ;; Don't do the splitting with memory operands, since it introduces risk
9275 ;; of memory mismatch stalls.  We may want to do the splitting for optimizing
9276 ;; for size, but that can (should?) be handled by generic code instead.
9277 (define_split
9278   [(set (match_operand 0 "register_operand" "")
9279         (and (match_operand 1 "register_operand" "")
9280              (match_operand 2 "const_int_operand" "")))
9281    (clobber (reg:CC FLAGS_REG))]
9282    "reload_completed
9283     && QI_REG_P (operands[0])
9284     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9285     && !(~INTVAL (operands[2]) & ~(255 << 8))
9286     && GET_MODE (operands[0]) != QImode"
9287   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9288                    (and:SI (zero_extract:SI (match_dup 1)
9289                                             (const_int 8) (const_int 8))
9290                            (match_dup 2)))
9291               (clobber (reg:CC FLAGS_REG))])]
9292   "operands[0] = gen_lowpart (SImode, operands[0]);
9293    operands[1] = gen_lowpart (SImode, operands[1]);
9294    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9296 ;; Since AND can be encoded with sign extended immediate, this is only
9297 ;; profitable when 7th bit is not set.
9298 (define_split
9299   [(set (match_operand 0 "register_operand" "")
9300         (and (match_operand 1 "general_operand" "")
9301              (match_operand 2 "const_int_operand" "")))
9302    (clobber (reg:CC FLAGS_REG))]
9303    "reload_completed
9304     && ANY_QI_REG_P (operands[0])
9305     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9306     && !(~INTVAL (operands[2]) & ~255)
9307     && !(INTVAL (operands[2]) & 128)
9308     && GET_MODE (operands[0]) != QImode"
9309   [(parallel [(set (strict_low_part (match_dup 0))
9310                    (and:QI (match_dup 1)
9311                            (match_dup 2)))
9312               (clobber (reg:CC FLAGS_REG))])]
9313   "operands[0] = gen_lowpart (QImode, operands[0]);
9314    operands[1] = gen_lowpart (QImode, operands[1]);
9315    operands[2] = gen_lowpart (QImode, operands[2]);")
9317 ;; Logical inclusive OR instructions
9319 ;; %%% This used to optimize known byte-wide and operations to memory.
9320 ;; If this is considered useful, it should be done with splitters.
9322 (define_expand "iordi3"
9323   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9324         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
9325                 (match_operand:DI 2 "x86_64_general_operand" "")))
9326    (clobber (reg:CC FLAGS_REG))]
9327   "TARGET_64BIT"
9328   "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
9330 (define_insn "*iordi_1_rex64"
9331   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9332         (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9333                 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
9334    (clobber (reg:CC FLAGS_REG))]
9335   "TARGET_64BIT
9336    && ix86_binary_operator_ok (IOR, DImode, operands)"
9337   "or{q}\t{%2, %0|%0, %2}"
9338   [(set_attr "type" "alu")
9339    (set_attr "mode" "DI")])
9341 (define_insn "*iordi_2_rex64"
9342   [(set (reg FLAGS_REG)
9343         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9344                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9345                  (const_int 0)))
9346    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9347         (ior:DI (match_dup 1) (match_dup 2)))]
9348   "TARGET_64BIT
9349    && ix86_match_ccmode (insn, CCNOmode)
9350    && ix86_binary_operator_ok (IOR, DImode, operands)"
9351   "or{q}\t{%2, %0|%0, %2}"
9352   [(set_attr "type" "alu")
9353    (set_attr "mode" "DI")])
9355 (define_insn "*iordi_3_rex64"
9356   [(set (reg FLAGS_REG)
9357         (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9358                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9359                  (const_int 0)))
9360    (clobber (match_scratch:DI 0 "=r"))]
9361   "TARGET_64BIT
9362    && ix86_match_ccmode (insn, CCNOmode)
9363    && ix86_binary_operator_ok (IOR, DImode, operands)"
9364   "or{q}\t{%2, %0|%0, %2}"
9365   [(set_attr "type" "alu")
9366    (set_attr "mode" "DI")])
9369 (define_expand "iorsi3"
9370   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9371         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
9372                 (match_operand:SI 2 "general_operand" "")))
9373    (clobber (reg:CC FLAGS_REG))]
9374   ""
9375   "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
9377 (define_insn "*iorsi_1"
9378   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9379         (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9380                 (match_operand:SI 2 "general_operand" "ri,g")))
9381    (clobber (reg:CC FLAGS_REG))]
9382   "ix86_binary_operator_ok (IOR, SImode, operands)"
9383   "or{l}\t{%2, %0|%0, %2}"
9384   [(set_attr "type" "alu")
9385    (set_attr "mode" "SI")])
9387 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9388 (define_insn "*iorsi_1_zext"
9389   [(set (match_operand:DI 0 "register_operand" "=r")
9390         (zero_extend:DI
9391           (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9392                   (match_operand:SI 2 "general_operand" "g"))))
9393    (clobber (reg:CC FLAGS_REG))]
9394   "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9395   "or{l}\t{%2, %k0|%k0, %2}"
9396   [(set_attr "type" "alu")
9397    (set_attr "mode" "SI")])
9399 (define_insn "*iorsi_1_zext_imm"
9400   [(set (match_operand:DI 0 "register_operand" "=r")
9401         (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9402                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9403    (clobber (reg:CC FLAGS_REG))]
9404   "TARGET_64BIT"
9405   "or{l}\t{%2, %k0|%k0, %2}"
9406   [(set_attr "type" "alu")
9407    (set_attr "mode" "SI")])
9409 (define_insn "*iorsi_2"
9410   [(set (reg FLAGS_REG)
9411         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9412                          (match_operand:SI 2 "general_operand" "g,ri"))
9413                  (const_int 0)))
9414    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9415         (ior:SI (match_dup 1) (match_dup 2)))]
9416   "ix86_match_ccmode (insn, CCNOmode)
9417    && ix86_binary_operator_ok (IOR, SImode, operands)"
9418   "or{l}\t{%2, %0|%0, %2}"
9419   [(set_attr "type" "alu")
9420    (set_attr "mode" "SI")])
9422 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9423 ;; ??? Special case for immediate operand is missing - it is tricky.
9424 (define_insn "*iorsi_2_zext"
9425   [(set (reg FLAGS_REG)
9426         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9427                          (match_operand:SI 2 "general_operand" "g"))
9428                  (const_int 0)))
9429    (set (match_operand:DI 0 "register_operand" "=r")
9430         (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9431   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9432    && ix86_binary_operator_ok (IOR, SImode, operands)"
9433   "or{l}\t{%2, %k0|%k0, %2}"
9434   [(set_attr "type" "alu")
9435    (set_attr "mode" "SI")])
9437 (define_insn "*iorsi_2_zext_imm"
9438   [(set (reg FLAGS_REG)
9439         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9440                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9441                  (const_int 0)))
9442    (set (match_operand:DI 0 "register_operand" "=r")
9443         (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9444   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9445    && ix86_binary_operator_ok (IOR, SImode, operands)"
9446   "or{l}\t{%2, %k0|%k0, %2}"
9447   [(set_attr "type" "alu")
9448    (set_attr "mode" "SI")])
9450 (define_insn "*iorsi_3"
9451   [(set (reg FLAGS_REG)
9452         (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9453                          (match_operand:SI 2 "general_operand" "g"))
9454                  (const_int 0)))
9455    (clobber (match_scratch:SI 0 "=r"))]
9456   "ix86_match_ccmode (insn, CCNOmode)
9457    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9458   "or{l}\t{%2, %0|%0, %2}"
9459   [(set_attr "type" "alu")
9460    (set_attr "mode" "SI")])
9462 (define_expand "iorhi3"
9463   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9464         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9465                 (match_operand:HI 2 "general_operand" "")))
9466    (clobber (reg:CC FLAGS_REG))]
9467   "TARGET_HIMODE_MATH"
9468   "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9470 (define_insn "*iorhi_1"
9471   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9472         (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9473                 (match_operand:HI 2 "general_operand" "g,ri")))
9474    (clobber (reg:CC FLAGS_REG))]
9475   "ix86_binary_operator_ok (IOR, HImode, operands)"
9476   "or{w}\t{%2, %0|%0, %2}"
9477   [(set_attr "type" "alu")
9478    (set_attr "mode" "HI")])
9480 (define_insn "*iorhi_2"
9481   [(set (reg FLAGS_REG)
9482         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9483                          (match_operand:HI 2 "general_operand" "g,ri"))
9484                  (const_int 0)))
9485    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9486         (ior:HI (match_dup 1) (match_dup 2)))]
9487   "ix86_match_ccmode (insn, CCNOmode)
9488    && ix86_binary_operator_ok (IOR, HImode, operands)"
9489   "or{w}\t{%2, %0|%0, %2}"
9490   [(set_attr "type" "alu")
9491    (set_attr "mode" "HI")])
9493 (define_insn "*iorhi_3"
9494   [(set (reg FLAGS_REG)
9495         (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9496                          (match_operand:HI 2 "general_operand" "g"))
9497                  (const_int 0)))
9498    (clobber (match_scratch:HI 0 "=r"))]
9499   "ix86_match_ccmode (insn, CCNOmode)
9500    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9501   "or{w}\t{%2, %0|%0, %2}"
9502   [(set_attr "type" "alu")
9503    (set_attr "mode" "HI")])
9505 (define_expand "iorqi3"
9506   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9507         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9508                 (match_operand:QI 2 "general_operand" "")))
9509    (clobber (reg:CC FLAGS_REG))]
9510   "TARGET_QIMODE_MATH"
9511   "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9513 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9514 (define_insn "*iorqi_1"
9515   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9516         (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9517                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9518    (clobber (reg:CC FLAGS_REG))]
9519   "ix86_binary_operator_ok (IOR, QImode, operands)"
9520   "@
9521    or{b}\t{%2, %0|%0, %2}
9522    or{b}\t{%2, %0|%0, %2}
9523    or{l}\t{%k2, %k0|%k0, %k2}"
9524   [(set_attr "type" "alu")
9525    (set_attr "mode" "QI,QI,SI")])
9527 (define_insn "*iorqi_1_slp"
9528   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9529         (ior:QI (match_dup 0)
9530                 (match_operand:QI 1 "general_operand" "qmi,qi")))
9531    (clobber (reg:CC FLAGS_REG))]
9532   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9533    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9534   "or{b}\t{%1, %0|%0, %1}"
9535   [(set_attr "type" "alu1")
9536    (set_attr "mode" "QI")])
9538 (define_insn "*iorqi_2"
9539   [(set (reg FLAGS_REG)
9540         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9541                          (match_operand:QI 2 "general_operand" "qim,qi"))
9542                  (const_int 0)))
9543    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9544         (ior:QI (match_dup 1) (match_dup 2)))]
9545   "ix86_match_ccmode (insn, CCNOmode)
9546    && ix86_binary_operator_ok (IOR, QImode, operands)"
9547   "or{b}\t{%2, %0|%0, %2}"
9548   [(set_attr "type" "alu")
9549    (set_attr "mode" "QI")])
9551 (define_insn "*iorqi_2_slp"
9552   [(set (reg FLAGS_REG)
9553         (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9554                          (match_operand:QI 1 "general_operand" "qim,qi"))
9555                  (const_int 0)))
9556    (set (strict_low_part (match_dup 0))
9557         (ior:QI (match_dup 0) (match_dup 1)))]
9558   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9559    && ix86_match_ccmode (insn, CCNOmode)
9560    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9561   "or{b}\t{%1, %0|%0, %1}"
9562   [(set_attr "type" "alu1")
9563    (set_attr "mode" "QI")])
9565 (define_insn "*iorqi_3"
9566   [(set (reg FLAGS_REG)
9567         (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9568                          (match_operand:QI 2 "general_operand" "qim"))
9569                  (const_int 0)))
9570    (clobber (match_scratch:QI 0 "=q"))]
9571   "ix86_match_ccmode (insn, CCNOmode)
9572    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9573   "or{b}\t{%2, %0|%0, %2}"
9574   [(set_attr "type" "alu")
9575    (set_attr "mode" "QI")])
9577 (define_insn "iorqi_ext_0"
9578   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9579                          (const_int 8)
9580                          (const_int 8))
9581         (ior:SI
9582           (zero_extract:SI
9583             (match_operand 1 "ext_register_operand" "0")
9584             (const_int 8)
9585             (const_int 8))
9586           (match_operand 2 "const_int_operand" "n")))
9587    (clobber (reg:CC FLAGS_REG))]
9588   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9589   "or{b}\t{%2, %h0|%h0, %2}"
9590   [(set_attr "type" "alu")
9591    (set_attr "length_immediate" "1")
9592    (set_attr "mode" "QI")])
9594 (define_insn "*iorqi_ext_1"
9595   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9596                          (const_int 8)
9597                          (const_int 8))
9598         (ior:SI
9599           (zero_extract:SI
9600             (match_operand 1 "ext_register_operand" "0")
9601             (const_int 8)
9602             (const_int 8))
9603           (zero_extend:SI
9604             (match_operand:QI 2 "general_operand" "Qm"))))
9605    (clobber (reg:CC FLAGS_REG))]
9606   "!TARGET_64BIT
9607    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9608   "or{b}\t{%2, %h0|%h0, %2}"
9609   [(set_attr "type" "alu")
9610    (set_attr "length_immediate" "0")
9611    (set_attr "mode" "QI")])
9613 (define_insn "*iorqi_ext_1_rex64"
9614   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9615                          (const_int 8)
9616                          (const_int 8))
9617         (ior:SI
9618           (zero_extract:SI
9619             (match_operand 1 "ext_register_operand" "0")
9620             (const_int 8)
9621             (const_int 8))
9622           (zero_extend:SI
9623             (match_operand 2 "ext_register_operand" "Q"))))
9624    (clobber (reg:CC FLAGS_REG))]
9625   "TARGET_64BIT
9626    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9627   "or{b}\t{%2, %h0|%h0, %2}"
9628   [(set_attr "type" "alu")
9629    (set_attr "length_immediate" "0")
9630    (set_attr "mode" "QI")])
9632 (define_insn "*iorqi_ext_2"
9633   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9634                          (const_int 8)
9635                          (const_int 8))
9636         (ior:SI
9637           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9638                            (const_int 8)
9639                            (const_int 8))
9640           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9641                            (const_int 8)
9642                            (const_int 8))))
9643    (clobber (reg:CC FLAGS_REG))]
9644   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9645   "ior{b}\t{%h2, %h0|%h0, %h2}"
9646   [(set_attr "type" "alu")
9647    (set_attr "length_immediate" "0")
9648    (set_attr "mode" "QI")])
9650 (define_split
9651   [(set (match_operand 0 "register_operand" "")
9652         (ior (match_operand 1 "register_operand" "")
9653              (match_operand 2 "const_int_operand" "")))
9654    (clobber (reg:CC FLAGS_REG))]
9655    "reload_completed
9656     && QI_REG_P (operands[0])
9657     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9658     && !(INTVAL (operands[2]) & ~(255 << 8))
9659     && GET_MODE (operands[0]) != QImode"
9660   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9661                    (ior:SI (zero_extract:SI (match_dup 1)
9662                                             (const_int 8) (const_int 8))
9663                            (match_dup 2)))
9664               (clobber (reg:CC FLAGS_REG))])]
9665   "operands[0] = gen_lowpart (SImode, operands[0]);
9666    operands[1] = gen_lowpart (SImode, operands[1]);
9667    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9669 ;; Since OR can be encoded with sign extended immediate, this is only
9670 ;; profitable when 7th bit is set.
9671 (define_split
9672   [(set (match_operand 0 "register_operand" "")
9673         (ior (match_operand 1 "general_operand" "")
9674              (match_operand 2 "const_int_operand" "")))
9675    (clobber (reg:CC FLAGS_REG))]
9676    "reload_completed
9677     && ANY_QI_REG_P (operands[0])
9678     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
9679     && !(INTVAL (operands[2]) & ~255)
9680     && (INTVAL (operands[2]) & 128)
9681     && GET_MODE (operands[0]) != QImode"
9682   [(parallel [(set (strict_low_part (match_dup 0))
9683                    (ior:QI (match_dup 1)
9684                            (match_dup 2)))
9685               (clobber (reg:CC FLAGS_REG))])]
9686   "operands[0] = gen_lowpart (QImode, operands[0]);
9687    operands[1] = gen_lowpart (QImode, operands[1]);
9688    operands[2] = gen_lowpart (QImode, operands[2]);")
9690 ;; Logical XOR instructions
9692 ;; %%% This used to optimize known byte-wide and operations to memory.
9693 ;; If this is considered useful, it should be done with splitters.
9695 (define_expand "xordi3"
9696   [(set (match_operand:DI 0 "nonimmediate_operand" "")
9697         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9698                 (match_operand:DI 2 "x86_64_general_operand" "")))
9699    (clobber (reg:CC FLAGS_REG))]
9700   "TARGET_64BIT"
9701   "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9703 (define_insn "*xordi_1_rex64"
9704   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9705         (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9706                 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9707    (clobber (reg:CC FLAGS_REG))]
9708   "TARGET_64BIT
9709    && ix86_binary_operator_ok (XOR, DImode, operands)"
9710   "xor{q}\t{%2, %0|%0, %2}"
9711   [(set_attr "type" "alu")
9712    (set_attr "mode" "DI")])
9714 (define_insn "*xordi_2_rex64"
9715   [(set (reg FLAGS_REG)
9716         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9717                          (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9718                  (const_int 0)))
9719    (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9720         (xor:DI (match_dup 1) (match_dup 2)))]
9721   "TARGET_64BIT
9722    && ix86_match_ccmode (insn, CCNOmode)
9723    && ix86_binary_operator_ok (XOR, DImode, operands)"
9724   "xor{q}\t{%2, %0|%0, %2}"
9725   [(set_attr "type" "alu")
9726    (set_attr "mode" "DI")])
9728 (define_insn "*xordi_3_rex64"
9729   [(set (reg FLAGS_REG)
9730         (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9731                          (match_operand:DI 2 "x86_64_general_operand" "rem"))
9732                  (const_int 0)))
9733    (clobber (match_scratch:DI 0 "=r"))]
9734   "TARGET_64BIT
9735    && ix86_match_ccmode (insn, CCNOmode)
9736    && ix86_binary_operator_ok (XOR, DImode, operands)"
9737   "xor{q}\t{%2, %0|%0, %2}"
9738   [(set_attr "type" "alu")
9739    (set_attr "mode" "DI")])
9741 (define_expand "xorsi3"
9742   [(set (match_operand:SI 0 "nonimmediate_operand" "")
9743         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9744                 (match_operand:SI 2 "general_operand" "")))
9745    (clobber (reg:CC FLAGS_REG))]
9746   ""
9747   "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9749 (define_insn "*xorsi_1"
9750   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9751         (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9752                 (match_operand:SI 2 "general_operand" "ri,rm")))
9753    (clobber (reg:CC FLAGS_REG))]
9754   "ix86_binary_operator_ok (XOR, SImode, operands)"
9755   "xor{l}\t{%2, %0|%0, %2}"
9756   [(set_attr "type" "alu")
9757    (set_attr "mode" "SI")])
9759 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9760 ;; Add speccase for immediates
9761 (define_insn "*xorsi_1_zext"
9762   [(set (match_operand:DI 0 "register_operand" "=r")
9763         (zero_extend:DI
9764           (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9765                   (match_operand:SI 2 "general_operand" "g"))))
9766    (clobber (reg:CC FLAGS_REG))]
9767   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9768   "xor{l}\t{%2, %k0|%k0, %2}"
9769   [(set_attr "type" "alu")
9770    (set_attr "mode" "SI")])
9772 (define_insn "*xorsi_1_zext_imm"
9773   [(set (match_operand:DI 0 "register_operand" "=r")
9774         (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9775                 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9776    (clobber (reg:CC FLAGS_REG))]
9777   "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9778   "xor{l}\t{%2, %k0|%k0, %2}"
9779   [(set_attr "type" "alu")
9780    (set_attr "mode" "SI")])
9782 (define_insn "*xorsi_2"
9783   [(set (reg FLAGS_REG)
9784         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9785                          (match_operand:SI 2 "general_operand" "g,ri"))
9786                  (const_int 0)))
9787    (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9788         (xor:SI (match_dup 1) (match_dup 2)))]
9789   "ix86_match_ccmode (insn, CCNOmode)
9790    && ix86_binary_operator_ok (XOR, SImode, operands)"
9791   "xor{l}\t{%2, %0|%0, %2}"
9792   [(set_attr "type" "alu")
9793    (set_attr "mode" "SI")])
9795 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9796 ;; ??? Special case for immediate operand is missing - it is tricky.
9797 (define_insn "*xorsi_2_zext"
9798   [(set (reg FLAGS_REG)
9799         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9800                          (match_operand:SI 2 "general_operand" "g"))
9801                  (const_int 0)))
9802    (set (match_operand:DI 0 "register_operand" "=r")
9803         (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9804   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9805    && ix86_binary_operator_ok (XOR, SImode, operands)"
9806   "xor{l}\t{%2, %k0|%k0, %2}"
9807   [(set_attr "type" "alu")
9808    (set_attr "mode" "SI")])
9810 (define_insn "*xorsi_2_zext_imm"
9811   [(set (reg FLAGS_REG)
9812         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9813                          (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9814                  (const_int 0)))
9815    (set (match_operand:DI 0 "register_operand" "=r")
9816         (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9817   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9818    && ix86_binary_operator_ok (XOR, SImode, operands)"
9819   "xor{l}\t{%2, %k0|%k0, %2}"
9820   [(set_attr "type" "alu")
9821    (set_attr "mode" "SI")])
9823 (define_insn "*xorsi_3"
9824   [(set (reg FLAGS_REG)
9825         (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9826                          (match_operand:SI 2 "general_operand" "g"))
9827                  (const_int 0)))
9828    (clobber (match_scratch:SI 0 "=r"))]
9829   "ix86_match_ccmode (insn, CCNOmode)
9830    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9831   "xor{l}\t{%2, %0|%0, %2}"
9832   [(set_attr "type" "alu")
9833    (set_attr "mode" "SI")])
9835 (define_expand "xorhi3"
9836   [(set (match_operand:HI 0 "nonimmediate_operand" "")
9837         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9838                 (match_operand:HI 2 "general_operand" "")))
9839    (clobber (reg:CC FLAGS_REG))]
9840   "TARGET_HIMODE_MATH"
9841   "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9843 (define_insn "*xorhi_1"
9844   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9845         (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9846                 (match_operand:HI 2 "general_operand" "g,ri")))
9847    (clobber (reg:CC FLAGS_REG))]
9848   "ix86_binary_operator_ok (XOR, HImode, operands)"
9849   "xor{w}\t{%2, %0|%0, %2}"
9850   [(set_attr "type" "alu")
9851    (set_attr "mode" "HI")])
9853 (define_insn "*xorhi_2"
9854   [(set (reg FLAGS_REG)
9855         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9856                          (match_operand:HI 2 "general_operand" "g,ri"))
9857                  (const_int 0)))
9858    (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9859         (xor:HI (match_dup 1) (match_dup 2)))]
9860   "ix86_match_ccmode (insn, CCNOmode)
9861    && ix86_binary_operator_ok (XOR, HImode, operands)"
9862   "xor{w}\t{%2, %0|%0, %2}"
9863   [(set_attr "type" "alu")
9864    (set_attr "mode" "HI")])
9866 (define_insn "*xorhi_3"
9867   [(set (reg FLAGS_REG)
9868         (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9869                          (match_operand:HI 2 "general_operand" "g"))
9870                  (const_int 0)))
9871    (clobber (match_scratch:HI 0 "=r"))]
9872   "ix86_match_ccmode (insn, CCNOmode)
9873    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9874   "xor{w}\t{%2, %0|%0, %2}"
9875   [(set_attr "type" "alu")
9876    (set_attr "mode" "HI")])
9878 (define_expand "xorqi3"
9879   [(set (match_operand:QI 0 "nonimmediate_operand" "")
9880         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9881                 (match_operand:QI 2 "general_operand" "")))
9882    (clobber (reg:CC FLAGS_REG))]
9883   "TARGET_QIMODE_MATH"
9884   "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9886 ;; %%% Potential partial reg stall on alternative 2.  What to do?
9887 (define_insn "*xorqi_1"
9888   [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9889         (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9890                 (match_operand:QI 2 "general_operand" "qmi,qi,ri")))
9891    (clobber (reg:CC FLAGS_REG))]
9892   "ix86_binary_operator_ok (XOR, QImode, operands)"
9893   "@
9894    xor{b}\t{%2, %0|%0, %2}
9895    xor{b}\t{%2, %0|%0, %2}
9896    xor{l}\t{%k2, %k0|%k0, %k2}"
9897   [(set_attr "type" "alu")
9898    (set_attr "mode" "QI,QI,SI")])
9900 (define_insn "*xorqi_1_slp"
9901   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9902         (xor:QI (match_dup 0)
9903                 (match_operand:QI 1 "general_operand" "qi,qmi")))
9904    (clobber (reg:CC FLAGS_REG))]
9905   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
9906    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9907   "xor{b}\t{%1, %0|%0, %1}"
9908   [(set_attr "type" "alu1")
9909    (set_attr "mode" "QI")])
9911 (define_insn "xorqi_ext_0"
9912   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9913                          (const_int 8)
9914                          (const_int 8))
9915         (xor:SI
9916           (zero_extract:SI
9917             (match_operand 1 "ext_register_operand" "0")
9918             (const_int 8)
9919             (const_int 8))
9920           (match_operand 2 "const_int_operand" "n")))
9921    (clobber (reg:CC FLAGS_REG))]
9922   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9923   "xor{b}\t{%2, %h0|%h0, %2}"
9924   [(set_attr "type" "alu")
9925    (set_attr "length_immediate" "1")
9926    (set_attr "mode" "QI")])
9928 (define_insn "*xorqi_ext_1"
9929   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9930                          (const_int 8)
9931                          (const_int 8))
9932         (xor:SI
9933           (zero_extract:SI
9934             (match_operand 1 "ext_register_operand" "0")
9935             (const_int 8)
9936             (const_int 8))
9937           (zero_extend:SI
9938             (match_operand:QI 2 "general_operand" "Qm"))))
9939    (clobber (reg:CC FLAGS_REG))]
9940   "!TARGET_64BIT
9941    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9942   "xor{b}\t{%2, %h0|%h0, %2}"
9943   [(set_attr "type" "alu")
9944    (set_attr "length_immediate" "0")
9945    (set_attr "mode" "QI")])
9947 (define_insn "*xorqi_ext_1_rex64"
9948   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9949                          (const_int 8)
9950                          (const_int 8))
9951         (xor:SI
9952           (zero_extract:SI
9953             (match_operand 1 "ext_register_operand" "0")
9954             (const_int 8)
9955             (const_int 8))
9956           (zero_extend:SI
9957             (match_operand 2 "ext_register_operand" "Q"))))
9958    (clobber (reg:CC FLAGS_REG))]
9959   "TARGET_64BIT
9960    && (!TARGET_PARTIAL_REG_STALL || optimize_size)"
9961   "xor{b}\t{%2, %h0|%h0, %2}"
9962   [(set_attr "type" "alu")
9963    (set_attr "length_immediate" "0")
9964    (set_attr "mode" "QI")])
9966 (define_insn "*xorqi_ext_2"
9967   [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9968                          (const_int 8)
9969                          (const_int 8))
9970         (xor:SI
9971           (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9972                            (const_int 8)
9973                            (const_int 8))
9974           (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9975                            (const_int 8)
9976                            (const_int 8))))
9977    (clobber (reg:CC FLAGS_REG))]
9978   "(!TARGET_PARTIAL_REG_STALL || optimize_size)"
9979   "xor{b}\t{%h2, %h0|%h0, %h2}"
9980   [(set_attr "type" "alu")
9981    (set_attr "length_immediate" "0")
9982    (set_attr "mode" "QI")])
9984 (define_insn "*xorqi_cc_1"
9985   [(set (reg FLAGS_REG)
9986         (compare
9987           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9988                   (match_operand:QI 2 "general_operand" "qim,qi"))
9989           (const_int 0)))
9990    (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9991         (xor:QI (match_dup 1) (match_dup 2)))]
9992   "ix86_match_ccmode (insn, CCNOmode)
9993    && ix86_binary_operator_ok (XOR, QImode, operands)"
9994   "xor{b}\t{%2, %0|%0, %2}"
9995   [(set_attr "type" "alu")
9996    (set_attr "mode" "QI")])
9998 (define_insn "*xorqi_2_slp"
9999   [(set (reg FLAGS_REG)
10000         (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10001                          (match_operand:QI 1 "general_operand" "qim,qi"))
10002                  (const_int 0)))
10003    (set (strict_low_part (match_dup 0))
10004         (xor:QI (match_dup 0) (match_dup 1)))]
10005   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
10006    && ix86_match_ccmode (insn, CCNOmode)
10007    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10008   "xor{b}\t{%1, %0|%0, %1}"
10009   [(set_attr "type" "alu1")
10010    (set_attr "mode" "QI")])
10012 (define_insn "*xorqi_cc_2"
10013   [(set (reg FLAGS_REG)
10014         (compare
10015           (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10016                   (match_operand:QI 2 "general_operand" "qim"))
10017           (const_int 0)))
10018    (clobber (match_scratch:QI 0 "=q"))]
10019   "ix86_match_ccmode (insn, CCNOmode)
10020    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10021   "xor{b}\t{%2, %0|%0, %2}"
10022   [(set_attr "type" "alu")
10023    (set_attr "mode" "QI")])
10025 (define_insn "*xorqi_cc_ext_1"
10026   [(set (reg FLAGS_REG)
10027         (compare
10028           (xor:SI
10029             (zero_extract:SI
10030               (match_operand 1 "ext_register_operand" "0")
10031               (const_int 8)
10032               (const_int 8))
10033             (match_operand:QI 2 "general_operand" "qmn"))
10034           (const_int 0)))
10035    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10036                          (const_int 8)
10037                          (const_int 8))
10038         (xor:SI
10039           (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10040           (match_dup 2)))]
10041   "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10042   "xor{b}\t{%2, %h0|%h0, %2}"
10043   [(set_attr "type" "alu")
10044    (set_attr "mode" "QI")])
10046 (define_insn "*xorqi_cc_ext_1_rex64"
10047   [(set (reg FLAGS_REG)
10048         (compare
10049           (xor:SI
10050             (zero_extract:SI
10051               (match_operand 1 "ext_register_operand" "0")
10052               (const_int 8)
10053               (const_int 8))
10054             (match_operand:QI 2 "nonmemory_operand" "Qn"))
10055           (const_int 0)))
10056    (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
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   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10063   "xor{b}\t{%2, %h0|%h0, %2}"
10064   [(set_attr "type" "alu")
10065    (set_attr "mode" "QI")])
10067 (define_expand "xorqi_cc_ext_1"
10068   [(parallel [
10069      (set (reg:CCNO FLAGS_REG)
10070           (compare:CCNO
10071             (xor:SI
10072               (zero_extract:SI
10073                 (match_operand 1 "ext_register_operand" "")
10074                 (const_int 8)
10075                 (const_int 8))
10076               (match_operand:QI 2 "general_operand" ""))
10077             (const_int 0)))
10078      (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10079                            (const_int 8)
10080                            (const_int 8))
10081           (xor:SI
10082             (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10083             (match_dup 2)))])]
10084   ""
10085   "")
10087 (define_split
10088   [(set (match_operand 0 "register_operand" "")
10089         (xor (match_operand 1 "register_operand" "")
10090              (match_operand 2 "const_int_operand" "")))
10091    (clobber (reg:CC FLAGS_REG))]
10092    "reload_completed
10093     && QI_REG_P (operands[0])
10094     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10095     && !(INTVAL (operands[2]) & ~(255 << 8))
10096     && GET_MODE (operands[0]) != QImode"
10097   [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10098                    (xor:SI (zero_extract:SI (match_dup 1)
10099                                             (const_int 8) (const_int 8))
10100                            (match_dup 2)))
10101               (clobber (reg:CC FLAGS_REG))])]
10102   "operands[0] = gen_lowpart (SImode, operands[0]);
10103    operands[1] = gen_lowpart (SImode, operands[1]);
10104    operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10106 ;; Since XOR can be encoded with sign extended immediate, this is only
10107 ;; profitable when 7th bit is set.
10108 (define_split
10109   [(set (match_operand 0 "register_operand" "")
10110         (xor (match_operand 1 "general_operand" "")
10111              (match_operand 2 "const_int_operand" "")))
10112    (clobber (reg:CC FLAGS_REG))]
10113    "reload_completed
10114     && ANY_QI_REG_P (operands[0])
10115     && (!TARGET_PARTIAL_REG_STALL || optimize_size)
10116     && !(INTVAL (operands[2]) & ~255)
10117     && (INTVAL (operands[2]) & 128)
10118     && GET_MODE (operands[0]) != QImode"
10119   [(parallel [(set (strict_low_part (match_dup 0))
10120                    (xor:QI (match_dup 1)
10121                            (match_dup 2)))
10122               (clobber (reg:CC FLAGS_REG))])]
10123   "operands[0] = gen_lowpart (QImode, operands[0]);
10124    operands[1] = gen_lowpart (QImode, operands[1]);
10125    operands[2] = gen_lowpart (QImode, operands[2]);")
10127 ;; Negation instructions
10129 (define_expand "negti2"
10130   [(parallel [(set (match_operand:TI 0 "nonimmediate_operand" "")
10131                    (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10132               (clobber (reg:CC FLAGS_REG))])]
10133   "TARGET_64BIT"
10134   "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10136 (define_insn "*negti2_1"
10137   [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10138         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10139    (clobber (reg:CC FLAGS_REG))]
10140   "TARGET_64BIT
10141    && ix86_unary_operator_ok (NEG, TImode, operands)"
10142   "#")
10144 (define_split
10145   [(set (match_operand:TI 0 "nonimmediate_operand" "")
10146         (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10147    (clobber (reg:CC FLAGS_REG))]
10148   "TARGET_64BIT && reload_completed"
10149   [(parallel
10150     [(set (reg:CCZ FLAGS_REG)
10151           (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10152      (set (match_dup 0) (neg:DI (match_dup 1)))])
10153    (parallel
10154     [(set (match_dup 2)
10155           (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10156                             (match_dup 3))
10157                    (const_int 0)))
10158      (clobber (reg:CC FLAGS_REG))])
10159    (parallel
10160     [(set (match_dup 2)
10161           (neg:DI (match_dup 2)))
10162      (clobber (reg:CC FLAGS_REG))])]
10163   "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10165 (define_expand "negdi2"
10166   [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
10167                    (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))
10168               (clobber (reg:CC FLAGS_REG))])]
10169   ""
10170   "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10172 (define_insn "*negdi2_1"
10173   [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10174         (neg:DI (match_operand:DI 1 "general_operand" "0")))
10175    (clobber (reg:CC FLAGS_REG))]
10176   "!TARGET_64BIT
10177    && ix86_unary_operator_ok (NEG, DImode, operands)"
10178   "#")
10180 (define_split
10181   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10182         (neg:DI (match_operand:DI 1 "general_operand" "")))
10183    (clobber (reg:CC FLAGS_REG))]
10184   "!TARGET_64BIT && reload_completed"
10185   [(parallel
10186     [(set (reg:CCZ FLAGS_REG)
10187           (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10188      (set (match_dup 0) (neg:SI (match_dup 1)))])
10189    (parallel
10190     [(set (match_dup 2)
10191           (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10192                             (match_dup 3))
10193                    (const_int 0)))
10194      (clobber (reg:CC FLAGS_REG))])
10195    (parallel
10196     [(set (match_dup 2)
10197           (neg:SI (match_dup 2)))
10198      (clobber (reg:CC FLAGS_REG))])]
10199   "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10201 (define_insn "*negdi2_1_rex64"
10202   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10203         (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10204    (clobber (reg:CC FLAGS_REG))]
10205   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10206   "neg{q}\t%0"
10207   [(set_attr "type" "negnot")
10208    (set_attr "mode" "DI")])
10210 ;; The problem with neg is that it does not perform (compare x 0),
10211 ;; it really performs (compare 0 x), which leaves us with the zero
10212 ;; flag being the only useful item.
10214 (define_insn "*negdi2_cmpz_rex64"
10215   [(set (reg:CCZ FLAGS_REG)
10216         (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10217                      (const_int 0)))
10218    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10219         (neg:DI (match_dup 1)))]
10220   "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10221   "neg{q}\t%0"
10222   [(set_attr "type" "negnot")
10223    (set_attr "mode" "DI")])
10226 (define_expand "negsi2"
10227   [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
10228                    (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))
10229               (clobber (reg:CC FLAGS_REG))])]
10230   ""
10231   "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10233 (define_insn "*negsi2_1"
10234   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10235         (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10236    (clobber (reg:CC FLAGS_REG))]
10237   "ix86_unary_operator_ok (NEG, SImode, operands)"
10238   "neg{l}\t%0"
10239   [(set_attr "type" "negnot")
10240    (set_attr "mode" "SI")])
10242 ;; Combine is quite creative about this pattern.
10243 (define_insn "*negsi2_1_zext"
10244   [(set (match_operand:DI 0 "register_operand" "=r")
10245         (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10246                                         (const_int 32)))
10247                      (const_int 32)))
10248    (clobber (reg:CC FLAGS_REG))]
10249   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10250   "neg{l}\t%k0"
10251   [(set_attr "type" "negnot")
10252    (set_attr "mode" "SI")])
10254 ;; The problem with neg is that it does not perform (compare x 0),
10255 ;; it really performs (compare 0 x), which leaves us with the zero
10256 ;; flag being the only useful item.
10258 (define_insn "*negsi2_cmpz"
10259   [(set (reg:CCZ FLAGS_REG)
10260         (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10261                      (const_int 0)))
10262    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10263         (neg:SI (match_dup 1)))]
10264   "ix86_unary_operator_ok (NEG, SImode, operands)"
10265   "neg{l}\t%0"
10266   [(set_attr "type" "negnot")
10267    (set_attr "mode" "SI")])
10269 (define_insn "*negsi2_cmpz_zext"
10270   [(set (reg:CCZ FLAGS_REG)
10271         (compare:CCZ (lshiftrt:DI
10272                        (neg:DI (ashift:DI
10273                                  (match_operand:DI 1 "register_operand" "0")
10274                                  (const_int 32)))
10275                        (const_int 32))
10276                      (const_int 0)))
10277    (set (match_operand:DI 0 "register_operand" "=r")
10278         (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
10279                                         (const_int 32)))
10280                      (const_int 32)))]
10281   "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10282   "neg{l}\t%k0"
10283   [(set_attr "type" "negnot")
10284    (set_attr "mode" "SI")])
10286 (define_expand "neghi2"
10287   [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
10288                    (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))
10289               (clobber (reg:CC FLAGS_REG))])]
10290   "TARGET_HIMODE_MATH"
10291   "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
10293 (define_insn "*neghi2_1"
10294   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10295         (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
10296    (clobber (reg:CC FLAGS_REG))]
10297   "ix86_unary_operator_ok (NEG, HImode, operands)"
10298   "neg{w}\t%0"
10299   [(set_attr "type" "negnot")
10300    (set_attr "mode" "HI")])
10302 (define_insn "*neghi2_cmpz"
10303   [(set (reg:CCZ FLAGS_REG)
10304         (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10305                      (const_int 0)))
10306    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10307         (neg:HI (match_dup 1)))]
10308   "ix86_unary_operator_ok (NEG, HImode, operands)"
10309   "neg{w}\t%0"
10310   [(set_attr "type" "negnot")
10311    (set_attr "mode" "HI")])
10313 (define_expand "negqi2"
10314   [(parallel [(set (match_operand:QI 0 "nonimmediate_operand" "")
10315                    (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))
10316               (clobber (reg:CC FLAGS_REG))])]
10317   "TARGET_QIMODE_MATH"
10318   "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
10320 (define_insn "*negqi2_1"
10321   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10322         (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
10323    (clobber (reg:CC FLAGS_REG))]
10324   "ix86_unary_operator_ok (NEG, QImode, operands)"
10325   "neg{b}\t%0"
10326   [(set_attr "type" "negnot")
10327    (set_attr "mode" "QI")])
10329 (define_insn "*negqi2_cmpz"
10330   [(set (reg:CCZ FLAGS_REG)
10331         (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10332                      (const_int 0)))
10333    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10334         (neg:QI (match_dup 1)))]
10335   "ix86_unary_operator_ok (NEG, QImode, operands)"
10336   "neg{b}\t%0"
10337   [(set_attr "type" "negnot")
10338    (set_attr "mode" "QI")])
10340 ;; Changing of sign for FP values is doable using integer unit too.
10342 (define_expand "<code><mode>2"
10343   [(set (match_operand:X87MODEF 0 "register_operand" "")
10344         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
10345   "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10346   "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
10348 (define_insn "*absneg<mode>2_mixed"
10349   [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
10350         (match_operator:MODEF 3 "absneg_operator"
10351           [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
10352    (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
10353    (clobber (reg:CC FLAGS_REG))]
10354   "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
10355   "#")
10357 (define_insn "*absneg<mode>2_sse"
10358   [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
10359         (match_operator:MODEF 3 "absneg_operator"
10360           [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
10361    (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
10362    (clobber (reg:CC FLAGS_REG))]
10363   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
10364   "#")
10366 (define_insn "*absneg<mode>2_i387"
10367   [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
10368         (match_operator:X87MODEF 3 "absneg_operator"
10369           [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
10370    (use (match_operand 2 "" ""))
10371    (clobber (reg:CC FLAGS_REG))]
10372   "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
10373   "#")
10375 (define_expand "<code>tf2"
10376   [(set (match_operand:TF 0 "register_operand" "")
10377         (absneg:TF (match_operand:TF 1 "register_operand" "")))]
10378   "TARGET_64BIT"
10379   "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
10381 (define_insn "*absnegtf2_sse"
10382   [(set (match_operand:TF 0 "register_operand" "=x,x")
10383         (match_operator:TF 3 "absneg_operator"
10384           [(match_operand:TF 1 "register_operand" "0,x")]))
10385    (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
10386    (clobber (reg:CC FLAGS_REG))]
10387   "TARGET_64BIT"
10388   "#")
10390 ;; Splitters for fp abs and neg.
10392 (define_split
10393   [(set (match_operand 0 "fp_register_operand" "")
10394         (match_operator 1 "absneg_operator" [(match_dup 0)]))
10395    (use (match_operand 2 "" ""))
10396    (clobber (reg:CC FLAGS_REG))]
10397   "reload_completed"
10398   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
10400 (define_split
10401   [(set (match_operand 0 "register_operand" "")
10402         (match_operator 3 "absneg_operator"
10403           [(match_operand 1 "register_operand" "")]))
10404    (use (match_operand 2 "nonimmediate_operand" ""))
10405    (clobber (reg:CC FLAGS_REG))]
10406   "reload_completed && SSE_REG_P (operands[0])"
10407   [(set (match_dup 0) (match_dup 3))]
10409   enum machine_mode mode = GET_MODE (operands[0]);
10410   enum machine_mode vmode = GET_MODE (operands[2]);
10411   rtx tmp;
10413   operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10414   operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10415   if (operands_match_p (operands[0], operands[2]))
10416     {
10417       tmp = operands[1];
10418       operands[1] = operands[2];
10419       operands[2] = tmp;
10420     }
10421   if (GET_CODE (operands[3]) == ABS)
10422     tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10423   else
10424     tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10425   operands[3] = tmp;
10428 (define_split
10429   [(set (match_operand:SF 0 "register_operand" "")
10430         (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10431    (use (match_operand:V4SF 2 "" ""))
10432    (clobber (reg:CC FLAGS_REG))]
10433   "reload_completed"
10434   [(parallel [(set (match_dup 0) (match_dup 1))
10435               (clobber (reg:CC FLAGS_REG))])]
10437   rtx tmp;
10438   operands[0] = gen_lowpart (SImode, operands[0]);
10439   if (GET_CODE (operands[1]) == ABS)
10440     {
10441       tmp = gen_int_mode (0x7fffffff, SImode);
10442       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10443     }
10444   else
10445     {
10446       tmp = gen_int_mode (0x80000000, SImode);
10447       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10448     }
10449   operands[1] = tmp;
10452 (define_split
10453   [(set (match_operand:DF 0 "register_operand" "")
10454         (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10455    (use (match_operand 2 "" ""))
10456    (clobber (reg:CC FLAGS_REG))]
10457   "reload_completed"
10458   [(parallel [(set (match_dup 0) (match_dup 1))
10459               (clobber (reg:CC FLAGS_REG))])]
10461   rtx tmp;
10462   if (TARGET_64BIT)
10463     {
10464       tmp = gen_lowpart (DImode, operands[0]);
10465       tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10466       operands[0] = tmp;
10468       if (GET_CODE (operands[1]) == ABS)
10469         tmp = const0_rtx;
10470       else
10471         tmp = gen_rtx_NOT (DImode, tmp);
10472     }
10473   else
10474     {
10475       operands[0] = gen_highpart (SImode, operands[0]);
10476       if (GET_CODE (operands[1]) == ABS)
10477         {
10478           tmp = gen_int_mode (0x7fffffff, SImode);
10479           tmp = gen_rtx_AND (SImode, operands[0], tmp);
10480         }
10481       else
10482         {
10483           tmp = gen_int_mode (0x80000000, SImode);
10484           tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10485         }
10486     }
10487   operands[1] = tmp;
10490 (define_split
10491   [(set (match_operand:XF 0 "register_operand" "")
10492         (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10493    (use (match_operand 2 "" ""))
10494    (clobber (reg:CC FLAGS_REG))]
10495   "reload_completed"
10496   [(parallel [(set (match_dup 0) (match_dup 1))
10497               (clobber (reg:CC FLAGS_REG))])]
10499   rtx tmp;
10500   operands[0] = gen_rtx_REG (SImode,
10501                              true_regnum (operands[0])
10502                              + (TARGET_64BIT ? 1 : 2));
10503   if (GET_CODE (operands[1]) == ABS)
10504     {
10505       tmp = GEN_INT (0x7fff);
10506       tmp = gen_rtx_AND (SImode, operands[0], tmp);
10507     }
10508   else
10509     {
10510       tmp = GEN_INT (0x8000);
10511       tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10512     }
10513   operands[1] = tmp;
10516 ;; Conditionalize these after reload. If they match before reload, we
10517 ;; lose the clobber and ability to use integer instructions.
10519 (define_insn "*<code><mode>2_1"
10520   [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10521         (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10522   "TARGET_80387
10523    && (reload_completed
10524        || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10525   "f<absnegprefix>"
10526   [(set_attr "type" "fsgn")
10527    (set_attr "mode" "<MODE>")])
10529 (define_insn "*<code>extendsfdf2"
10530   [(set (match_operand:DF 0 "register_operand" "=f")
10531         (absneg:DF (float_extend:DF
10532                      (match_operand:SF 1 "register_operand" "0"))))]
10533   "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10534   "f<absnegprefix>"
10535   [(set_attr "type" "fsgn")
10536    (set_attr "mode" "DF")])
10538 (define_insn "*<code>extendsfxf2"
10539   [(set (match_operand:XF 0 "register_operand" "=f")
10540         (absneg:XF (float_extend:XF
10541                      (match_operand:SF 1 "register_operand" "0"))))]
10542   "TARGET_80387"
10543   "f<absnegprefix>"
10544   [(set_attr "type" "fsgn")
10545    (set_attr "mode" "XF")])
10547 (define_insn "*<code>extenddfxf2"
10548   [(set (match_operand:XF 0 "register_operand" "=f")
10549         (absneg:XF (float_extend:XF
10550                       (match_operand:DF 1 "register_operand" "0"))))]
10551   "TARGET_80387"
10552   "f<absnegprefix>"
10553   [(set_attr "type" "fsgn")
10554    (set_attr "mode" "XF")])
10556 ;; Copysign instructions
10558 (define_mode_iterator CSGNMODE [SF DF TF])
10559 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10561 (define_expand "copysign<mode>3"
10562   [(match_operand:CSGNMODE 0 "register_operand" "")
10563    (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10564    (match_operand:CSGNMODE 2 "register_operand" "")]
10565   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10566    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10568   ix86_expand_copysign (operands);
10569   DONE;
10572 (define_insn_and_split "copysign<mode>3_const"
10573   [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10574         (unspec:CSGNMODE
10575           [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10576            (match_operand:CSGNMODE 2 "register_operand" "0")
10577            (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10578           UNSPEC_COPYSIGN))]
10579   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10580    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10581   "#"
10582   "&& reload_completed"
10583   [(const_int 0)]
10585   ix86_split_copysign_const (operands);
10586   DONE;
10589 (define_insn "copysign<mode>3_var"
10590   [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10591         (unspec:CSGNMODE
10592           [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10593            (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10594            (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10595            (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10596           UNSPEC_COPYSIGN))
10597    (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10598   "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10599    || (TARGET_64BIT && (<MODE>mode == TFmode))"
10600   "#")
10602 (define_split
10603   [(set (match_operand:CSGNMODE 0 "register_operand" "")
10604         (unspec:CSGNMODE
10605           [(match_operand:CSGNMODE 2 "register_operand" "")
10606            (match_operand:CSGNMODE 3 "register_operand" "")
10607            (match_operand:<CSGNVMODE> 4 "" "")
10608            (match_operand:<CSGNVMODE> 5 "" "")]
10609           UNSPEC_COPYSIGN))
10610    (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10611   "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10612     || (TARGET_64BIT && (<MODE>mode == TFmode)))
10613    && reload_completed"
10614   [(const_int 0)]
10616   ix86_split_copysign_var (operands);
10617   DONE;
10620 ;; One complement instructions
10622 (define_expand "one_cmpldi2"
10623   [(set (match_operand:DI 0 "nonimmediate_operand" "")
10624         (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10625   "TARGET_64BIT"
10626   "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10628 (define_insn "*one_cmpldi2_1_rex64"
10629   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10630         (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10631   "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10632   "not{q}\t%0"
10633   [(set_attr "type" "negnot")
10634    (set_attr "mode" "DI")])
10636 (define_insn "*one_cmpldi2_2_rex64"
10637   [(set (reg FLAGS_REG)
10638         (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10639                  (const_int 0)))
10640    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10641         (not:DI (match_dup 1)))]
10642   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10643    && ix86_unary_operator_ok (NOT, DImode, operands)"
10644   "#"
10645   [(set_attr "type" "alu1")
10646    (set_attr "mode" "DI")])
10648 (define_split
10649   [(set (match_operand 0 "flags_reg_operand" "")
10650         (match_operator 2 "compare_operator"
10651           [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10652            (const_int 0)]))
10653    (set (match_operand:DI 1 "nonimmediate_operand" "")
10654         (not:DI (match_dup 3)))]
10655   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10656   [(parallel [(set (match_dup 0)
10657                    (match_op_dup 2
10658                      [(xor:DI (match_dup 3) (const_int -1))
10659                       (const_int 0)]))
10660               (set (match_dup 1)
10661                    (xor:DI (match_dup 3) (const_int -1)))])]
10662   "")
10664 (define_expand "one_cmplsi2"
10665   [(set (match_operand:SI 0 "nonimmediate_operand" "")
10666         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10667   ""
10668   "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10670 (define_insn "*one_cmplsi2_1"
10671   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10672         (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10673   "ix86_unary_operator_ok (NOT, SImode, operands)"
10674   "not{l}\t%0"
10675   [(set_attr "type" "negnot")
10676    (set_attr "mode" "SI")])
10678 ;; ??? Currently never generated - xor is used instead.
10679 (define_insn "*one_cmplsi2_1_zext"
10680   [(set (match_operand:DI 0 "register_operand" "=r")
10681         (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10682   "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10683   "not{l}\t%k0"
10684   [(set_attr "type" "negnot")
10685    (set_attr "mode" "SI")])
10687 (define_insn "*one_cmplsi2_2"
10688   [(set (reg FLAGS_REG)
10689         (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10690                  (const_int 0)))
10691    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10692         (not:SI (match_dup 1)))]
10693   "ix86_match_ccmode (insn, CCNOmode)
10694    && ix86_unary_operator_ok (NOT, SImode, operands)"
10695   "#"
10696   [(set_attr "type" "alu1")
10697    (set_attr "mode" "SI")])
10699 (define_split
10700   [(set (match_operand 0 "flags_reg_operand" "")
10701         (match_operator 2 "compare_operator"
10702           [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10703            (const_int 0)]))
10704    (set (match_operand:SI 1 "nonimmediate_operand" "")
10705         (not:SI (match_dup 3)))]
10706   "ix86_match_ccmode (insn, CCNOmode)"
10707   [(parallel [(set (match_dup 0)
10708                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10709                                     (const_int 0)]))
10710               (set (match_dup 1)
10711                    (xor:SI (match_dup 3) (const_int -1)))])]
10712   "")
10714 ;; ??? Currently never generated - xor is used instead.
10715 (define_insn "*one_cmplsi2_2_zext"
10716   [(set (reg FLAGS_REG)
10717         (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10718                  (const_int 0)))
10719    (set (match_operand:DI 0 "register_operand" "=r")
10720         (zero_extend:DI (not:SI (match_dup 1))))]
10721   "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10722    && ix86_unary_operator_ok (NOT, SImode, operands)"
10723   "#"
10724   [(set_attr "type" "alu1")
10725    (set_attr "mode" "SI")])
10727 (define_split
10728   [(set (match_operand 0 "flags_reg_operand" "")
10729         (match_operator 2 "compare_operator"
10730           [(not:SI (match_operand:SI 3 "register_operand" ""))
10731            (const_int 0)]))
10732    (set (match_operand:DI 1 "register_operand" "")
10733         (zero_extend:DI (not:SI (match_dup 3))))]
10734   "ix86_match_ccmode (insn, CCNOmode)"
10735   [(parallel [(set (match_dup 0)
10736                    (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10737                                     (const_int 0)]))
10738               (set (match_dup 1)
10739                    (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10740   "")
10742 (define_expand "one_cmplhi2"
10743   [(set (match_operand:HI 0 "nonimmediate_operand" "")
10744         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10745   "TARGET_HIMODE_MATH"
10746   "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10748 (define_insn "*one_cmplhi2_1"
10749   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10750         (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10751   "ix86_unary_operator_ok (NOT, HImode, operands)"
10752   "not{w}\t%0"
10753   [(set_attr "type" "negnot")
10754    (set_attr "mode" "HI")])
10756 (define_insn "*one_cmplhi2_2"
10757   [(set (reg FLAGS_REG)
10758         (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10759                  (const_int 0)))
10760    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10761         (not:HI (match_dup 1)))]
10762   "ix86_match_ccmode (insn, CCNOmode)
10763    && ix86_unary_operator_ok (NEG, HImode, operands)"
10764   "#"
10765   [(set_attr "type" "alu1")
10766    (set_attr "mode" "HI")])
10768 (define_split
10769   [(set (match_operand 0 "flags_reg_operand" "")
10770         (match_operator 2 "compare_operator"
10771           [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10772            (const_int 0)]))
10773    (set (match_operand:HI 1 "nonimmediate_operand" "")
10774         (not:HI (match_dup 3)))]
10775   "ix86_match_ccmode (insn, CCNOmode)"
10776   [(parallel [(set (match_dup 0)
10777                    (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10778                                     (const_int 0)]))
10779               (set (match_dup 1)
10780                    (xor:HI (match_dup 3) (const_int -1)))])]
10781   "")
10783 ;; %%% Potential partial reg stall on alternative 1.  What to do?
10784 (define_expand "one_cmplqi2"
10785   [(set (match_operand:QI 0 "nonimmediate_operand" "")
10786         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10787   "TARGET_QIMODE_MATH"
10788   "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10790 (define_insn "*one_cmplqi2_1"
10791   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10792         (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10793   "ix86_unary_operator_ok (NOT, QImode, operands)"
10794   "@
10795    not{b}\t%0
10796    not{l}\t%k0"
10797   [(set_attr "type" "negnot")
10798    (set_attr "mode" "QI,SI")])
10800 (define_insn "*one_cmplqi2_2"
10801   [(set (reg FLAGS_REG)
10802         (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10803                  (const_int 0)))
10804    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10805         (not:QI (match_dup 1)))]
10806   "ix86_match_ccmode (insn, CCNOmode)
10807    && ix86_unary_operator_ok (NOT, QImode, operands)"
10808   "#"
10809   [(set_attr "type" "alu1")
10810    (set_attr "mode" "QI")])
10812 (define_split
10813   [(set (match_operand 0 "flags_reg_operand" "")
10814         (match_operator 2 "compare_operator"
10815           [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10816            (const_int 0)]))
10817    (set (match_operand:QI 1 "nonimmediate_operand" "")
10818         (not:QI (match_dup 3)))]
10819   "ix86_match_ccmode (insn, CCNOmode)"
10820   [(parallel [(set (match_dup 0)
10821                    (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10822                                     (const_int 0)]))
10823               (set (match_dup 1)
10824                    (xor:QI (match_dup 3) (const_int -1)))])]
10825   "")
10827 ;; Arithmetic shift instructions
10829 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10830 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem".  If the shift count
10831 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10832 ;; from the assembler input.
10834 ;; This instruction shifts the target reg/mem as usual, but instead of
10835 ;; shifting in zeros, bits are shifted in from reg operand.  If the insn
10836 ;; is a left shift double, bits are taken from the high order bits of
10837 ;; reg, else if the insn is a shift right double, bits are taken from the
10838 ;; low order bits of reg.  So if %eax is "1234" and %edx is "5678",
10839 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10841 ;; Since sh[lr]d does not change the `reg' operand, that is done
10842 ;; separately, making all shifts emit pairs of shift double and normal
10843 ;; shift.  Since sh[lr]d does not shift more than 31 bits, and we wish to
10844 ;; support a 63 bit shift, each shift where the count is in a reg expands
10845 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10847 ;; If the shift count is a constant, we need never emit more than one
10848 ;; shift pair, instead using moves and sign extension for counts greater
10849 ;; than 31.
10851 (define_expand "ashlti3"
10852   [(parallel [(set (match_operand:TI 0 "register_operand" "")
10853                    (ashift:TI (match_operand:TI 1 "register_operand" "")
10854                               (match_operand:QI 2 "nonmemory_operand" "")))
10855               (clobber (reg:CC FLAGS_REG))])]
10856   "TARGET_64BIT"
10858   if (! immediate_operand (operands[2], QImode))
10859     {
10860       emit_insn (gen_ashlti3_1 (operands[0], operands[1], operands[2]));
10861       DONE;
10862     }
10863   ix86_expand_binary_operator (ASHIFT, TImode, operands);
10864   DONE;
10867 (define_insn "ashlti3_1"
10868   [(set (match_operand:TI 0 "register_operand" "=r")
10869         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10870                    (match_operand:QI 2 "register_operand" "c")))
10871    (clobber (match_scratch:DI 3 "=&r"))
10872    (clobber (reg:CC FLAGS_REG))]
10873   "TARGET_64BIT"
10874   "#"
10875   [(set_attr "type" "multi")])
10877 ;; This pattern must be defined before *ashlti3_2 to prevent
10878 ;; combine pass from converting sse2_ashlti3 to *ashlti3_2.
10880 (define_insn "sse2_ashlti3"
10881   [(set (match_operand:TI 0 "register_operand" "=x")
10882         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10883                    (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10884   "TARGET_SSE2"
10886   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10887   return "pslldq\t{%2, %0|%0, %2}";
10889   [(set_attr "type" "sseishft")
10890    (set_attr "prefix_data16" "1")
10891    (set_attr "mode" "TI")])
10893 (define_insn "*ashlti3_2"
10894   [(set (match_operand:TI 0 "register_operand" "=r")
10895         (ashift:TI (match_operand:TI 1 "register_operand" "0")
10896                    (match_operand:QI 2 "immediate_operand" "O")))
10897    (clobber (reg:CC FLAGS_REG))]
10898   "TARGET_64BIT"
10899   "#"
10900   [(set_attr "type" "multi")])
10902 (define_split
10903   [(set (match_operand:TI 0 "register_operand" "")
10904         (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10905                    (match_operand:QI 2 "register_operand" "")))
10906    (clobber (match_scratch:DI 3 ""))
10907    (clobber (reg:CC FLAGS_REG))]
10908   "TARGET_64BIT && reload_completed"
10909   [(const_int 0)]
10910   "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10912 (define_split
10913   [(set (match_operand:TI 0 "register_operand" "")
10914         (ashift:TI (match_operand:TI 1 "register_operand" "")
10915                    (match_operand:QI 2 "immediate_operand" "")))
10916    (clobber (reg:CC FLAGS_REG))]
10917   "TARGET_64BIT && reload_completed"
10918   [(const_int 0)]
10919   "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10921 (define_insn "x86_64_shld"
10922   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
10923         (ior:DI (ashift:DI (match_dup 0)
10924                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
10925                 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r,r")
10926                   (minus:QI (const_int 64) (match_dup 2)))))
10927    (clobber (reg:CC FLAGS_REG))]
10928   "TARGET_64BIT"
10929   "@
10930    shld{q}\t{%2, %1, %0|%0, %1, %2}
10931    shld{q}\t{%s2%1, %0|%0, %1, %2}"
10932   [(set_attr "type" "ishift")
10933    (set_attr "prefix_0f" "1")
10934    (set_attr "mode" "DI")
10935    (set_attr "athlon_decode" "vector")
10936    (set_attr "amdfam10_decode" "vector")])
10938 (define_expand "x86_64_shift_adj"
10939   [(set (reg:CCZ FLAGS_REG)
10940         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10941                              (const_int 64))
10942                      (const_int 0)))
10943    (set (match_operand:DI 0 "register_operand" "")
10944         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10945                          (match_operand:DI 1 "register_operand" "")
10946                          (match_dup 0)))
10947    (set (match_dup 1)
10948         (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10949                          (match_operand:DI 3 "register_operand" "r")
10950                          (match_dup 1)))]
10951   "TARGET_64BIT"
10952   "")
10954 (define_expand "ashldi3"
10955   [(set (match_operand:DI 0 "shiftdi_operand" "")
10956         (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10957                    (match_operand:QI 2 "nonmemory_operand" "")))]
10958   ""
10959   "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10961 (define_insn "*ashldi3_1_rex64"
10962   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10963         (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10964                    (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10965    (clobber (reg:CC FLAGS_REG))]
10966   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10968   switch (get_attr_type (insn))
10969     {
10970     case TYPE_ALU:
10971       gcc_assert (operands[2] == const1_rtx);
10972       gcc_assert (rtx_equal_p (operands[0], operands[1]));
10973       return "add{q}\t%0, %0";
10975     case TYPE_LEA:
10976       gcc_assert (CONST_INT_P (operands[2]));
10977       gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10978       operands[1] = gen_rtx_MULT (DImode, operands[1],
10979                                   GEN_INT (1 << INTVAL (operands[2])));
10980       return "lea{q}\t{%a1, %0|%0, %a1}";
10982     default:
10983       if (REG_P (operands[2]))
10984         return "sal{q}\t{%b2, %0|%0, %b2}";
10985       else if (operands[2] == const1_rtx
10986                && (TARGET_SHIFT1 || optimize_size))
10987         return "sal{q}\t%0";
10988       else
10989         return "sal{q}\t{%2, %0|%0, %2}";
10990     }
10992   [(set (attr "type")
10993      (cond [(eq_attr "alternative" "1")
10994               (const_string "lea")
10995             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10996                           (const_int 0))
10997                       (match_operand 0 "register_operand" ""))
10998                  (match_operand 2 "const1_operand" ""))
10999               (const_string "alu")
11000            ]
11001            (const_string "ishift")))
11002    (set_attr "mode" "DI")])
11004 ;; Convert lea to the lea pattern to avoid flags dependency.
11005 (define_split
11006   [(set (match_operand:DI 0 "register_operand" "")
11007         (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11008                    (match_operand:QI 2 "immediate_operand" "")))
11009    (clobber (reg:CC FLAGS_REG))]
11010   "TARGET_64BIT && reload_completed
11011    && true_regnum (operands[0]) != true_regnum (operands[1])"
11012   [(set (match_dup 0)
11013         (mult:DI (match_dup 1)
11014                  (match_dup 2)))]
11015   "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11017 ;; This pattern can't accept a variable shift count, since shifts by
11018 ;; zero don't affect the flags.  We assume that shifts by constant
11019 ;; zero are optimized away.
11020 (define_insn "*ashldi3_cmp_rex64"
11021   [(set (reg FLAGS_REG)
11022         (compare
11023           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11024                      (match_operand:QI 2 "immediate_operand" "e"))
11025           (const_int 0)))
11026    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11027         (ashift:DI (match_dup 1) (match_dup 2)))]
11028   "TARGET_64BIT
11029    && (optimize_size
11030        || !TARGET_PARTIAL_FLAG_REG_STALL
11031        || (operands[2] == const1_rtx
11032            && (TARGET_SHIFT1
11033                || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11034    && ix86_match_ccmode (insn, CCGOCmode)
11035    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11037   switch (get_attr_type (insn))
11038     {
11039     case TYPE_ALU:
11040       gcc_assert (operands[2] == const1_rtx);
11041       return "add{q}\t%0, %0";
11043     default:
11044       if (REG_P (operands[2]))
11045         return "sal{q}\t{%b2, %0|%0, %b2}";
11046       else if (operands[2] == const1_rtx
11047                && (TARGET_SHIFT1 || optimize_size))
11048         return "sal{q}\t%0";
11049       else
11050         return "sal{q}\t{%2, %0|%0, %2}";
11051     }
11053   [(set (attr "type")
11054      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11055                           (const_int 0))
11056                       (match_operand 0 "register_operand" ""))
11057                  (match_operand 2 "const1_operand" ""))
11058               (const_string "alu")
11059            ]
11060            (const_string "ishift")))
11061    (set_attr "mode" "DI")])
11063 (define_insn "*ashldi3_cconly_rex64"
11064   [(set (reg FLAGS_REG)
11065         (compare
11066           (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11067                      (match_operand:QI 2 "immediate_operand" "e"))
11068           (const_int 0)))
11069    (clobber (match_scratch:DI 0 "=r"))]
11070   "TARGET_64BIT
11071    && (optimize_size
11072        || !TARGET_PARTIAL_FLAG_REG_STALL
11073        || (operands[2] == const1_rtx
11074            && (TARGET_SHIFT1
11075                || TARGET_DOUBLE_WITH_ADD)))
11076    && ix86_match_ccmode (insn, CCGOCmode)
11077    && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11079   switch (get_attr_type (insn))
11080     {
11081     case TYPE_ALU:
11082       gcc_assert (operands[2] == const1_rtx);
11083       return "add{q}\t%0, %0";
11085     default:
11086       if (REG_P (operands[2]))
11087         return "sal{q}\t{%b2, %0|%0, %b2}";
11088       else if (operands[2] == const1_rtx
11089                && (TARGET_SHIFT1 || optimize_size))
11090         return "sal{q}\t%0";
11091       else
11092         return "sal{q}\t{%2, %0|%0, %2}";
11093     }
11095   [(set (attr "type")
11096      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11097                           (const_int 0))
11098                       (match_operand 0 "register_operand" ""))
11099                  (match_operand 2 "const1_operand" ""))
11100               (const_string "alu")
11101            ]
11102            (const_string "ishift")))
11103    (set_attr "mode" "DI")])
11105 (define_insn "*ashldi3_1"
11106   [(set (match_operand:DI 0 "register_operand" "=&r,r")
11107         (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11108                    (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11109    (clobber (reg:CC FLAGS_REG))]
11110   "!TARGET_64BIT"
11111   "#"
11112   [(set_attr "type" "multi")])
11114 ;; By default we don't ask for a scratch register, because when DImode
11115 ;; values are manipulated, registers are already at a premium.  But if
11116 ;; we have one handy, we won't turn it away.
11117 (define_peephole2
11118   [(match_scratch:SI 3 "r")
11119    (parallel [(set (match_operand:DI 0 "register_operand" "")
11120                    (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11121                               (match_operand:QI 2 "nonmemory_operand" "")))
11122               (clobber (reg:CC FLAGS_REG))])
11123    (match_dup 3)]
11124   "!TARGET_64BIT && TARGET_CMOVE"
11125   [(const_int 0)]
11126   "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11128 (define_split
11129   [(set (match_operand:DI 0 "register_operand" "")
11130         (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11131                    (match_operand:QI 2 "nonmemory_operand" "")))
11132    (clobber (reg:CC FLAGS_REG))]
11133   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11134                      ? epilogue_completed : reload_completed)"
11135   [(const_int 0)]
11136   "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11138 (define_insn "x86_shld_1"
11139   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
11140         (ior:SI (ashift:SI (match_dup 0)
11141                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
11142                 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
11143                   (minus:QI (const_int 32) (match_dup 2)))))
11144    (clobber (reg:CC FLAGS_REG))]
11145   ""
11146   "@
11147    shld{l}\t{%2, %1, %0|%0, %1, %2}
11148    shld{l}\t{%s2%1, %0|%0, %1, %2}"
11149   [(set_attr "type" "ishift")
11150    (set_attr "prefix_0f" "1")
11151    (set_attr "mode" "SI")
11152    (set_attr "pent_pair" "np")
11153    (set_attr "athlon_decode" "vector")
11154    (set_attr "amdfam10_decode" "vector")])
11156 (define_expand "x86_shift_adj_1"
11157   [(set (reg:CCZ FLAGS_REG)
11158         (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11159                              (const_int 32))
11160                      (const_int 0)))
11161    (set (match_operand:SI 0 "register_operand" "")
11162         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11163                          (match_operand:SI 1 "register_operand" "")
11164                          (match_dup 0)))
11165    (set (match_dup 1)
11166         (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11167                          (match_operand:SI 3 "register_operand" "r")
11168                          (match_dup 1)))]
11169   "TARGET_CMOVE"
11170   "")
11172 (define_expand "x86_shift_adj_2"
11173   [(use (match_operand:SI 0 "register_operand" ""))
11174    (use (match_operand:SI 1 "register_operand" ""))
11175    (use (match_operand:QI 2 "register_operand" ""))]
11176   ""
11178   rtx label = gen_label_rtx ();
11179   rtx tmp;
11181   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11183   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11184   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11185   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11186                               gen_rtx_LABEL_REF (VOIDmode, label),
11187                               pc_rtx);
11188   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11189   JUMP_LABEL (tmp) = label;
11191   emit_move_insn (operands[0], operands[1]);
11192   ix86_expand_clear (operands[1]);
11194   emit_label (label);
11195   LABEL_NUSES (label) = 1;
11197   DONE;
11200 (define_expand "ashlsi3"
11201   [(set (match_operand:SI 0 "nonimmediate_operand" "")
11202         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11203                    (match_operand:QI 2 "nonmemory_operand" "")))
11204    (clobber (reg:CC FLAGS_REG))]
11205   ""
11206   "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11208 (define_insn "*ashlsi3_1"
11209   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11210         (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11211                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11212    (clobber (reg:CC FLAGS_REG))]
11213   "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11215   switch (get_attr_type (insn))
11216     {
11217     case TYPE_ALU:
11218       gcc_assert (operands[2] == const1_rtx);
11219       gcc_assert (rtx_equal_p (operands[0], operands[1]));
11220       return "add{l}\t%0, %0";
11222     case TYPE_LEA:
11223       return "#";
11225     default:
11226       if (REG_P (operands[2]))
11227         return "sal{l}\t{%b2, %0|%0, %b2}";
11228       else if (operands[2] == const1_rtx
11229                && (TARGET_SHIFT1 || optimize_size))
11230         return "sal{l}\t%0";
11231       else
11232         return "sal{l}\t{%2, %0|%0, %2}";
11233     }
11235   [(set (attr "type")
11236      (cond [(eq_attr "alternative" "1")
11237               (const_string "lea")
11238             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11239                           (const_int 0))
11240                       (match_operand 0 "register_operand" ""))
11241                  (match_operand 2 "const1_operand" ""))
11242               (const_string "alu")
11243            ]
11244            (const_string "ishift")))
11245    (set_attr "mode" "SI")])
11247 ;; Convert lea to the lea pattern to avoid flags dependency.
11248 (define_split
11249   [(set (match_operand 0 "register_operand" "")
11250         (ashift (match_operand 1 "index_register_operand" "")
11251                 (match_operand:QI 2 "const_int_operand" "")))
11252    (clobber (reg:CC FLAGS_REG))]
11253   "reload_completed
11254    && true_regnum (operands[0]) != true_regnum (operands[1])
11255    && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
11256   [(const_int 0)]
11258   rtx pat;
11259   enum machine_mode mode = GET_MODE (operands[0]);
11261   if (GET_MODE_SIZE (mode) < 4)
11262     operands[0] = gen_lowpart (SImode, operands[0]);
11263   if (mode != Pmode)
11264     operands[1] = gen_lowpart (Pmode, operands[1]);
11265   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11267   pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
11268   if (Pmode != SImode)
11269     pat = gen_rtx_SUBREG (SImode, pat, 0);
11270   emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
11271   DONE;
11274 ;; Rare case of shifting RSP is handled by generating move and shift
11275 (define_split
11276   [(set (match_operand 0 "register_operand" "")
11277         (ashift (match_operand 1 "register_operand" "")
11278                 (match_operand:QI 2 "const_int_operand" "")))
11279    (clobber (reg:CC FLAGS_REG))]
11280   "reload_completed
11281    && true_regnum (operands[0]) != true_regnum (operands[1])"
11282   [(const_int 0)]
11284   rtx pat, clob;
11285   emit_move_insn (operands[0], operands[1]);
11286   pat = gen_rtx_SET (VOIDmode, operands[0],
11287                      gen_rtx_ASHIFT (GET_MODE (operands[0]),
11288                                      operands[0], operands[2]));
11289   clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
11290   emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
11291   DONE;
11294 (define_insn "*ashlsi3_1_zext"
11295   [(set (match_operand:DI 0 "register_operand" "=r,r")
11296         (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
11297                         (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
11298    (clobber (reg:CC FLAGS_REG))]
11299   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11301   switch (get_attr_type (insn))
11302     {
11303     case TYPE_ALU:
11304       gcc_assert (operands[2] == const1_rtx);
11305       return "add{l}\t%k0, %k0";
11307     case TYPE_LEA:
11308       return "#";
11310     default:
11311       if (REG_P (operands[2]))
11312         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11313       else if (operands[2] == const1_rtx
11314                && (TARGET_SHIFT1 || optimize_size))
11315         return "sal{l}\t%k0";
11316       else
11317         return "sal{l}\t{%2, %k0|%k0, %2}";
11318     }
11320   [(set (attr "type")
11321      (cond [(eq_attr "alternative" "1")
11322               (const_string "lea")
11323             (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11324                      (const_int 0))
11325                  (match_operand 2 "const1_operand" ""))
11326               (const_string "alu")
11327            ]
11328            (const_string "ishift")))
11329    (set_attr "mode" "SI")])
11331 ;; Convert lea to the lea pattern to avoid flags dependency.
11332 (define_split
11333   [(set (match_operand:DI 0 "register_operand" "")
11334         (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
11335                                 (match_operand:QI 2 "const_int_operand" ""))))
11336    (clobber (reg:CC FLAGS_REG))]
11337   "TARGET_64BIT && reload_completed
11338    && true_regnum (operands[0]) != true_regnum (operands[1])"
11339   [(set (match_dup 0) (zero_extend:DI
11340                         (subreg:SI (mult:SI (match_dup 1)
11341                                             (match_dup 2)) 0)))]
11343   operands[1] = gen_lowpart (Pmode, operands[1]);
11344   operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11347 ;; This pattern can't accept a variable shift count, since shifts by
11348 ;; zero don't affect the flags.  We assume that shifts by constant
11349 ;; zero are optimized away.
11350 (define_insn "*ashlsi3_cmp"
11351   [(set (reg FLAGS_REG)
11352         (compare
11353           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11354                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11355           (const_int 0)))
11356    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11357         (ashift:SI (match_dup 1) (match_dup 2)))]
11358    "(optimize_size
11359      || !TARGET_PARTIAL_FLAG_REG_STALL
11360      || (operands[2] == const1_rtx
11361          && (TARGET_SHIFT1
11362              || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11363    && ix86_match_ccmode (insn, CCGOCmode)
11364    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11366   switch (get_attr_type (insn))
11367     {
11368     case TYPE_ALU:
11369       gcc_assert (operands[2] == const1_rtx);
11370       return "add{l}\t%0, %0";
11372     default:
11373       if (REG_P (operands[2]))
11374         return "sal{l}\t{%b2, %0|%0, %b2}";
11375       else if (operands[2] == const1_rtx
11376                && (TARGET_SHIFT1 || optimize_size))
11377         return "sal{l}\t%0";
11378       else
11379         return "sal{l}\t{%2, %0|%0, %2}";
11380     }
11382   [(set (attr "type")
11383      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11384                           (const_int 0))
11385                       (match_operand 0 "register_operand" ""))
11386                  (match_operand 2 "const1_operand" ""))
11387               (const_string "alu")
11388            ]
11389            (const_string "ishift")))
11390    (set_attr "mode" "SI")])
11392 (define_insn "*ashlsi3_cconly"
11393   [(set (reg FLAGS_REG)
11394         (compare
11395           (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11396                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11397           (const_int 0)))
11398    (clobber (match_scratch:SI 0 "=r"))]
11399   "(optimize_size
11400     || !TARGET_PARTIAL_FLAG_REG_STALL
11401     || (operands[2] == const1_rtx
11402         && (TARGET_SHIFT1
11403             || TARGET_DOUBLE_WITH_ADD)))
11404    && ix86_match_ccmode (insn, CCGOCmode)
11405    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11407   switch (get_attr_type (insn))
11408     {
11409     case TYPE_ALU:
11410       gcc_assert (operands[2] == const1_rtx);
11411       return "add{l}\t%0, %0";
11413     default:
11414       if (REG_P (operands[2]))
11415         return "sal{l}\t{%b2, %0|%0, %b2}";
11416       else if (operands[2] == const1_rtx
11417                && (TARGET_SHIFT1 || optimize_size))
11418         return "sal{l}\t%0";
11419       else
11420         return "sal{l}\t{%2, %0|%0, %2}";
11421     }
11423   [(set (attr "type")
11424      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11425                           (const_int 0))
11426                       (match_operand 0 "register_operand" ""))
11427                  (match_operand 2 "const1_operand" ""))
11428               (const_string "alu")
11429            ]
11430            (const_string "ishift")))
11431    (set_attr "mode" "SI")])
11433 (define_insn "*ashlsi3_cmp_zext"
11434   [(set (reg FLAGS_REG)
11435         (compare
11436           (ashift:SI (match_operand:SI 1 "register_operand" "0")
11437                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11438           (const_int 0)))
11439    (set (match_operand:DI 0 "register_operand" "=r")
11440         (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11441   "TARGET_64BIT
11442    && (optimize_size
11443        || !TARGET_PARTIAL_FLAG_REG_STALL
11444        || (operands[2] == const1_rtx
11445            && (TARGET_SHIFT1
11446                || TARGET_DOUBLE_WITH_ADD)))
11447    && ix86_match_ccmode (insn, CCGOCmode)
11448    && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11450   switch (get_attr_type (insn))
11451     {
11452     case TYPE_ALU:
11453       gcc_assert (operands[2] == const1_rtx);
11454       return "add{l}\t%k0, %k0";
11456     default:
11457       if (REG_P (operands[2]))
11458         return "sal{l}\t{%b2, %k0|%k0, %b2}";
11459       else if (operands[2] == const1_rtx
11460                && (TARGET_SHIFT1 || optimize_size))
11461         return "sal{l}\t%k0";
11462       else
11463         return "sal{l}\t{%2, %k0|%k0, %2}";
11464     }
11466   [(set (attr "type")
11467      (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11468                      (const_int 0))
11469                  (match_operand 2 "const1_operand" ""))
11470               (const_string "alu")
11471            ]
11472            (const_string "ishift")))
11473    (set_attr "mode" "SI")])
11475 (define_expand "ashlhi3"
11476   [(set (match_operand:HI 0 "nonimmediate_operand" "")
11477         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11478                    (match_operand:QI 2 "nonmemory_operand" "")))
11479    (clobber (reg:CC FLAGS_REG))]
11480   "TARGET_HIMODE_MATH"
11481   "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11483 (define_insn "*ashlhi3_1_lea"
11484   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11485         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11486                    (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11487    (clobber (reg:CC FLAGS_REG))]
11488   "!TARGET_PARTIAL_REG_STALL
11489    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11491   switch (get_attr_type (insn))
11492     {
11493     case TYPE_LEA:
11494       return "#";
11495     case TYPE_ALU:
11496       gcc_assert (operands[2] == const1_rtx);
11497       return "add{w}\t%0, %0";
11499     default:
11500       if (REG_P (operands[2]))
11501         return "sal{w}\t{%b2, %0|%0, %b2}";
11502       else if (operands[2] == const1_rtx
11503                && (TARGET_SHIFT1 || optimize_size))
11504         return "sal{w}\t%0";
11505       else
11506         return "sal{w}\t{%2, %0|%0, %2}";
11507     }
11509   [(set (attr "type")
11510      (cond [(eq_attr "alternative" "1")
11511               (const_string "lea")
11512             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11513                           (const_int 0))
11514                       (match_operand 0 "register_operand" ""))
11515                  (match_operand 2 "const1_operand" ""))
11516               (const_string "alu")
11517            ]
11518            (const_string "ishift")))
11519    (set_attr "mode" "HI,SI")])
11521 (define_insn "*ashlhi3_1"
11522   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11523         (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11524                    (match_operand:QI 2 "nonmemory_operand" "cI")))
11525    (clobber (reg:CC FLAGS_REG))]
11526   "TARGET_PARTIAL_REG_STALL
11527    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11529   switch (get_attr_type (insn))
11530     {
11531     case TYPE_ALU:
11532       gcc_assert (operands[2] == const1_rtx);
11533       return "add{w}\t%0, %0";
11535     default:
11536       if (REG_P (operands[2]))
11537         return "sal{w}\t{%b2, %0|%0, %b2}";
11538       else if (operands[2] == const1_rtx
11539                && (TARGET_SHIFT1 || optimize_size))
11540         return "sal{w}\t%0";
11541       else
11542         return "sal{w}\t{%2, %0|%0, %2}";
11543     }
11545   [(set (attr "type")
11546      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11547                           (const_int 0))
11548                       (match_operand 0 "register_operand" ""))
11549                  (match_operand 2 "const1_operand" ""))
11550               (const_string "alu")
11551            ]
11552            (const_string "ishift")))
11553    (set_attr "mode" "HI")])
11555 ;; This pattern can't accept a variable shift count, since shifts by
11556 ;; zero don't affect the flags.  We assume that shifts by constant
11557 ;; zero are optimized away.
11558 (define_insn "*ashlhi3_cmp"
11559   [(set (reg FLAGS_REG)
11560         (compare
11561           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11562                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11563           (const_int 0)))
11564    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11565         (ashift:HI (match_dup 1) (match_dup 2)))]
11566   "(optimize_size
11567     || !TARGET_PARTIAL_FLAG_REG_STALL
11568     || (operands[2] == const1_rtx
11569         && (TARGET_SHIFT1
11570             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11571    && ix86_match_ccmode (insn, CCGOCmode)
11572    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11574   switch (get_attr_type (insn))
11575     {
11576     case TYPE_ALU:
11577       gcc_assert (operands[2] == const1_rtx);
11578       return "add{w}\t%0, %0";
11580     default:
11581       if (REG_P (operands[2]))
11582         return "sal{w}\t{%b2, %0|%0, %b2}";
11583       else if (operands[2] == const1_rtx
11584                && (TARGET_SHIFT1 || optimize_size))
11585         return "sal{w}\t%0";
11586       else
11587         return "sal{w}\t{%2, %0|%0, %2}";
11588     }
11590   [(set (attr "type")
11591      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11592                           (const_int 0))
11593                       (match_operand 0 "register_operand" ""))
11594                  (match_operand 2 "const1_operand" ""))
11595               (const_string "alu")
11596            ]
11597            (const_string "ishift")))
11598    (set_attr "mode" "HI")])
11600 (define_insn "*ashlhi3_cconly"
11601   [(set (reg FLAGS_REG)
11602         (compare
11603           (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11604                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11605           (const_int 0)))
11606    (clobber (match_scratch:HI 0 "=r"))]
11607   "(optimize_size
11608     || !TARGET_PARTIAL_FLAG_REG_STALL
11609     || (operands[2] == const1_rtx
11610         && (TARGET_SHIFT1
11611             || TARGET_DOUBLE_WITH_ADD)))
11612    && ix86_match_ccmode (insn, CCGOCmode)
11613    && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11615   switch (get_attr_type (insn))
11616     {
11617     case TYPE_ALU:
11618       gcc_assert (operands[2] == const1_rtx);
11619       return "add{w}\t%0, %0";
11621     default:
11622       if (REG_P (operands[2]))
11623         return "sal{w}\t{%b2, %0|%0, %b2}";
11624       else if (operands[2] == const1_rtx
11625                && (TARGET_SHIFT1 || optimize_size))
11626         return "sal{w}\t%0";
11627       else
11628         return "sal{w}\t{%2, %0|%0, %2}";
11629     }
11631   [(set (attr "type")
11632      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11633                           (const_int 0))
11634                       (match_operand 0 "register_operand" ""))
11635                  (match_operand 2 "const1_operand" ""))
11636               (const_string "alu")
11637            ]
11638            (const_string "ishift")))
11639    (set_attr "mode" "HI")])
11641 (define_expand "ashlqi3"
11642   [(set (match_operand:QI 0 "nonimmediate_operand" "")
11643         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11644                    (match_operand:QI 2 "nonmemory_operand" "")))
11645    (clobber (reg:CC FLAGS_REG))]
11646   "TARGET_QIMODE_MATH"
11647   "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11649 ;; %%% Potential partial reg stall on alternative 2.  What to do?
11651 (define_insn "*ashlqi3_1_lea"
11652   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11653         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11654                    (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11655    (clobber (reg:CC FLAGS_REG))]
11656   "!TARGET_PARTIAL_REG_STALL
11657    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11659   switch (get_attr_type (insn))
11660     {
11661     case TYPE_LEA:
11662       return "#";
11663     case TYPE_ALU:
11664       gcc_assert (operands[2] == const1_rtx);
11665       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11666         return "add{l}\t%k0, %k0";
11667       else
11668         return "add{b}\t%0, %0";
11670     default:
11671       if (REG_P (operands[2]))
11672         {
11673           if (get_attr_mode (insn) == MODE_SI)
11674             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11675           else
11676             return "sal{b}\t{%b2, %0|%0, %b2}";
11677         }
11678       else if (operands[2] == const1_rtx
11679                && (TARGET_SHIFT1 || optimize_size))
11680         {
11681           if (get_attr_mode (insn) == MODE_SI)
11682             return "sal{l}\t%0";
11683           else
11684             return "sal{b}\t%0";
11685         }
11686       else
11687         {
11688           if (get_attr_mode (insn) == MODE_SI)
11689             return "sal{l}\t{%2, %k0|%k0, %2}";
11690           else
11691             return "sal{b}\t{%2, %0|%0, %2}";
11692         }
11693     }
11695   [(set (attr "type")
11696      (cond [(eq_attr "alternative" "2")
11697               (const_string "lea")
11698             (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11699                           (const_int 0))
11700                       (match_operand 0 "register_operand" ""))
11701                  (match_operand 2 "const1_operand" ""))
11702               (const_string "alu")
11703            ]
11704            (const_string "ishift")))
11705    (set_attr "mode" "QI,SI,SI")])
11707 (define_insn "*ashlqi3_1"
11708   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11709         (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11710                    (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11711    (clobber (reg:CC FLAGS_REG))]
11712   "TARGET_PARTIAL_REG_STALL
11713    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11715   switch (get_attr_type (insn))
11716     {
11717     case TYPE_ALU:
11718       gcc_assert (operands[2] == const1_rtx);
11719       if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11720         return "add{l}\t%k0, %k0";
11721       else
11722         return "add{b}\t%0, %0";
11724     default:
11725       if (REG_P (operands[2]))
11726         {
11727           if (get_attr_mode (insn) == MODE_SI)
11728             return "sal{l}\t{%b2, %k0|%k0, %b2}";
11729           else
11730             return "sal{b}\t{%b2, %0|%0, %b2}";
11731         }
11732       else if (operands[2] == const1_rtx
11733                && (TARGET_SHIFT1 || optimize_size))
11734         {
11735           if (get_attr_mode (insn) == MODE_SI)
11736             return "sal{l}\t%0";
11737           else
11738             return "sal{b}\t%0";
11739         }
11740       else
11741         {
11742           if (get_attr_mode (insn) == MODE_SI)
11743             return "sal{l}\t{%2, %k0|%k0, %2}";
11744           else
11745             return "sal{b}\t{%2, %0|%0, %2}";
11746         }
11747     }
11749   [(set (attr "type")
11750      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11751                           (const_int 0))
11752                       (match_operand 0 "register_operand" ""))
11753                  (match_operand 2 "const1_operand" ""))
11754               (const_string "alu")
11755            ]
11756            (const_string "ishift")))
11757    (set_attr "mode" "QI,SI")])
11759 ;; This pattern can't accept a variable shift count, since shifts by
11760 ;; zero don't affect the flags.  We assume that shifts by constant
11761 ;; zero are optimized away.
11762 (define_insn "*ashlqi3_cmp"
11763   [(set (reg FLAGS_REG)
11764         (compare
11765           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11766                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11767           (const_int 0)))
11768    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11769         (ashift:QI (match_dup 1) (match_dup 2)))]
11770   "(optimize_size
11771     || !TARGET_PARTIAL_FLAG_REG_STALL
11772     || (operands[2] == const1_rtx
11773         && (TARGET_SHIFT1
11774             || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11775    && ix86_match_ccmode (insn, CCGOCmode)
11776    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11778   switch (get_attr_type (insn))
11779     {
11780     case TYPE_ALU:
11781       gcc_assert (operands[2] == const1_rtx);
11782       return "add{b}\t%0, %0";
11784     default:
11785       if (REG_P (operands[2]))
11786         return "sal{b}\t{%b2, %0|%0, %b2}";
11787       else if (operands[2] == const1_rtx
11788                && (TARGET_SHIFT1 || optimize_size))
11789         return "sal{b}\t%0";
11790       else
11791         return "sal{b}\t{%2, %0|%0, %2}";
11792     }
11794   [(set (attr "type")
11795      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11796                           (const_int 0))
11797                       (match_operand 0 "register_operand" ""))
11798                  (match_operand 2 "const1_operand" ""))
11799               (const_string "alu")
11800            ]
11801            (const_string "ishift")))
11802    (set_attr "mode" "QI")])
11804 (define_insn "*ashlqi3_cconly"
11805   [(set (reg FLAGS_REG)
11806         (compare
11807           (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11808                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
11809           (const_int 0)))
11810    (clobber (match_scratch:QI 0 "=q"))]
11811   "(optimize_size
11812     || !TARGET_PARTIAL_FLAG_REG_STALL
11813     || (operands[2] == const1_rtx
11814         && (TARGET_SHIFT1
11815             || TARGET_DOUBLE_WITH_ADD)))
11816    && ix86_match_ccmode (insn, CCGOCmode)
11817    && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11819   switch (get_attr_type (insn))
11820     {
11821     case TYPE_ALU:
11822       gcc_assert (operands[2] == const1_rtx);
11823       return "add{b}\t%0, %0";
11825     default:
11826       if (REG_P (operands[2]))
11827         return "sal{b}\t{%b2, %0|%0, %b2}";
11828       else if (operands[2] == const1_rtx
11829                && (TARGET_SHIFT1 || optimize_size))
11830         return "sal{b}\t%0";
11831       else
11832         return "sal{b}\t{%2, %0|%0, %2}";
11833     }
11835   [(set (attr "type")
11836      (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11837                           (const_int 0))
11838                       (match_operand 0 "register_operand" ""))
11839                  (match_operand 2 "const1_operand" ""))
11840               (const_string "alu")
11841            ]
11842            (const_string "ishift")))
11843    (set_attr "mode" "QI")])
11845 ;; See comment above `ashldi3' about how this works.
11847 (define_expand "ashrti3"
11848   [(parallel [(set (match_operand:TI 0 "register_operand" "")
11849                    (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11850                                 (match_operand:QI 2 "nonmemory_operand" "")))
11851               (clobber (reg:CC FLAGS_REG))])]
11852   "TARGET_64BIT"
11854   if (! immediate_operand (operands[2], QImode))
11855     {
11856       emit_insn (gen_ashrti3_1 (operands[0], operands[1], operands[2]));
11857       DONE;
11858     }
11859   ix86_expand_binary_operator (ASHIFTRT, TImode, operands);
11860   DONE;
11863 (define_insn "ashrti3_1"
11864   [(set (match_operand:TI 0 "register_operand" "=r")
11865         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11866                      (match_operand:QI 2 "register_operand" "c")))
11867    (clobber (match_scratch:DI 3 "=&r"))
11868    (clobber (reg:CC FLAGS_REG))]
11869   "TARGET_64BIT"
11870   "#"
11871   [(set_attr "type" "multi")])
11873 (define_insn "*ashrti3_2"
11874   [(set (match_operand:TI 0 "register_operand" "=r")
11875         (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11876                      (match_operand:QI 2 "immediate_operand" "O")))
11877    (clobber (reg:CC FLAGS_REG))]
11878   "TARGET_64BIT"
11879   "#"
11880   [(set_attr "type" "multi")])
11882 (define_split
11883   [(set (match_operand:TI 0 "register_operand" "")
11884         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11885                      (match_operand:QI 2 "register_operand" "")))
11886    (clobber (match_scratch:DI 3 ""))
11887    (clobber (reg:CC FLAGS_REG))]
11888   "TARGET_64BIT && reload_completed"
11889   [(const_int 0)]
11890   "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11892 (define_split
11893   [(set (match_operand:TI 0 "register_operand" "")
11894         (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11895                      (match_operand:QI 2 "immediate_operand" "")))
11896    (clobber (reg:CC FLAGS_REG))]
11897   "TARGET_64BIT && reload_completed"
11898   [(const_int 0)]
11899   "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11901 (define_insn "x86_64_shrd"
11902   [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m,r*m")
11903         (ior:DI (ashiftrt:DI (match_dup 0)
11904                   (match_operand:QI 2 "nonmemory_operand" "J,c"))
11905                 (ashift:DI (match_operand:DI 1 "register_operand" "r,r")
11906                   (minus:QI (const_int 64) (match_dup 2)))))
11907    (clobber (reg:CC FLAGS_REG))]
11908   "TARGET_64BIT"
11909   "@
11910    shrd{q}\t{%2, %1, %0|%0, %1, %2}
11911    shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11912   [(set_attr "type" "ishift")
11913    (set_attr "prefix_0f" "1")
11914    (set_attr "mode" "DI")
11915    (set_attr "athlon_decode" "vector")
11916    (set_attr "amdfam10_decode" "vector")])
11918 (define_expand "ashrdi3"
11919   [(set (match_operand:DI 0 "shiftdi_operand" "")
11920         (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11921                      (match_operand:QI 2 "nonmemory_operand" "")))]
11922   ""
11923   "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11925 (define_insn "*ashrdi3_63_rex64"
11926   [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11927         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11928                      (match_operand:DI 2 "const_int_operand" "i,i")))
11929    (clobber (reg:CC FLAGS_REG))]
11930   "TARGET_64BIT && INTVAL (operands[2]) == 63
11931    && (TARGET_USE_CLTD || optimize_size)
11932    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11933   "@
11934    {cqto|cqo}
11935    sar{q}\t{%2, %0|%0, %2}"
11936   [(set_attr "type" "imovx,ishift")
11937    (set_attr "prefix_0f" "0,*")
11938    (set_attr "length_immediate" "0,*")
11939    (set_attr "modrm" "0,1")
11940    (set_attr "mode" "DI")])
11942 (define_insn "*ashrdi3_1_one_bit_rex64"
11943   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11944         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11945                      (match_operand:QI 2 "const1_operand" "")))
11946    (clobber (reg:CC FLAGS_REG))]
11947   "TARGET_64BIT
11948    && (TARGET_SHIFT1 || optimize_size)
11949    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11950   "sar{q}\t%0"
11951   [(set_attr "type" "ishift")
11952    (set (attr "length")
11953      (if_then_else (match_operand:DI 0 "register_operand" "")
11954         (const_string "2")
11955         (const_string "*")))])
11957 (define_insn "*ashrdi3_1_rex64"
11958   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11959         (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11960                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
11961    (clobber (reg:CC FLAGS_REG))]
11962   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11963   "@
11964    sar{q}\t{%2, %0|%0, %2}
11965    sar{q}\t{%b2, %0|%0, %b2}"
11966   [(set_attr "type" "ishift")
11967    (set_attr "mode" "DI")])
11969 ;; This pattern can't accept a variable shift count, since shifts by
11970 ;; zero don't affect the flags.  We assume that shifts by constant
11971 ;; zero are optimized away.
11972 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11973   [(set (reg FLAGS_REG)
11974         (compare
11975           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11976                        (match_operand:QI 2 "const1_operand" ""))
11977           (const_int 0)))
11978    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11979         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11980   "TARGET_64BIT
11981    && (TARGET_SHIFT1 || optimize_size)
11982    && ix86_match_ccmode (insn, CCGOCmode)
11983    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11984   "sar{q}\t%0"
11985   [(set_attr "type" "ishift")
11986    (set (attr "length")
11987      (if_then_else (match_operand:DI 0 "register_operand" "")
11988         (const_string "2")
11989         (const_string "*")))])
11991 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11992   [(set (reg FLAGS_REG)
11993         (compare
11994           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11995                        (match_operand:QI 2 "const1_operand" ""))
11996           (const_int 0)))
11997    (clobber (match_scratch:DI 0 "=r"))]
11998   "TARGET_64BIT
11999    && (TARGET_SHIFT1 || optimize_size)
12000    && ix86_match_ccmode (insn, CCGOCmode)
12001    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12002   "sar{q}\t%0"
12003   [(set_attr "type" "ishift")
12004    (set_attr "length" "2")])
12006 ;; This pattern can't accept a variable shift count, since shifts by
12007 ;; zero don't affect the flags.  We assume that shifts by constant
12008 ;; zero are optimized away.
12009 (define_insn "*ashrdi3_cmp_rex64"
12010   [(set (reg FLAGS_REG)
12011         (compare
12012           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12013                        (match_operand:QI 2 "const_int_operand" "n"))
12014           (const_int 0)))
12015    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12016         (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12017   "TARGET_64BIT
12018    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12019    && ix86_match_ccmode (insn, CCGOCmode)
12020    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12021   "sar{q}\t{%2, %0|%0, %2}"
12022   [(set_attr "type" "ishift")
12023    (set_attr "mode" "DI")])
12025 (define_insn "*ashrdi3_cconly_rex64"
12026   [(set (reg FLAGS_REG)
12027         (compare
12028           (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12029                        (match_operand:QI 2 "const_int_operand" "n"))
12030           (const_int 0)))
12031    (clobber (match_scratch:DI 0 "=r"))]
12032   "TARGET_64BIT
12033    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12034    && ix86_match_ccmode (insn, CCGOCmode)
12035    && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12036   "sar{q}\t{%2, %0|%0, %2}"
12037   [(set_attr "type" "ishift")
12038    (set_attr "mode" "DI")])
12040 (define_insn "*ashrdi3_1"
12041   [(set (match_operand:DI 0 "register_operand" "=r")
12042         (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12043                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12044    (clobber (reg:CC FLAGS_REG))]
12045   "!TARGET_64BIT"
12046   "#"
12047   [(set_attr "type" "multi")])
12049 ;; By default we don't ask for a scratch register, because when DImode
12050 ;; values are manipulated, registers are already at a premium.  But if
12051 ;; we have one handy, we won't turn it away.
12052 (define_peephole2
12053   [(match_scratch:SI 3 "r")
12054    (parallel [(set (match_operand:DI 0 "register_operand" "")
12055                    (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12056                                 (match_operand:QI 2 "nonmemory_operand" "")))
12057               (clobber (reg:CC FLAGS_REG))])
12058    (match_dup 3)]
12059   "!TARGET_64BIT && TARGET_CMOVE"
12060   [(const_int 0)]
12061   "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12063 (define_split
12064   [(set (match_operand:DI 0 "register_operand" "")
12065         (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12066                      (match_operand:QI 2 "nonmemory_operand" "")))
12067    (clobber (reg:CC FLAGS_REG))]
12068   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12069                      ? epilogue_completed : reload_completed)"
12070   [(const_int 0)]
12071   "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12073 (define_insn "x86_shrd_1"
12074   [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m,r*m")
12075         (ior:SI (ashiftrt:SI (match_dup 0)
12076                   (match_operand:QI 2 "nonmemory_operand" "I,c"))
12077                 (ashift:SI (match_operand:SI 1 "register_operand" "r,r")
12078                   (minus:QI (const_int 32) (match_dup 2)))))
12079    (clobber (reg:CC FLAGS_REG))]
12080   ""
12081   "@
12082    shrd{l}\t{%2, %1, %0|%0, %1, %2}
12083    shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12084   [(set_attr "type" "ishift")
12085    (set_attr "prefix_0f" "1")
12086    (set_attr "pent_pair" "np")
12087    (set_attr "mode" "SI")])
12089 (define_expand "x86_shift_adj_3"
12090   [(use (match_operand:SI 0 "register_operand" ""))
12091    (use (match_operand:SI 1 "register_operand" ""))
12092    (use (match_operand:QI 2 "register_operand" ""))]
12093   ""
12095   rtx label = gen_label_rtx ();
12096   rtx tmp;
12098   emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
12100   tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12101   tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12102   tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12103                               gen_rtx_LABEL_REF (VOIDmode, label),
12104                               pc_rtx);
12105   tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12106   JUMP_LABEL (tmp) = label;
12108   emit_move_insn (operands[0], operands[1]);
12109   emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
12111   emit_label (label);
12112   LABEL_NUSES (label) = 1;
12114   DONE;
12117 (define_insn "ashrsi3_31"
12118   [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
12119         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
12120                      (match_operand:SI 2 "const_int_operand" "i,i")))
12121    (clobber (reg:CC FLAGS_REG))]
12122   "INTVAL (operands[2]) == 31 && (TARGET_USE_CLTD || optimize_size)
12123    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12124   "@
12125    {cltd|cdq}
12126    sar{l}\t{%2, %0|%0, %2}"
12127   [(set_attr "type" "imovx,ishift")
12128    (set_attr "prefix_0f" "0,*")
12129    (set_attr "length_immediate" "0,*")
12130    (set_attr "modrm" "0,1")
12131    (set_attr "mode" "SI")])
12133 (define_insn "*ashrsi3_31_zext"
12134   [(set (match_operand:DI 0 "register_operand" "=*d,r")
12135         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
12136                                      (match_operand:SI 2 "const_int_operand" "i,i"))))
12137    (clobber (reg:CC FLAGS_REG))]
12138   "TARGET_64BIT && (TARGET_USE_CLTD || optimize_size)
12139    && INTVAL (operands[2]) == 31
12140    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12141   "@
12142    {cltd|cdq}
12143    sar{l}\t{%2, %k0|%k0, %2}"
12144   [(set_attr "type" "imovx,ishift")
12145    (set_attr "prefix_0f" "0,*")
12146    (set_attr "length_immediate" "0,*")
12147    (set_attr "modrm" "0,1")
12148    (set_attr "mode" "SI")])
12150 (define_expand "ashrsi3"
12151   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12152         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12153                      (match_operand:QI 2 "nonmemory_operand" "")))
12154    (clobber (reg:CC FLAGS_REG))]
12155   ""
12156   "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
12158 (define_insn "*ashrsi3_1_one_bit"
12159   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12160         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12161                      (match_operand:QI 2 "const1_operand" "")))
12162    (clobber (reg:CC FLAGS_REG))]
12163   "(TARGET_SHIFT1 || optimize_size)
12164    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12165   "sar{l}\t%0"
12166   [(set_attr "type" "ishift")
12167    (set (attr "length")
12168      (if_then_else (match_operand:SI 0 "register_operand" "")
12169         (const_string "2")
12170         (const_string "*")))])
12172 (define_insn "*ashrsi3_1_one_bit_zext"
12173   [(set (match_operand:DI 0 "register_operand" "=r")
12174         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12175                                      (match_operand:QI 2 "const1_operand" ""))))
12176    (clobber (reg:CC FLAGS_REG))]
12177   "TARGET_64BIT
12178    && (TARGET_SHIFT1 || optimize_size)
12179    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12180   "sar{l}\t%k0"
12181   [(set_attr "type" "ishift")
12182    (set_attr "length" "2")])
12184 (define_insn "*ashrsi3_1"
12185   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12186         (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12187                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12188    (clobber (reg:CC FLAGS_REG))]
12189   "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12190   "@
12191    sar{l}\t{%2, %0|%0, %2}
12192    sar{l}\t{%b2, %0|%0, %b2}"
12193   [(set_attr "type" "ishift")
12194    (set_attr "mode" "SI")])
12196 (define_insn "*ashrsi3_1_zext"
12197   [(set (match_operand:DI 0 "register_operand" "=r,r")
12198         (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
12199                                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12200    (clobber (reg:CC FLAGS_REG))]
12201   "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12202   "@
12203    sar{l}\t{%2, %k0|%k0, %2}
12204    sar{l}\t{%b2, %k0|%k0, %b2}"
12205   [(set_attr "type" "ishift")
12206    (set_attr "mode" "SI")])
12208 ;; This pattern can't accept a variable shift count, since shifts by
12209 ;; zero don't affect the flags.  We assume that shifts by constant
12210 ;; zero are optimized away.
12211 (define_insn "*ashrsi3_one_bit_cmp"
12212   [(set (reg FLAGS_REG)
12213         (compare
12214           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12215                        (match_operand:QI 2 "const1_operand" ""))
12216           (const_int 0)))
12217    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12218         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12219   "(TARGET_SHIFT1 || optimize_size)
12220    && ix86_match_ccmode (insn, CCGOCmode)
12221    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12222   "sar{l}\t%0"
12223   [(set_attr "type" "ishift")
12224    (set (attr "length")
12225      (if_then_else (match_operand:SI 0 "register_operand" "")
12226         (const_string "2")
12227         (const_string "*")))])
12229 (define_insn "*ashrsi3_one_bit_cconly"
12230   [(set (reg FLAGS_REG)
12231         (compare
12232           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12233                        (match_operand:QI 2 "const1_operand" ""))
12234           (const_int 0)))
12235    (clobber (match_scratch:SI 0 "=r"))]
12236   "(TARGET_SHIFT1 || optimize_size)
12237    && ix86_match_ccmode (insn, CCGOCmode)
12238    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12239   "sar{l}\t%0"
12240   [(set_attr "type" "ishift")
12241    (set_attr "length" "2")])
12243 (define_insn "*ashrsi3_one_bit_cmp_zext"
12244   [(set (reg FLAGS_REG)
12245         (compare
12246           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12247                        (match_operand:QI 2 "const1_operand" ""))
12248           (const_int 0)))
12249    (set (match_operand:DI 0 "register_operand" "=r")
12250         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12251   "TARGET_64BIT
12252    && (TARGET_SHIFT1 || optimize_size)
12253    && ix86_match_ccmode (insn, CCmode)
12254    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12255   "sar{l}\t%k0"
12256   [(set_attr "type" "ishift")
12257    (set_attr "length" "2")])
12259 ;; This pattern can't accept a variable shift count, since shifts by
12260 ;; zero don't affect the flags.  We assume that shifts by constant
12261 ;; zero are optimized away.
12262 (define_insn "*ashrsi3_cmp"
12263   [(set (reg FLAGS_REG)
12264         (compare
12265           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12266                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12267           (const_int 0)))
12268    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12269         (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12270   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12271    && ix86_match_ccmode (insn, CCGOCmode)
12272    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12273   "sar{l}\t{%2, %0|%0, %2}"
12274   [(set_attr "type" "ishift")
12275    (set_attr "mode" "SI")])
12277 (define_insn "*ashrsi3_cconly"
12278   [(set (reg FLAGS_REG)
12279         (compare
12280           (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12281                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12282           (const_int 0)))
12283    (clobber (match_scratch:SI 0 "=r"))]
12284   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12285    && ix86_match_ccmode (insn, CCGOCmode)
12286    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12287   "sar{l}\t{%2, %0|%0, %2}"
12288   [(set_attr "type" "ishift")
12289    (set_attr "mode" "SI")])
12291 (define_insn "*ashrsi3_cmp_zext"
12292   [(set (reg FLAGS_REG)
12293         (compare
12294           (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12295                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12296           (const_int 0)))
12297    (set (match_operand:DI 0 "register_operand" "=r")
12298         (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12299   "TARGET_64BIT
12300    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12301    && ix86_match_ccmode (insn, CCGOCmode)
12302    && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12303   "sar{l}\t{%2, %k0|%k0, %2}"
12304   [(set_attr "type" "ishift")
12305    (set_attr "mode" "SI")])
12307 (define_expand "ashrhi3"
12308   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12309         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12310                      (match_operand:QI 2 "nonmemory_operand" "")))
12311    (clobber (reg:CC FLAGS_REG))]
12312   "TARGET_HIMODE_MATH"
12313   "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12315 (define_insn "*ashrhi3_1_one_bit"
12316   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12317         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12318                      (match_operand:QI 2 "const1_operand" "")))
12319    (clobber (reg:CC FLAGS_REG))]
12320   "(TARGET_SHIFT1 || optimize_size)
12321    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12322   "sar{w}\t%0"
12323   [(set_attr "type" "ishift")
12324    (set (attr "length")
12325      (if_then_else (match_operand 0 "register_operand" "")
12326         (const_string "2")
12327         (const_string "*")))])
12329 (define_insn "*ashrhi3_1"
12330   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12331         (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12332                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12333    (clobber (reg:CC FLAGS_REG))]
12334   "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12335   "@
12336    sar{w}\t{%2, %0|%0, %2}
12337    sar{w}\t{%b2, %0|%0, %b2}"
12338   [(set_attr "type" "ishift")
12339    (set_attr "mode" "HI")])
12341 ;; This pattern can't accept a variable shift count, since shifts by
12342 ;; zero don't affect the flags.  We assume that shifts by constant
12343 ;; zero are optimized away.
12344 (define_insn "*ashrhi3_one_bit_cmp"
12345   [(set (reg FLAGS_REG)
12346         (compare
12347           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12348                        (match_operand:QI 2 "const1_operand" ""))
12349           (const_int 0)))
12350    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12351         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12352   "(TARGET_SHIFT1 || optimize_size)
12353    && ix86_match_ccmode (insn, CCGOCmode)
12354    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12355   "sar{w}\t%0"
12356   [(set_attr "type" "ishift")
12357    (set (attr "length")
12358      (if_then_else (match_operand 0 "register_operand" "")
12359         (const_string "2")
12360         (const_string "*")))])
12362 (define_insn "*ashrhi3_one_bit_cconly"
12363   [(set (reg FLAGS_REG)
12364         (compare
12365           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12366                        (match_operand:QI 2 "const1_operand" ""))
12367           (const_int 0)))
12368    (clobber (match_scratch:HI 0 "=r"))]
12369   "(TARGET_SHIFT1 || optimize_size)
12370    && ix86_match_ccmode (insn, CCGOCmode)
12371    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12372   "sar{w}\t%0"
12373   [(set_attr "type" "ishift")
12374    (set_attr "length" "2")])
12376 ;; This pattern can't accept a variable shift count, since shifts by
12377 ;; zero don't affect the flags.  We assume that shifts by constant
12378 ;; zero are optimized away.
12379 (define_insn "*ashrhi3_cmp"
12380   [(set (reg FLAGS_REG)
12381         (compare
12382           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12383                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12384           (const_int 0)))
12385    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12386         (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12387   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12388    && ix86_match_ccmode (insn, CCGOCmode)
12389    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12390   "sar{w}\t{%2, %0|%0, %2}"
12391   [(set_attr "type" "ishift")
12392    (set_attr "mode" "HI")])
12394 (define_insn "*ashrhi3_cconly"
12395   [(set (reg FLAGS_REG)
12396         (compare
12397           (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12398                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12399           (const_int 0)))
12400    (clobber (match_scratch:HI 0 "=r"))]
12401   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12402    && ix86_match_ccmode (insn, CCGOCmode)
12403    && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12404   "sar{w}\t{%2, %0|%0, %2}"
12405   [(set_attr "type" "ishift")
12406    (set_attr "mode" "HI")])
12408 (define_expand "ashrqi3"
12409   [(set (match_operand:QI 0 "nonimmediate_operand" "")
12410         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12411                      (match_operand:QI 2 "nonmemory_operand" "")))
12412    (clobber (reg:CC FLAGS_REG))]
12413   "TARGET_QIMODE_MATH"
12414   "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12416 (define_insn "*ashrqi3_1_one_bit"
12417   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12418         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12419                      (match_operand:QI 2 "const1_operand" "")))
12420    (clobber (reg:CC FLAGS_REG))]
12421   "(TARGET_SHIFT1 || optimize_size)
12422    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12423   "sar{b}\t%0"
12424   [(set_attr "type" "ishift")
12425    (set (attr "length")
12426      (if_then_else (match_operand 0 "register_operand" "")
12427         (const_string "2")
12428         (const_string "*")))])
12430 (define_insn "*ashrqi3_1_one_bit_slp"
12431   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12432         (ashiftrt:QI (match_dup 0)
12433                      (match_operand:QI 1 "const1_operand" "")))
12434    (clobber (reg:CC FLAGS_REG))]
12435   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12436    && (TARGET_SHIFT1 || optimize_size)
12437    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12438   "sar{b}\t%0"
12439   [(set_attr "type" "ishift1")
12440    (set (attr "length")
12441      (if_then_else (match_operand 0 "register_operand" "")
12442         (const_string "2")
12443         (const_string "*")))])
12445 (define_insn "*ashrqi3_1"
12446   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12447         (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12448                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12449    (clobber (reg:CC FLAGS_REG))]
12450   "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12451   "@
12452    sar{b}\t{%2, %0|%0, %2}
12453    sar{b}\t{%b2, %0|%0, %b2}"
12454   [(set_attr "type" "ishift")
12455    (set_attr "mode" "QI")])
12457 (define_insn "*ashrqi3_1_slp"
12458   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12459         (ashiftrt:QI (match_dup 0)
12460                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
12461    (clobber (reg:CC FLAGS_REG))]
12462   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
12463    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12464   "@
12465    sar{b}\t{%1, %0|%0, %1}
12466    sar{b}\t{%b1, %0|%0, %b1}"
12467   [(set_attr "type" "ishift1")
12468    (set_attr "mode" "QI")])
12470 ;; This pattern can't accept a variable shift count, since shifts by
12471 ;; zero don't affect the flags.  We assume that shifts by constant
12472 ;; zero are optimized away.
12473 (define_insn "*ashrqi3_one_bit_cmp"
12474   [(set (reg FLAGS_REG)
12475         (compare
12476           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12477                        (match_operand:QI 2 "const1_operand" "I"))
12478           (const_int 0)))
12479    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12480         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12481   "(TARGET_SHIFT1 || optimize_size)
12482    && ix86_match_ccmode (insn, CCGOCmode)
12483    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12484   "sar{b}\t%0"
12485   [(set_attr "type" "ishift")
12486    (set (attr "length")
12487      (if_then_else (match_operand 0 "register_operand" "")
12488         (const_string "2")
12489         (const_string "*")))])
12491 (define_insn "*ashrqi3_one_bit_cconly"
12492   [(set (reg FLAGS_REG)
12493         (compare
12494           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12495                        (match_operand:QI 2 "const1_operand" "I"))
12496           (const_int 0)))
12497    (clobber (match_scratch:QI 0 "=q"))]
12498   "(TARGET_SHIFT1 || optimize_size)
12499    && ix86_match_ccmode (insn, CCGOCmode)
12500    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12501   "sar{b}\t%0"
12502   [(set_attr "type" "ishift")
12503    (set_attr "length" "2")])
12505 ;; This pattern can't accept a variable shift count, since shifts by
12506 ;; zero don't affect the flags.  We assume that shifts by constant
12507 ;; zero are optimized away.
12508 (define_insn "*ashrqi3_cmp"
12509   [(set (reg FLAGS_REG)
12510         (compare
12511           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12512                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12513           (const_int 0)))
12514    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12515         (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12516   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12517    && ix86_match_ccmode (insn, CCGOCmode)
12518    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12519   "sar{b}\t{%2, %0|%0, %2}"
12520   [(set_attr "type" "ishift")
12521    (set_attr "mode" "QI")])
12523 (define_insn "*ashrqi3_cconly"
12524   [(set (reg FLAGS_REG)
12525         (compare
12526           (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12527                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12528           (const_int 0)))
12529    (clobber (match_scratch:QI 0 "=q"))]
12530   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12531    && ix86_match_ccmode (insn, CCGOCmode)
12532    && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12533   "sar{b}\t{%2, %0|%0, %2}"
12534   [(set_attr "type" "ishift")
12535    (set_attr "mode" "QI")])
12538 ;; Logical shift instructions
12540 ;; See comment above `ashldi3' about how this works.
12542 (define_expand "lshrti3"
12543   [(parallel [(set (match_operand:TI 0 "register_operand" "")
12544                    (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12545                                 (match_operand:QI 2 "nonmemory_operand" "")))
12546               (clobber (reg:CC FLAGS_REG))])]
12547   "TARGET_64BIT"
12549   if (! immediate_operand (operands[2], QImode))
12550     {
12551       emit_insn (gen_lshrti3_1 (operands[0], operands[1], operands[2]));
12552       DONE;
12553     }
12554   ix86_expand_binary_operator (LSHIFTRT, TImode, operands);
12555   DONE;
12558 (define_insn "lshrti3_1"
12559   [(set (match_operand:TI 0 "register_operand" "=r")
12560         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12561                      (match_operand:QI 2 "register_operand" "c")))
12562    (clobber (match_scratch:DI 3 "=&r"))
12563    (clobber (reg:CC FLAGS_REG))]
12564   "TARGET_64BIT"
12565   "#"
12566   [(set_attr "type" "multi")])
12568 ;; This pattern must be defined before *lshrti3_2 to prevent
12569 ;; combine pass from converting sse2_lshrti3 to *lshrti3_2.
12571 (define_insn "sse2_lshrti3"
12572   [(set (match_operand:TI 0 "register_operand" "=x")
12573         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12574                      (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12575   "TARGET_SSE2"
12577   operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12578   return "psrldq\t{%2, %0|%0, %2}";
12580   [(set_attr "type" "sseishft")
12581    (set_attr "prefix_data16" "1")
12582    (set_attr "mode" "TI")])
12584 (define_insn "*lshrti3_2"
12585   [(set (match_operand:TI 0 "register_operand" "=r")
12586         (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12587                      (match_operand:QI 2 "immediate_operand" "O")))
12588    (clobber (reg:CC FLAGS_REG))]
12589   "TARGET_64BIT"
12590   "#"
12591   [(set_attr "type" "multi")])
12593 (define_split
12594   [(set (match_operand:TI 0 "register_operand" "")
12595         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12596                      (match_operand:QI 2 "register_operand" "")))
12597    (clobber (match_scratch:DI 3 ""))
12598    (clobber (reg:CC FLAGS_REG))]
12599   "TARGET_64BIT && reload_completed"
12600   [(const_int 0)]
12601   "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12603 (define_split
12604   [(set (match_operand:TI 0 "register_operand" "")
12605         (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12606                      (match_operand:QI 2 "immediate_operand" "")))
12607    (clobber (reg:CC FLAGS_REG))]
12608   "TARGET_64BIT && reload_completed"
12609   [(const_int 0)]
12610   "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12612 (define_expand "lshrdi3"
12613   [(set (match_operand:DI 0 "shiftdi_operand" "")
12614         (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12615                      (match_operand:QI 2 "nonmemory_operand" "")))]
12616   ""
12617   "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12619 (define_insn "*lshrdi3_1_one_bit_rex64"
12620   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12621         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12622                      (match_operand:QI 2 "const1_operand" "")))
12623    (clobber (reg:CC FLAGS_REG))]
12624   "TARGET_64BIT
12625    && (TARGET_SHIFT1 || optimize_size)
12626    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12627   "shr{q}\t%0"
12628   [(set_attr "type" "ishift")
12629    (set (attr "length")
12630      (if_then_else (match_operand:DI 0 "register_operand" "")
12631         (const_string "2")
12632         (const_string "*")))])
12634 (define_insn "*lshrdi3_1_rex64"
12635   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12636         (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12637                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
12638    (clobber (reg:CC FLAGS_REG))]
12639   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12640   "@
12641    shr{q}\t{%2, %0|%0, %2}
12642    shr{q}\t{%b2, %0|%0, %b2}"
12643   [(set_attr "type" "ishift")
12644    (set_attr "mode" "DI")])
12646 ;; This pattern can't accept a variable shift count, since shifts by
12647 ;; zero don't affect the flags.  We assume that shifts by constant
12648 ;; zero are optimized away.
12649 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12650   [(set (reg FLAGS_REG)
12651         (compare
12652           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12653                        (match_operand:QI 2 "const1_operand" ""))
12654           (const_int 0)))
12655    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12656         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12657   "TARGET_64BIT
12658    && (TARGET_SHIFT1 || optimize_size)
12659    && ix86_match_ccmode (insn, CCGOCmode)
12660    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12661   "shr{q}\t%0"
12662   [(set_attr "type" "ishift")
12663    (set (attr "length")
12664      (if_then_else (match_operand:DI 0 "register_operand" "")
12665         (const_string "2")
12666         (const_string "*")))])
12668 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12669   [(set (reg FLAGS_REG)
12670         (compare
12671           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12672                        (match_operand:QI 2 "const1_operand" ""))
12673           (const_int 0)))
12674    (clobber (match_scratch:DI 0 "=r"))]
12675   "TARGET_64BIT
12676    && (TARGET_SHIFT1 || optimize_size)
12677    && ix86_match_ccmode (insn, CCGOCmode)
12678    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12679   "shr{q}\t%0"
12680   [(set_attr "type" "ishift")
12681    (set_attr "length" "2")])
12683 ;; This pattern can't accept a variable shift count, since shifts by
12684 ;; zero don't affect the flags.  We assume that shifts by constant
12685 ;; zero are optimized away.
12686 (define_insn "*lshrdi3_cmp_rex64"
12687   [(set (reg FLAGS_REG)
12688         (compare
12689           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12690                        (match_operand:QI 2 "const_int_operand" "e"))
12691           (const_int 0)))
12692    (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12693         (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12694   "TARGET_64BIT
12695    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12696    && ix86_match_ccmode (insn, CCGOCmode)
12697    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12698   "shr{q}\t{%2, %0|%0, %2}"
12699   [(set_attr "type" "ishift")
12700    (set_attr "mode" "DI")])
12702 (define_insn "*lshrdi3_cconly_rex64"
12703   [(set (reg FLAGS_REG)
12704         (compare
12705           (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12706                        (match_operand:QI 2 "const_int_operand" "e"))
12707           (const_int 0)))
12708    (clobber (match_scratch:DI 0 "=r"))]
12709   "TARGET_64BIT
12710    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12711    && ix86_match_ccmode (insn, CCGOCmode)
12712    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12713   "shr{q}\t{%2, %0|%0, %2}"
12714   [(set_attr "type" "ishift")
12715    (set_attr "mode" "DI")])
12717 (define_insn "*lshrdi3_1"
12718   [(set (match_operand:DI 0 "register_operand" "=r")
12719         (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12720                      (match_operand:QI 2 "nonmemory_operand" "Jc")))
12721    (clobber (reg:CC FLAGS_REG))]
12722   "!TARGET_64BIT"
12723   "#"
12724   [(set_attr "type" "multi")])
12726 ;; By default we don't ask for a scratch register, because when DImode
12727 ;; values are manipulated, registers are already at a premium.  But if
12728 ;; we have one handy, we won't turn it away.
12729 (define_peephole2
12730   [(match_scratch:SI 3 "r")
12731    (parallel [(set (match_operand:DI 0 "register_operand" "")
12732                    (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12733                                 (match_operand:QI 2 "nonmemory_operand" "")))
12734               (clobber (reg:CC FLAGS_REG))])
12735    (match_dup 3)]
12736   "!TARGET_64BIT && TARGET_CMOVE"
12737   [(const_int 0)]
12738   "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12740 (define_split
12741   [(set (match_operand:DI 0 "register_operand" "")
12742         (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12743                      (match_operand:QI 2 "nonmemory_operand" "")))
12744    (clobber (reg:CC FLAGS_REG))]
12745   "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12746                      ? epilogue_completed : reload_completed)"
12747   [(const_int 0)]
12748   "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12750 (define_expand "lshrsi3"
12751   [(set (match_operand:SI 0 "nonimmediate_operand" "")
12752         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12753                      (match_operand:QI 2 "nonmemory_operand" "")))
12754    (clobber (reg:CC FLAGS_REG))]
12755   ""
12756   "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12758 (define_insn "*lshrsi3_1_one_bit"
12759   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12760         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12761                      (match_operand:QI 2 "const1_operand" "")))
12762    (clobber (reg:CC FLAGS_REG))]
12763   "(TARGET_SHIFT1 || optimize_size)
12764    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12765   "shr{l}\t%0"
12766   [(set_attr "type" "ishift")
12767    (set (attr "length")
12768      (if_then_else (match_operand:SI 0 "register_operand" "")
12769         (const_string "2")
12770         (const_string "*")))])
12772 (define_insn "*lshrsi3_1_one_bit_zext"
12773   [(set (match_operand:DI 0 "register_operand" "=r")
12774         (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12775                      (match_operand:QI 2 "const1_operand" "")))
12776    (clobber (reg:CC FLAGS_REG))]
12777   "TARGET_64BIT
12778    && (TARGET_SHIFT1 || optimize_size)
12779    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12780   "shr{l}\t%k0"
12781   [(set_attr "type" "ishift")
12782    (set_attr "length" "2")])
12784 (define_insn "*lshrsi3_1"
12785   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12786         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12787                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12788    (clobber (reg:CC FLAGS_REG))]
12789   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12790   "@
12791    shr{l}\t{%2, %0|%0, %2}
12792    shr{l}\t{%b2, %0|%0, %b2}"
12793   [(set_attr "type" "ishift")
12794    (set_attr "mode" "SI")])
12796 (define_insn "*lshrsi3_1_zext"
12797   [(set (match_operand:DI 0 "register_operand" "=r,r")
12798         (zero_extend:DI
12799           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12800                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12801    (clobber (reg:CC FLAGS_REG))]
12802   "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12803   "@
12804    shr{l}\t{%2, %k0|%k0, %2}
12805    shr{l}\t{%b2, %k0|%k0, %b2}"
12806   [(set_attr "type" "ishift")
12807    (set_attr "mode" "SI")])
12809 ;; This pattern can't accept a variable shift count, since shifts by
12810 ;; zero don't affect the flags.  We assume that shifts by constant
12811 ;; zero are optimized away.
12812 (define_insn "*lshrsi3_one_bit_cmp"
12813   [(set (reg FLAGS_REG)
12814         (compare
12815           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12816                        (match_operand:QI 2 "const1_operand" ""))
12817           (const_int 0)))
12818    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12819         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12820   "(TARGET_SHIFT1 || optimize_size)
12821    && ix86_match_ccmode (insn, CCGOCmode)
12822    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12823   "shr{l}\t%0"
12824   [(set_attr "type" "ishift")
12825    (set (attr "length")
12826      (if_then_else (match_operand:SI 0 "register_operand" "")
12827         (const_string "2")
12828         (const_string "*")))])
12830 (define_insn "*lshrsi3_one_bit_cconly"
12831   [(set (reg FLAGS_REG)
12832         (compare
12833           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12834                        (match_operand:QI 2 "const1_operand" ""))
12835           (const_int 0)))
12836    (clobber (match_scratch:SI 0 "=r"))]
12837   "(TARGET_SHIFT1 || optimize_size)
12838    && ix86_match_ccmode (insn, CCGOCmode)
12839    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12840   "shr{l}\t%0"
12841   [(set_attr "type" "ishift")
12842    (set_attr "length" "2")])
12844 (define_insn "*lshrsi3_cmp_one_bit_zext"
12845   [(set (reg FLAGS_REG)
12846         (compare
12847           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12848                        (match_operand:QI 2 "const1_operand" ""))
12849           (const_int 0)))
12850    (set (match_operand:DI 0 "register_operand" "=r")
12851         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12852   "TARGET_64BIT
12853    && (TARGET_SHIFT1 || optimize_size)
12854    && ix86_match_ccmode (insn, CCGOCmode)
12855    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12856   "shr{l}\t%k0"
12857   [(set_attr "type" "ishift")
12858    (set_attr "length" "2")])
12860 ;; This pattern can't accept a variable shift count, since shifts by
12861 ;; zero don't affect the flags.  We assume that shifts by constant
12862 ;; zero are optimized away.
12863 (define_insn "*lshrsi3_cmp"
12864   [(set (reg FLAGS_REG)
12865         (compare
12866           (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12867                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12868           (const_int 0)))
12869    (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12870         (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12871   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12872    && ix86_match_ccmode (insn, CCGOCmode)
12873    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12874   "shr{l}\t{%2, %0|%0, %2}"
12875   [(set_attr "type" "ishift")
12876    (set_attr "mode" "SI")])
12878 (define_insn "*lshrsi3_cconly"
12879   [(set (reg FLAGS_REG)
12880       (compare
12881         (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12882                      (match_operand:QI 2 "const_1_to_31_operand" "I"))
12883         (const_int 0)))
12884    (clobber (match_scratch:SI 0 "=r"))]
12885   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12886    && ix86_match_ccmode (insn, CCGOCmode)
12887    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12888   "shr{l}\t{%2, %0|%0, %2}"
12889   [(set_attr "type" "ishift")
12890    (set_attr "mode" "SI")])
12892 (define_insn "*lshrsi3_cmp_zext"
12893   [(set (reg FLAGS_REG)
12894         (compare
12895           (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12896                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12897           (const_int 0)))
12898    (set (match_operand:DI 0 "register_operand" "=r")
12899         (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12900   "TARGET_64BIT
12901    && (optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12902    && ix86_match_ccmode (insn, CCGOCmode)
12903    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12904   "shr{l}\t{%2, %k0|%k0, %2}"
12905   [(set_attr "type" "ishift")
12906    (set_attr "mode" "SI")])
12908 (define_expand "lshrhi3"
12909   [(set (match_operand:HI 0 "nonimmediate_operand" "")
12910         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12911                      (match_operand:QI 2 "nonmemory_operand" "")))
12912    (clobber (reg:CC FLAGS_REG))]
12913   "TARGET_HIMODE_MATH"
12914   "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12916 (define_insn "*lshrhi3_1_one_bit"
12917   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12918         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12919                      (match_operand:QI 2 "const1_operand" "")))
12920    (clobber (reg:CC FLAGS_REG))]
12921   "(TARGET_SHIFT1 || optimize_size)
12922    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12923   "shr{w}\t%0"
12924   [(set_attr "type" "ishift")
12925    (set (attr "length")
12926      (if_then_else (match_operand 0 "register_operand" "")
12927         (const_string "2")
12928         (const_string "*")))])
12930 (define_insn "*lshrhi3_1"
12931   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12932         (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12933                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
12934    (clobber (reg:CC FLAGS_REG))]
12935   "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12936   "@
12937    shr{w}\t{%2, %0|%0, %2}
12938    shr{w}\t{%b2, %0|%0, %b2}"
12939   [(set_attr "type" "ishift")
12940    (set_attr "mode" "HI")])
12942 ;; This pattern can't accept a variable shift count, since shifts by
12943 ;; zero don't affect the flags.  We assume that shifts by constant
12944 ;; zero are optimized away.
12945 (define_insn "*lshrhi3_one_bit_cmp"
12946   [(set (reg FLAGS_REG)
12947         (compare
12948           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12949                        (match_operand:QI 2 "const1_operand" ""))
12950           (const_int 0)))
12951    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12952         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12953   "(TARGET_SHIFT1 || optimize_size)
12954    && ix86_match_ccmode (insn, CCGOCmode)
12955    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12956   "shr{w}\t%0"
12957   [(set_attr "type" "ishift")
12958    (set (attr "length")
12959      (if_then_else (match_operand:SI 0 "register_operand" "")
12960         (const_string "2")
12961         (const_string "*")))])
12963 (define_insn "*lshrhi3_one_bit_cconly"
12964   [(set (reg FLAGS_REG)
12965         (compare
12966           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12967                        (match_operand:QI 2 "const1_operand" ""))
12968           (const_int 0)))
12969    (clobber (match_scratch:HI 0 "=r"))]
12970   "(TARGET_SHIFT1 || optimize_size)
12971    && ix86_match_ccmode (insn, CCGOCmode)
12972    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12973   "shr{w}\t%0"
12974   [(set_attr "type" "ishift")
12975    (set_attr "length" "2")])
12977 ;; This pattern can't accept a variable shift count, since shifts by
12978 ;; zero don't affect the flags.  We assume that shifts by constant
12979 ;; zero are optimized away.
12980 (define_insn "*lshrhi3_cmp"
12981   [(set (reg FLAGS_REG)
12982         (compare
12983           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12984                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
12985           (const_int 0)))
12986    (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12987         (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12988   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
12989    && ix86_match_ccmode (insn, CCGOCmode)
12990    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12991   "shr{w}\t{%2, %0|%0, %2}"
12992   [(set_attr "type" "ishift")
12993    (set_attr "mode" "HI")])
12995 (define_insn "*lshrhi3_cconly"
12996   [(set (reg FLAGS_REG)
12997         (compare
12998           (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12999                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13000           (const_int 0)))
13001    (clobber (match_scratch:HI 0 "=r"))]
13002   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13003    && ix86_match_ccmode (insn, CCGOCmode)
13004    && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13005   "shr{w}\t{%2, %0|%0, %2}"
13006   [(set_attr "type" "ishift")
13007    (set_attr "mode" "HI")])
13009 (define_expand "lshrqi3"
13010   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13011         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13012                      (match_operand:QI 2 "nonmemory_operand" "")))
13013    (clobber (reg:CC FLAGS_REG))]
13014   "TARGET_QIMODE_MATH"
13015   "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13017 (define_insn "*lshrqi3_1_one_bit"
13018   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13019         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13020                      (match_operand:QI 2 "const1_operand" "")))
13021    (clobber (reg:CC FLAGS_REG))]
13022   "(TARGET_SHIFT1 || optimize_size)
13023    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13024   "shr{b}\t%0"
13025   [(set_attr "type" "ishift")
13026    (set (attr "length")
13027      (if_then_else (match_operand 0 "register_operand" "")
13028         (const_string "2")
13029         (const_string "*")))])
13031 (define_insn "*lshrqi3_1_one_bit_slp"
13032   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13033         (lshiftrt:QI (match_dup 0)
13034                      (match_operand:QI 1 "const1_operand" "")))
13035    (clobber (reg:CC FLAGS_REG))]
13036   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13037    && (TARGET_SHIFT1 || optimize_size)"
13038   "shr{b}\t%0"
13039   [(set_attr "type" "ishift1")
13040    (set (attr "length")
13041      (if_then_else (match_operand 0 "register_operand" "")
13042         (const_string "2")
13043         (const_string "*")))])
13045 (define_insn "*lshrqi3_1"
13046   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13047         (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13048                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13049    (clobber (reg:CC FLAGS_REG))]
13050   "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13051   "@
13052    shr{b}\t{%2, %0|%0, %2}
13053    shr{b}\t{%b2, %0|%0, %b2}"
13054   [(set_attr "type" "ishift")
13055    (set_attr "mode" "QI")])
13057 (define_insn "*lshrqi3_1_slp"
13058   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13059         (lshiftrt:QI (match_dup 0)
13060                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13061    (clobber (reg:CC FLAGS_REG))]
13062   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13063    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13064   "@
13065    shr{b}\t{%1, %0|%0, %1}
13066    shr{b}\t{%b1, %0|%0, %b1}"
13067   [(set_attr "type" "ishift1")
13068    (set_attr "mode" "QI")])
13070 ;; This pattern can't accept a variable shift count, since shifts by
13071 ;; zero don't affect the flags.  We assume that shifts by constant
13072 ;; zero are optimized away.
13073 (define_insn "*lshrqi2_one_bit_cmp"
13074   [(set (reg FLAGS_REG)
13075         (compare
13076           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13077                        (match_operand:QI 2 "const1_operand" ""))
13078           (const_int 0)))
13079    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13080         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13081   "(TARGET_SHIFT1 || optimize_size)
13082    && ix86_match_ccmode (insn, CCGOCmode)
13083    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13084   "shr{b}\t%0"
13085   [(set_attr "type" "ishift")
13086    (set (attr "length")
13087      (if_then_else (match_operand:SI 0 "register_operand" "")
13088         (const_string "2")
13089         (const_string "*")))])
13091 (define_insn "*lshrqi2_one_bit_cconly"
13092   [(set (reg FLAGS_REG)
13093         (compare
13094           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13095                        (match_operand:QI 2 "const1_operand" ""))
13096           (const_int 0)))
13097    (clobber (match_scratch:QI 0 "=q"))]
13098   "(TARGET_SHIFT1 || optimize_size)
13099    && ix86_match_ccmode (insn, CCGOCmode)
13100    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13101   "shr{b}\t%0"
13102   [(set_attr "type" "ishift")
13103    (set_attr "length" "2")])
13105 ;; This pattern can't accept a variable shift count, since shifts by
13106 ;; zero don't affect the flags.  We assume that shifts by constant
13107 ;; zero are optimized away.
13108 (define_insn "*lshrqi2_cmp"
13109   [(set (reg FLAGS_REG)
13110         (compare
13111           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13112                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13113           (const_int 0)))
13114    (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13115         (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13116   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13117    && ix86_match_ccmode (insn, CCGOCmode)
13118    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13119   "shr{b}\t{%2, %0|%0, %2}"
13120   [(set_attr "type" "ishift")
13121    (set_attr "mode" "QI")])
13123 (define_insn "*lshrqi2_cconly"
13124   [(set (reg FLAGS_REG)
13125         (compare
13126           (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13127                        (match_operand:QI 2 "const_1_to_31_operand" "I"))
13128           (const_int 0)))
13129    (clobber (match_scratch:QI 0 "=q"))]
13130   "(optimize_size || !TARGET_PARTIAL_FLAG_REG_STALL)
13131    && ix86_match_ccmode (insn, CCGOCmode)
13132    && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13133   "shr{b}\t{%2, %0|%0, %2}"
13134   [(set_attr "type" "ishift")
13135    (set_attr "mode" "QI")])
13137 ;; Rotate instructions
13139 (define_expand "rotldi3"
13140   [(set (match_operand:DI 0 "shiftdi_operand" "")
13141         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13142                    (match_operand:QI 2 "nonmemory_operand" "")))
13143    (clobber (reg:CC FLAGS_REG))]
13144  ""
13146   if (TARGET_64BIT)
13147     {
13148       ix86_expand_binary_operator (ROTATE, DImode, operands);
13149       DONE;
13150     }
13151   if (!const_1_to_31_operand (operands[2], VOIDmode))
13152     FAIL;
13153   emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
13154   DONE;
13157 ;; Implement rotation using two double-precision shift instructions
13158 ;; and a scratch register.
13159 (define_insn_and_split "ix86_rotldi3"
13160  [(set (match_operand:DI 0 "register_operand" "=r")
13161        (rotate:DI (match_operand:DI 1 "register_operand" "0")
13162                   (match_operand:QI 2 "const_1_to_31_operand" "I")))
13163   (clobber (reg:CC FLAGS_REG))
13164   (clobber (match_scratch:SI 3 "=&r"))]
13165  "!TARGET_64BIT"
13166  ""
13167  "&& reload_completed"
13168  [(set (match_dup 3) (match_dup 4))
13169   (parallel
13170    [(set (match_dup 4)
13171          (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
13172                  (lshiftrt:SI (match_dup 5)
13173                               (minus:QI (const_int 32) (match_dup 2)))))
13174     (clobber (reg:CC FLAGS_REG))])
13175   (parallel
13176    [(set (match_dup 5)
13177          (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
13178                  (lshiftrt:SI (match_dup 3)
13179                               (minus:QI (const_int 32) (match_dup 2)))))
13180     (clobber (reg:CC FLAGS_REG))])]
13181  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13183 (define_insn "*rotlsi3_1_one_bit_rex64"
13184   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13185         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13186                    (match_operand:QI 2 "const1_operand" "")))
13187    (clobber (reg:CC FLAGS_REG))]
13188   "TARGET_64BIT
13189    && (TARGET_SHIFT1 || optimize_size)
13190    && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13191   "rol{q}\t%0"
13192   [(set_attr "type" "rotate")
13193    (set (attr "length")
13194      (if_then_else (match_operand:DI 0 "register_operand" "")
13195         (const_string "2")
13196         (const_string "*")))])
13198 (define_insn "*rotldi3_1_rex64"
13199   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13200         (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13201                    (match_operand:QI 2 "nonmemory_operand" "e,c")))
13202    (clobber (reg:CC FLAGS_REG))]
13203   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
13204   "@
13205    rol{q}\t{%2, %0|%0, %2}
13206    rol{q}\t{%b2, %0|%0, %b2}"
13207   [(set_attr "type" "rotate")
13208    (set_attr "mode" "DI")])
13210 (define_expand "rotlsi3"
13211   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13212         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
13213                    (match_operand:QI 2 "nonmemory_operand" "")))
13214    (clobber (reg:CC FLAGS_REG))]
13215   ""
13216   "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
13218 (define_insn "*rotlsi3_1_one_bit"
13219   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13220         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13221                    (match_operand:QI 2 "const1_operand" "")))
13222    (clobber (reg:CC FLAGS_REG))]
13223   "(TARGET_SHIFT1 || optimize_size)
13224    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13225   "rol{l}\t%0"
13226   [(set_attr "type" "rotate")
13227    (set (attr "length")
13228      (if_then_else (match_operand:SI 0 "register_operand" "")
13229         (const_string "2")
13230         (const_string "*")))])
13232 (define_insn "*rotlsi3_1_one_bit_zext"
13233   [(set (match_operand:DI 0 "register_operand" "=r")
13234         (zero_extend:DI
13235           (rotate:SI (match_operand:SI 1 "register_operand" "0")
13236                      (match_operand:QI 2 "const1_operand" ""))))
13237    (clobber (reg:CC FLAGS_REG))]
13238   "TARGET_64BIT
13239    && (TARGET_SHIFT1 || optimize_size)
13240    && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13241   "rol{l}\t%k0"
13242   [(set_attr "type" "rotate")
13243    (set_attr "length" "2")])
13245 (define_insn "*rotlsi3_1"
13246   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13247         (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13248                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13249    (clobber (reg:CC FLAGS_REG))]
13250   "ix86_binary_operator_ok (ROTATE, SImode, operands)"
13251   "@
13252    rol{l}\t{%2, %0|%0, %2}
13253    rol{l}\t{%b2, %0|%0, %b2}"
13254   [(set_attr "type" "rotate")
13255    (set_attr "mode" "SI")])
13257 (define_insn "*rotlsi3_1_zext"
13258   [(set (match_operand:DI 0 "register_operand" "=r,r")
13259         (zero_extend:DI
13260           (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
13261                      (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13262    (clobber (reg:CC FLAGS_REG))]
13263   "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
13264   "@
13265    rol{l}\t{%2, %k0|%k0, %2}
13266    rol{l}\t{%b2, %k0|%k0, %b2}"
13267   [(set_attr "type" "rotate")
13268    (set_attr "mode" "SI")])
13270 (define_expand "rotlhi3"
13271   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13272         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13273                    (match_operand:QI 2 "nonmemory_operand" "")))
13274    (clobber (reg:CC FLAGS_REG))]
13275   "TARGET_HIMODE_MATH"
13276   "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13278 (define_insn "*rotlhi3_1_one_bit"
13279   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13280         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13281                    (match_operand:QI 2 "const1_operand" "")))
13282    (clobber (reg:CC FLAGS_REG))]
13283   "(TARGET_SHIFT1 || optimize_size)
13284    && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13285   "rol{w}\t%0"
13286   [(set_attr "type" "rotate")
13287    (set (attr "length")
13288      (if_then_else (match_operand 0 "register_operand" "")
13289         (const_string "2")
13290         (const_string "*")))])
13292 (define_insn "*rotlhi3_1"
13293   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13294         (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13295                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13296    (clobber (reg:CC FLAGS_REG))]
13297   "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13298   "@
13299    rol{w}\t{%2, %0|%0, %2}
13300    rol{w}\t{%b2, %0|%0, %b2}"
13301   [(set_attr "type" "rotate")
13302    (set_attr "mode" "HI")])
13304 (define_split
13305  [(set (match_operand:HI 0 "register_operand" "")
13306        (rotate:HI (match_dup 0) (const_int 8)))
13307   (clobber (reg:CC FLAGS_REG))]
13308  "reload_completed"
13309  [(parallel [(set (strict_low_part (match_dup 0))
13310                   (bswap:HI (match_dup 0)))
13311              (clobber (reg:CC FLAGS_REG))])]
13312  "")
13314 (define_expand "rotlqi3"
13315   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13316         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13317                    (match_operand:QI 2 "nonmemory_operand" "")))
13318    (clobber (reg:CC FLAGS_REG))]
13319   "TARGET_QIMODE_MATH"
13320   "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13322 (define_insn "*rotlqi3_1_one_bit_slp"
13323   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13324         (rotate:QI (match_dup 0)
13325                    (match_operand:QI 1 "const1_operand" "")))
13326    (clobber (reg:CC FLAGS_REG))]
13327   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13328    && (TARGET_SHIFT1 || optimize_size)"
13329   "rol{b}\t%0"
13330   [(set_attr "type" "rotate1")
13331    (set (attr "length")
13332      (if_then_else (match_operand 0 "register_operand" "")
13333         (const_string "2")
13334         (const_string "*")))])
13336 (define_insn "*rotlqi3_1_one_bit"
13337   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13338         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13339                    (match_operand:QI 2 "const1_operand" "")))
13340    (clobber (reg:CC FLAGS_REG))]
13341   "(TARGET_SHIFT1 || optimize_size)
13342    && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13343   "rol{b}\t%0"
13344   [(set_attr "type" "rotate")
13345    (set (attr "length")
13346      (if_then_else (match_operand 0 "register_operand" "")
13347         (const_string "2")
13348         (const_string "*")))])
13350 (define_insn "*rotlqi3_1_slp"
13351   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13352         (rotate:QI (match_dup 0)
13353                    (match_operand:QI 1 "nonmemory_operand" "I,c")))
13354    (clobber (reg:CC FLAGS_REG))]
13355   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13356    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13357   "@
13358    rol{b}\t{%1, %0|%0, %1}
13359    rol{b}\t{%b1, %0|%0, %b1}"
13360   [(set_attr "type" "rotate1")
13361    (set_attr "mode" "QI")])
13363 (define_insn "*rotlqi3_1"
13364   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13365         (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13366                    (match_operand:QI 2 "nonmemory_operand" "I,c")))
13367    (clobber (reg:CC FLAGS_REG))]
13368   "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13369   "@
13370    rol{b}\t{%2, %0|%0, %2}
13371    rol{b}\t{%b2, %0|%0, %b2}"
13372   [(set_attr "type" "rotate")
13373    (set_attr "mode" "QI")])
13375 (define_expand "rotrdi3"
13376   [(set (match_operand:DI 0 "shiftdi_operand" "")
13377         (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13378                    (match_operand:QI 2 "nonmemory_operand" "")))
13379    (clobber (reg:CC FLAGS_REG))]
13380  ""
13382   if (TARGET_64BIT)
13383     {
13384       ix86_expand_binary_operator (ROTATERT, DImode, operands);
13385       DONE;
13386     }
13387   if (!const_1_to_31_operand (operands[2], VOIDmode))
13388     FAIL;
13389   emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13390   DONE;
13393 ;; Implement rotation using two double-precision shift instructions
13394 ;; and a scratch register.
13395 (define_insn_and_split "ix86_rotrdi3"
13396  [(set (match_operand:DI 0 "register_operand" "=r")
13397        (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13398                     (match_operand:QI 2 "const_1_to_31_operand" "I")))
13399   (clobber (reg:CC FLAGS_REG))
13400   (clobber (match_scratch:SI 3 "=&r"))]
13401  "!TARGET_64BIT"
13402  ""
13403  "&& reload_completed"
13404  [(set (match_dup 3) (match_dup 4))
13405   (parallel
13406    [(set (match_dup 4)
13407          (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13408                  (ashift:SI (match_dup 5)
13409                             (minus:QI (const_int 32) (match_dup 2)))))
13410     (clobber (reg:CC FLAGS_REG))])
13411   (parallel
13412    [(set (match_dup 5)
13413          (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13414                  (ashift:SI (match_dup 3)
13415                             (minus:QI (const_int 32) (match_dup 2)))))
13416     (clobber (reg:CC FLAGS_REG))])]
13417  "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13419 (define_insn "*rotrdi3_1_one_bit_rex64"
13420   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13421         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13422                      (match_operand:QI 2 "const1_operand" "")))
13423    (clobber (reg:CC FLAGS_REG))]
13424   "TARGET_64BIT
13425    && (TARGET_SHIFT1 || optimize_size)
13426    && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13427   "ror{q}\t%0"
13428   [(set_attr "type" "rotate")
13429    (set (attr "length")
13430      (if_then_else (match_operand:DI 0 "register_operand" "")
13431         (const_string "2")
13432         (const_string "*")))])
13434 (define_insn "*rotrdi3_1_rex64"
13435   [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13436         (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13437                      (match_operand:QI 2 "nonmemory_operand" "J,c")))
13438    (clobber (reg:CC FLAGS_REG))]
13439   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13440   "@
13441    ror{q}\t{%2, %0|%0, %2}
13442    ror{q}\t{%b2, %0|%0, %b2}"
13443   [(set_attr "type" "rotate")
13444    (set_attr "mode" "DI")])
13446 (define_expand "rotrsi3"
13447   [(set (match_operand:SI 0 "nonimmediate_operand" "")
13448         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13449                      (match_operand:QI 2 "nonmemory_operand" "")))
13450    (clobber (reg:CC FLAGS_REG))]
13451   ""
13452   "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13454 (define_insn "*rotrsi3_1_one_bit"
13455   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13456         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13457                      (match_operand:QI 2 "const1_operand" "")))
13458    (clobber (reg:CC FLAGS_REG))]
13459   "(TARGET_SHIFT1 || optimize_size)
13460    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13461   "ror{l}\t%0"
13462   [(set_attr "type" "rotate")
13463    (set (attr "length")
13464      (if_then_else (match_operand:SI 0 "register_operand" "")
13465         (const_string "2")
13466         (const_string "*")))])
13468 (define_insn "*rotrsi3_1_one_bit_zext"
13469   [(set (match_operand:DI 0 "register_operand" "=r")
13470         (zero_extend:DI
13471           (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13472                        (match_operand:QI 2 "const1_operand" ""))))
13473    (clobber (reg:CC FLAGS_REG))]
13474   "TARGET_64BIT
13475    && (TARGET_SHIFT1 || optimize_size)
13476    && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13477   "ror{l}\t%k0"
13478   [(set_attr "type" "rotate")
13479    (set (attr "length")
13480      (if_then_else (match_operand:SI 0 "register_operand" "")
13481         (const_string "2")
13482         (const_string "*")))])
13484 (define_insn "*rotrsi3_1"
13485   [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13486         (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13487                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13488    (clobber (reg:CC FLAGS_REG))]
13489   "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13490   "@
13491    ror{l}\t{%2, %0|%0, %2}
13492    ror{l}\t{%b2, %0|%0, %b2}"
13493   [(set_attr "type" "rotate")
13494    (set_attr "mode" "SI")])
13496 (define_insn "*rotrsi3_1_zext"
13497   [(set (match_operand:DI 0 "register_operand" "=r,r")
13498         (zero_extend:DI
13499           (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13500                        (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13501    (clobber (reg:CC FLAGS_REG))]
13502   "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13503   "@
13504    ror{l}\t{%2, %k0|%k0, %2}
13505    ror{l}\t{%b2, %k0|%k0, %b2}"
13506   [(set_attr "type" "rotate")
13507    (set_attr "mode" "SI")])
13509 (define_expand "rotrhi3"
13510   [(set (match_operand:HI 0 "nonimmediate_operand" "")
13511         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13512                      (match_operand:QI 2 "nonmemory_operand" "")))
13513    (clobber (reg:CC FLAGS_REG))]
13514   "TARGET_HIMODE_MATH"
13515   "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13517 (define_insn "*rotrhi3_one_bit"
13518   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13519         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13520                      (match_operand:QI 2 "const1_operand" "")))
13521    (clobber (reg:CC FLAGS_REG))]
13522   "(TARGET_SHIFT1 || optimize_size)
13523    && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13524   "ror{w}\t%0"
13525   [(set_attr "type" "rotate")
13526    (set (attr "length")
13527      (if_then_else (match_operand 0 "register_operand" "")
13528         (const_string "2")
13529         (const_string "*")))])
13531 (define_insn "*rotrhi3_1"
13532   [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13533         (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13534                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13535    (clobber (reg:CC FLAGS_REG))]
13536   "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13537   "@
13538    ror{w}\t{%2, %0|%0, %2}
13539    ror{w}\t{%b2, %0|%0, %b2}"
13540   [(set_attr "type" "rotate")
13541    (set_attr "mode" "HI")])
13543 (define_split
13544  [(set (match_operand:HI 0 "register_operand" "")
13545        (rotatert:HI (match_dup 0) (const_int 8)))
13546   (clobber (reg:CC FLAGS_REG))]
13547  "reload_completed"
13548  [(parallel [(set (strict_low_part (match_dup 0))
13549                   (bswap:HI (match_dup 0)))
13550              (clobber (reg:CC FLAGS_REG))])]
13551  "")
13553 (define_expand "rotrqi3"
13554   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13555         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13556                      (match_operand:QI 2 "nonmemory_operand" "")))
13557    (clobber (reg:CC FLAGS_REG))]
13558   "TARGET_QIMODE_MATH"
13559   "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13561 (define_insn "*rotrqi3_1_one_bit"
13562   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13563         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13564                      (match_operand:QI 2 "const1_operand" "")))
13565    (clobber (reg:CC FLAGS_REG))]
13566   "(TARGET_SHIFT1 || optimize_size)
13567    && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13568   "ror{b}\t%0"
13569   [(set_attr "type" "rotate")
13570    (set (attr "length")
13571      (if_then_else (match_operand 0 "register_operand" "")
13572         (const_string "2")
13573         (const_string "*")))])
13575 (define_insn "*rotrqi3_1_one_bit_slp"
13576   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13577         (rotatert:QI (match_dup 0)
13578                      (match_operand:QI 1 "const1_operand" "")))
13579    (clobber (reg:CC FLAGS_REG))]
13580   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13581    && (TARGET_SHIFT1 || optimize_size)"
13582   "ror{b}\t%0"
13583   [(set_attr "type" "rotate1")
13584    (set (attr "length")
13585      (if_then_else (match_operand 0 "register_operand" "")
13586         (const_string "2")
13587         (const_string "*")))])
13589 (define_insn "*rotrqi3_1"
13590   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13591         (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13592                      (match_operand:QI 2 "nonmemory_operand" "I,c")))
13593    (clobber (reg:CC FLAGS_REG))]
13594   "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13595   "@
13596    ror{b}\t{%2, %0|%0, %2}
13597    ror{b}\t{%b2, %0|%0, %b2}"
13598   [(set_attr "type" "rotate")
13599    (set_attr "mode" "QI")])
13601 (define_insn "*rotrqi3_1_slp"
13602   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13603         (rotatert:QI (match_dup 0)
13604                      (match_operand:QI 1 "nonmemory_operand" "I,c")))
13605    (clobber (reg:CC FLAGS_REG))]
13606   "(! TARGET_PARTIAL_REG_STALL || optimize_size)
13607    && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13608   "@
13609    ror{b}\t{%1, %0|%0, %1}
13610    ror{b}\t{%b1, %0|%0, %b1}"
13611   [(set_attr "type" "rotate1")
13612    (set_attr "mode" "QI")])
13614 ;; Bit set / bit test instructions
13616 (define_expand "extv"
13617   [(set (match_operand:SI 0 "register_operand" "")
13618         (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13619                          (match_operand:SI 2 "const8_operand" "")
13620                          (match_operand:SI 3 "const8_operand" "")))]
13621   ""
13623   /* Handle extractions from %ah et al.  */
13624   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13625     FAIL;
13627   /* From mips.md: extract_bit_field doesn't verify that our source
13628      matches the predicate, so check it again here.  */
13629   if (! ext_register_operand (operands[1], VOIDmode))
13630     FAIL;
13633 (define_expand "extzv"
13634   [(set (match_operand:SI 0 "register_operand" "")
13635         (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13636                          (match_operand:SI 2 "const8_operand" "")
13637                          (match_operand:SI 3 "const8_operand" "")))]
13638   ""
13640   /* Handle extractions from %ah et al.  */
13641   if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13642     FAIL;
13644   /* From mips.md: extract_bit_field doesn't verify that our source
13645      matches the predicate, so check it again here.  */
13646   if (! ext_register_operand (operands[1], VOIDmode))
13647     FAIL;
13650 (define_expand "insv"
13651   [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13652                       (match_operand 1 "const8_operand" "")
13653                       (match_operand 2 "const8_operand" ""))
13654         (match_operand 3 "register_operand" ""))]
13655   ""
13657   /* Handle insertions to %ah et al.  */
13658   if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13659     FAIL;
13661   /* From mips.md: insert_bit_field doesn't verify that our source
13662      matches the predicate, so check it again here.  */
13663   if (! ext_register_operand (operands[0], VOIDmode))
13664     FAIL;
13666   if (TARGET_64BIT)
13667     emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13668   else
13669     emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13671   DONE;
13674 ;; %%% bts, btr, btc, bt.
13675 ;; In general these instructions are *slow* when applied to memory,
13676 ;; since they enforce atomic operation.  When applied to registers,
13677 ;; it depends on the cpu implementation.  They're never faster than
13678 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13679 ;; no point.  But in 64-bit, we can't hold the relevant immediates
13680 ;; within the instruction itself, so operating on bits in the high
13681 ;; 32-bits of a register becomes easier.
13683 ;; These are slow on Nocona, but fast on Athlon64.  We do require the use
13684 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13685 ;; negdf respectively, so they can never be disabled entirely.
13687 (define_insn "*btsq"
13688   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13689                          (const_int 1)
13690                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13691         (const_int 1))
13692    (clobber (reg:CC FLAGS_REG))]
13693   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13694   "bts{q}\t{%1, %0|%0, %1}"
13695   [(set_attr "type" "alu1")])
13697 (define_insn "*btrq"
13698   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13699                          (const_int 1)
13700                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13701         (const_int 0))
13702    (clobber (reg:CC FLAGS_REG))]
13703   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13704   "btr{q}\t{%1, %0|%0, %1}"
13705   [(set_attr "type" "alu1")])
13707 (define_insn "*btcq"
13708   [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13709                          (const_int 1)
13710                          (match_operand:DI 1 "const_0_to_63_operand" ""))
13711         (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13712    (clobber (reg:CC FLAGS_REG))]
13713   "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13714   "btc{q}\t{%1, %0|%0, %1}"
13715   [(set_attr "type" "alu1")])
13717 ;; Allow Nocona to avoid these instructions if a register is available.
13719 (define_peephole2
13720   [(match_scratch:DI 2 "r")
13721    (parallel [(set (zero_extract:DI
13722                      (match_operand:DI 0 "register_operand" "")
13723                      (const_int 1)
13724                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13725                    (const_int 1))
13726               (clobber (reg:CC FLAGS_REG))])]
13727   "TARGET_64BIT && !TARGET_USE_BT"
13728   [(const_int 0)]
13730   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13731   rtx op1;
13733   if (HOST_BITS_PER_WIDE_INT >= 64)
13734     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13735   else if (i < HOST_BITS_PER_WIDE_INT)
13736     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13737   else
13738     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13740   op1 = immed_double_const (lo, hi, DImode);
13741   if (i >= 31)
13742     {
13743       emit_move_insn (operands[2], op1);
13744       op1 = operands[2];
13745     }
13747   emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13748   DONE;
13751 (define_peephole2
13752   [(match_scratch:DI 2 "r")
13753    (parallel [(set (zero_extract:DI
13754                      (match_operand:DI 0 "register_operand" "")
13755                      (const_int 1)
13756                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13757                    (const_int 0))
13758               (clobber (reg:CC FLAGS_REG))])]
13759   "TARGET_64BIT && !TARGET_USE_BT"
13760   [(const_int 0)]
13762   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13763   rtx op1;
13765   if (HOST_BITS_PER_WIDE_INT >= 64)
13766     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13767   else if (i < HOST_BITS_PER_WIDE_INT)
13768     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13769   else
13770     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13772   op1 = immed_double_const (~lo, ~hi, DImode);
13773   if (i >= 32)
13774     {
13775       emit_move_insn (operands[2], op1);
13776       op1 = operands[2];
13777     }
13779   emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13780   DONE;
13783 (define_peephole2
13784   [(match_scratch:DI 2 "r")
13785    (parallel [(set (zero_extract:DI
13786                      (match_operand:DI 0 "register_operand" "")
13787                      (const_int 1)
13788                      (match_operand:DI 1 "const_0_to_63_operand" ""))
13789               (not:DI (zero_extract:DI
13790                         (match_dup 0) (const_int 1) (match_dup 1))))
13791               (clobber (reg:CC FLAGS_REG))])]
13792   "TARGET_64BIT && !TARGET_USE_BT"
13793   [(const_int 0)]
13795   HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13796   rtx op1;
13798   if (HOST_BITS_PER_WIDE_INT >= 64)
13799     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13800   else if (i < HOST_BITS_PER_WIDE_INT)
13801     lo = (HOST_WIDE_INT)1 << i, hi = 0;
13802   else
13803     lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13805   op1 = immed_double_const (lo, hi, DImode);
13806   if (i >= 31)
13807     {
13808       emit_move_insn (operands[2], op1);
13809       op1 = operands[2];
13810     }
13812   emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13813   DONE;
13816 (define_insn "*btdi_rex64"
13817   [(set (reg:CCC FLAGS_REG)
13818         (compare:CCC
13819           (zero_extract:DI
13820             (match_operand:DI 0 "register_operand" "r")
13821             (const_int 1)
13822             (match_operand:DI 1 "nonmemory_operand" "rN"))
13823           (const_int 0)))]
13824   "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
13825   "bt{q}\t{%1, %0|%0, %1}"
13826   [(set_attr "type" "alu1")])
13828 (define_insn "*btsi"
13829   [(set (reg:CCC FLAGS_REG)
13830         (compare:CCC
13831           (zero_extract:SI
13832             (match_operand:SI 0 "register_operand" "r")
13833             (const_int 1)
13834             (match_operand:SI 1 "nonmemory_operand" "rN"))
13835           (const_int 0)))]
13836   "TARGET_USE_BT || optimize_size"
13837   "bt{l}\t{%1, %0|%0, %1}"
13838   [(set_attr "type" "alu1")])
13840 ;; Store-flag instructions.
13842 ;; For all sCOND expanders, also expand the compare or test insn that
13843 ;; generates cc0.  Generate an equality comparison if `seq' or `sne'.
13845 ;; %%% Do the expansion to SImode.  If PII, do things the xor+setcc way
13846 ;; to avoid partial register stalls.  Otherwise do things the setcc+movzx
13847 ;; way, which can later delete the movzx if only QImode is needed.
13849 (define_expand "s<code>"
13850   [(set (match_operand:QI 0 "register_operand" "")
13851         (int_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13852   ""
13853   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13855 (define_expand "s<code>"
13856   [(set (match_operand:QI 0 "register_operand" "")
13857         (fp_cond:QI (reg:CC FLAGS_REG) (const_int 0)))]
13858   "TARGET_80387 || TARGET_SSE"
13859   "if (ix86_expand_setcc (<CODE>, operands[0])) DONE; else FAIL;")
13861 (define_insn "*setcc_1"
13862   [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13863         (match_operator:QI 1 "ix86_comparison_operator"
13864           [(reg FLAGS_REG) (const_int 0)]))]
13865   ""
13866   "set%C1\t%0"
13867   [(set_attr "type" "setcc")
13868    (set_attr "mode" "QI")])
13870 (define_insn "*setcc_2"
13871   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13872         (match_operator:QI 1 "ix86_comparison_operator"
13873           [(reg FLAGS_REG) (const_int 0)]))]
13874   ""
13875   "set%C1\t%0"
13876   [(set_attr "type" "setcc")
13877    (set_attr "mode" "QI")])
13879 ;; In general it is not safe to assume too much about CCmode registers,
13880 ;; so simplify-rtx stops when it sees a second one.  Under certain
13881 ;; conditions this is safe on x86, so help combine not create
13883 ;;      seta    %al
13884 ;;      testb   %al, %al
13885 ;;      sete    %al
13887 (define_split
13888   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13889         (ne:QI (match_operator 1 "ix86_comparison_operator"
13890                  [(reg FLAGS_REG) (const_int 0)])
13891             (const_int 0)))]
13892   ""
13893   [(set (match_dup 0) (match_dup 1))]
13895   PUT_MODE (operands[1], QImode);
13898 (define_split
13899   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13900         (ne:QI (match_operator 1 "ix86_comparison_operator"
13901                  [(reg FLAGS_REG) (const_int 0)])
13902             (const_int 0)))]
13903   ""
13904   [(set (match_dup 0) (match_dup 1))]
13906   PUT_MODE (operands[1], QImode);
13909 (define_split
13910   [(set (match_operand:QI 0 "nonimmediate_operand" "")
13911         (eq:QI (match_operator 1 "ix86_comparison_operator"
13912                  [(reg FLAGS_REG) (const_int 0)])
13913             (const_int 0)))]
13914   ""
13915   [(set (match_dup 0) (match_dup 1))]
13917   rtx new_op1 = copy_rtx (operands[1]);
13918   operands[1] = new_op1;
13919   PUT_MODE (new_op1, QImode);
13920   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13921                                              GET_MODE (XEXP (new_op1, 0))));
13923   /* Make sure that (a) the CCmode we have for the flags is strong
13924      enough for the reversed compare or (b) we have a valid FP compare.  */
13925   if (! ix86_comparison_operator (new_op1, VOIDmode))
13926     FAIL;
13929 (define_split
13930   [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13931         (eq:QI (match_operator 1 "ix86_comparison_operator"
13932                  [(reg FLAGS_REG) (const_int 0)])
13933             (const_int 0)))]
13934   ""
13935   [(set (match_dup 0) (match_dup 1))]
13937   rtx new_op1 = copy_rtx (operands[1]);
13938   operands[1] = new_op1;
13939   PUT_MODE (new_op1, QImode);
13940   PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13941                                              GET_MODE (XEXP (new_op1, 0))));
13943   /* Make sure that (a) the CCmode we have for the flags is strong
13944      enough for the reversed compare or (b) we have a valid FP compare.  */
13945   if (! ix86_comparison_operator (new_op1, VOIDmode))
13946     FAIL;
13949 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13950 ;; subsequent logical operations are used to imitate conditional moves.
13951 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13952 ;; it directly.
13954 (define_insn "*sse_setcc<mode>"
13955   [(set (match_operand:MODEF 0 "register_operand" "=x")
13956         (match_operator:MODEF 1 "sse_comparison_operator"
13957           [(match_operand:MODEF 2 "register_operand" "0")
13958            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13959   "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
13960   "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13961   [(set_attr "type" "ssecmp")
13962    (set_attr "mode" "<MODE>")])
13964 (define_insn "*sse5_setcc<mode>"
13965   [(set (match_operand:MODEF 0 "register_operand" "=x")
13966         (match_operator:MODEF 1 "sse5_comparison_float_operator"
13967           [(match_operand:MODEF 2 "register_operand" "x")
13968            (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13969   "TARGET_SSE5"
13970   "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13971   [(set_attr "type" "sse4arg")
13972    (set_attr "mode" "<MODE>")])
13975 ;; Basic conditional jump instructions.
13976 ;; We ignore the overflow flag for signed branch instructions.
13978 ;; For all bCOND expanders, also expand the compare or test insn that
13979 ;; generates reg FLAGS_REG.  Generate an equality comparison if `beq' or `bne'.
13981 (define_expand "b<code>"
13982   [(set (pc)
13983         (if_then_else (int_cond:CC (reg:CC FLAGS_REG)
13984                                    (const_int 0))
13985                       (label_ref (match_operand 0 ""))
13986                       (pc)))]
13987   ""
13988   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13990 (define_expand "b<code>"
13991   [(set (pc)
13992         (if_then_else (fp_cond:CC (reg:CC FLAGS_REG)
13993                                   (const_int 0))
13994                       (label_ref (match_operand 0 ""))
13995                       (pc)))]
13996   "TARGET_80387 || TARGET_SSE_MATH"
13997   "ix86_expand_branch (<CODE>, operands[0]); DONE;")
13999 (define_insn "*jcc_1"
14000   [(set (pc)
14001         (if_then_else (match_operator 1 "ix86_comparison_operator"
14002                                       [(reg FLAGS_REG) (const_int 0)])
14003                       (label_ref (match_operand 0 "" ""))
14004                       (pc)))]
14005   ""
14006   "%+j%C1\t%l0"
14007   [(set_attr "type" "ibr")
14008    (set_attr "modrm" "0")
14009    (set (attr "length")
14010            (if_then_else (and (ge (minus (match_dup 0) (pc))
14011                                   (const_int -126))
14012                               (lt (minus (match_dup 0) (pc))
14013                                   (const_int 128)))
14014              (const_int 2)
14015              (const_int 6)))])
14017 (define_insn "*jcc_2"
14018   [(set (pc)
14019         (if_then_else (match_operator 1 "ix86_comparison_operator"
14020                                       [(reg FLAGS_REG) (const_int 0)])
14021                       (pc)
14022                       (label_ref (match_operand 0 "" ""))))]
14023   ""
14024   "%+j%c1\t%l0"
14025   [(set_attr "type" "ibr")
14026    (set_attr "modrm" "0")
14027    (set (attr "length")
14028            (if_then_else (and (ge (minus (match_dup 0) (pc))
14029                                   (const_int -126))
14030                               (lt (minus (match_dup 0) (pc))
14031                                   (const_int 128)))
14032              (const_int 2)
14033              (const_int 6)))])
14035 ;; In general it is not safe to assume too much about CCmode registers,
14036 ;; so simplify-rtx stops when it sees a second one.  Under certain
14037 ;; conditions this is safe on x86, so help combine not create
14039 ;;      seta    %al
14040 ;;      testb   %al, %al
14041 ;;      je      Lfoo
14043 (define_split
14044   [(set (pc)
14045         (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14046                                       [(reg FLAGS_REG) (const_int 0)])
14047                           (const_int 0))
14048                       (label_ref (match_operand 1 "" ""))
14049                       (pc)))]
14050   ""
14051   [(set (pc)
14052         (if_then_else (match_dup 0)
14053                       (label_ref (match_dup 1))
14054                       (pc)))]
14056   PUT_MODE (operands[0], VOIDmode);
14059 (define_split
14060   [(set (pc)
14061         (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14062                                       [(reg FLAGS_REG) (const_int 0)])
14063                           (const_int 0))
14064                       (label_ref (match_operand 1 "" ""))
14065                       (pc)))]
14066   ""
14067   [(set (pc)
14068         (if_then_else (match_dup 0)
14069                       (label_ref (match_dup 1))
14070                       (pc)))]
14072   rtx new_op0 = copy_rtx (operands[0]);
14073   operands[0] = new_op0;
14074   PUT_MODE (new_op0, VOIDmode);
14075   PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14076                                              GET_MODE (XEXP (new_op0, 0))));
14078   /* Make sure that (a) the CCmode we have for the flags is strong
14079      enough for the reversed compare or (b) we have a valid FP compare.  */
14080   if (! ix86_comparison_operator (new_op0, VOIDmode))
14081     FAIL;
14084 ;; zero_extend in SImode is correct, since this is what combine pass
14085 ;; generates from shift insn with QImode operand.  Actually, the mode of
14086 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14087 ;; appropriate modulo of the bit offset value.
14089 (define_insn_and_split "*jcc_btdi_rex64"
14090   [(set (pc)
14091         (if_then_else (match_operator 0 "bt_comparison_operator"
14092                         [(zero_extract:DI
14093                            (match_operand:DI 1 "register_operand" "r")
14094                            (const_int 1)
14095                            (zero_extend:SI
14096                              (match_operand:QI 2 "register_operand" "r")))
14097                          (const_int 0)])
14098                       (label_ref (match_operand 3 "" ""))
14099                       (pc)))]
14100   "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
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 3))
14113                       (pc)))]
14115   operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14117   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14120 ;; avoid useless masking of bit offset operand
14121 (define_insn_and_split "*jcc_btdi_mask_rex64"
14122   [(set (pc)
14123         (if_then_else (match_operator 0 "bt_comparison_operator"
14124                         [(zero_extract:DI
14125                            (match_operand:DI 1 "register_operand" "r")
14126                            (const_int 1)
14127                            (and:SI
14128                              (match_operand:SI 2 "register_operand" "r")
14129                              (match_operand:SI 3 "const_int_operand" "n")))])
14130                       (label_ref (match_operand 4 "" ""))
14131                       (pc)))]
14132   "TARGET_64BIT && (TARGET_USE_BT || optimize_size)
14133    && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14134   "#"
14135   "&& 1"
14136   [(set (reg:CCC FLAGS_REG)
14137         (compare:CCC
14138           (zero_extract:DI
14139             (match_dup 1)
14140             (const_int 1)
14141             (match_dup 2))
14142           (const_int 0)))
14143    (set (pc)
14144         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14145                       (label_ref (match_dup 4))
14146                       (pc)))]
14148   operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
14150   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14153 (define_insn_and_split "*jcc_btsi"
14154   [(set (pc)
14155         (if_then_else (match_operator 0 "bt_comparison_operator"
14156                         [(zero_extract:SI
14157                            (match_operand:SI 1 "register_operand" "r")
14158                            (const_int 1)
14159                            (zero_extend:SI
14160                              (match_operand:QI 2 "register_operand" "r")))
14161                          (const_int 0)])
14162                       (label_ref (match_operand 3 "" ""))
14163                       (pc)))]
14164   "TARGET_USE_BT || optimize_size"
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 3))
14177                       (pc)))]
14179   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14181   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14184 ;; avoid useless masking of bit offset operand
14185 (define_insn_and_split "*jcc_btsi_mask"
14186   [(set (pc)
14187         (if_then_else (match_operator 0 "bt_comparison_operator"
14188                         [(zero_extract:SI
14189                            (match_operand:SI 1 "register_operand" "r")
14190                            (const_int 1)
14191                            (and:SI
14192                              (match_operand:SI 2 "register_operand" "r")
14193                              (match_operand:SI 3 "const_int_operand" "n")))])
14194                       (label_ref (match_operand 4 "" ""))
14195                       (pc)))]
14196   "(TARGET_USE_BT || optimize_size)
14197    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14198   "#"
14199   "&& 1"
14200   [(set (reg:CCC FLAGS_REG)
14201         (compare:CCC
14202           (zero_extract:SI
14203             (match_dup 1)
14204             (const_int 1)
14205             (match_dup 2))
14206           (const_int 0)))
14207    (set (pc)
14208         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14209                       (label_ref (match_dup 4))
14210                       (pc)))]
14211   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14213 (define_insn_and_split "*jcc_btsi_1"
14214   [(set (pc)
14215         (if_then_else (match_operator 0 "bt_comparison_operator"
14216                         [(and:SI
14217                            (lshiftrt:SI
14218                              (match_operand:SI 1 "register_operand" "r")
14219                              (match_operand:QI 2 "register_operand" "r"))
14220                            (const_int 1))
14221                          (const_int 0)])
14222                       (label_ref (match_operand 3 "" ""))
14223                       (pc)))]
14224   "TARGET_USE_BT || optimize_size"
14225   "#"
14226   "&& 1"
14227   [(set (reg:CCC FLAGS_REG)
14228         (compare:CCC
14229           (zero_extract:SI
14230             (match_dup 1)
14231             (const_int 1)
14232             (match_dup 2))
14233           (const_int 0)))
14234    (set (pc)
14235         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14236                       (label_ref (match_dup 3))
14237                       (pc)))]
14239   operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
14241   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14244 ;; avoid useless masking of bit offset operand
14245 (define_insn_and_split "*jcc_btsi_mask_1"
14246   [(set (pc)
14247         (if_then_else
14248           (match_operator 0 "bt_comparison_operator"
14249             [(and:SI
14250                (lshiftrt:SI
14251                  (match_operand:SI 1 "register_operand" "r")
14252                  (subreg:QI
14253                    (and:SI
14254                      (match_operand:SI 2 "register_operand" "r")
14255                      (match_operand:SI 3 "const_int_operand" "n")) 0))
14256                (const_int 1))
14257              (const_int 0)])
14258           (label_ref (match_operand 4 "" ""))
14259           (pc)))]
14260   "(TARGET_USE_BT || optimize_size)
14261    && (INTVAL (operands[3]) & 0x1f) == 0x1f"
14262   "#"
14263   "&& 1"
14264   [(set (reg:CCC FLAGS_REG)
14265         (compare:CCC
14266           (zero_extract:SI
14267             (match_dup 1)
14268             (const_int 1)
14269             (match_dup 2))
14270           (const_int 0)))
14271    (set (pc)
14272         (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14273                       (label_ref (match_dup 4))
14274                       (pc)))]
14275   "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14277 ;; Define combination compare-and-branch fp compare instructions to use
14278 ;; during early optimization.  Splitting the operation apart early makes
14279 ;; for bad code when we want to reverse the operation.
14281 (define_insn "*fp_jcc_1_mixed"
14282   [(set (pc)
14283         (if_then_else (match_operator 0 "comparison_operator"
14284                         [(match_operand 1 "register_operand" "f,x")
14285                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14286           (label_ref (match_operand 3 "" ""))
14287           (pc)))
14288    (clobber (reg:CCFP FPSR_REG))
14289    (clobber (reg:CCFP FLAGS_REG))]
14290   "TARGET_MIX_SSE_I387
14291    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14292    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14293    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14294   "#")
14296 (define_insn "*fp_jcc_1_sse"
14297   [(set (pc)
14298         (if_then_else (match_operator 0 "comparison_operator"
14299                         [(match_operand 1 "register_operand" "x")
14300                          (match_operand 2 "nonimmediate_operand" "xm")])
14301           (label_ref (match_operand 3 "" ""))
14302           (pc)))
14303    (clobber (reg:CCFP FPSR_REG))
14304    (clobber (reg:CCFP FLAGS_REG))]
14305   "TARGET_SSE_MATH
14306    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14307    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14308    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14309   "#")
14311 (define_insn "*fp_jcc_1_387"
14312   [(set (pc)
14313         (if_then_else (match_operator 0 "comparison_operator"
14314                         [(match_operand 1 "register_operand" "f")
14315                          (match_operand 2 "register_operand" "f")])
14316           (label_ref (match_operand 3 "" ""))
14317           (pc)))
14318    (clobber (reg:CCFP FPSR_REG))
14319    (clobber (reg:CCFP FLAGS_REG))]
14320   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14321    && TARGET_CMOVE
14322    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14323    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14324   "#")
14326 (define_insn "*fp_jcc_2_mixed"
14327   [(set (pc)
14328         (if_then_else (match_operator 0 "comparison_operator"
14329                         [(match_operand 1 "register_operand" "f,x")
14330                          (match_operand 2 "nonimmediate_operand" "f,xm")])
14331           (pc)
14332           (label_ref (match_operand 3 "" ""))))
14333    (clobber (reg:CCFP FPSR_REG))
14334    (clobber (reg:CCFP FLAGS_REG))]
14335   "TARGET_MIX_SSE_I387
14336    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14337    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14338    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14339   "#")
14341 (define_insn "*fp_jcc_2_sse"
14342   [(set (pc)
14343         (if_then_else (match_operator 0 "comparison_operator"
14344                         [(match_operand 1 "register_operand" "x")
14345                          (match_operand 2 "nonimmediate_operand" "xm")])
14346           (pc)
14347           (label_ref (match_operand 3 "" ""))))
14348    (clobber (reg:CCFP FPSR_REG))
14349    (clobber (reg:CCFP FLAGS_REG))]
14350   "TARGET_SSE_MATH
14351    && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
14352    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14353    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14354   "#")
14356 (define_insn "*fp_jcc_2_387"
14357   [(set (pc)
14358         (if_then_else (match_operator 0 "comparison_operator"
14359                         [(match_operand 1 "register_operand" "f")
14360                          (match_operand 2 "register_operand" "f")])
14361           (pc)
14362           (label_ref (match_operand 3 "" ""))))
14363    (clobber (reg:CCFP FPSR_REG))
14364    (clobber (reg:CCFP FLAGS_REG))]
14365   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14366    && TARGET_CMOVE
14367    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14368    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14369   "#")
14371 (define_insn "*fp_jcc_3_387"
14372   [(set (pc)
14373         (if_then_else (match_operator 0 "comparison_operator"
14374                         [(match_operand 1 "register_operand" "f")
14375                          (match_operand 2 "nonimmediate_operand" "fm")])
14376           (label_ref (match_operand 3 "" ""))
14377           (pc)))
14378    (clobber (reg:CCFP FPSR_REG))
14379    (clobber (reg:CCFP FLAGS_REG))
14380    (clobber (match_scratch:HI 4 "=a"))]
14381   "TARGET_80387
14382    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14383    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14384    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14385    && SELECT_CC_MODE (GET_CODE (operands[0]),
14386                       operands[1], operands[2]) == CCFPmode
14387    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14388   "#")
14390 (define_insn "*fp_jcc_4_387"
14391   [(set (pc)
14392         (if_then_else (match_operator 0 "comparison_operator"
14393                         [(match_operand 1 "register_operand" "f")
14394                          (match_operand 2 "nonimmediate_operand" "fm")])
14395           (pc)
14396           (label_ref (match_operand 3 "" ""))))
14397    (clobber (reg:CCFP FPSR_REG))
14398    (clobber (reg:CCFP FLAGS_REG))
14399    (clobber (match_scratch:HI 4 "=a"))]
14400   "TARGET_80387
14401    && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14402    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14403    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14404    && SELECT_CC_MODE (GET_CODE (operands[0]),
14405                       operands[1], operands[2]) == CCFPmode
14406    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14407   "#")
14409 (define_insn "*fp_jcc_5_387"
14410   [(set (pc)
14411         (if_then_else (match_operator 0 "comparison_operator"
14412                         [(match_operand 1 "register_operand" "f")
14413                          (match_operand 2 "register_operand" "f")])
14414           (label_ref (match_operand 3 "" ""))
14415           (pc)))
14416    (clobber (reg:CCFP FPSR_REG))
14417    (clobber (reg:CCFP FLAGS_REG))
14418    (clobber (match_scratch:HI 4 "=a"))]
14419   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14420    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14421    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14422   "#")
14424 (define_insn "*fp_jcc_6_387"
14425   [(set (pc)
14426         (if_then_else (match_operator 0 "comparison_operator"
14427                         [(match_operand 1 "register_operand" "f")
14428                          (match_operand 2 "register_operand" "f")])
14429           (pc)
14430           (label_ref (match_operand 3 "" ""))))
14431    (clobber (reg:CCFP FPSR_REG))
14432    (clobber (reg:CCFP FLAGS_REG))
14433    (clobber (match_scratch:HI 4 "=a"))]
14434   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14435    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14436    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14437   "#")
14439 (define_insn "*fp_jcc_7_387"
14440   [(set (pc)
14441         (if_then_else (match_operator 0 "comparison_operator"
14442                         [(match_operand 1 "register_operand" "f")
14443                          (match_operand 2 "const0_operand" "X")])
14444           (label_ref (match_operand 3 "" ""))
14445           (pc)))
14446    (clobber (reg:CCFP FPSR_REG))
14447    (clobber (reg:CCFP FLAGS_REG))
14448    (clobber (match_scratch:HI 4 "=a"))]
14449   "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14450    && GET_MODE (operands[1]) == GET_MODE (operands[2])
14451    && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
14452    && SELECT_CC_MODE (GET_CODE (operands[0]),
14453                       operands[1], operands[2]) == CCFPmode
14454    && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
14455   "#")
14457 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14458 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14459 ;; with a precedence over other operators and is always put in the first
14460 ;; place. Swap condition and operands to match ficom instruction.
14462 (define_insn "*fp_jcc_8<mode>_387"
14463   [(set (pc)
14464         (if_then_else (match_operator 0 "comparison_operator"
14465                         [(match_operator 1 "float_operator"
14466                            [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14467                            (match_operand 3 "register_operand" "f,f")])
14468           (label_ref (match_operand 4 "" ""))
14469           (pc)))
14470    (clobber (reg:CCFP FPSR_REG))
14471    (clobber (reg:CCFP FLAGS_REG))
14472    (clobber (match_scratch:HI 5 "=a,a"))]
14473   "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14474    && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)
14475    && GET_MODE (operands[1]) == GET_MODE (operands[3])
14476    && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
14477    && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14478    && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
14479   "#")
14481 (define_split
14482   [(set (pc)
14483         (if_then_else (match_operator 0 "comparison_operator"
14484                         [(match_operand 1 "register_operand" "")
14485                          (match_operand 2 "nonimmediate_operand" "")])
14486           (match_operand 3 "" "")
14487           (match_operand 4 "" "")))
14488    (clobber (reg:CCFP FPSR_REG))
14489    (clobber (reg:CCFP FLAGS_REG))]
14490   "reload_completed"
14491   [(const_int 0)]
14493   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14494                         operands[3], operands[4], NULL_RTX, NULL_RTX);
14495   DONE;
14498 (define_split
14499   [(set (pc)
14500         (if_then_else (match_operator 0 "comparison_operator"
14501                         [(match_operand 1 "register_operand" "")
14502                          (match_operand 2 "general_operand" "")])
14503           (match_operand 3 "" "")
14504           (match_operand 4 "" "")))
14505    (clobber (reg:CCFP FPSR_REG))
14506    (clobber (reg:CCFP FLAGS_REG))
14507    (clobber (match_scratch:HI 5 "=a"))]
14508   "reload_completed"
14509   [(const_int 0)]
14511   ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14512                         operands[3], operands[4], operands[5], NULL_RTX);
14513   DONE;
14516 (define_split
14517   [(set (pc)
14518         (if_then_else (match_operator 0 "comparison_operator"
14519                         [(match_operator 1 "float_operator"
14520                            [(match_operand:X87MODEI12 2 "memory_operand" "")])
14521                            (match_operand 3 "register_operand" "")])
14522           (match_operand 4 "" "")
14523           (match_operand 5 "" "")))
14524    (clobber (reg:CCFP FPSR_REG))
14525    (clobber (reg:CCFP FLAGS_REG))
14526    (clobber (match_scratch:HI 6 "=a"))]
14527   "reload_completed"
14528   [(const_int 0)]
14530   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14531   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14532                         operands[3], operands[7],
14533                         operands[4], operands[5], operands[6], NULL_RTX);
14534   DONE;
14537 ;; %%% Kill this when reload knows how to do it.
14538 (define_split
14539   [(set (pc)
14540         (if_then_else (match_operator 0 "comparison_operator"
14541                         [(match_operator 1 "float_operator"
14542                            [(match_operand:X87MODEI12 2 "register_operand" "")])
14543                            (match_operand 3 "register_operand" "")])
14544           (match_operand 4 "" "")
14545           (match_operand 5 "" "")))
14546    (clobber (reg:CCFP FPSR_REG))
14547    (clobber (reg:CCFP FLAGS_REG))
14548    (clobber (match_scratch:HI 6 "=a"))]
14549   "reload_completed"
14550   [(const_int 0)]
14552   operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14553   operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14554   ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14555                         operands[3], operands[7],
14556                         operands[4], operands[5], operands[6], operands[2]);
14557   DONE;
14560 ;; Unconditional and other jump instructions
14562 (define_insn "jump"
14563   [(set (pc)
14564         (label_ref (match_operand 0 "" "")))]
14565   ""
14566   "jmp\t%l0"
14567   [(set_attr "type" "ibr")
14568    (set (attr "length")
14569            (if_then_else (and (ge (minus (match_dup 0) (pc))
14570                                   (const_int -126))
14571                               (lt (minus (match_dup 0) (pc))
14572                                   (const_int 128)))
14573              (const_int 2)
14574              (const_int 5)))
14575    (set_attr "modrm" "0")])
14577 (define_expand "indirect_jump"
14578   [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14579   ""
14580   "")
14582 (define_insn "*indirect_jump"
14583   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14584   ""
14585   "jmp\t%A0"
14586   [(set_attr "type" "ibr")
14587    (set_attr "length_immediate" "0")])
14589 (define_expand "tablejump"
14590   [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14591               (use (label_ref (match_operand 1 "" "")))])]
14592   ""
14594   /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14595      relative.  Convert the relative address to an absolute address.  */
14596   if (flag_pic)
14597     {
14598       rtx op0, op1;
14599       enum rtx_code code;
14601       /* We can't use @GOTOFF for text labels on VxWorks;
14602          see gotoff_operand.  */
14603       if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14604         {
14605           code = PLUS;
14606           op0 = operands[0];
14607           op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14608         }
14609       else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14610         {
14611           code = PLUS;
14612           op0 = operands[0];
14613           op1 = pic_offset_table_rtx;
14614         }
14615       else
14616         {
14617           code = MINUS;
14618           op0 = pic_offset_table_rtx;
14619           op1 = operands[0];
14620         }
14622       operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14623                                          OPTAB_DIRECT);
14624     }
14627 (define_insn "*tablejump_1"
14628   [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14629    (use (label_ref (match_operand 1 "" "")))]
14630   ""
14631   "jmp\t%A0"
14632   [(set_attr "type" "ibr")
14633    (set_attr "length_immediate" "0")])
14635 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14637 (define_peephole2
14638   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14639    (set (match_operand:QI 1 "register_operand" "")
14640         (match_operator:QI 2 "ix86_comparison_operator"
14641           [(reg FLAGS_REG) (const_int 0)]))
14642    (set (match_operand 3 "q_regs_operand" "")
14643         (zero_extend (match_dup 1)))]
14644   "(peep2_reg_dead_p (3, operands[1])
14645     || operands_match_p (operands[1], operands[3]))
14646    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14647   [(set (match_dup 4) (match_dup 0))
14648    (set (strict_low_part (match_dup 5))
14649         (match_dup 2))]
14651   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14652   operands[5] = gen_lowpart (QImode, operands[3]);
14653   ix86_expand_clear (operands[3]);
14656 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14658 (define_peephole2
14659   [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14660    (set (match_operand:QI 1 "register_operand" "")
14661         (match_operator:QI 2 "ix86_comparison_operator"
14662           [(reg FLAGS_REG) (const_int 0)]))
14663    (parallel [(set (match_operand 3 "q_regs_operand" "")
14664                    (zero_extend (match_dup 1)))
14665               (clobber (reg:CC FLAGS_REG))])]
14666   "(peep2_reg_dead_p (3, operands[1])
14667     || operands_match_p (operands[1], operands[3]))
14668    && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14669   [(set (match_dup 4) (match_dup 0))
14670    (set (strict_low_part (match_dup 5))
14671         (match_dup 2))]
14673   operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14674   operands[5] = gen_lowpart (QImode, operands[3]);
14675   ix86_expand_clear (operands[3]);
14678 ;; Call instructions.
14680 ;; The predicates normally associated with named expanders are not properly
14681 ;; checked for calls.  This is a bug in the generic code, but it isn't that
14682 ;; easy to fix.  Ignore it for now and be prepared to fix things up.
14684 ;; Call subroutine returning no value.
14686 (define_expand "call_pop"
14687   [(parallel [(call (match_operand:QI 0 "" "")
14688                     (match_operand:SI 1 "" ""))
14689               (set (reg:SI SP_REG)
14690                    (plus:SI (reg:SI SP_REG)
14691                             (match_operand:SI 3 "" "")))])]
14692   "!TARGET_64BIT"
14694   ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
14695   DONE;
14698 (define_insn "*call_pop_0"
14699   [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14700          (match_operand:SI 1 "" ""))
14701    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14702                             (match_operand:SI 2 "immediate_operand" "")))]
14703   "!TARGET_64BIT"
14705   if (SIBLING_CALL_P (insn))
14706     return "jmp\t%P0";
14707   else
14708     return "call\t%P0";
14710   [(set_attr "type" "call")])
14712 (define_insn "*call_pop_1"
14713   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14714          (match_operand:SI 1 "" ""))
14715    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
14716                             (match_operand:SI 2 "immediate_operand" "i")))]
14717   "!TARGET_64BIT"
14719   if (constant_call_address_operand (operands[0], Pmode))
14720     {
14721       if (SIBLING_CALL_P (insn))
14722         return "jmp\t%P0";
14723       else
14724         return "call\t%P0";
14725     }
14726   if (SIBLING_CALL_P (insn))
14727     return "jmp\t%A0";
14728   else
14729     return "call\t%A0";
14731   [(set_attr "type" "call")])
14733 (define_expand "call"
14734   [(call (match_operand:QI 0 "" "")
14735          (match_operand 1 "" ""))
14736    (use (match_operand 2 "" ""))]
14737   ""
14739   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14740   DONE;
14743 (define_expand "sibcall"
14744   [(call (match_operand:QI 0 "" "")
14745          (match_operand 1 "" ""))
14746    (use (match_operand 2 "" ""))]
14747   ""
14749   ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14750   DONE;
14753 (define_insn "*call_0"
14754   [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14755          (match_operand 1 "" ""))]
14756   ""
14758   if (SIBLING_CALL_P (insn))
14759     return "jmp\t%P0";
14760   else
14761     return "call\t%P0";
14763   [(set_attr "type" "call")])
14765 (define_insn "*call_1"
14766   [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
14767          (match_operand 1 "" ""))]
14768   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
14770   if (constant_call_address_operand (operands[0], Pmode))
14771     return "call\t%P0";
14772   return "call\t%A0";
14774   [(set_attr "type" "call")])
14776 (define_insn "*sibcall_1"
14777   [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
14778          (match_operand 1 "" ""))]
14779   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
14781   if (constant_call_address_operand (operands[0], Pmode))
14782     return "jmp\t%P0";
14783   return "jmp\t%A0";
14785   [(set_attr "type" "call")])
14787 (define_insn "*call_1_rex64"
14788   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14789          (match_operand 1 "" ""))]
14790   "!SIBLING_CALL_P (insn) && TARGET_64BIT
14791    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14793   if (constant_call_address_operand (operands[0], Pmode))
14794     return "call\t%P0";
14795   return "call\t%A0";
14797   [(set_attr "type" "call")])
14799 (define_insn "*call_1_rex64_large"
14800   [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14801          (match_operand 1 "" ""))]
14802   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
14803   "call\t%A0"
14804   [(set_attr "type" "call")])
14806 (define_insn "*sibcall_1_rex64"
14807   [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
14808          (match_operand 1 "" ""))]
14809   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14810   "jmp\t%P0"
14811   [(set_attr "type" "call")])
14813 (define_insn "*sibcall_1_rex64_v"
14814   [(call (mem:QI (reg:DI R11_REG))
14815          (match_operand 0 "" ""))]
14816   "SIBLING_CALL_P (insn) && TARGET_64BIT"
14817   "jmp\t{*%%}r11"
14818   [(set_attr "type" "call")])
14821 ;; Call subroutine, returning value in operand 0
14823 (define_expand "call_value_pop"
14824   [(parallel [(set (match_operand 0 "" "")
14825                    (call (match_operand:QI 1 "" "")
14826                          (match_operand:SI 2 "" "")))
14827               (set (reg:SI SP_REG)
14828                    (plus:SI (reg:SI SP_REG)
14829                             (match_operand:SI 4 "" "")))])]
14830   "!TARGET_64BIT"
14832   ix86_expand_call (operands[0], operands[1], operands[2],
14833                     operands[3], operands[4], 0);
14834   DONE;
14837 (define_expand "call_value"
14838   [(set (match_operand 0 "" "")
14839         (call (match_operand:QI 1 "" "")
14840               (match_operand:SI 2 "" "")))
14841    (use (match_operand:SI 3 "" ""))]
14842   ;; Operand 2 not used on the i386.
14843   ""
14845   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
14846   DONE;
14849 (define_expand "sibcall_value"
14850   [(set (match_operand 0 "" "")
14851         (call (match_operand:QI 1 "" "")
14852               (match_operand:SI 2 "" "")))
14853    (use (match_operand:SI 3 "" ""))]
14854   ;; Operand 2 not used on the i386.
14855   ""
14857   ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
14858   DONE;
14861 ;; Call subroutine returning any type.
14863 (define_expand "untyped_call"
14864   [(parallel [(call (match_operand 0 "" "")
14865                     (const_int 0))
14866               (match_operand 1 "" "")
14867               (match_operand 2 "" "")])]
14868   ""
14870   int i;
14872   /* In order to give reg-stack an easier job in validating two
14873      coprocessor registers as containing a possible return value,
14874      simply pretend the untyped call returns a complex long double
14875      value.  */
14877   ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14878                      ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14879                     operands[0], const0_rtx,
14880                     GEN_INT ((DEFAULT_ABI == SYSV_ABI ? X86_64_SSE_REGPARM_MAX
14881                                                       : X64_SSE_REGPARM_MAX)
14882                              - 1),
14883                     NULL, 0);
14885   for (i = 0; i < XVECLEN (operands[2], 0); i++)
14886     {
14887       rtx set = XVECEXP (operands[2], 0, i);
14888       emit_move_insn (SET_DEST (set), SET_SRC (set));
14889     }
14891   /* The optimizer does not know that the call sets the function value
14892      registers we stored in the result block.  We avoid problems by
14893      claiming that all hard registers are used and clobbered at this
14894      point.  */
14895   emit_insn (gen_blockage ());
14897   DONE;
14900 ;; Prologue and epilogue instructions
14902 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14903 ;; all of memory.  This blocks insns from being moved across this point.
14905 (define_insn "blockage"
14906   [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14907   ""
14908   ""
14909   [(set_attr "length" "0")])
14911 ;; As USE insns aren't meaningful after reload, this is used instead
14912 ;; to prevent deleting instructions setting registers for PIC code
14913 (define_insn "prologue_use"
14914   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14915   ""
14916   ""
14917   [(set_attr "length" "0")])
14919 ;; Insn emitted into the body of a function to return from a function.
14920 ;; This is only done if the function's epilogue is known to be simple.
14921 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14923 (define_expand "return"
14924   [(return)]
14925   "ix86_can_use_return_insn_p ()"
14927   if (crtl->args.pops_args)
14928     {
14929       rtx popc = GEN_INT (crtl->args.pops_args);
14930       emit_jump_insn (gen_return_pop_internal (popc));
14931       DONE;
14932     }
14935 (define_insn "return_internal"
14936   [(return)]
14937   "reload_completed"
14938   "ret"
14939   [(set_attr "length" "1")
14940    (set_attr "length_immediate" "0")
14941    (set_attr "modrm" "0")])
14943 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14944 ;; instruction Athlon and K8 have.
14946 (define_insn "return_internal_long"
14947   [(return)
14948    (unspec [(const_int 0)] UNSPEC_REP)]
14949   "reload_completed"
14950   "rep\;ret"
14951   [(set_attr "length" "1")
14952    (set_attr "length_immediate" "0")
14953    (set_attr "prefix_rep" "1")
14954    (set_attr "modrm" "0")])
14956 (define_insn "return_pop_internal"
14957   [(return)
14958    (use (match_operand:SI 0 "const_int_operand" ""))]
14959   "reload_completed"
14960   "ret\t%0"
14961   [(set_attr "length" "3")
14962    (set_attr "length_immediate" "2")
14963    (set_attr "modrm" "0")])
14965 (define_insn "return_indirect_internal"
14966   [(return)
14967    (use (match_operand:SI 0 "register_operand" "r"))]
14968   "reload_completed"
14969   "jmp\t%A0"
14970   [(set_attr "type" "ibr")
14971    (set_attr "length_immediate" "0")])
14973 (define_insn "nop"
14974   [(const_int 0)]
14975   ""
14976   "nop"
14977   [(set_attr "length" "1")
14978    (set_attr "length_immediate" "0")
14979    (set_attr "modrm" "0")])
14981 ;; Align to 16-byte boundary, max skip in op0.  Used to avoid
14982 ;; branch prediction penalty for the third jump in a 16-byte
14983 ;; block on K8.
14985 (define_insn "align"
14986   [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14987   ""
14989 #ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
14990   ASM_OUTPUT_MAX_SKIP_ALIGN (asm_out_file, 4, (int)INTVAL (operands[0]));
14991 #else
14992   /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14993      The align insn is used to avoid 3 jump instructions in the row to improve
14994      branch prediction and the benefits hardly outweigh the cost of extra 8
14995      nops on the average inserted by full alignment pseudo operation.  */
14996 #endif
14997   return "";
14999   [(set_attr "length" "16")])
15001 (define_expand "prologue"
15002   [(const_int 0)]
15003   ""
15004   "ix86_expand_prologue (); DONE;")
15006 (define_insn "set_got"
15007   [(set (match_operand:SI 0 "register_operand" "=r")
15008         (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15009    (clobber (reg:CC FLAGS_REG))]
15010   "!TARGET_64BIT"
15011   { return output_set_got (operands[0], NULL_RTX); }
15012   [(set_attr "type" "multi")
15013    (set_attr "length" "12")])
15015 (define_insn "set_got_labelled"
15016   [(set (match_operand:SI 0 "register_operand" "=r")
15017         (unspec:SI [(label_ref (match_operand 1 "" ""))]
15018          UNSPEC_SET_GOT))
15019    (clobber (reg:CC FLAGS_REG))]
15020   "!TARGET_64BIT"
15021   { return output_set_got (operands[0], operands[1]); }
15022   [(set_attr "type" "multi")
15023    (set_attr "length" "12")])
15025 (define_insn "set_got_rex64"
15026   [(set (match_operand:DI 0 "register_operand" "=r")
15027         (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15028   "TARGET_64BIT"
15029   "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15030   [(set_attr "type" "lea")
15031    (set_attr "length" "6")])
15033 (define_insn "set_rip_rex64"
15034   [(set (match_operand:DI 0 "register_operand" "=r")
15035         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_RIP))]
15036   "TARGET_64BIT"
15037   "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15038   [(set_attr "type" "lea")
15039    (set_attr "length" "6")])
15041 (define_insn "set_got_offset_rex64"
15042   [(set (match_operand:DI 0 "register_operand" "=r")
15043         (unspec:DI [(match_operand:DI 1 "" "")] UNSPEC_SET_GOT_OFFSET))]
15044   "TARGET_64BIT"
15045   "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15046   [(set_attr "type" "imov")
15047    (set_attr "length" "11")])
15049 (define_expand "epilogue"
15050   [(const_int 0)]
15051   ""
15052   "ix86_expand_epilogue (1); DONE;")
15054 (define_expand "sibcall_epilogue"
15055   [(const_int 0)]
15056   ""
15057   "ix86_expand_epilogue (0); DONE;")
15059 (define_expand "eh_return"
15060   [(use (match_operand 0 "register_operand" ""))]
15061   ""
15063   rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15065   /* Tricky bit: we write the address of the handler to which we will
15066      be returning into someone else's stack frame, one word below the
15067      stack address we wish to restore.  */
15068   tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15069   tmp = plus_constant (tmp, -UNITS_PER_WORD);
15070   tmp = gen_rtx_MEM (Pmode, tmp);
15071   emit_move_insn (tmp, ra);
15073   if (Pmode == SImode)
15074     emit_jump_insn (gen_eh_return_si (sa));
15075   else
15076     emit_jump_insn (gen_eh_return_di (sa));
15077   emit_barrier ();
15078   DONE;
15081 (define_insn_and_split "eh_return_<mode>"
15082   [(set (pc)
15083         (unspec [(match_operand:P 0 "register_operand" "c")]
15084                  UNSPEC_EH_RETURN))]
15085   ""
15086   "#"
15087   "reload_completed"
15088   [(const_int 0)]
15089   "ix86_expand_epilogue (2); DONE;")
15091 (define_insn "leave"
15092   [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15093    (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
15094    (clobber (mem:BLK (scratch)))]
15095   "!TARGET_64BIT"
15096   "leave"
15097   [(set_attr "type" "leave")])
15099 (define_insn "leave_rex64"
15100   [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
15101    (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
15102    (clobber (mem:BLK (scratch)))]
15103   "TARGET_64BIT"
15104   "leave"
15105   [(set_attr "type" "leave")])
15107 (define_expand "ffssi2"
15108   [(parallel
15109      [(set (match_operand:SI 0 "register_operand" "")
15110            (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15111       (clobber (match_scratch:SI 2 ""))
15112       (clobber (reg:CC FLAGS_REG))])]
15113   ""
15115   if (TARGET_CMOVE)
15116     {
15117       emit_insn (gen_ffs_cmove (operands[0], operands[1]));
15118       DONE;
15119     }
15122 (define_expand "ffs_cmove"
15123   [(set (match_dup 2) (const_int -1))
15124    (parallel [(set (reg:CCZ FLAGS_REG)
15125                    (compare:CCZ (match_operand:SI 1 "register_operand" "")
15126                                 (const_int 0)))
15127               (set (match_operand:SI 0 "nonimmediate_operand" "")
15128                    (ctz:SI (match_dup 1)))])
15129    (set (match_dup 0) (if_then_else:SI
15130                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15131                         (match_dup 2)
15132                         (match_dup 0)))
15133    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15134               (clobber (reg:CC FLAGS_REG))])]
15135   "TARGET_CMOVE"
15136   "operands[2] = gen_reg_rtx (SImode);")
15138 (define_insn_and_split "*ffs_no_cmove"
15139   [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
15140         (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15141    (clobber (match_scratch:SI 2 "=&q"))
15142    (clobber (reg:CC FLAGS_REG))]
15143   "!TARGET_CMOVE"
15144   "#"
15145   "&& reload_completed"
15146   [(parallel [(set (reg:CCZ FLAGS_REG)
15147                    (compare:CCZ (match_dup 1) (const_int 0)))
15148               (set (match_dup 0) (ctz:SI (match_dup 1)))])
15149    (set (strict_low_part (match_dup 3))
15150         (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
15151    (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
15152               (clobber (reg:CC FLAGS_REG))])
15153    (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
15154               (clobber (reg:CC FLAGS_REG))])
15155    (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
15156               (clobber (reg:CC FLAGS_REG))])]
15158   operands[3] = gen_lowpart (QImode, operands[2]);
15159   ix86_expand_clear (operands[2]);
15162 (define_insn "*ffssi_1"
15163   [(set (reg:CCZ FLAGS_REG)
15164         (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
15165                      (const_int 0)))
15166    (set (match_operand:SI 0 "register_operand" "=r")
15167         (ctz:SI (match_dup 1)))]
15168   ""
15169   "bsf{l}\t{%1, %0|%0, %1}"
15170   [(set_attr "prefix_0f" "1")])
15172 (define_expand "ffsdi2"
15173   [(set (match_dup 2) (const_int -1))
15174    (parallel [(set (reg:CCZ FLAGS_REG)
15175                    (compare:CCZ (match_operand:DI 1 "register_operand" "")
15176                                 (const_int 0)))
15177               (set (match_operand:DI 0 "nonimmediate_operand" "")
15178                    (ctz:DI (match_dup 1)))])
15179    (set (match_dup 0) (if_then_else:DI
15180                         (eq (reg:CCZ FLAGS_REG) (const_int 0))
15181                         (match_dup 2)
15182                         (match_dup 0)))
15183    (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
15184               (clobber (reg:CC FLAGS_REG))])]
15185   "TARGET_64BIT"
15186   "operands[2] = gen_reg_rtx (DImode);")
15188 (define_insn "*ffsdi_1"
15189   [(set (reg:CCZ FLAGS_REG)
15190         (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
15191                      (const_int 0)))
15192    (set (match_operand:DI 0 "register_operand" "=r")
15193         (ctz:DI (match_dup 1)))]
15194   "TARGET_64BIT"
15195   "bsf{q}\t{%1, %0|%0, %1}"
15196   [(set_attr "prefix_0f" "1")])
15198 (define_insn "ctzsi2"
15199   [(set (match_operand:SI 0 "register_operand" "=r")
15200         (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
15201    (clobber (reg:CC FLAGS_REG))]
15202   ""
15203   "bsf{l}\t{%1, %0|%0, %1}"
15204   [(set_attr "prefix_0f" "1")])
15206 (define_insn "ctzdi2"
15207   [(set (match_operand:DI 0 "register_operand" "=r")
15208         (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15209    (clobber (reg:CC FLAGS_REG))]
15210   "TARGET_64BIT"
15211   "bsf{q}\t{%1, %0|%0, %1}"
15212   [(set_attr "prefix_0f" "1")])
15214 (define_expand "clzsi2"
15215   [(parallel
15216      [(set (match_operand:SI 0 "register_operand" "")
15217            (minus:SI (const_int 31)
15218                      (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
15219       (clobber (reg:CC FLAGS_REG))])
15220    (parallel
15221      [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
15222       (clobber (reg:CC FLAGS_REG))])]
15223   ""
15225   if (TARGET_ABM)
15226     {
15227       emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
15228       DONE;
15229     }
15232 (define_insn "clzsi2_abm"
15233   [(set (match_operand:SI 0 "register_operand" "=r")
15234         (clz:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15235    (clobber (reg:CC FLAGS_REG))]
15236   "TARGET_ABM"
15237   "lzcnt{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 "*bsr"
15243   [(set (match_operand:SI 0 "register_operand" "=r")
15244         (minus:SI (const_int 31)
15245                   (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
15246    (clobber (reg:CC FLAGS_REG))]
15247   ""
15248   "bsr{l}\t{%1, %0|%0, %1}"
15249   [(set_attr "prefix_0f" "1")
15250    (set_attr "mode" "SI")])
15252 (define_insn "popcountsi2"
15253   [(set (match_operand:SI 0 "register_operand" "=r")
15254         (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "")))
15255    (clobber (reg:CC FLAGS_REG))]
15256   "TARGET_POPCNT"
15257   "popcnt{l}\t{%1, %0|%0, %1}"
15258   [(set_attr "prefix_rep" "1")
15259    (set_attr "type" "bitmanip")
15260    (set_attr "mode" "SI")])
15262 (define_insn "*popcountsi2_cmp"
15263   [(set (reg FLAGS_REG)
15264         (compare
15265           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15266           (const_int 0)))
15267    (set (match_operand:SI 0 "register_operand" "=r")
15268         (popcount:SI (match_dup 1)))]
15269   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15270   "popcnt{l}\t{%1, %0|%0, %1}"
15271   [(set_attr "prefix_rep" "1")
15272    (set_attr "type" "bitmanip")
15273    (set_attr "mode" "SI")])
15275 (define_insn "*popcountsi2_cmp_zext"
15276   [(set (reg FLAGS_REG)
15277         (compare
15278           (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15279           (const_int 0)))
15280    (set (match_operand:DI 0 "register_operand" "=r")
15281         (zero_extend:DI(popcount:SI (match_dup 1))))]
15282   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15283   "popcnt{l}\t{%1, %0|%0, %1}"
15284   [(set_attr "prefix_rep" "1")
15285    (set_attr "type" "bitmanip")
15286    (set_attr "mode" "SI")])
15288 (define_expand "bswapsi2"
15289   [(set (match_operand:SI 0 "register_operand" "")
15290         (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15291   ""
15293   if (!TARGET_BSWAP)
15294     {
15295       rtx x = operands[0];
15297       emit_move_insn (x, operands[1]);
15298       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15299       emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15300       emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15301       DONE;
15302     }
15305 (define_insn "*bswapsi_1"
15306   [(set (match_operand:SI 0 "register_operand" "=r")
15307         (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15308   "TARGET_BSWAP"
15309   "bswap\t%0"
15310   [(set_attr "prefix_0f" "1")
15311    (set_attr "length" "2")])
15313 (define_insn "*bswaphi_lowpart_1"
15314   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15315         (bswap:HI (match_dup 0)))
15316    (clobber (reg:CC FLAGS_REG))]
15317   "TARGET_USE_XCHGB || optimize_size"
15318   "@
15319     xchg{b}\t{%h0, %b0|%b0, %h0}
15320     rol{w}\t{$8, %0|%0, 8}"
15321   [(set_attr "length" "2,4")
15322    (set_attr "mode" "QI,HI")])
15324 (define_insn "bswaphi_lowpart"
15325   [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15326         (bswap:HI (match_dup 0)))
15327    (clobber (reg:CC FLAGS_REG))]
15328   ""
15329   "rol{w}\t{$8, %0|%0, 8}"
15330   [(set_attr "length" "4")
15331    (set_attr "mode" "HI")])
15333 (define_insn "bswapdi2"
15334   [(set (match_operand:DI 0 "register_operand" "=r")
15335         (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15336   "TARGET_64BIT"
15337   "bswap\t%0"
15338   [(set_attr "prefix_0f" "1")
15339    (set_attr "length" "3")])
15341 (define_expand "clzdi2"
15342   [(parallel
15343      [(set (match_operand:DI 0 "register_operand" "")
15344            (minus:DI (const_int 63)
15345                      (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15346       (clobber (reg:CC FLAGS_REG))])
15347    (parallel
15348      [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15349       (clobber (reg:CC FLAGS_REG))])]
15350   "TARGET_64BIT"
15352   if (TARGET_ABM)
15353     {
15354       emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15355       DONE;
15356     }
15359 (define_insn "clzdi2_abm"
15360   [(set (match_operand:DI 0 "register_operand" "=r")
15361         (clz:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15362    (clobber (reg:CC FLAGS_REG))]
15363   "TARGET_64BIT && TARGET_ABM"
15364   "lzcnt{q}\t{%1, %0|%0, %1}"
15365   [(set_attr "prefix_rep" "1")
15366    (set_attr "type" "bitmanip")
15367    (set_attr "mode" "DI")])
15369 (define_insn "*bsr_rex64"
15370   [(set (match_operand:DI 0 "register_operand" "=r")
15371         (minus:DI (const_int 63)
15372                   (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15373    (clobber (reg:CC FLAGS_REG))]
15374   "TARGET_64BIT"
15375   "bsr{q}\t{%1, %0|%0, %1}"
15376   [(set_attr "prefix_0f" "1")
15377    (set_attr "mode" "DI")])
15379 (define_insn "popcountdi2"
15380   [(set (match_operand:DI 0 "register_operand" "=r")
15381         (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "")))
15382    (clobber (reg:CC FLAGS_REG))]
15383   "TARGET_64BIT && TARGET_POPCNT"
15384   "popcnt{q}\t{%1, %0|%0, %1}"
15385   [(set_attr "prefix_rep" "1")
15386    (set_attr "type" "bitmanip")
15387    (set_attr "mode" "DI")])
15389 (define_insn "*popcountdi2_cmp"
15390   [(set (reg FLAGS_REG)
15391         (compare
15392           (popcount:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))
15393           (const_int 0)))
15394    (set (match_operand:DI 0 "register_operand" "=r")
15395         (popcount:DI (match_dup 1)))]
15396   "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15397   "popcnt{q}\t{%1, %0|%0, %1}"
15398   [(set_attr "prefix_rep" "1")
15399    (set_attr "type" "bitmanip")
15400    (set_attr "mode" "DI")])
15402 (define_expand "clzhi2"
15403   [(parallel
15404      [(set (match_operand:HI 0 "register_operand" "")
15405            (minus:HI (const_int 15)
15406                      (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15407       (clobber (reg:CC FLAGS_REG))])
15408    (parallel
15409      [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15410       (clobber (reg:CC FLAGS_REG))])]
15411   ""
15413   if (TARGET_ABM)
15414     {
15415       emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15416       DONE;
15417     }
15420 (define_insn "clzhi2_abm"
15421   [(set (match_operand:HI 0 "register_operand" "=r")
15422         (clz:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15423    (clobber (reg:CC FLAGS_REG))]
15424   "TARGET_ABM"
15425   "lzcnt{w}\t{%1, %0|%0, %1}"
15426   [(set_attr "prefix_rep" "1")
15427    (set_attr "type" "bitmanip")
15428    (set_attr "mode" "HI")])
15430 (define_insn "*bsrhi"
15431   [(set (match_operand:HI 0 "register_operand" "=r")
15432         (minus:HI (const_int 15)
15433                   (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15434    (clobber (reg:CC FLAGS_REG))]
15435   ""
15436   "bsr{w}\t{%1, %0|%0, %1}"
15437   [(set_attr "prefix_0f" "1")
15438    (set_attr "mode" "HI")])
15440 (define_insn "popcounthi2"
15441   [(set (match_operand:HI 0 "register_operand" "=r")
15442         (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "")))
15443    (clobber (reg:CC FLAGS_REG))]
15444   "TARGET_POPCNT"
15445   "popcnt{w}\t{%1, %0|%0, %1}"
15446   [(set_attr "prefix_rep" "1")
15447    (set_attr "type" "bitmanip")
15448    (set_attr "mode" "HI")])
15450 (define_insn "*popcounthi2_cmp"
15451   [(set (reg FLAGS_REG)
15452         (compare
15453           (popcount:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))
15454           (const_int 0)))
15455    (set (match_operand:HI 0 "register_operand" "=r")
15456         (popcount:HI (match_dup 1)))]
15457   "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15458   "popcnt{w}\t{%1, %0|%0, %1}"
15459   [(set_attr "prefix_rep" "1")
15460    (set_attr "type" "bitmanip")
15461    (set_attr "mode" "HI")])
15463 (define_expand "paritydi2"
15464   [(set (match_operand:DI 0 "register_operand" "")
15465         (parity:DI (match_operand:DI 1 "register_operand" "")))]
15466   "! TARGET_POPCNT"
15468   rtx scratch = gen_reg_rtx (QImode);
15469   rtx cond;
15471   emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15472                                 NULL_RTX, operands[1]));
15474   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15475                          gen_rtx_REG (CCmode, FLAGS_REG),
15476                          const0_rtx);
15477   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15479   if (TARGET_64BIT)
15480     emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15481   else
15482     {
15483       rtx tmp = gen_reg_rtx (SImode);
15485       emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15486       emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15487     }
15488   DONE;
15491 (define_insn_and_split "paritydi2_cmp"
15492   [(set (reg:CC FLAGS_REG)
15493         (parity:CC (match_operand:DI 3 "register_operand" "0")))
15494    (clobber (match_scratch:DI 0 "=r"))
15495    (clobber (match_scratch:SI 1 "=&r"))
15496    (clobber (match_scratch:HI 2 "=Q"))]
15497   "! TARGET_POPCNT"
15498   "#"
15499   "&& reload_completed"
15500   [(parallel
15501      [(set (match_dup 1)
15502            (xor:SI (match_dup 1) (match_dup 4)))
15503       (clobber (reg:CC FLAGS_REG))])
15504    (parallel
15505      [(set (reg:CC FLAGS_REG)
15506            (parity:CC (match_dup 1)))
15507       (clobber (match_dup 1))
15508       (clobber (match_dup 2))])]
15510   operands[4] = gen_lowpart (SImode, operands[3]);
15512   if (TARGET_64BIT)
15513     {
15514       emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15515       emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15516     }
15517   else
15518     operands[1] = gen_highpart (SImode, operands[3]);
15521 (define_expand "paritysi2"
15522   [(set (match_operand:SI 0 "register_operand" "")
15523         (parity:SI (match_operand:SI 1 "register_operand" "")))]
15524   "! TARGET_POPCNT"
15526   rtx scratch = gen_reg_rtx (QImode);
15527   rtx cond;
15529   emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15531   cond = gen_rtx_fmt_ee (ORDERED, QImode,
15532                          gen_rtx_REG (CCmode, FLAGS_REG),
15533                          const0_rtx);
15534   emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15536   emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15537   DONE;
15540 (define_insn_and_split "paritysi2_cmp"
15541   [(set (reg:CC FLAGS_REG)
15542         (parity:CC (match_operand:SI 2 "register_operand" "0")))
15543    (clobber (match_scratch:SI 0 "=r"))
15544    (clobber (match_scratch:HI 1 "=&Q"))]
15545   "! TARGET_POPCNT"
15546   "#"
15547   "&& reload_completed"
15548   [(parallel
15549      [(set (match_dup 1)
15550            (xor:HI (match_dup 1) (match_dup 3)))
15551       (clobber (reg:CC FLAGS_REG))])
15552    (parallel
15553      [(set (reg:CC FLAGS_REG)
15554            (parity:CC (match_dup 1)))
15555       (clobber (match_dup 1))])]
15557   operands[3] = gen_lowpart (HImode, operands[2]);
15559   emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15560   emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15563 (define_insn "*parityhi2_cmp"
15564   [(set (reg:CC FLAGS_REG)
15565         (parity:CC (match_operand:HI 1 "register_operand" "0")))
15566    (clobber (match_scratch:HI 0 "=Q"))]
15567   "! TARGET_POPCNT"
15568   "xor{b}\t{%h0, %b0|%b0, %h0}"
15569   [(set_attr "length" "2")
15570    (set_attr "mode" "HI")])
15572 (define_insn "*parityqi2_cmp"
15573   [(set (reg:CC FLAGS_REG)
15574         (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15575   "! TARGET_POPCNT"
15576   "test{b}\t%0, %0"
15577   [(set_attr "length" "2")
15578    (set_attr "mode" "QI")])
15580 ;; Thread-local storage patterns for ELF.
15582 ;; Note that these code sequences must appear exactly as shown
15583 ;; in order to allow linker relaxation.
15585 (define_insn "*tls_global_dynamic_32_gnu"
15586   [(set (match_operand:SI 0 "register_operand" "=a")
15587         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15588                     (match_operand:SI 2 "tls_symbolic_operand" "")
15589                     (match_operand:SI 3 "call_insn_operand" "")]
15590                     UNSPEC_TLS_GD))
15591    (clobber (match_scratch:SI 4 "=d"))
15592    (clobber (match_scratch:SI 5 "=c"))
15593    (clobber (reg:CC FLAGS_REG))]
15594   "!TARGET_64BIT && TARGET_GNU_TLS"
15595   "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15596   [(set_attr "type" "multi")
15597    (set_attr "length" "12")])
15599 (define_insn "*tls_global_dynamic_32_sun"
15600   [(set (match_operand:SI 0 "register_operand" "=a")
15601         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15602                     (match_operand:SI 2 "tls_symbolic_operand" "")
15603                     (match_operand:SI 3 "call_insn_operand" "")]
15604                     UNSPEC_TLS_GD))
15605    (clobber (match_scratch:SI 4 "=d"))
15606    (clobber (match_scratch:SI 5 "=c"))
15607    (clobber (reg:CC FLAGS_REG))]
15608   "!TARGET_64BIT && TARGET_SUN_TLS"
15609   "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15610         push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15611   [(set_attr "type" "multi")
15612    (set_attr "length" "14")])
15614 (define_expand "tls_global_dynamic_32"
15615   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15616                    (unspec:SI
15617                     [(match_dup 2)
15618                      (match_operand:SI 1 "tls_symbolic_operand" "")
15619                      (match_dup 3)]
15620                     UNSPEC_TLS_GD))
15621               (clobber (match_scratch:SI 4 ""))
15622               (clobber (match_scratch:SI 5 ""))
15623               (clobber (reg:CC FLAGS_REG))])]
15624   ""
15626   if (flag_pic)
15627     operands[2] = pic_offset_table_rtx;
15628   else
15629     {
15630       operands[2] = gen_reg_rtx (Pmode);
15631       emit_insn (gen_set_got (operands[2]));
15632     }
15633   if (TARGET_GNU2_TLS)
15634     {
15635        emit_insn (gen_tls_dynamic_gnu2_32
15636                   (operands[0], operands[1], operands[2]));
15637        DONE;
15638     }
15639   operands[3] = ix86_tls_get_addr ();
15642 (define_insn "*tls_global_dynamic_64"
15643   [(set (match_operand:DI 0 "register_operand" "=a")
15644         (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15645                  (match_operand:DI 3 "" "")))
15646    (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15647               UNSPEC_TLS_GD)]
15648   "TARGET_64BIT"
15649   ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
15650   [(set_attr "type" "multi")
15651    (set_attr "length" "16")])
15653 (define_expand "tls_global_dynamic_64"
15654   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15655                    (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15656               (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15657                          UNSPEC_TLS_GD)])]
15658   ""
15660   if (TARGET_GNU2_TLS)
15661     {
15662        emit_insn (gen_tls_dynamic_gnu2_64
15663                   (operands[0], operands[1]));
15664        DONE;
15665     }
15666   operands[2] = ix86_tls_get_addr ();
15669 (define_insn "*tls_local_dynamic_base_32_gnu"
15670   [(set (match_operand:SI 0 "register_operand" "=a")
15671         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15672                     (match_operand:SI 2 "call_insn_operand" "")]
15673                    UNSPEC_TLS_LD_BASE))
15674    (clobber (match_scratch:SI 3 "=d"))
15675    (clobber (match_scratch:SI 4 "=c"))
15676    (clobber (reg:CC FLAGS_REG))]
15677   "!TARGET_64BIT && TARGET_GNU_TLS"
15678   "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15679   [(set_attr "type" "multi")
15680    (set_attr "length" "11")])
15682 (define_insn "*tls_local_dynamic_base_32_sun"
15683   [(set (match_operand:SI 0 "register_operand" "=a")
15684         (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15685                     (match_operand:SI 2 "call_insn_operand" "")]
15686                    UNSPEC_TLS_LD_BASE))
15687    (clobber (match_scratch:SI 3 "=d"))
15688    (clobber (match_scratch:SI 4 "=c"))
15689    (clobber (reg:CC FLAGS_REG))]
15690   "!TARGET_64BIT && TARGET_SUN_TLS"
15691   "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15692         push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15693   [(set_attr "type" "multi")
15694    (set_attr "length" "13")])
15696 (define_expand "tls_local_dynamic_base_32"
15697   [(parallel [(set (match_operand:SI 0 "register_operand" "")
15698                    (unspec:SI [(match_dup 1) (match_dup 2)]
15699                               UNSPEC_TLS_LD_BASE))
15700               (clobber (match_scratch:SI 3 ""))
15701               (clobber (match_scratch:SI 4 ""))
15702               (clobber (reg:CC FLAGS_REG))])]
15703   ""
15705   if (flag_pic)
15706     operands[1] = pic_offset_table_rtx;
15707   else
15708     {
15709       operands[1] = gen_reg_rtx (Pmode);
15710       emit_insn (gen_set_got (operands[1]));
15711     }
15712   if (TARGET_GNU2_TLS)
15713     {
15714        emit_insn (gen_tls_dynamic_gnu2_32
15715                   (operands[0], ix86_tls_module_base (), operands[1]));
15716        DONE;
15717     }
15718   operands[2] = ix86_tls_get_addr ();
15721 (define_insn "*tls_local_dynamic_base_64"
15722   [(set (match_operand:DI 0 "register_operand" "=a")
15723         (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15724                  (match_operand:DI 2 "" "")))
15725    (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15726   "TARGET_64BIT"
15727   "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15728   [(set_attr "type" "multi")
15729    (set_attr "length" "12")])
15731 (define_expand "tls_local_dynamic_base_64"
15732   [(parallel [(set (match_operand:DI 0 "register_operand" "")
15733                    (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15734               (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15735   ""
15737   if (TARGET_GNU2_TLS)
15738     {
15739        emit_insn (gen_tls_dynamic_gnu2_64
15740                   (operands[0], ix86_tls_module_base ()));
15741        DONE;
15742     }
15743   operands[1] = ix86_tls_get_addr ();
15746 ;; Local dynamic of a single variable is a lose.  Show combine how
15747 ;; to convert that back to global dynamic.
15749 (define_insn_and_split "*tls_local_dynamic_32_once"
15750   [(set (match_operand:SI 0 "register_operand" "=a")
15751         (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15752                              (match_operand:SI 2 "call_insn_operand" "")]
15753                             UNSPEC_TLS_LD_BASE)
15754                  (const:SI (unspec:SI
15755                             [(match_operand:SI 3 "tls_symbolic_operand" "")]
15756                             UNSPEC_DTPOFF))))
15757    (clobber (match_scratch:SI 4 "=d"))
15758    (clobber (match_scratch:SI 5 "=c"))
15759    (clobber (reg:CC FLAGS_REG))]
15760   ""
15761   "#"
15762   ""
15763   [(parallel [(set (match_dup 0)
15764                    (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15765                               UNSPEC_TLS_GD))
15766               (clobber (match_dup 4))
15767               (clobber (match_dup 5))
15768               (clobber (reg:CC FLAGS_REG))])]
15769   "")
15771 ;; Load and add the thread base pointer from %gs:0.
15773 (define_insn "*load_tp_si"
15774   [(set (match_operand:SI 0 "register_operand" "=r")
15775         (unspec:SI [(const_int 0)] UNSPEC_TP))]
15776   "!TARGET_64BIT"
15777   "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15778   [(set_attr "type" "imov")
15779    (set_attr "modrm" "0")
15780    (set_attr "length" "7")
15781    (set_attr "memory" "load")
15782    (set_attr "imm_disp" "false")])
15784 (define_insn "*add_tp_si"
15785   [(set (match_operand:SI 0 "register_operand" "=r")
15786         (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15787                  (match_operand:SI 1 "register_operand" "0")))
15788    (clobber (reg:CC FLAGS_REG))]
15789   "!TARGET_64BIT"
15790   "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15791   [(set_attr "type" "alu")
15792    (set_attr "modrm" "0")
15793    (set_attr "length" "7")
15794    (set_attr "memory" "load")
15795    (set_attr "imm_disp" "false")])
15797 (define_insn "*load_tp_di"
15798   [(set (match_operand:DI 0 "register_operand" "=r")
15799         (unspec:DI [(const_int 0)] UNSPEC_TP))]
15800   "TARGET_64BIT"
15801   "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15802   [(set_attr "type" "imov")
15803    (set_attr "modrm" "0")
15804    (set_attr "length" "7")
15805    (set_attr "memory" "load")
15806    (set_attr "imm_disp" "false")])
15808 (define_insn "*add_tp_di"
15809   [(set (match_operand:DI 0 "register_operand" "=r")
15810         (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15811                  (match_operand:DI 1 "register_operand" "0")))
15812    (clobber (reg:CC FLAGS_REG))]
15813   "TARGET_64BIT"
15814   "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15815   [(set_attr "type" "alu")
15816    (set_attr "modrm" "0")
15817    (set_attr "length" "7")
15818    (set_attr "memory" "load")
15819    (set_attr "imm_disp" "false")])
15821 ;; GNU2 TLS patterns can be split.
15823 (define_expand "tls_dynamic_gnu2_32"
15824   [(set (match_dup 3)
15825         (plus:SI (match_operand:SI 2 "register_operand" "")
15826                  (const:SI
15827                   (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15828                              UNSPEC_TLSDESC))))
15829    (parallel
15830     [(set (match_operand:SI 0 "register_operand" "")
15831           (unspec:SI [(match_dup 1) (match_dup 3)
15832                       (match_dup 2) (reg:SI SP_REG)]
15833                       UNSPEC_TLSDESC))
15834      (clobber (reg:CC FLAGS_REG))])]
15835   "!TARGET_64BIT && TARGET_GNU2_TLS"
15837   operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15838   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15841 (define_insn "*tls_dynamic_lea_32"
15842   [(set (match_operand:SI 0 "register_operand" "=r")
15843         (plus:SI (match_operand:SI 1 "register_operand" "b")
15844                  (const:SI
15845                   (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15846                               UNSPEC_TLSDESC))))]
15847   "!TARGET_64BIT && TARGET_GNU2_TLS"
15848   "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15849   [(set_attr "type" "lea")
15850    (set_attr "mode" "SI")
15851    (set_attr "length" "6")
15852    (set_attr "length_address" "4")])
15854 (define_insn "*tls_dynamic_call_32"
15855   [(set (match_operand:SI 0 "register_operand" "=a")
15856         (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15857                     (match_operand:SI 2 "register_operand" "0")
15858                     ;; we have to make sure %ebx still points to the GOT
15859                     (match_operand:SI 3 "register_operand" "b")
15860                     (reg:SI SP_REG)]
15861                    UNSPEC_TLSDESC))
15862    (clobber (reg:CC FLAGS_REG))]
15863   "!TARGET_64BIT && TARGET_GNU2_TLS"
15864   "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15865   [(set_attr "type" "call")
15866    (set_attr "length" "2")
15867    (set_attr "length_address" "0")])
15869 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15870   [(set (match_operand:SI 0 "register_operand" "=&a")
15871         (plus:SI
15872          (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15873                      (match_operand:SI 4 "" "")
15874                      (match_operand:SI 2 "register_operand" "b")
15875                      (reg:SI SP_REG)]
15876                     UNSPEC_TLSDESC)
15877          (const:SI (unspec:SI
15878                     [(match_operand:SI 1 "tls_symbolic_operand" "")]
15879                     UNSPEC_DTPOFF))))
15880    (clobber (reg:CC FLAGS_REG))]
15881   "!TARGET_64BIT && TARGET_GNU2_TLS"
15882   "#"
15883   ""
15884   [(set (match_dup 0) (match_dup 5))]
15886   operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15887   emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15890 (define_expand "tls_dynamic_gnu2_64"
15891   [(set (match_dup 2)
15892         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15893                    UNSPEC_TLSDESC))
15894    (parallel
15895     [(set (match_operand:DI 0 "register_operand" "")
15896           (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15897                      UNSPEC_TLSDESC))
15898      (clobber (reg:CC FLAGS_REG))])]
15899   "TARGET_64BIT && TARGET_GNU2_TLS"
15901   operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15902   ix86_tls_descriptor_calls_expanded_in_cfun = true;
15905 (define_insn "*tls_dynamic_lea_64"
15906   [(set (match_operand:DI 0 "register_operand" "=r")
15907         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15908                    UNSPEC_TLSDESC))]
15909   "TARGET_64BIT && TARGET_GNU2_TLS"
15910   "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15911   [(set_attr "type" "lea")
15912    (set_attr "mode" "DI")
15913    (set_attr "length" "7")
15914    (set_attr "length_address" "4")])
15916 (define_insn "*tls_dynamic_call_64"
15917   [(set (match_operand:DI 0 "register_operand" "=a")
15918         (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15919                     (match_operand:DI 2 "register_operand" "0")
15920                     (reg:DI SP_REG)]
15921                    UNSPEC_TLSDESC))
15922    (clobber (reg:CC FLAGS_REG))]
15923   "TARGET_64BIT && TARGET_GNU2_TLS"
15924   "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15925   [(set_attr "type" "call")
15926    (set_attr "length" "2")
15927    (set_attr "length_address" "0")])
15929 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15930   [(set (match_operand:DI 0 "register_operand" "=&a")
15931         (plus:DI
15932          (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15933                      (match_operand:DI 3 "" "")
15934                      (reg:DI SP_REG)]
15935                     UNSPEC_TLSDESC)
15936          (const:DI (unspec:DI
15937                     [(match_operand:DI 1 "tls_symbolic_operand" "")]
15938                     UNSPEC_DTPOFF))))
15939    (clobber (reg:CC FLAGS_REG))]
15940   "TARGET_64BIT && TARGET_GNU2_TLS"
15941   "#"
15942   ""
15943   [(set (match_dup 0) (match_dup 4))]
15945   operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
15946   emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15951 ;; These patterns match the binary 387 instructions for addM3, subM3,
15952 ;; mulM3 and divM3.  There are three patterns for each of DFmode and
15953 ;; SFmode.  The first is the normal insn, the second the same insn but
15954 ;; with one operand a conversion, and the third the same insn but with
15955 ;; the other operand a conversion.  The conversion may be SFmode or
15956 ;; SImode if the target mode DFmode, but only SImode if the target mode
15957 ;; is SFmode.
15959 ;; Gcc is slightly more smart about handling normal two address instructions
15960 ;; so use special patterns for add and mull.
15962 (define_insn "*fop_<mode>_comm_mixed"
15963   [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15964         (match_operator:MODEF 3 "binary_fp_operator"
15965           [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
15966            (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15967   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15968    && COMMUTATIVE_ARITH_P (operands[3])
15969    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15970   "* return output_387_binary_op (insn, operands);"
15971   [(set (attr "type")
15972         (if_then_else (eq_attr "alternative" "1")
15973            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15974               (const_string "ssemul")
15975               (const_string "sseadd"))
15976            (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15977               (const_string "fmul")
15978               (const_string "fop"))))
15979    (set_attr "mode" "<MODE>")])
15981 (define_insn "*fop_<mode>_comm_sse"
15982   [(set (match_operand:MODEF 0 "register_operand" "=x")
15983         (match_operator:MODEF 3 "binary_fp_operator"
15984           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15985            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15986   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15987    && COMMUTATIVE_ARITH_P (operands[3])
15988    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15989   "* return output_387_binary_op (insn, operands);"
15990   [(set (attr "type")
15991         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15992            (const_string "ssemul")
15993            (const_string "sseadd")))
15994    (set_attr "mode" "<MODE>")])
15996 (define_insn "*fop_<mode>_comm_i387"
15997   [(set (match_operand:MODEF 0 "register_operand" "=f")
15998         (match_operator:MODEF 3 "binary_fp_operator"
15999           [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16000            (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16001   "TARGET_80387
16002    && COMMUTATIVE_ARITH_P (operands[3])
16003    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16004   "* return output_387_binary_op (insn, operands);"
16005   [(set (attr "type")
16006         (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16007            (const_string "fmul")
16008            (const_string "fop")))
16009    (set_attr "mode" "<MODE>")])
16011 (define_insn "*fop_<mode>_1_mixed"
16012   [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16013         (match_operator:MODEF 3 "binary_fp_operator"
16014           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
16015            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16016   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16017    && !COMMUTATIVE_ARITH_P (operands[3])
16018    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16019   "* return output_387_binary_op (insn, operands);"
16020   [(set (attr "type")
16021         (cond [(and (eq_attr "alternative" "2")
16022                     (match_operand:MODEF 3 "mult_operator" ""))
16023                  (const_string "ssemul")
16024                (and (eq_attr "alternative" "2")
16025                     (match_operand:MODEF 3 "div_operator" ""))
16026                  (const_string "ssediv")
16027                (eq_attr "alternative" "2")
16028                  (const_string "sseadd")
16029                (match_operand:MODEF 3 "mult_operator" "")
16030                  (const_string "fmul")
16031                (match_operand:MODEF 3 "div_operator" "")
16032                  (const_string "fdiv")
16033               ]
16034               (const_string "fop")))
16035    (set_attr "mode" "<MODE>")])
16037 (define_insn "*rcpsf2_sse"
16038   [(set (match_operand:SF 0 "register_operand" "=x")
16039         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16040                    UNSPEC_RCP))]
16041   "TARGET_SSE_MATH"
16042   "rcpss\t{%1, %0|%0, %1}"
16043   [(set_attr "type" "sse")
16044    (set_attr "mode" "SF")])
16046 (define_insn "*fop_<mode>_1_sse"
16047   [(set (match_operand:MODEF 0 "register_operand" "=x")
16048         (match_operator:MODEF 3 "binary_fp_operator"
16049           [(match_operand:MODEF 1 "register_operand" "0")
16050            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16051   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16052    && !COMMUTATIVE_ARITH_P (operands[3])"
16053   "* return output_387_binary_op (insn, operands);"
16054   [(set (attr "type")
16055         (cond [(match_operand:MODEF 3 "mult_operator" "")
16056                  (const_string "ssemul")
16057                (match_operand:MODEF 3 "div_operator" "")
16058                  (const_string "ssediv")
16059               ]
16060               (const_string "sseadd")))
16061    (set_attr "mode" "<MODE>")])
16063 ;; This pattern is not fully shadowed by the pattern above.
16064 (define_insn "*fop_<mode>_1_i387"
16065   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16066         (match_operator:MODEF 3 "binary_fp_operator"
16067           [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
16068            (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
16069   "TARGET_80387 && !TARGET_SSE_MATH
16070    && !COMMUTATIVE_ARITH_P (operands[3])
16071    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16072   "* return output_387_binary_op (insn, operands);"
16073   [(set (attr "type")
16074         (cond [(match_operand:MODEF 3 "mult_operator" "")
16075                  (const_string "fmul")
16076                (match_operand:MODEF 3 "div_operator" "")
16077                  (const_string "fdiv")
16078               ]
16079               (const_string "fop")))
16080    (set_attr "mode" "<MODE>")])
16082 ;; ??? Add SSE splitters for these!
16083 (define_insn "*fop_<MODEF:mode>_2_i387"
16084   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16085         (match_operator:MODEF 3 "binary_fp_operator"
16086           [(float:MODEF
16087              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16088            (match_operand:MODEF 2 "register_operand" "0,0")]))]
16089   "TARGET_80387 && !TARGET_SSE_MATH
16090    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_size)"
16091   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16092   [(set (attr "type")
16093         (cond [(match_operand:MODEF 3 "mult_operator" "")
16094                  (const_string "fmul")
16095                (match_operand:MODEF 3 "div_operator" "")
16096                  (const_string "fdiv")
16097               ]
16098               (const_string "fop")))
16099    (set_attr "fp_int_src" "true")
16100    (set_attr "mode" "<X87MODEI12:MODE>")])
16102 (define_insn "*fop_<MODEF:mode>_3_i387"
16103   [(set (match_operand:MODEF 0 "register_operand" "=f,f")
16104         (match_operator:MODEF 3 "binary_fp_operator"
16105           [(match_operand:MODEF 1 "register_operand" "0,0")
16106            (float:MODEF
16107              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16108   "TARGET_80387 && !TARGET_SSE_MATH
16109    && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_size)"
16110   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16111   [(set (attr "type")
16112         (cond [(match_operand:MODEF 3 "mult_operator" "")
16113                  (const_string "fmul")
16114                (match_operand:MODEF 3 "div_operator" "")
16115                  (const_string "fdiv")
16116               ]
16117               (const_string "fop")))
16118    (set_attr "fp_int_src" "true")
16119    (set_attr "mode" "<MODE>")])
16121 (define_insn "*fop_df_4_i387"
16122   [(set (match_operand:DF 0 "register_operand" "=f,f")
16123         (match_operator:DF 3 "binary_fp_operator"
16124            [(float_extend:DF
16125              (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
16126             (match_operand:DF 2 "register_operand" "0,f")]))]
16127   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)
16128    && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16129   "* return output_387_binary_op (insn, operands);"
16130   [(set (attr "type")
16131         (cond [(match_operand:DF 3 "mult_operator" "")
16132                  (const_string "fmul")
16133                (match_operand:DF 3 "div_operator" "")
16134                  (const_string "fdiv")
16135               ]
16136               (const_string "fop")))
16137    (set_attr "mode" "SF")])
16139 (define_insn "*fop_df_5_i387"
16140   [(set (match_operand:DF 0 "register_operand" "=f,f")
16141         (match_operator:DF 3 "binary_fp_operator"
16142           [(match_operand:DF 1 "register_operand" "0,f")
16143            (float_extend:DF
16144             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16145   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16146   "* return output_387_binary_op (insn, operands);"
16147   [(set (attr "type")
16148         (cond [(match_operand:DF 3 "mult_operator" "")
16149                  (const_string "fmul")
16150                (match_operand:DF 3 "div_operator" "")
16151                  (const_string "fdiv")
16152               ]
16153               (const_string "fop")))
16154    (set_attr "mode" "SF")])
16156 (define_insn "*fop_df_6_i387"
16157   [(set (match_operand:DF 0 "register_operand" "=f,f")
16158         (match_operator:DF 3 "binary_fp_operator"
16159           [(float_extend:DF
16160             (match_operand:SF 1 "register_operand" "0,f"))
16161            (float_extend:DF
16162             (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
16163   "TARGET_80387 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
16164   "* return output_387_binary_op (insn, operands);"
16165   [(set (attr "type")
16166         (cond [(match_operand:DF 3 "mult_operator" "")
16167                  (const_string "fmul")
16168                (match_operand:DF 3 "div_operator" "")
16169                  (const_string "fdiv")
16170               ]
16171               (const_string "fop")))
16172    (set_attr "mode" "SF")])
16174 (define_insn "*fop_xf_comm_i387"
16175   [(set (match_operand:XF 0 "register_operand" "=f")
16176         (match_operator:XF 3 "binary_fp_operator"
16177                         [(match_operand:XF 1 "register_operand" "%0")
16178                          (match_operand:XF 2 "register_operand" "f")]))]
16179   "TARGET_80387
16180    && COMMUTATIVE_ARITH_P (operands[3])"
16181   "* return output_387_binary_op (insn, operands);"
16182   [(set (attr "type")
16183         (if_then_else (match_operand:XF 3 "mult_operator" "")
16184            (const_string "fmul")
16185            (const_string "fop")))
16186    (set_attr "mode" "XF")])
16188 (define_insn "*fop_xf_1_i387"
16189   [(set (match_operand:XF 0 "register_operand" "=f,f")
16190         (match_operator:XF 3 "binary_fp_operator"
16191                         [(match_operand:XF 1 "register_operand" "0,f")
16192                          (match_operand:XF 2 "register_operand" "f,0")]))]
16193   "TARGET_80387
16194    && !COMMUTATIVE_ARITH_P (operands[3])"
16195   "* return output_387_binary_op (insn, operands);"
16196   [(set (attr "type")
16197         (cond [(match_operand:XF 3 "mult_operator" "")
16198                  (const_string "fmul")
16199                (match_operand:XF 3 "div_operator" "")
16200                  (const_string "fdiv")
16201               ]
16202               (const_string "fop")))
16203    (set_attr "mode" "XF")])
16205 (define_insn "*fop_xf_2_i387"
16206   [(set (match_operand:XF 0 "register_operand" "=f,f")
16207         (match_operator:XF 3 "binary_fp_operator"
16208           [(float:XF
16209              (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16210            (match_operand:XF 2 "register_operand" "0,0")]))]
16211   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)"
16212   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16213   [(set (attr "type")
16214         (cond [(match_operand:XF 3 "mult_operator" "")
16215                  (const_string "fmul")
16216                (match_operand:XF 3 "div_operator" "")
16217                  (const_string "fdiv")
16218               ]
16219               (const_string "fop")))
16220    (set_attr "fp_int_src" "true")
16221    (set_attr "mode" "<MODE>")])
16223 (define_insn "*fop_xf_3_i387"
16224   [(set (match_operand:XF 0 "register_operand" "=f,f")
16225         (match_operator:XF 3 "binary_fp_operator"
16226           [(match_operand:XF 1 "register_operand" "0,0")
16227            (float:XF
16228              (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16229   "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_size)"
16230   "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16231   [(set (attr "type")
16232         (cond [(match_operand:XF 3 "mult_operator" "")
16233                  (const_string "fmul")
16234                (match_operand:XF 3 "div_operator" "")
16235                  (const_string "fdiv")
16236               ]
16237               (const_string "fop")))
16238    (set_attr "fp_int_src" "true")
16239    (set_attr "mode" "<MODE>")])
16241 (define_insn "*fop_xf_4_i387"
16242   [(set (match_operand:XF 0 "register_operand" "=f,f")
16243         (match_operator:XF 3 "binary_fp_operator"
16244            [(float_extend:XF
16245               (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16246             (match_operand:XF 2 "register_operand" "0,f")]))]
16247   "TARGET_80387"
16248   "* return output_387_binary_op (insn, operands);"
16249   [(set (attr "type")
16250         (cond [(match_operand:XF 3 "mult_operator" "")
16251                  (const_string "fmul")
16252                (match_operand:XF 3 "div_operator" "")
16253                  (const_string "fdiv")
16254               ]
16255               (const_string "fop")))
16256    (set_attr "mode" "<MODE>")])
16258 (define_insn "*fop_xf_5_i387"
16259   [(set (match_operand:XF 0 "register_operand" "=f,f")
16260         (match_operator:XF 3 "binary_fp_operator"
16261           [(match_operand:XF 1 "register_operand" "0,f")
16262            (float_extend:XF
16263              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16264   "TARGET_80387"
16265   "* return output_387_binary_op (insn, operands);"
16266   [(set (attr "type")
16267         (cond [(match_operand:XF 3 "mult_operator" "")
16268                  (const_string "fmul")
16269                (match_operand:XF 3 "div_operator" "")
16270                  (const_string "fdiv")
16271               ]
16272               (const_string "fop")))
16273    (set_attr "mode" "<MODE>")])
16275 (define_insn "*fop_xf_6_i387"
16276   [(set (match_operand:XF 0 "register_operand" "=f,f")
16277         (match_operator:XF 3 "binary_fp_operator"
16278           [(float_extend:XF
16279              (match_operand:MODEF 1 "register_operand" "0,f"))
16280            (float_extend:XF
16281              (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16282   "TARGET_80387"
16283   "* return output_387_binary_op (insn, operands);"
16284   [(set (attr "type")
16285         (cond [(match_operand:XF 3 "mult_operator" "")
16286                  (const_string "fmul")
16287                (match_operand:XF 3 "div_operator" "")
16288                  (const_string "fdiv")
16289               ]
16290               (const_string "fop")))
16291    (set_attr "mode" "<MODE>")])
16293 (define_split
16294   [(set (match_operand 0 "register_operand" "")
16295         (match_operator 3 "binary_fp_operator"
16296            [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16297             (match_operand 2 "register_operand" "")]))]
16298   "reload_completed
16299    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16300   [(const_int 0)]
16302   operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16303   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16304   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16305                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16306                                           GET_MODE (operands[3]),
16307                                           operands[4],
16308                                           operands[2])));
16309   ix86_free_from_memory (GET_MODE (operands[1]));
16310   DONE;
16313 (define_split
16314   [(set (match_operand 0 "register_operand" "")
16315         (match_operator 3 "binary_fp_operator"
16316            [(match_operand 1 "register_operand" "")
16317             (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16318   "reload_completed
16319    && X87_FLOAT_MODE_P (GET_MODE (operands[0]))"
16320   [(const_int 0)]
16322   operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16323   operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16324   emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16325                           gen_rtx_fmt_ee (GET_CODE (operands[3]),
16326                                           GET_MODE (operands[3]),
16327                                           operands[1],
16328                                           operands[4])));
16329   ix86_free_from_memory (GET_MODE (operands[2]));
16330   DONE;
16333 ;; FPU special functions.
16335 ;; This pattern implements a no-op XFmode truncation for
16336 ;; all fancy i386 XFmode math functions.
16338 (define_insn "truncxf<mode>2_i387_noop_unspec"
16339   [(set (match_operand:MODEF 0 "register_operand" "=f")
16340         (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16341         UNSPEC_TRUNC_NOOP))]
16342   "TARGET_USE_FANCY_MATH_387"
16343   "* return output_387_reg_move (insn, operands);"
16344   [(set_attr "type" "fmov")
16345    (set_attr "mode" "<MODE>")])
16347 (define_insn "sqrtxf2"
16348   [(set (match_operand:XF 0 "register_operand" "=f")
16349         (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16350   "TARGET_USE_FANCY_MATH_387"
16351   "fsqrt"
16352   [(set_attr "type" "fpspc")
16353    (set_attr "mode" "XF")
16354    (set_attr "athlon_decode" "direct")
16355    (set_attr "amdfam10_decode" "direct")])
16357 (define_insn "sqrt_extend<mode>xf2_i387"
16358   [(set (match_operand:XF 0 "register_operand" "=f")
16359         (sqrt:XF
16360           (float_extend:XF
16361             (match_operand:MODEF 1 "register_operand" "0"))))]
16362   "TARGET_USE_FANCY_MATH_387"
16363   "fsqrt"
16364   [(set_attr "type" "fpspc")
16365    (set_attr "mode" "XF")
16366    (set_attr "athlon_decode" "direct")
16367    (set_attr "amdfam10_decode" "direct")])
16369 (define_insn "*rsqrtsf2_sse"
16370   [(set (match_operand:SF 0 "register_operand" "=x")
16371         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16372                    UNSPEC_RSQRT))]
16373   "TARGET_SSE_MATH"
16374   "rsqrtss\t{%1, %0|%0, %1}"
16375   [(set_attr "type" "sse")
16376    (set_attr "mode" "SF")])
16378 (define_expand "rsqrtsf2"
16379   [(set (match_operand:SF 0 "register_operand" "")
16380         (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16381                    UNSPEC_RSQRT))]
16382   "TARGET_SSE_MATH"
16384   ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16385   DONE;
16388 (define_insn "*sqrt<mode>2_sse"
16389   [(set (match_operand:MODEF 0 "register_operand" "=x")
16390         (sqrt:MODEF
16391           (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16392   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16393   "sqrts<ssemodefsuffix>\t{%1, %0|%0, %1}"
16394   [(set_attr "type" "sse")
16395    (set_attr "mode" "<MODE>")
16396    (set_attr "athlon_decode" "*")
16397    (set_attr "amdfam10_decode" "*")])
16399 (define_expand "sqrt<mode>2"
16400   [(set (match_operand:MODEF 0 "register_operand" "")
16401         (sqrt:MODEF
16402           (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16403   "TARGET_USE_FANCY_MATH_387
16404    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16406   if (<MODE>mode == SFmode
16407       && TARGET_SSE_MATH && TARGET_RECIP && !optimize_size
16408       && flag_finite_math_only && !flag_trapping_math
16409       && flag_unsafe_math_optimizations)
16410     {
16411       ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16412       DONE;
16413     }
16415   if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16416     {
16417       rtx op0 = gen_reg_rtx (XFmode);
16418       rtx op1 = force_reg (<MODE>mode, operands[1]);
16420       emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16421       emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16422       DONE;
16423    }
16426 (define_insn "fpremxf4_i387"
16427   [(set (match_operand:XF 0 "register_operand" "=f")
16428         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16429                     (match_operand:XF 3 "register_operand" "1")]
16430                    UNSPEC_FPREM_F))
16431    (set (match_operand:XF 1 "register_operand" "=u")
16432         (unspec:XF [(match_dup 2) (match_dup 3)]
16433                    UNSPEC_FPREM_U))
16434    (set (reg:CCFP FPSR_REG)
16435         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16436                      UNSPEC_C2_FLAG))]
16437   "TARGET_USE_FANCY_MATH_387"
16438   "fprem"
16439   [(set_attr "type" "fpspc")
16440    (set_attr "mode" "XF")])
16442 (define_expand "fmodxf3"
16443   [(use (match_operand:XF 0 "register_operand" ""))
16444    (use (match_operand:XF 1 "general_operand" ""))
16445    (use (match_operand:XF 2 "general_operand" ""))]
16446   "TARGET_USE_FANCY_MATH_387"
16448   rtx label = gen_label_rtx ();
16450   rtx op1 = gen_reg_rtx (XFmode);
16451   rtx op2 = gen_reg_rtx (XFmode);
16453   emit_move_insn (op1, operands[1]);
16454   emit_move_insn (op2, operands[2]);
16456   emit_label (label);
16457   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16458   ix86_emit_fp_unordered_jump (label);
16459   LABEL_NUSES (label) = 1;
16461   emit_move_insn (operands[0], op1);
16462   DONE;
16465 (define_expand "fmod<mode>3"
16466   [(use (match_operand:MODEF 0 "register_operand" ""))
16467    (use (match_operand:MODEF 1 "general_operand" ""))
16468    (use (match_operand:MODEF 2 "general_operand" ""))]
16469   "TARGET_USE_FANCY_MATH_387"
16471   rtx label = gen_label_rtx ();
16473   rtx op1 = gen_reg_rtx (XFmode);
16474   rtx op2 = gen_reg_rtx (XFmode);
16476   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16477   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16479   emit_label (label);
16480   emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16481   ix86_emit_fp_unordered_jump (label);
16482   LABEL_NUSES (label) = 1;
16484   /* Truncate the result properly for strict SSE math.  */
16485   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16486       && !TARGET_MIX_SSE_I387)
16487     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16488   else
16489     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16491   DONE;
16494 (define_insn "fprem1xf4_i387"
16495   [(set (match_operand:XF 0 "register_operand" "=f")
16496         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16497                     (match_operand:XF 3 "register_operand" "1")]
16498                    UNSPEC_FPREM1_F))
16499    (set (match_operand:XF 1 "register_operand" "=u")
16500         (unspec:XF [(match_dup 2) (match_dup 3)]
16501                    UNSPEC_FPREM1_U))
16502    (set (reg:CCFP FPSR_REG)
16503         (unspec:CCFP [(match_dup 2) (match_dup 3)]
16504                      UNSPEC_C2_FLAG))]
16505   "TARGET_USE_FANCY_MATH_387"
16506   "fprem1"
16507   [(set_attr "type" "fpspc")
16508    (set_attr "mode" "XF")])
16510 (define_expand "remainderxf3"
16511   [(use (match_operand:XF 0 "register_operand" ""))
16512    (use (match_operand:XF 1 "general_operand" ""))
16513    (use (match_operand:XF 2 "general_operand" ""))]
16514   "TARGET_USE_FANCY_MATH_387"
16516   rtx label = gen_label_rtx ();
16518   rtx op1 = gen_reg_rtx (XFmode);
16519   rtx op2 = gen_reg_rtx (XFmode);
16521   emit_move_insn (op1, operands[1]);
16522   emit_move_insn (op2, operands[2]);
16524   emit_label (label);
16525   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16526   ix86_emit_fp_unordered_jump (label);
16527   LABEL_NUSES (label) = 1;
16529   emit_move_insn (operands[0], op1);
16530   DONE;
16533 (define_expand "remainder<mode>3"
16534   [(use (match_operand:MODEF 0 "register_operand" ""))
16535    (use (match_operand:MODEF 1 "general_operand" ""))
16536    (use (match_operand:MODEF 2 "general_operand" ""))]
16537   "TARGET_USE_FANCY_MATH_387"
16539   rtx label = gen_label_rtx ();
16541   rtx op1 = gen_reg_rtx (XFmode);
16542   rtx op2 = gen_reg_rtx (XFmode);
16544   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16545   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16547   emit_label (label);
16549   emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16550   ix86_emit_fp_unordered_jump (label);
16551   LABEL_NUSES (label) = 1;
16553   /* Truncate the result properly for strict SSE math.  */
16554   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16555       && !TARGET_MIX_SSE_I387)
16556     emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16557   else
16558     emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16560   DONE;
16563 (define_insn "*sinxf2_i387"
16564   [(set (match_operand:XF 0 "register_operand" "=f")
16565         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16566   "TARGET_USE_FANCY_MATH_387
16567    && flag_unsafe_math_optimizations"
16568   "fsin"
16569   [(set_attr "type" "fpspc")
16570    (set_attr "mode" "XF")])
16572 (define_insn "*sin_extend<mode>xf2_i387"
16573   [(set (match_operand:XF 0 "register_operand" "=f")
16574         (unspec:XF [(float_extend:XF
16575                       (match_operand:MODEF 1 "register_operand" "0"))]
16576                    UNSPEC_SIN))]
16577   "TARGET_USE_FANCY_MATH_387
16578    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16579        || TARGET_MIX_SSE_I387)
16580    && flag_unsafe_math_optimizations"
16581   "fsin"
16582   [(set_attr "type" "fpspc")
16583    (set_attr "mode" "XF")])
16585 (define_insn "*cosxf2_i387"
16586   [(set (match_operand:XF 0 "register_operand" "=f")
16587         (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16588   "TARGET_USE_FANCY_MATH_387
16589    && flag_unsafe_math_optimizations"
16590   "fcos"
16591   [(set_attr "type" "fpspc")
16592    (set_attr "mode" "XF")])
16594 (define_insn "*cos_extend<mode>xf2_i387"
16595   [(set (match_operand:XF 0 "register_operand" "=f")
16596         (unspec:XF [(float_extend:XF
16597                       (match_operand:MODEF 1 "register_operand" "0"))]
16598                    UNSPEC_COS))]
16599   "TARGET_USE_FANCY_MATH_387
16600    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16601        || TARGET_MIX_SSE_I387)
16602    && flag_unsafe_math_optimizations"
16603   "fcos"
16604   [(set_attr "type" "fpspc")
16605    (set_attr "mode" "XF")])
16607 ;; When sincos pattern is defined, sin and cos builtin functions will be
16608 ;; expanded to sincos pattern with one of its outputs left unused.
16609 ;; CSE pass will figure out if two sincos patterns can be combined,
16610 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16611 ;; depending on the unused output.
16613 (define_insn "sincosxf3"
16614   [(set (match_operand:XF 0 "register_operand" "=f")
16615         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16616                    UNSPEC_SINCOS_COS))
16617    (set (match_operand:XF 1 "register_operand" "=u")
16618         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16619   "TARGET_USE_FANCY_MATH_387
16620    && flag_unsafe_math_optimizations"
16621   "fsincos"
16622   [(set_attr "type" "fpspc")
16623    (set_attr "mode" "XF")])
16625 (define_split
16626   [(set (match_operand:XF 0 "register_operand" "")
16627         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16628                    UNSPEC_SINCOS_COS))
16629    (set (match_operand:XF 1 "register_operand" "")
16630         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16631   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16632    && !(reload_completed || reload_in_progress)"
16633   [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16634   "")
16636 (define_split
16637   [(set (match_operand:XF 0 "register_operand" "")
16638         (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16639                    UNSPEC_SINCOS_COS))
16640    (set (match_operand:XF 1 "register_operand" "")
16641         (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16642   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16643    && !(reload_completed || reload_in_progress)"
16644   [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16645   "")
16647 (define_insn "sincos_extend<mode>xf3_i387"
16648   [(set (match_operand:XF 0 "register_operand" "=f")
16649         (unspec:XF [(float_extend:XF
16650                       (match_operand:MODEF 2 "register_operand" "0"))]
16651                    UNSPEC_SINCOS_COS))
16652    (set (match_operand:XF 1 "register_operand" "=u")
16653         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16654   "TARGET_USE_FANCY_MATH_387
16655    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16656        || TARGET_MIX_SSE_I387)
16657    && flag_unsafe_math_optimizations"
16658   "fsincos"
16659   [(set_attr "type" "fpspc")
16660    (set_attr "mode" "XF")])
16662 (define_split
16663   [(set (match_operand:XF 0 "register_operand" "")
16664         (unspec:XF [(float_extend:XF
16665                       (match_operand:MODEF 2 "register_operand" ""))]
16666                    UNSPEC_SINCOS_COS))
16667    (set (match_operand:XF 1 "register_operand" "")
16668         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16669   "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16670    && !(reload_completed || reload_in_progress)"
16671   [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16672   "")
16674 (define_split
16675   [(set (match_operand:XF 0 "register_operand" "")
16676         (unspec:XF [(float_extend:XF
16677                       (match_operand:MODEF 2 "register_operand" ""))]
16678                    UNSPEC_SINCOS_COS))
16679    (set (match_operand:XF 1 "register_operand" "")
16680         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16681   "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16682    && !(reload_completed || reload_in_progress)"
16683   [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16684   "")
16686 (define_expand "sincos<mode>3"
16687   [(use (match_operand:MODEF 0 "register_operand" ""))
16688    (use (match_operand:MODEF 1 "register_operand" ""))
16689    (use (match_operand:MODEF 2 "register_operand" ""))]
16690   "TARGET_USE_FANCY_MATH_387
16691    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16692        || TARGET_MIX_SSE_I387)
16693    && flag_unsafe_math_optimizations"
16695   rtx op0 = gen_reg_rtx (XFmode);
16696   rtx op1 = gen_reg_rtx (XFmode);
16698   emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16699   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16700   emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16701   DONE;
16704 (define_insn "fptanxf4_i387"
16705   [(set (match_operand:XF 0 "register_operand" "=f")
16706         (match_operand:XF 3 "const_double_operand" "F"))
16707    (set (match_operand:XF 1 "register_operand" "=u")
16708         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16709                    UNSPEC_TAN))]
16710   "TARGET_USE_FANCY_MATH_387
16711    && flag_unsafe_math_optimizations
16712    && standard_80387_constant_p (operands[3]) == 2"
16713   "fptan"
16714   [(set_attr "type" "fpspc")
16715    (set_attr "mode" "XF")])
16717 (define_insn "fptan_extend<mode>xf4_i387"
16718   [(set (match_operand:MODEF 0 "register_operand" "=f")
16719         (match_operand:MODEF 3 "const_double_operand" "F"))
16720    (set (match_operand:XF 1 "register_operand" "=u")
16721         (unspec:XF [(float_extend:XF
16722                       (match_operand:MODEF 2 "register_operand" "0"))]
16723                    UNSPEC_TAN))]
16724   "TARGET_USE_FANCY_MATH_387
16725    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16726        || TARGET_MIX_SSE_I387)
16727    && flag_unsafe_math_optimizations
16728    && standard_80387_constant_p (operands[3]) == 2"
16729   "fptan"
16730   [(set_attr "type" "fpspc")
16731    (set_attr "mode" "XF")])
16733 (define_expand "tanxf2"
16734   [(use (match_operand:XF 0 "register_operand" ""))
16735    (use (match_operand:XF 1 "register_operand" ""))]
16736   "TARGET_USE_FANCY_MATH_387
16737    && flag_unsafe_math_optimizations"
16739   rtx one = gen_reg_rtx (XFmode);
16740   rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16742   emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16743   DONE;
16746 (define_expand "tan<mode>2"
16747   [(use (match_operand:MODEF 0 "register_operand" ""))
16748    (use (match_operand:MODEF 1 "register_operand" ""))]
16749   "TARGET_USE_FANCY_MATH_387
16750    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16751        || TARGET_MIX_SSE_I387)
16752    && flag_unsafe_math_optimizations"
16754   rtx op0 = gen_reg_rtx (XFmode);
16756   rtx one = gen_reg_rtx (<MODE>mode);
16757   rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16759   emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16760                                              operands[1], op2));
16761   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16762   DONE;
16765 (define_insn "*fpatanxf3_i387"
16766   [(set (match_operand:XF 0 "register_operand" "=f")
16767         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16768                     (match_operand:XF 2 "register_operand" "u")]
16769                    UNSPEC_FPATAN))
16770    (clobber (match_scratch:XF 3 "=2"))]
16771   "TARGET_USE_FANCY_MATH_387
16772    && flag_unsafe_math_optimizations"
16773   "fpatan"
16774   [(set_attr "type" "fpspc")
16775    (set_attr "mode" "XF")])
16777 (define_insn "fpatan_extend<mode>xf3_i387"
16778   [(set (match_operand:XF 0 "register_operand" "=f")
16779         (unspec:XF [(float_extend:XF
16780                       (match_operand:MODEF 1 "register_operand" "0"))
16781                     (float_extend:XF
16782                       (match_operand:MODEF 2 "register_operand" "u"))]
16783                    UNSPEC_FPATAN))
16784    (clobber (match_scratch:XF 3 "=2"))]
16785   "TARGET_USE_FANCY_MATH_387
16786    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16787        || TARGET_MIX_SSE_I387)
16788    && flag_unsafe_math_optimizations"
16789   "fpatan"
16790   [(set_attr "type" "fpspc")
16791    (set_attr "mode" "XF")])
16793 (define_expand "atan2xf3"
16794   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16795                    (unspec:XF [(match_operand:XF 2 "register_operand" "")
16796                                (match_operand:XF 1 "register_operand" "")]
16797                               UNSPEC_FPATAN))
16798               (clobber (match_scratch:XF 3 ""))])]
16799   "TARGET_USE_FANCY_MATH_387
16800    && flag_unsafe_math_optimizations"
16801   "")
16803 (define_expand "atan2<mode>3"
16804   [(use (match_operand:MODEF 0 "register_operand" ""))
16805    (use (match_operand:MODEF 1 "register_operand" ""))
16806    (use (match_operand:MODEF 2 "register_operand" ""))]
16807   "TARGET_USE_FANCY_MATH_387
16808    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16809        || TARGET_MIX_SSE_I387)
16810    && flag_unsafe_math_optimizations"
16812   rtx op0 = gen_reg_rtx (XFmode);
16814   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16815   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16816   DONE;
16819 (define_expand "atanxf2"
16820   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16821                    (unspec:XF [(match_dup 2)
16822                                (match_operand:XF 1 "register_operand" "")]
16823                               UNSPEC_FPATAN))
16824               (clobber (match_scratch:XF 3 ""))])]
16825   "TARGET_USE_FANCY_MATH_387
16826    && flag_unsafe_math_optimizations"
16828   operands[2] = gen_reg_rtx (XFmode);
16829   emit_move_insn (operands[2], CONST1_RTX (XFmode));  /* fld1 */
16832 (define_expand "atan<mode>2"
16833   [(use (match_operand:MODEF 0 "register_operand" ""))
16834    (use (match_operand:MODEF 1 "register_operand" ""))]
16835   "TARGET_USE_FANCY_MATH_387
16836    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16837        || TARGET_MIX_SSE_I387)
16838    && flag_unsafe_math_optimizations"
16840   rtx op0 = gen_reg_rtx (XFmode);
16842   rtx op2 = gen_reg_rtx (<MODE>mode);
16843   emit_move_insn (op2, CONST1_RTX (<MODE>mode));  /* fld1 */
16845   emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16846   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16847   DONE;
16850 (define_expand "asinxf2"
16851   [(set (match_dup 2)
16852         (mult:XF (match_operand:XF 1 "register_operand" "")
16853                  (match_dup 1)))
16854    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16855    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16856    (parallel [(set (match_operand:XF 0 "register_operand" "")
16857                    (unspec:XF [(match_dup 5) (match_dup 1)]
16858                               UNSPEC_FPATAN))
16859               (clobber (match_scratch:XF 6 ""))])]
16860   "TARGET_USE_FANCY_MATH_387
16861    && flag_unsafe_math_optimizations && !optimize_size"
16863   int i;
16865   for (i = 2; i < 6; i++)
16866     operands[i] = gen_reg_rtx (XFmode);
16868   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16871 (define_expand "asin<mode>2"
16872   [(use (match_operand:MODEF 0 "register_operand" ""))
16873    (use (match_operand:MODEF 1 "general_operand" ""))]
16874  "TARGET_USE_FANCY_MATH_387
16875    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16876        || TARGET_MIX_SSE_I387)
16877    && flag_unsafe_math_optimizations && !optimize_size"
16879   rtx op0 = gen_reg_rtx (XFmode);
16880   rtx op1 = gen_reg_rtx (XFmode);
16882   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16883   emit_insn (gen_asinxf2 (op0, op1));
16884   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16885   DONE;
16888 (define_expand "acosxf2"
16889   [(set (match_dup 2)
16890         (mult:XF (match_operand:XF 1 "register_operand" "")
16891                  (match_dup 1)))
16892    (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16893    (set (match_dup 5) (sqrt:XF (match_dup 4)))
16894    (parallel [(set (match_operand:XF 0 "register_operand" "")
16895                    (unspec:XF [(match_dup 1) (match_dup 5)]
16896                               UNSPEC_FPATAN))
16897               (clobber (match_scratch:XF 6 ""))])]
16898   "TARGET_USE_FANCY_MATH_387
16899    && flag_unsafe_math_optimizations && !optimize_size"
16901   int i;
16903   for (i = 2; i < 6; i++)
16904     operands[i] = gen_reg_rtx (XFmode);
16906   emit_move_insn (operands[3], CONST1_RTX (XFmode));  /* fld1 */
16909 (define_expand "acos<mode>2"
16910   [(use (match_operand:MODEF 0 "register_operand" ""))
16911    (use (match_operand:MODEF 1 "general_operand" ""))]
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 && !optimize_size"
16917   rtx op0 = gen_reg_rtx (XFmode);
16918   rtx op1 = gen_reg_rtx (XFmode);
16920   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16921   emit_insn (gen_acosxf2 (op0, op1));
16922   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16923   DONE;
16926 (define_insn "fyl2xxf3_i387"
16927   [(set (match_operand:XF 0 "register_operand" "=f")
16928         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16929                     (match_operand:XF 2 "register_operand" "u")]
16930                    UNSPEC_FYL2X))
16931    (clobber (match_scratch:XF 3 "=2"))]
16932   "TARGET_USE_FANCY_MATH_387
16933    && flag_unsafe_math_optimizations"
16934   "fyl2x"
16935   [(set_attr "type" "fpspc")
16936    (set_attr "mode" "XF")])
16938 (define_insn "fyl2x_extend<mode>xf3_i387"
16939   [(set (match_operand:XF 0 "register_operand" "=f")
16940         (unspec:XF [(float_extend:XF
16941                       (match_operand:MODEF 1 "register_operand" "0"))
16942                     (match_operand:XF 2 "register_operand" "u")]
16943                    UNSPEC_FYL2X))
16944    (clobber (match_scratch:XF 3 "=2"))]
16945   "TARGET_USE_FANCY_MATH_387
16946    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16947        || TARGET_MIX_SSE_I387)
16948    && flag_unsafe_math_optimizations"
16949   "fyl2x"
16950   [(set_attr "type" "fpspc")
16951    (set_attr "mode" "XF")])
16953 (define_expand "logxf2"
16954   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16955                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16956                                (match_dup 2)] UNSPEC_FYL2X))
16957               (clobber (match_scratch:XF 3 ""))])]
16958   "TARGET_USE_FANCY_MATH_387
16959    && flag_unsafe_math_optimizations"
16961   operands[2] = gen_reg_rtx (XFmode);
16962   emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16965 (define_expand "log<mode>2"
16966   [(use (match_operand:MODEF 0 "register_operand" ""))
16967    (use (match_operand:MODEF 1 "register_operand" ""))]
16968   "TARGET_USE_FANCY_MATH_387
16969    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16970        || TARGET_MIX_SSE_I387)
16971    && flag_unsafe_math_optimizations"
16973   rtx op0 = gen_reg_rtx (XFmode);
16975   rtx op2 = gen_reg_rtx (XFmode);
16976   emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16978   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16979   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16980   DONE;
16983 (define_expand "log10xf2"
16984   [(parallel [(set (match_operand:XF 0 "register_operand" "")
16985                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
16986                                (match_dup 2)] UNSPEC_FYL2X))
16987               (clobber (match_scratch:XF 3 ""))])]
16988   "TARGET_USE_FANCY_MATH_387
16989    && flag_unsafe_math_optimizations"
16991   operands[2] = gen_reg_rtx (XFmode);
16992   emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16995 (define_expand "log10<mode>2"
16996   [(use (match_operand:MODEF 0 "register_operand" ""))
16997    (use (match_operand:MODEF 1 "register_operand" ""))]
16998   "TARGET_USE_FANCY_MATH_387
16999    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17000        || TARGET_MIX_SSE_I387)
17001    && flag_unsafe_math_optimizations"
17003   rtx op0 = gen_reg_rtx (XFmode);
17005   rtx op2 = gen_reg_rtx (XFmode);
17006   emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
17008   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17009   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17010   DONE;
17013 (define_expand "log2xf2"
17014   [(parallel [(set (match_operand:XF 0 "register_operand" "")
17015                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17016                                (match_dup 2)] UNSPEC_FYL2X))
17017               (clobber (match_scratch:XF 3 ""))])]
17018   "TARGET_USE_FANCY_MATH_387
17019    && flag_unsafe_math_optimizations"
17021   operands[2] = gen_reg_rtx (XFmode);
17022   emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17025 (define_expand "log2<mode>2"
17026   [(use (match_operand:MODEF 0 "register_operand" ""))
17027    (use (match_operand:MODEF 1 "register_operand" ""))]
17028   "TARGET_USE_FANCY_MATH_387
17029    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17030        || TARGET_MIX_SSE_I387)
17031    && flag_unsafe_math_optimizations"
17033   rtx op0 = gen_reg_rtx (XFmode);
17035   rtx op2 = gen_reg_rtx (XFmode);
17036   emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17038   emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
17039   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17040   DONE;
17043 (define_insn "fyl2xp1xf3_i387"
17044   [(set (match_operand:XF 0 "register_operand" "=f")
17045         (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17046                     (match_operand:XF 2 "register_operand" "u")]
17047                    UNSPEC_FYL2XP1))
17048    (clobber (match_scratch:XF 3 "=2"))]
17049   "TARGET_USE_FANCY_MATH_387
17050    && flag_unsafe_math_optimizations"
17051   "fyl2xp1"
17052   [(set_attr "type" "fpspc")
17053    (set_attr "mode" "XF")])
17055 (define_insn "fyl2xp1_extend<mode>xf3_i387"
17056   [(set (match_operand:XF 0 "register_operand" "=f")
17057         (unspec:XF [(float_extend:XF
17058                       (match_operand:MODEF 1 "register_operand" "0"))
17059                     (match_operand:XF 2 "register_operand" "u")]
17060                    UNSPEC_FYL2XP1))
17061    (clobber (match_scratch:XF 3 "=2"))]
17062   "TARGET_USE_FANCY_MATH_387
17063    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17064        || TARGET_MIX_SSE_I387)
17065    && flag_unsafe_math_optimizations"
17066   "fyl2xp1"
17067   [(set_attr "type" "fpspc")
17068    (set_attr "mode" "XF")])
17070 (define_expand "log1pxf2"
17071   [(use (match_operand:XF 0 "register_operand" ""))
17072    (use (match_operand:XF 1 "register_operand" ""))]
17073   "TARGET_USE_FANCY_MATH_387
17074    && flag_unsafe_math_optimizations && !optimize_size"
17076   ix86_emit_i387_log1p (operands[0], operands[1]);
17077   DONE;
17080 (define_expand "log1p<mode>2"
17081   [(use (match_operand:MODEF 0 "register_operand" ""))
17082    (use (match_operand:MODEF 1 "register_operand" ""))]
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 && !optimize_size"
17088   rtx op0 = gen_reg_rtx (XFmode);
17090   operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
17092   ix86_emit_i387_log1p (op0, operands[1]);
17093   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17094   DONE;
17097 (define_insn "fxtractxf3_i387"
17098   [(set (match_operand:XF 0 "register_operand" "=f")
17099         (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17100                    UNSPEC_XTRACT_FRACT))
17101    (set (match_operand:XF 1 "register_operand" "=u")
17102         (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
17103   "TARGET_USE_FANCY_MATH_387
17104    && flag_unsafe_math_optimizations"
17105   "fxtract"
17106   [(set_attr "type" "fpspc")
17107    (set_attr "mode" "XF")])
17109 (define_insn "fxtract_extend<mode>xf3_i387"
17110   [(set (match_operand:XF 0 "register_operand" "=f")
17111         (unspec:XF [(float_extend:XF
17112                       (match_operand:MODEF 2 "register_operand" "0"))]
17113                    UNSPEC_XTRACT_FRACT))
17114    (set (match_operand:XF 1 "register_operand" "=u")
17115         (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
17116   "TARGET_USE_FANCY_MATH_387
17117    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17118        || TARGET_MIX_SSE_I387)
17119    && flag_unsafe_math_optimizations"
17120   "fxtract"
17121   [(set_attr "type" "fpspc")
17122    (set_attr "mode" "XF")])
17124 (define_expand "logbxf2"
17125   [(parallel [(set (match_dup 2)
17126                    (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17127                               UNSPEC_XTRACT_FRACT))
17128               (set (match_operand:XF 0 "register_operand" "")
17129                    (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17130   "TARGET_USE_FANCY_MATH_387
17131    && flag_unsafe_math_optimizations"
17133   operands[2] = gen_reg_rtx (XFmode);
17136 (define_expand "logb<mode>2"
17137   [(use (match_operand:MODEF 0 "register_operand" ""))
17138    (use (match_operand:MODEF 1 "register_operand" ""))]
17139   "TARGET_USE_FANCY_MATH_387
17140    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17141        || TARGET_MIX_SSE_I387)
17142    && flag_unsafe_math_optimizations"
17144   rtx op0 = gen_reg_rtx (XFmode);
17145   rtx op1 = gen_reg_rtx (XFmode);
17147   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17148   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
17149   DONE;
17152 (define_expand "ilogbxf2"
17153   [(use (match_operand:SI 0 "register_operand" ""))
17154    (use (match_operand:XF 1 "register_operand" ""))]
17155   "TARGET_USE_FANCY_MATH_387
17156    && flag_unsafe_math_optimizations && !optimize_size"
17158   rtx op0 = gen_reg_rtx (XFmode);
17159   rtx op1 = gen_reg_rtx (XFmode);
17161   emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17162   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17163   DONE;
17166 (define_expand "ilogb<mode>2"
17167   [(use (match_operand:SI 0 "register_operand" ""))
17168    (use (match_operand:MODEF 1 "register_operand" ""))]
17169   "TARGET_USE_FANCY_MATH_387
17170    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17171        || TARGET_MIX_SSE_I387)
17172    && flag_unsafe_math_optimizations && !optimize_size"
17174   rtx op0 = gen_reg_rtx (XFmode);
17175   rtx op1 = gen_reg_rtx (XFmode);
17177   emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17178   emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17179   DONE;
17182 (define_insn "*f2xm1xf2_i387"
17183   [(set (match_operand:XF 0 "register_operand" "=f")
17184         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17185                    UNSPEC_F2XM1))]
17186   "TARGET_USE_FANCY_MATH_387
17187    && flag_unsafe_math_optimizations"
17188   "f2xm1"
17189   [(set_attr "type" "fpspc")
17190    (set_attr "mode" "XF")])
17192 (define_insn "*fscalexf4_i387"
17193   [(set (match_operand:XF 0 "register_operand" "=f")
17194         (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17195                     (match_operand:XF 3 "register_operand" "1")]
17196                    UNSPEC_FSCALE_FRACT))
17197    (set (match_operand:XF 1 "register_operand" "=u")
17198         (unspec:XF [(match_dup 2) (match_dup 3)]
17199                    UNSPEC_FSCALE_EXP))]
17200   "TARGET_USE_FANCY_MATH_387
17201    && flag_unsafe_math_optimizations"
17202   "fscale"
17203   [(set_attr "type" "fpspc")
17204    (set_attr "mode" "XF")])
17206 (define_expand "expNcorexf3"
17207   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17208                                (match_operand:XF 2 "register_operand" "")))
17209    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17210    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17211    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17212    (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17213    (parallel [(set (match_operand:XF 0 "register_operand" "")
17214                    (unspec:XF [(match_dup 8) (match_dup 4)]
17215                               UNSPEC_FSCALE_FRACT))
17216               (set (match_dup 9)
17217                    (unspec:XF [(match_dup 8) (match_dup 4)]
17218                               UNSPEC_FSCALE_EXP))])]
17219   "TARGET_USE_FANCY_MATH_387
17220    && flag_unsafe_math_optimizations && !optimize_size"
17222   int i;
17224   for (i = 3; i < 10; i++)
17225     operands[i] = gen_reg_rtx (XFmode);
17227   emit_move_insn (operands[7], CONST1_RTX (XFmode));  /* fld1 */
17230 (define_expand "expxf2"
17231   [(use (match_operand:XF 0 "register_operand" ""))
17232    (use (match_operand:XF 1 "register_operand" ""))]
17233   "TARGET_USE_FANCY_MATH_387
17234    && flag_unsafe_math_optimizations && !optimize_size"
17236   rtx op2 = gen_reg_rtx (XFmode);
17237   emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17239   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17240   DONE;
17243 (define_expand "exp<mode>2"
17244   [(use (match_operand:MODEF 0 "register_operand" ""))
17245    (use (match_operand:MODEF 1 "general_operand" ""))]
17246  "TARGET_USE_FANCY_MATH_387
17247    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17248        || TARGET_MIX_SSE_I387)
17249    && flag_unsafe_math_optimizations && !optimize_size"
17251   rtx op0 = gen_reg_rtx (XFmode);
17252   rtx op1 = gen_reg_rtx (XFmode);
17254   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17255   emit_insn (gen_expxf2 (op0, op1));
17256   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17257   DONE;
17260 (define_expand "exp10xf2"
17261   [(use (match_operand:XF 0 "register_operand" ""))
17262    (use (match_operand:XF 1 "register_operand" ""))]
17263   "TARGET_USE_FANCY_MATH_387
17264    && flag_unsafe_math_optimizations && !optimize_size"
17266   rtx op2 = gen_reg_rtx (XFmode);
17267   emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17269   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17270   DONE;
17273 (define_expand "exp10<mode>2"
17274   [(use (match_operand:MODEF 0 "register_operand" ""))
17275    (use (match_operand:MODEF 1 "general_operand" ""))]
17276  "TARGET_USE_FANCY_MATH_387
17277    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17278        || TARGET_MIX_SSE_I387)
17279    && flag_unsafe_math_optimizations && !optimize_size"
17281   rtx op0 = gen_reg_rtx (XFmode);
17282   rtx op1 = gen_reg_rtx (XFmode);
17284   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17285   emit_insn (gen_exp10xf2 (op0, op1));
17286   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17287   DONE;
17290 (define_expand "exp2xf2"
17291   [(use (match_operand:XF 0 "register_operand" ""))
17292    (use (match_operand:XF 1 "register_operand" ""))]
17293   "TARGET_USE_FANCY_MATH_387
17294    && flag_unsafe_math_optimizations && !optimize_size"
17296   rtx op2 = gen_reg_rtx (XFmode);
17297   emit_move_insn (op2, CONST1_RTX (XFmode));  /* fld1 */
17299   emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17300   DONE;
17303 (define_expand "exp2<mode>2"
17304   [(use (match_operand:MODEF 0 "register_operand" ""))
17305    (use (match_operand:MODEF 1 "general_operand" ""))]
17306  "TARGET_USE_FANCY_MATH_387
17307    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17308        || TARGET_MIX_SSE_I387)
17309    && flag_unsafe_math_optimizations && !optimize_size"
17311   rtx op0 = gen_reg_rtx (XFmode);
17312   rtx op1 = gen_reg_rtx (XFmode);
17314   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17315   emit_insn (gen_exp2xf2 (op0, op1));
17316   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17317   DONE;
17320 (define_expand "expm1xf2"
17321   [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17322                                (match_dup 2)))
17323    (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17324    (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17325    (set (match_dup 9) (float_extend:XF (match_dup 13)))
17326    (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17327    (parallel [(set (match_dup 7)
17328                    (unspec:XF [(match_dup 6) (match_dup 4)]
17329                               UNSPEC_FSCALE_FRACT))
17330               (set (match_dup 8)
17331                    (unspec:XF [(match_dup 6) (match_dup 4)]
17332                               UNSPEC_FSCALE_EXP))])
17333    (parallel [(set (match_dup 10)
17334                    (unspec:XF [(match_dup 9) (match_dup 8)]
17335                               UNSPEC_FSCALE_FRACT))
17336               (set (match_dup 11)
17337                    (unspec:XF [(match_dup 9) (match_dup 8)]
17338                               UNSPEC_FSCALE_EXP))])
17339    (set (match_dup 12) (minus:XF (match_dup 10)
17340                                  (float_extend:XF (match_dup 13))))
17341    (set (match_operand:XF 0 "register_operand" "")
17342         (plus:XF (match_dup 12) (match_dup 7)))]
17343   "TARGET_USE_FANCY_MATH_387
17344    && flag_unsafe_math_optimizations && !optimize_size"
17346   int i;
17348   for (i = 2; i < 13; i++)
17349     operands[i] = gen_reg_rtx (XFmode);
17351   operands[13]
17352     = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17354   emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17357 (define_expand "expm1<mode>2"
17358   [(use (match_operand:MODEF 0 "register_operand" ""))
17359    (use (match_operand:MODEF 1 "general_operand" ""))]
17360  "TARGET_USE_FANCY_MATH_387
17361    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17362        || TARGET_MIX_SSE_I387)
17363    && flag_unsafe_math_optimizations && !optimize_size"
17365   rtx op0 = gen_reg_rtx (XFmode);
17366   rtx op1 = gen_reg_rtx (XFmode);
17368   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17369   emit_insn (gen_expm1xf2 (op0, op1));
17370   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17371   DONE;
17374 (define_expand "ldexpxf3"
17375   [(set (match_dup 3)
17376         (float:XF (match_operand:SI 2 "register_operand" "")))
17377    (parallel [(set (match_operand:XF 0 " register_operand" "")
17378                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17379                                (match_dup 3)]
17380                               UNSPEC_FSCALE_FRACT))
17381               (set (match_dup 4)
17382                    (unspec:XF [(match_dup 1) (match_dup 3)]
17383                               UNSPEC_FSCALE_EXP))])]
17384   "TARGET_USE_FANCY_MATH_387
17385    && flag_unsafe_math_optimizations && !optimize_size"
17387   operands[3] = gen_reg_rtx (XFmode);
17388   operands[4] = gen_reg_rtx (XFmode);
17391 (define_expand "ldexp<mode>3"
17392   [(use (match_operand:MODEF 0 "register_operand" ""))
17393    (use (match_operand:MODEF 1 "general_operand" ""))
17394    (use (match_operand:SI 2 "register_operand" ""))]
17395  "TARGET_USE_FANCY_MATH_387
17396    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17397        || TARGET_MIX_SSE_I387)
17398    && flag_unsafe_math_optimizations && !optimize_size"
17400   rtx op0 = gen_reg_rtx (XFmode);
17401   rtx op1 = gen_reg_rtx (XFmode);
17403   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17404   emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17405   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17406   DONE;
17409 (define_expand "scalbxf3"
17410   [(parallel [(set (match_operand:XF 0 " register_operand" "")
17411                    (unspec:XF [(match_operand:XF 1 "register_operand" "")
17412                                (match_operand:XF 2 "register_operand" "")]
17413                               UNSPEC_FSCALE_FRACT))
17414               (set (match_dup 3)
17415                    (unspec:XF [(match_dup 1) (match_dup 2)]
17416                               UNSPEC_FSCALE_EXP))])]
17417   "TARGET_USE_FANCY_MATH_387
17418    && flag_unsafe_math_optimizations && !optimize_size"
17420   operands[3] = gen_reg_rtx (XFmode);
17423 (define_expand "scalb<mode>3"
17424   [(use (match_operand:MODEF 0 "register_operand" ""))
17425    (use (match_operand:MODEF 1 "general_operand" ""))
17426    (use (match_operand:MODEF 2 "register_operand" ""))]
17427  "TARGET_USE_FANCY_MATH_387
17428    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17429        || TARGET_MIX_SSE_I387)
17430    && flag_unsafe_math_optimizations && !optimize_size"
17432   rtx op0 = gen_reg_rtx (XFmode);
17433   rtx op1 = gen_reg_rtx (XFmode);
17434   rtx op2 = gen_reg_rtx (XFmode);
17436   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17437   emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17438   emit_insn (gen_scalbxf3 (op0, op1, op2));
17439   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17440   DONE;
17444 (define_insn "sse4_1_round<mode>2"
17445   [(set (match_operand:MODEF 0 "register_operand" "=x")
17446         (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17447                        (match_operand:SI 2 "const_0_to_15_operand" "n")]
17448                       UNSPEC_ROUND))]
17449   "TARGET_ROUND"
17450   "rounds<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
17451   [(set_attr "type" "ssecvt")
17452    (set_attr "prefix_extra" "1")
17453    (set_attr "mode" "<MODE>")])
17455 (define_insn "rintxf2"
17456   [(set (match_operand:XF 0 "register_operand" "=f")
17457         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17458                    UNSPEC_FRNDINT))]
17459   "TARGET_USE_FANCY_MATH_387
17460    && flag_unsafe_math_optimizations"
17461   "frndint"
17462   [(set_attr "type" "fpspc")
17463    (set_attr "mode" "XF")])
17465 (define_expand "rint<mode>2"
17466   [(use (match_operand:MODEF 0 "register_operand" ""))
17467    (use (match_operand:MODEF 1 "register_operand" ""))]
17468   "(TARGET_USE_FANCY_MATH_387
17469     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17470         || TARGET_MIX_SSE_I387)
17471     && flag_unsafe_math_optimizations)
17472    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17473        && !flag_trapping_math
17474        && (TARGET_ROUND || !optimize_size))"
17476   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17477       && !flag_trapping_math
17478       && (TARGET_ROUND || !optimize_size))
17479     {
17480       if (TARGET_ROUND)
17481         emit_insn (gen_sse4_1_round<mode>2
17482                    (operands[0], operands[1], GEN_INT (0x04)));
17483       else
17484         ix86_expand_rint (operand0, operand1);
17485     }
17486   else
17487     {
17488       rtx op0 = gen_reg_rtx (XFmode);
17489       rtx op1 = gen_reg_rtx (XFmode);
17491       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17492       emit_insn (gen_rintxf2 (op0, op1));
17494       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17495     }
17496   DONE;
17499 (define_expand "round<mode>2"
17500   [(match_operand:MODEF 0 "register_operand" "")
17501    (match_operand:MODEF 1 "nonimmediate_operand" "")]
17502   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17503    && !flag_trapping_math && !flag_rounding_math
17504    && !optimize_size"
17506   if (TARGET_64BIT || (<MODE>mode != DFmode))
17507     ix86_expand_round (operand0, operand1);
17508   else
17509     ix86_expand_rounddf_32 (operand0, operand1);
17510   DONE;
17513 (define_insn_and_split "*fistdi2_1"
17514   [(set (match_operand:DI 0 "nonimmediate_operand" "")
17515         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17516                    UNSPEC_FIST))]
17517   "TARGET_USE_FANCY_MATH_387
17518    && !(reload_completed || reload_in_progress)"
17519   "#"
17520   "&& 1"
17521   [(const_int 0)]
17523   if (memory_operand (operands[0], VOIDmode))
17524     emit_insn (gen_fistdi2 (operands[0], operands[1]));
17525   else
17526     {
17527       operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17528       emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17529                                          operands[2]));
17530     }
17531   DONE;
17533   [(set_attr "type" "fpspc")
17534    (set_attr "mode" "DI")])
17536 (define_insn "fistdi2"
17537   [(set (match_operand:DI 0 "memory_operand" "=m")
17538         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17539                    UNSPEC_FIST))
17540    (clobber (match_scratch:XF 2 "=&1f"))]
17541   "TARGET_USE_FANCY_MATH_387"
17542   "* return output_fix_trunc (insn, operands, 0);"
17543   [(set_attr "type" "fpspc")
17544    (set_attr "mode" "DI")])
17546 (define_insn "fistdi2_with_temp"
17547   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17548         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17549                    UNSPEC_FIST))
17550    (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17551    (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17552   "TARGET_USE_FANCY_MATH_387"
17553   "#"
17554   [(set_attr "type" "fpspc")
17555    (set_attr "mode" "DI")])
17557 (define_split
17558   [(set (match_operand:DI 0 "register_operand" "")
17559         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17560                    UNSPEC_FIST))
17561    (clobber (match_operand:DI 2 "memory_operand" ""))
17562    (clobber (match_scratch 3 ""))]
17563   "reload_completed"
17564   [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17565               (clobber (match_dup 3))])
17566    (set (match_dup 0) (match_dup 2))]
17567   "")
17569 (define_split
17570   [(set (match_operand:DI 0 "memory_operand" "")
17571         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17572                    UNSPEC_FIST))
17573    (clobber (match_operand:DI 2 "memory_operand" ""))
17574    (clobber (match_scratch 3 ""))]
17575   "reload_completed"
17576   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17577               (clobber (match_dup 3))])]
17578   "")
17580 (define_insn_and_split "*fist<mode>2_1"
17581   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17582         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17583                            UNSPEC_FIST))]
17584   "TARGET_USE_FANCY_MATH_387
17585    && !(reload_completed || reload_in_progress)"
17586   "#"
17587   "&& 1"
17588   [(const_int 0)]
17590   operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17591   emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17592                                         operands[2]));
17593   DONE;
17595   [(set_attr "type" "fpspc")
17596    (set_attr "mode" "<MODE>")])
17598 (define_insn "fist<mode>2"
17599   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17600         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17601                            UNSPEC_FIST))]
17602   "TARGET_USE_FANCY_MATH_387"
17603   "* return output_fix_trunc (insn, operands, 0);"
17604   [(set_attr "type" "fpspc")
17605    (set_attr "mode" "<MODE>")])
17607 (define_insn "fist<mode>2_with_temp"
17608   [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17609         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17610                            UNSPEC_FIST))
17611    (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17612   "TARGET_USE_FANCY_MATH_387"
17613   "#"
17614   [(set_attr "type" "fpspc")
17615    (set_attr "mode" "<MODE>")])
17617 (define_split
17618   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17619         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17620                            UNSPEC_FIST))
17621    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17622   "reload_completed"
17623   [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17624    (set (match_dup 0) (match_dup 2))]
17625   "")
17627 (define_split
17628   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17629         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17630                            UNSPEC_FIST))
17631    (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17632   "reload_completed"
17633   [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17634   "")
17636 (define_expand "lrintxf<mode>2"
17637   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17638      (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17639                       UNSPEC_FIST))]
17640   "TARGET_USE_FANCY_MATH_387"
17641   "")
17643 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17644   [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17645      (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17646                         UNSPEC_FIX_NOTRUNC))]
17647   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17648    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17649   "")
17651 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17652   [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17653    (match_operand:MODEF 1 "register_operand" "")]
17654   "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17655    && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17656    && !flag_trapping_math && !flag_rounding_math
17657    && !optimize_size"
17659   ix86_expand_lround (operand0, operand1);
17660   DONE;
17663 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17664 (define_insn_and_split "frndintxf2_floor"
17665   [(set (match_operand:XF 0 "register_operand" "")
17666         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17667          UNSPEC_FRNDINT_FLOOR))
17668    (clobber (reg:CC FLAGS_REG))]
17669   "TARGET_USE_FANCY_MATH_387
17670    && flag_unsafe_math_optimizations
17671    && !(reload_completed || reload_in_progress)"
17672   "#"
17673   "&& 1"
17674   [(const_int 0)]
17676   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17678   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17679   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17681   emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17682                                         operands[2], operands[3]));
17683   DONE;
17685   [(set_attr "type" "frndint")
17686    (set_attr "i387_cw" "floor")
17687    (set_attr "mode" "XF")])
17689 (define_insn "frndintxf2_floor_i387"
17690   [(set (match_operand:XF 0 "register_operand" "=f")
17691         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17692          UNSPEC_FRNDINT_FLOOR))
17693    (use (match_operand:HI 2 "memory_operand" "m"))
17694    (use (match_operand:HI 3 "memory_operand" "m"))]
17695   "TARGET_USE_FANCY_MATH_387
17696    && flag_unsafe_math_optimizations"
17697   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17698   [(set_attr "type" "frndint")
17699    (set_attr "i387_cw" "floor")
17700    (set_attr "mode" "XF")])
17702 (define_expand "floorxf2"
17703   [(use (match_operand:XF 0 "register_operand" ""))
17704    (use (match_operand:XF 1 "register_operand" ""))]
17705   "TARGET_USE_FANCY_MATH_387
17706    && flag_unsafe_math_optimizations && !optimize_size"
17708   emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17709   DONE;
17712 (define_expand "floor<mode>2"
17713   [(use (match_operand:MODEF 0 "register_operand" ""))
17714    (use (match_operand:MODEF 1 "register_operand" ""))]
17715   "(TARGET_USE_FANCY_MATH_387
17716     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17717         || TARGET_MIX_SSE_I387)
17718     && flag_unsafe_math_optimizations && !optimize_size)
17719    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17720        && !flag_trapping_math
17721        && (TARGET_ROUND || !optimize_size))"
17723   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17724       && !flag_trapping_math
17725       && (TARGET_ROUND || !optimize_size))
17726     {
17727       if (TARGET_ROUND)
17728         emit_insn (gen_sse4_1_round<mode>2
17729                    (operands[0], operands[1], GEN_INT (0x01)));
17730       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17731         ix86_expand_floorceil (operand0, operand1, true);
17732       else
17733         ix86_expand_floorceildf_32 (operand0, operand1, true);
17734     }
17735   else
17736     {
17737       rtx op0 = gen_reg_rtx (XFmode);
17738       rtx op1 = gen_reg_rtx (XFmode);
17740       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17741       emit_insn (gen_frndintxf2_floor (op0, op1));
17743       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17744     }
17745   DONE;
17748 (define_insn_and_split "*fist<mode>2_floor_1"
17749   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17750         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17751          UNSPEC_FIST_FLOOR))
17752    (clobber (reg:CC FLAGS_REG))]
17753   "TARGET_USE_FANCY_MATH_387
17754    && flag_unsafe_math_optimizations
17755    && !(reload_completed || reload_in_progress)"
17756   "#"
17757   "&& 1"
17758   [(const_int 0)]
17760   ix86_optimize_mode_switching[I387_FLOOR] = 1;
17762   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17763   operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17764   if (memory_operand (operands[0], VOIDmode))
17765     emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17766                                       operands[2], operands[3]));
17767   else
17768     {
17769       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17770       emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17771                                                   operands[2], operands[3],
17772                                                   operands[4]));
17773     }
17774   DONE;
17776   [(set_attr "type" "fistp")
17777    (set_attr "i387_cw" "floor")
17778    (set_attr "mode" "<MODE>")])
17780 (define_insn "fistdi2_floor"
17781   [(set (match_operand:DI 0 "memory_operand" "=m")
17782         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17783          UNSPEC_FIST_FLOOR))
17784    (use (match_operand:HI 2 "memory_operand" "m"))
17785    (use (match_operand:HI 3 "memory_operand" "m"))
17786    (clobber (match_scratch:XF 4 "=&1f"))]
17787   "TARGET_USE_FANCY_MATH_387
17788    && flag_unsafe_math_optimizations"
17789   "* return output_fix_trunc (insn, operands, 0);"
17790   [(set_attr "type" "fistp")
17791    (set_attr "i387_cw" "floor")
17792    (set_attr "mode" "DI")])
17794 (define_insn "fistdi2_floor_with_temp"
17795   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17796         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17797          UNSPEC_FIST_FLOOR))
17798    (use (match_operand:HI 2 "memory_operand" "m,m"))
17799    (use (match_operand:HI 3 "memory_operand" "m,m"))
17800    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17801    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17802   "TARGET_USE_FANCY_MATH_387
17803    && flag_unsafe_math_optimizations"
17804   "#"
17805   [(set_attr "type" "fistp")
17806    (set_attr "i387_cw" "floor")
17807    (set_attr "mode" "DI")])
17809 (define_split
17810   [(set (match_operand:DI 0 "register_operand" "")
17811         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17812          UNSPEC_FIST_FLOOR))
17813    (use (match_operand:HI 2 "memory_operand" ""))
17814    (use (match_operand:HI 3 "memory_operand" ""))
17815    (clobber (match_operand:DI 4 "memory_operand" ""))
17816    (clobber (match_scratch 5 ""))]
17817   "reload_completed"
17818   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17819               (use (match_dup 2))
17820               (use (match_dup 3))
17821               (clobber (match_dup 5))])
17822    (set (match_dup 0) (match_dup 4))]
17823   "")
17825 (define_split
17826   [(set (match_operand:DI 0 "memory_operand" "")
17827         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17828          UNSPEC_FIST_FLOOR))
17829    (use (match_operand:HI 2 "memory_operand" ""))
17830    (use (match_operand:HI 3 "memory_operand" ""))
17831    (clobber (match_operand:DI 4 "memory_operand" ""))
17832    (clobber (match_scratch 5 ""))]
17833   "reload_completed"
17834   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17835               (use (match_dup 2))
17836               (use (match_dup 3))
17837               (clobber (match_dup 5))])]
17838   "")
17840 (define_insn "fist<mode>2_floor"
17841   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17842         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17843          UNSPEC_FIST_FLOOR))
17844    (use (match_operand:HI 2 "memory_operand" "m"))
17845    (use (match_operand:HI 3 "memory_operand" "m"))]
17846   "TARGET_USE_FANCY_MATH_387
17847    && flag_unsafe_math_optimizations"
17848   "* return output_fix_trunc (insn, operands, 0);"
17849   [(set_attr "type" "fistp")
17850    (set_attr "i387_cw" "floor")
17851    (set_attr "mode" "<MODE>")])
17853 (define_insn "fist<mode>2_floor_with_temp"
17854   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17855         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17856          UNSPEC_FIST_FLOOR))
17857    (use (match_operand:HI 2 "memory_operand" "m,m"))
17858    (use (match_operand:HI 3 "memory_operand" "m,m"))
17859    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17860   "TARGET_USE_FANCY_MATH_387
17861    && flag_unsafe_math_optimizations"
17862   "#"
17863   [(set_attr "type" "fistp")
17864    (set_attr "i387_cw" "floor")
17865    (set_attr "mode" "<MODE>")])
17867 (define_split
17868   [(set (match_operand:X87MODEI12 0 "register_operand" "")
17869         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17870          UNSPEC_FIST_FLOOR))
17871    (use (match_operand:HI 2 "memory_operand" ""))
17872    (use (match_operand:HI 3 "memory_operand" ""))
17873    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17874   "reload_completed"
17875   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17876                                   UNSPEC_FIST_FLOOR))
17877               (use (match_dup 2))
17878               (use (match_dup 3))])
17879    (set (match_dup 0) (match_dup 4))]
17880   "")
17882 (define_split
17883   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17884         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17885          UNSPEC_FIST_FLOOR))
17886    (use (match_operand:HI 2 "memory_operand" ""))
17887    (use (match_operand:HI 3 "memory_operand" ""))
17888    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17889   "reload_completed"
17890   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17891                                   UNSPEC_FIST_FLOOR))
17892               (use (match_dup 2))
17893               (use (match_dup 3))])]
17894   "")
17896 (define_expand "lfloorxf<mode>2"
17897   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17898                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17899                     UNSPEC_FIST_FLOOR))
17900               (clobber (reg:CC FLAGS_REG))])]
17901   "TARGET_USE_FANCY_MATH_387
17902    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17903    && flag_unsafe_math_optimizations"
17904   "")
17906 (define_expand "lfloor<mode>di2"
17907   [(match_operand:DI 0 "nonimmediate_operand" "")
17908    (match_operand:MODEF 1 "register_operand" "")]
17909   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
17910    && !flag_trapping_math
17911    && !optimize_size"
17913   ix86_expand_lfloorceil (operand0, operand1, true);
17914   DONE;
17917 (define_expand "lfloor<mode>si2"
17918   [(match_operand:SI 0 "nonimmediate_operand" "")
17919    (match_operand:MODEF 1 "register_operand" "")]
17920   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17921    && !flag_trapping_math
17922    && (!optimize_size || !TARGET_64BIT)"
17924   ix86_expand_lfloorceil (operand0, operand1, true);
17925   DONE;
17928 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17929 (define_insn_and_split "frndintxf2_ceil"
17930   [(set (match_operand:XF 0 "register_operand" "")
17931         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17932          UNSPEC_FRNDINT_CEIL))
17933    (clobber (reg:CC FLAGS_REG))]
17934   "TARGET_USE_FANCY_MATH_387
17935    && flag_unsafe_math_optimizations
17936    && !(reload_completed || reload_in_progress)"
17937   "#"
17938   "&& 1"
17939   [(const_int 0)]
17941   ix86_optimize_mode_switching[I387_CEIL] = 1;
17943   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17944   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17946   emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17947                                        operands[2], operands[3]));
17948   DONE;
17950   [(set_attr "type" "frndint")
17951    (set_attr "i387_cw" "ceil")
17952    (set_attr "mode" "XF")])
17954 (define_insn "frndintxf2_ceil_i387"
17955   [(set (match_operand:XF 0 "register_operand" "=f")
17956         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17957          UNSPEC_FRNDINT_CEIL))
17958    (use (match_operand:HI 2 "memory_operand" "m"))
17959    (use (match_operand:HI 3 "memory_operand" "m"))]
17960   "TARGET_USE_FANCY_MATH_387
17961    && flag_unsafe_math_optimizations"
17962   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17963   [(set_attr "type" "frndint")
17964    (set_attr "i387_cw" "ceil")
17965    (set_attr "mode" "XF")])
17967 (define_expand "ceilxf2"
17968   [(use (match_operand:XF 0 "register_operand" ""))
17969    (use (match_operand:XF 1 "register_operand" ""))]
17970   "TARGET_USE_FANCY_MATH_387
17971    && flag_unsafe_math_optimizations && !optimize_size"
17973   emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17974   DONE;
17977 (define_expand "ceil<mode>2"
17978   [(use (match_operand:MODEF 0 "register_operand" ""))
17979    (use (match_operand:MODEF 1 "register_operand" ""))]
17980   "(TARGET_USE_FANCY_MATH_387
17981     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17982         || TARGET_MIX_SSE_I387)
17983     && flag_unsafe_math_optimizations && !optimize_size)
17984    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17985        && !flag_trapping_math
17986        && (TARGET_ROUND || !optimize_size))"
17988   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17989       && !flag_trapping_math
17990       && (TARGET_ROUND || !optimize_size))
17991     {
17992       if (TARGET_ROUND)
17993         emit_insn (gen_sse4_1_round<mode>2
17994                    (operands[0], operands[1], GEN_INT (0x02)));
17995       else if (TARGET_64BIT || (<MODE>mode != DFmode))
17996         ix86_expand_floorceil (operand0, operand1, false);
17997       else
17998         ix86_expand_floorceildf_32 (operand0, operand1, false);
17999     }
18000   else
18001     {
18002       rtx op0 = gen_reg_rtx (XFmode);
18003       rtx op1 = gen_reg_rtx (XFmode);
18005       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18006       emit_insn (gen_frndintxf2_ceil (op0, op1));
18008       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18009     }
18010   DONE;
18013 (define_insn_and_split "*fist<mode>2_ceil_1"
18014   [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18015         (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18016          UNSPEC_FIST_CEIL))
18017    (clobber (reg:CC FLAGS_REG))]
18018   "TARGET_USE_FANCY_MATH_387
18019    && flag_unsafe_math_optimizations
18020    && !(reload_completed || reload_in_progress)"
18021   "#"
18022   "&& 1"
18023   [(const_int 0)]
18025   ix86_optimize_mode_switching[I387_CEIL] = 1;
18027   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18028   operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
18029   if (memory_operand (operands[0], VOIDmode))
18030     emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
18031                                      operands[2], operands[3]));
18032   else
18033     {
18034       operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18035       emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
18036                                                  operands[2], operands[3],
18037                                                  operands[4]));
18038     }
18039   DONE;
18041   [(set_attr "type" "fistp")
18042    (set_attr "i387_cw" "ceil")
18043    (set_attr "mode" "<MODE>")])
18045 (define_insn "fistdi2_ceil"
18046   [(set (match_operand:DI 0 "memory_operand" "=m")
18047         (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18048          UNSPEC_FIST_CEIL))
18049    (use (match_operand:HI 2 "memory_operand" "m"))
18050    (use (match_operand:HI 3 "memory_operand" "m"))
18051    (clobber (match_scratch:XF 4 "=&1f"))]
18052   "TARGET_USE_FANCY_MATH_387
18053    && flag_unsafe_math_optimizations"
18054   "* return output_fix_trunc (insn, operands, 0);"
18055   [(set_attr "type" "fistp")
18056    (set_attr "i387_cw" "ceil")
18057    (set_attr "mode" "DI")])
18059 (define_insn "fistdi2_ceil_with_temp"
18060   [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18061         (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18062          UNSPEC_FIST_CEIL))
18063    (use (match_operand:HI 2 "memory_operand" "m,m"))
18064    (use (match_operand:HI 3 "memory_operand" "m,m"))
18065    (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18066    (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18067   "TARGET_USE_FANCY_MATH_387
18068    && flag_unsafe_math_optimizations"
18069   "#"
18070   [(set_attr "type" "fistp")
18071    (set_attr "i387_cw" "ceil")
18072    (set_attr "mode" "DI")])
18074 (define_split
18075   [(set (match_operand:DI 0 "register_operand" "")
18076         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18077          UNSPEC_FIST_CEIL))
18078    (use (match_operand:HI 2 "memory_operand" ""))
18079    (use (match_operand:HI 3 "memory_operand" ""))
18080    (clobber (match_operand:DI 4 "memory_operand" ""))
18081    (clobber (match_scratch 5 ""))]
18082   "reload_completed"
18083   [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18084               (use (match_dup 2))
18085               (use (match_dup 3))
18086               (clobber (match_dup 5))])
18087    (set (match_dup 0) (match_dup 4))]
18088   "")
18090 (define_split
18091   [(set (match_operand:DI 0 "memory_operand" "")
18092         (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18093          UNSPEC_FIST_CEIL))
18094    (use (match_operand:HI 2 "memory_operand" ""))
18095    (use (match_operand:HI 3 "memory_operand" ""))
18096    (clobber (match_operand:DI 4 "memory_operand" ""))
18097    (clobber (match_scratch 5 ""))]
18098   "reload_completed"
18099   [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18100               (use (match_dup 2))
18101               (use (match_dup 3))
18102               (clobber (match_dup 5))])]
18103   "")
18105 (define_insn "fist<mode>2_ceil"
18106   [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18107         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18108          UNSPEC_FIST_CEIL))
18109    (use (match_operand:HI 2 "memory_operand" "m"))
18110    (use (match_operand:HI 3 "memory_operand" "m"))]
18111   "TARGET_USE_FANCY_MATH_387
18112    && flag_unsafe_math_optimizations"
18113   "* return output_fix_trunc (insn, operands, 0);"
18114   [(set_attr "type" "fistp")
18115    (set_attr "i387_cw" "ceil")
18116    (set_attr "mode" "<MODE>")])
18118 (define_insn "fist<mode>2_ceil_with_temp"
18119   [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18120         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18121          UNSPEC_FIST_CEIL))
18122    (use (match_operand:HI 2 "memory_operand" "m,m"))
18123    (use (match_operand:HI 3 "memory_operand" "m,m"))
18124    (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18125   "TARGET_USE_FANCY_MATH_387
18126    && flag_unsafe_math_optimizations"
18127   "#"
18128   [(set_attr "type" "fistp")
18129    (set_attr "i387_cw" "ceil")
18130    (set_attr "mode" "<MODE>")])
18132 (define_split
18133   [(set (match_operand:X87MODEI12 0 "register_operand" "")
18134         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18135          UNSPEC_FIST_CEIL))
18136    (use (match_operand:HI 2 "memory_operand" ""))
18137    (use (match_operand:HI 3 "memory_operand" ""))
18138    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18139   "reload_completed"
18140   [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18141                                   UNSPEC_FIST_CEIL))
18142               (use (match_dup 2))
18143               (use (match_dup 3))])
18144    (set (match_dup 0) (match_dup 4))]
18145   "")
18147 (define_split
18148   [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18149         (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18150          UNSPEC_FIST_CEIL))
18151    (use (match_operand:HI 2 "memory_operand" ""))
18152    (use (match_operand:HI 3 "memory_operand" ""))
18153    (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18154   "reload_completed"
18155   [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18156                                   UNSPEC_FIST_CEIL))
18157               (use (match_dup 2))
18158               (use (match_dup 3))])]
18159   "")
18161 (define_expand "lceilxf<mode>2"
18162   [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18163                    (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18164                     UNSPEC_FIST_CEIL))
18165               (clobber (reg:CC FLAGS_REG))])]
18166   "TARGET_USE_FANCY_MATH_387
18167    && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18168    && flag_unsafe_math_optimizations"
18169   "")
18171 (define_expand "lceil<mode>di2"
18172   [(match_operand:DI 0 "nonimmediate_operand" "")
18173    (match_operand:MODEF 1 "register_operand" "")]
18174   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
18175    && !flag_trapping_math"
18177   ix86_expand_lfloorceil (operand0, operand1, false);
18178   DONE;
18181 (define_expand "lceil<mode>si2"
18182   [(match_operand:SI 0 "nonimmediate_operand" "")
18183    (match_operand:MODEF 1 "register_operand" "")]
18184   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18185    && !flag_trapping_math"
18187   ix86_expand_lfloorceil (operand0, operand1, false);
18188   DONE;
18191 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18192 (define_insn_and_split "frndintxf2_trunc"
18193   [(set (match_operand:XF 0 "register_operand" "")
18194         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18195          UNSPEC_FRNDINT_TRUNC))
18196    (clobber (reg:CC FLAGS_REG))]
18197   "TARGET_USE_FANCY_MATH_387
18198    && flag_unsafe_math_optimizations
18199    && !(reload_completed || reload_in_progress)"
18200   "#"
18201   "&& 1"
18202   [(const_int 0)]
18204   ix86_optimize_mode_switching[I387_TRUNC] = 1;
18206   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18207   operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18209   emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18210                                         operands[2], operands[3]));
18211   DONE;
18213   [(set_attr "type" "frndint")
18214    (set_attr "i387_cw" "trunc")
18215    (set_attr "mode" "XF")])
18217 (define_insn "frndintxf2_trunc_i387"
18218   [(set (match_operand:XF 0 "register_operand" "=f")
18219         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18220          UNSPEC_FRNDINT_TRUNC))
18221    (use (match_operand:HI 2 "memory_operand" "m"))
18222    (use (match_operand:HI 3 "memory_operand" "m"))]
18223   "TARGET_USE_FANCY_MATH_387
18224    && flag_unsafe_math_optimizations"
18225   "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18226   [(set_attr "type" "frndint")
18227    (set_attr "i387_cw" "trunc")
18228    (set_attr "mode" "XF")])
18230 (define_expand "btruncxf2"
18231   [(use (match_operand:XF 0 "register_operand" ""))
18232    (use (match_operand:XF 1 "register_operand" ""))]
18233   "TARGET_USE_FANCY_MATH_387
18234    && flag_unsafe_math_optimizations && !optimize_size"
18236   emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18237   DONE;
18240 (define_expand "btrunc<mode>2"
18241   [(use (match_operand:MODEF 0 "register_operand" ""))
18242    (use (match_operand:MODEF 1 "register_operand" ""))]
18243   "(TARGET_USE_FANCY_MATH_387
18244     && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18245         || TARGET_MIX_SSE_I387)
18246     && flag_unsafe_math_optimizations && !optimize_size)
18247    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18248        && !flag_trapping_math
18249        && (TARGET_ROUND || !optimize_size))"
18251   if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18252       && !flag_trapping_math
18253       && (TARGET_ROUND || !optimize_size))
18254     {
18255       if (TARGET_ROUND)
18256         emit_insn (gen_sse4_1_round<mode>2
18257                    (operands[0], operands[1], GEN_INT (0x03)));
18258       else if (TARGET_64BIT || (<MODE>mode != DFmode))
18259         ix86_expand_trunc (operand0, operand1);
18260       else
18261         ix86_expand_truncdf_32 (operand0, operand1);
18262     }
18263   else
18264     {
18265       rtx op0 = gen_reg_rtx (XFmode);
18266       rtx op1 = gen_reg_rtx (XFmode);
18268       emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18269       emit_insn (gen_frndintxf2_trunc (op0, op1));
18271       emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18272     }
18273   DONE;
18276 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18277 (define_insn_and_split "frndintxf2_mask_pm"
18278   [(set (match_operand:XF 0 "register_operand" "")
18279         (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18280          UNSPEC_FRNDINT_MASK_PM))
18281    (clobber (reg:CC FLAGS_REG))]
18282   "TARGET_USE_FANCY_MATH_387
18283    && flag_unsafe_math_optimizations
18284    && !(reload_completed || reload_in_progress)"
18285   "#"
18286   "&& 1"
18287   [(const_int 0)]
18289   ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18291   operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18292   operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18294   emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18295                                           operands[2], operands[3]));
18296   DONE;
18298   [(set_attr "type" "frndint")
18299    (set_attr "i387_cw" "mask_pm")
18300    (set_attr "mode" "XF")])
18302 (define_insn "frndintxf2_mask_pm_i387"
18303   [(set (match_operand:XF 0 "register_operand" "=f")
18304         (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18305          UNSPEC_FRNDINT_MASK_PM))
18306    (use (match_operand:HI 2 "memory_operand" "m"))
18307    (use (match_operand:HI 3 "memory_operand" "m"))]
18308   "TARGET_USE_FANCY_MATH_387
18309    && flag_unsafe_math_optimizations"
18310   "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18311   [(set_attr "type" "frndint")
18312    (set_attr "i387_cw" "mask_pm")
18313    (set_attr "mode" "XF")])
18315 (define_expand "nearbyintxf2"
18316   [(use (match_operand:XF 0 "register_operand" ""))
18317    (use (match_operand:XF 1 "register_operand" ""))]
18318   "TARGET_USE_FANCY_MATH_387
18319    && flag_unsafe_math_optimizations"
18321   emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18323   DONE;
18326 (define_expand "nearbyint<mode>2"
18327   [(use (match_operand:MODEF 0 "register_operand" ""))
18328    (use (match_operand:MODEF 1 "register_operand" ""))]
18329   "TARGET_USE_FANCY_MATH_387
18330    && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18331        || TARGET_MIX_SSE_I387)
18332    && flag_unsafe_math_optimizations"
18334   rtx op0 = gen_reg_rtx (XFmode);
18335   rtx op1 = gen_reg_rtx (XFmode);
18337   emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18338   emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18340   emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18341   DONE;
18344 (define_insn "fxam<mode>2_i387"
18345   [(set (match_operand:HI 0 "register_operand" "=a")
18346         (unspec:HI
18347           [(match_operand:X87MODEF 1 "register_operand" "f")]
18348           UNSPEC_FXAM))]
18349   "TARGET_USE_FANCY_MATH_387"
18350   "fxam\n\tfnstsw\t%0"
18351   [(set_attr "type" "multi")
18352    (set_attr "unit" "i387")
18353    (set_attr "mode" "<MODE>")])
18355 (define_expand "isinf<mode>2"
18356   [(use (match_operand:SI 0 "register_operand" ""))
18357    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18358   "TARGET_USE_FANCY_MATH_387
18359    && TARGET_C99_FUNCTIONS
18360    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18362   rtx mask = GEN_INT (0x45);
18363   rtx val = GEN_INT (0x05);
18365   rtx cond;
18367   rtx scratch = gen_reg_rtx (HImode);
18368   rtx res = gen_reg_rtx (QImode);
18370   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18371   emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18372   emit_insn (gen_cmpqi_ext_3 (scratch, val));
18373   cond = gen_rtx_fmt_ee (EQ, QImode,
18374                          gen_rtx_REG (CCmode, FLAGS_REG),
18375                          const0_rtx);
18376   emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18377   emit_insn (gen_zero_extendqisi2 (operands[0], res));
18378   DONE;
18381 (define_expand "signbit<mode>2"
18382   [(use (match_operand:SI 0 "register_operand" ""))
18383    (use (match_operand:X87MODEF 1 "register_operand" ""))]
18384   "TARGET_USE_FANCY_MATH_387
18385    && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18387   rtx mask = GEN_INT (0x0200);
18389   rtx scratch = gen_reg_rtx (HImode);
18391   emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18392   emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18393   DONE;
18396 ;; Block operation instructions
18398 (define_insn "cld"
18399   [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18400   ""
18401   "cld"
18402   [(set_attr "length" "1")
18403    (set_attr "length_immediate" "0")
18404    (set_attr "modrm" "0")])
18406 (define_expand "movmemsi"
18407   [(use (match_operand:BLK 0 "memory_operand" ""))
18408    (use (match_operand:BLK 1 "memory_operand" ""))
18409    (use (match_operand:SI 2 "nonmemory_operand" ""))
18410    (use (match_operand:SI 3 "const_int_operand" ""))
18411    (use (match_operand:SI 4 "const_int_operand" ""))
18412    (use (match_operand:SI 5 "const_int_operand" ""))]
18413   ""
18415  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18416                          operands[4], operands[5]))
18417    DONE;
18418  else
18419    FAIL;
18422 (define_expand "movmemdi"
18423   [(use (match_operand:BLK 0 "memory_operand" ""))
18424    (use (match_operand:BLK 1 "memory_operand" ""))
18425    (use (match_operand:DI 2 "nonmemory_operand" ""))
18426    (use (match_operand:DI 3 "const_int_operand" ""))
18427    (use (match_operand:SI 4 "const_int_operand" ""))
18428    (use (match_operand:SI 5 "const_int_operand" ""))]
18429   "TARGET_64BIT"
18431  if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18432                          operands[4], operands[5]))
18433    DONE;
18434  else
18435    FAIL;
18438 ;; Most CPUs don't like single string operations
18439 ;; Handle this case here to simplify previous expander.
18441 (define_expand "strmov"
18442   [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18443    (set (match_operand 1 "memory_operand" "") (match_dup 4))
18444    (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18445               (clobber (reg:CC FLAGS_REG))])
18446    (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18447               (clobber (reg:CC FLAGS_REG))])]
18448   ""
18450   rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18452   /* If .md ever supports :P for Pmode, these can be directly
18453      in the pattern above.  */
18454   operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18455   operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18457   /* Can't use this if the user has appropriated esi or edi.  */
18458   if ((TARGET_SINGLE_STRINGOP || optimize_size)
18459       && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18460     {
18461       emit_insn (gen_strmov_singleop (operands[0], operands[1],
18462                                       operands[2], operands[3],
18463                                       operands[5], operands[6]));
18464       DONE;
18465     }
18467   operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18470 (define_expand "strmov_singleop"
18471   [(parallel [(set (match_operand 1 "memory_operand" "")
18472                    (match_operand 3 "memory_operand" ""))
18473               (set (match_operand 0 "register_operand" "")
18474                    (match_operand 4 "" ""))
18475               (set (match_operand 2 "register_operand" "")
18476                    (match_operand 5 "" ""))])]
18477   "TARGET_SINGLE_STRINGOP || optimize_size"
18478   "ix86_current_function_needs_cld = 1;")
18480 (define_insn "*strmovdi_rex_1"
18481   [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18482         (mem:DI (match_operand:DI 3 "register_operand" "1")))
18483    (set (match_operand:DI 0 "register_operand" "=D")
18484         (plus:DI (match_dup 2)
18485                  (const_int 8)))
18486    (set (match_operand:DI 1 "register_operand" "=S")
18487         (plus:DI (match_dup 3)
18488                  (const_int 8)))]
18489   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18490   "movsq"
18491   [(set_attr "type" "str")
18492    (set_attr "mode" "DI")
18493    (set_attr "memory" "both")])
18495 (define_insn "*strmovsi_1"
18496   [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18497         (mem:SI (match_operand:SI 3 "register_operand" "1")))
18498    (set (match_operand:SI 0 "register_operand" "=D")
18499         (plus:SI (match_dup 2)
18500                  (const_int 4)))
18501    (set (match_operand:SI 1 "register_operand" "=S")
18502         (plus:SI (match_dup 3)
18503                  (const_int 4)))]
18504   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18505   "movs{l|d}"
18506   [(set_attr "type" "str")
18507    (set_attr "mode" "SI")
18508    (set_attr "memory" "both")])
18510 (define_insn "*strmovsi_rex_1"
18511   [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18512         (mem:SI (match_operand:DI 3 "register_operand" "1")))
18513    (set (match_operand:DI 0 "register_operand" "=D")
18514         (plus:DI (match_dup 2)
18515                  (const_int 4)))
18516    (set (match_operand:DI 1 "register_operand" "=S")
18517         (plus:DI (match_dup 3)
18518                  (const_int 4)))]
18519   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18520   "movs{l|d}"
18521   [(set_attr "type" "str")
18522    (set_attr "mode" "SI")
18523    (set_attr "memory" "both")])
18525 (define_insn "*strmovhi_1"
18526   [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18527         (mem:HI (match_operand:SI 3 "register_operand" "1")))
18528    (set (match_operand:SI 0 "register_operand" "=D")
18529         (plus:SI (match_dup 2)
18530                  (const_int 2)))
18531    (set (match_operand:SI 1 "register_operand" "=S")
18532         (plus:SI (match_dup 3)
18533                  (const_int 2)))]
18534   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18535   "movsw"
18536   [(set_attr "type" "str")
18537    (set_attr "memory" "both")
18538    (set_attr "mode" "HI")])
18540 (define_insn "*strmovhi_rex_1"
18541   [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18542         (mem:HI (match_operand:DI 3 "register_operand" "1")))
18543    (set (match_operand:DI 0 "register_operand" "=D")
18544         (plus:DI (match_dup 2)
18545                  (const_int 2)))
18546    (set (match_operand:DI 1 "register_operand" "=S")
18547         (plus:DI (match_dup 3)
18548                  (const_int 2)))]
18549   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18550   "movsw"
18551   [(set_attr "type" "str")
18552    (set_attr "memory" "both")
18553    (set_attr "mode" "HI")])
18555 (define_insn "*strmovqi_1"
18556   [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18557         (mem:QI (match_operand:SI 3 "register_operand" "1")))
18558    (set (match_operand:SI 0 "register_operand" "=D")
18559         (plus:SI (match_dup 2)
18560                  (const_int 1)))
18561    (set (match_operand:SI 1 "register_operand" "=S")
18562         (plus:SI (match_dup 3)
18563                  (const_int 1)))]
18564   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18565   "movsb"
18566   [(set_attr "type" "str")
18567    (set_attr "memory" "both")
18568    (set_attr "mode" "QI")])
18570 (define_insn "*strmovqi_rex_1"
18571   [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18572         (mem:QI (match_operand:DI 3 "register_operand" "1")))
18573    (set (match_operand:DI 0 "register_operand" "=D")
18574         (plus:DI (match_dup 2)
18575                  (const_int 1)))
18576    (set (match_operand:DI 1 "register_operand" "=S")
18577         (plus:DI (match_dup 3)
18578                  (const_int 1)))]
18579   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18580   "movsb"
18581   [(set_attr "type" "str")
18582    (set_attr "memory" "both")
18583    (set_attr "mode" "QI")])
18585 (define_expand "rep_mov"
18586   [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18587               (set (match_operand 0 "register_operand" "")
18588                    (match_operand 5 "" ""))
18589               (set (match_operand 2 "register_operand" "")
18590                    (match_operand 6 "" ""))
18591               (set (match_operand 1 "memory_operand" "")
18592                    (match_operand 3 "memory_operand" ""))
18593               (use (match_dup 4))])]
18594   ""
18595   "ix86_current_function_needs_cld = 1;")
18597 (define_insn "*rep_movdi_rex64"
18598   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18599    (set (match_operand:DI 0 "register_operand" "=D")
18600         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18601                             (const_int 3))
18602                  (match_operand:DI 3 "register_operand" "0")))
18603    (set (match_operand:DI 1 "register_operand" "=S")
18604         (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18605                  (match_operand:DI 4 "register_operand" "1")))
18606    (set (mem:BLK (match_dup 3))
18607         (mem:BLK (match_dup 4)))
18608    (use (match_dup 5))]
18609   "TARGET_64BIT"
18610   "rep movsq"
18611   [(set_attr "type" "str")
18612    (set_attr "prefix_rep" "1")
18613    (set_attr "memory" "both")
18614    (set_attr "mode" "DI")])
18616 (define_insn "*rep_movsi"
18617   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18618    (set (match_operand:SI 0 "register_operand" "=D")
18619         (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18620                             (const_int 2))
18621                  (match_operand:SI 3 "register_operand" "0")))
18622    (set (match_operand:SI 1 "register_operand" "=S")
18623         (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18624                  (match_operand:SI 4 "register_operand" "1")))
18625    (set (mem:BLK (match_dup 3))
18626         (mem:BLK (match_dup 4)))
18627    (use (match_dup 5))]
18628   "!TARGET_64BIT"
18629   "rep movs{l|d}"
18630   [(set_attr "type" "str")
18631    (set_attr "prefix_rep" "1")
18632    (set_attr "memory" "both")
18633    (set_attr "mode" "SI")])
18635 (define_insn "*rep_movsi_rex64"
18636   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18637    (set (match_operand:DI 0 "register_operand" "=D")
18638         (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18639                             (const_int 2))
18640                  (match_operand:DI 3 "register_operand" "0")))
18641    (set (match_operand:DI 1 "register_operand" "=S")
18642         (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18643                  (match_operand:DI 4 "register_operand" "1")))
18644    (set (mem:BLK (match_dup 3))
18645         (mem:BLK (match_dup 4)))
18646    (use (match_dup 5))]
18647   "TARGET_64BIT"
18648   "rep movs{l|d}"
18649   [(set_attr "type" "str")
18650    (set_attr "prefix_rep" "1")
18651    (set_attr "memory" "both")
18652    (set_attr "mode" "SI")])
18654 (define_insn "*rep_movqi"
18655   [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18656    (set (match_operand:SI 0 "register_operand" "=D")
18657         (plus:SI (match_operand:SI 3 "register_operand" "0")
18658                  (match_operand:SI 5 "register_operand" "2")))
18659    (set (match_operand:SI 1 "register_operand" "=S")
18660         (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18661    (set (mem:BLK (match_dup 3))
18662         (mem:BLK (match_dup 4)))
18663    (use (match_dup 5))]
18664   "!TARGET_64BIT"
18665   "rep movsb"
18666   [(set_attr "type" "str")
18667    (set_attr "prefix_rep" "1")
18668    (set_attr "memory" "both")
18669    (set_attr "mode" "SI")])
18671 (define_insn "*rep_movqi_rex64"
18672   [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18673    (set (match_operand:DI 0 "register_operand" "=D")
18674         (plus:DI (match_operand:DI 3 "register_operand" "0")
18675                  (match_operand:DI 5 "register_operand" "2")))
18676    (set (match_operand:DI 1 "register_operand" "=S")
18677         (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18678    (set (mem:BLK (match_dup 3))
18679         (mem:BLK (match_dup 4)))
18680    (use (match_dup 5))]
18681   "TARGET_64BIT"
18682   "rep movsb"
18683   [(set_attr "type" "str")
18684    (set_attr "prefix_rep" "1")
18685    (set_attr "memory" "both")
18686    (set_attr "mode" "SI")])
18688 (define_expand "setmemsi"
18689    [(use (match_operand:BLK 0 "memory_operand" ""))
18690     (use (match_operand:SI 1 "nonmemory_operand" ""))
18691     (use (match_operand 2 "const_int_operand" ""))
18692     (use (match_operand 3 "const_int_operand" ""))
18693     (use (match_operand:SI 4 "const_int_operand" ""))
18694     (use (match_operand:SI 5 "const_int_operand" ""))]
18695   ""
18697  if (ix86_expand_setmem (operands[0], operands[1],
18698                          operands[2], operands[3],
18699                          operands[4], operands[5]))
18700    DONE;
18701  else
18702    FAIL;
18705 (define_expand "setmemdi"
18706    [(use (match_operand:BLK 0 "memory_operand" ""))
18707     (use (match_operand:DI 1 "nonmemory_operand" ""))
18708     (use (match_operand 2 "const_int_operand" ""))
18709     (use (match_operand 3 "const_int_operand" ""))
18710     (use (match_operand 4 "const_int_operand" ""))
18711     (use (match_operand 5 "const_int_operand" ""))]
18712   "TARGET_64BIT"
18714  if (ix86_expand_setmem (operands[0], operands[1],
18715                          operands[2], operands[3],
18716                          operands[4], operands[5]))
18717    DONE;
18718  else
18719    FAIL;
18722 ;; Most CPUs don't like single string operations
18723 ;; Handle this case here to simplify previous expander.
18725 (define_expand "strset"
18726   [(set (match_operand 1 "memory_operand" "")
18727         (match_operand 2 "register_operand" ""))
18728    (parallel [(set (match_operand 0 "register_operand" "")
18729                    (match_dup 3))
18730               (clobber (reg:CC FLAGS_REG))])]
18731   ""
18733   if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18734     operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18736   /* If .md ever supports :P for Pmode, this can be directly
18737      in the pattern above.  */
18738   operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18739                               GEN_INT (GET_MODE_SIZE (GET_MODE
18740                                                       (operands[2]))));
18741   if (TARGET_SINGLE_STRINGOP || optimize_size)
18742     {
18743       emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18744                                       operands[3]));
18745       DONE;
18746     }
18749 (define_expand "strset_singleop"
18750   [(parallel [(set (match_operand 1 "memory_operand" "")
18751                    (match_operand 2 "register_operand" ""))
18752               (set (match_operand 0 "register_operand" "")
18753                    (match_operand 3 "" ""))])]
18754   "TARGET_SINGLE_STRINGOP || optimize_size"
18755   "ix86_current_function_needs_cld = 1;")
18757 (define_insn "*strsetdi_rex_1"
18758   [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18759         (match_operand:DI 2 "register_operand" "a"))
18760    (set (match_operand:DI 0 "register_operand" "=D")
18761         (plus:DI (match_dup 1)
18762                  (const_int 8)))]
18763   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18764   "stosq"
18765   [(set_attr "type" "str")
18766    (set_attr "memory" "store")
18767    (set_attr "mode" "DI")])
18769 (define_insn "*strsetsi_1"
18770   [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18771         (match_operand:SI 2 "register_operand" "a"))
18772    (set (match_operand:SI 0 "register_operand" "=D")
18773         (plus:SI (match_dup 1)
18774                  (const_int 4)))]
18775   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18776   "stos{l|d}"
18777   [(set_attr "type" "str")
18778    (set_attr "memory" "store")
18779    (set_attr "mode" "SI")])
18781 (define_insn "*strsetsi_rex_1"
18782   [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18783         (match_operand:SI 2 "register_operand" "a"))
18784    (set (match_operand:DI 0 "register_operand" "=D")
18785         (plus:DI (match_dup 1)
18786                  (const_int 4)))]
18787   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18788   "stos{l|d}"
18789   [(set_attr "type" "str")
18790    (set_attr "memory" "store")
18791    (set_attr "mode" "SI")])
18793 (define_insn "*strsethi_1"
18794   [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18795         (match_operand:HI 2 "register_operand" "a"))
18796    (set (match_operand:SI 0 "register_operand" "=D")
18797         (plus:SI (match_dup 1)
18798                  (const_int 2)))]
18799   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18800   "stosw"
18801   [(set_attr "type" "str")
18802    (set_attr "memory" "store")
18803    (set_attr "mode" "HI")])
18805 (define_insn "*strsethi_rex_1"
18806   [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18807         (match_operand:HI 2 "register_operand" "a"))
18808    (set (match_operand:DI 0 "register_operand" "=D")
18809         (plus:DI (match_dup 1)
18810                  (const_int 2)))]
18811   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18812   "stosw"
18813   [(set_attr "type" "str")
18814    (set_attr "memory" "store")
18815    (set_attr "mode" "HI")])
18817 (define_insn "*strsetqi_1"
18818   [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18819         (match_operand:QI 2 "register_operand" "a"))
18820    (set (match_operand:SI 0 "register_operand" "=D")
18821         (plus:SI (match_dup 1)
18822                  (const_int 1)))]
18823   "!TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18824   "stosb"
18825   [(set_attr "type" "str")
18826    (set_attr "memory" "store")
18827    (set_attr "mode" "QI")])
18829 (define_insn "*strsetqi_rex_1"
18830   [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18831         (match_operand:QI 2 "register_operand" "a"))
18832    (set (match_operand:DI 0 "register_operand" "=D")
18833         (plus:DI (match_dup 1)
18834                  (const_int 1)))]
18835   "TARGET_64BIT && (TARGET_SINGLE_STRINGOP || optimize_size)"
18836   "stosb"
18837   [(set_attr "type" "str")
18838    (set_attr "memory" "store")
18839    (set_attr "mode" "QI")])
18841 (define_expand "rep_stos"
18842   [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18843               (set (match_operand 0 "register_operand" "")
18844                    (match_operand 4 "" ""))
18845               (set (match_operand 2 "memory_operand" "") (const_int 0))
18846               (use (match_operand 3 "register_operand" ""))
18847               (use (match_dup 1))])]
18848   ""
18849   "ix86_current_function_needs_cld = 1;")
18851 (define_insn "*rep_stosdi_rex64"
18852   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18853    (set (match_operand:DI 0 "register_operand" "=D")
18854         (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18855                             (const_int 3))
18856                  (match_operand:DI 3 "register_operand" "0")))
18857    (set (mem:BLK (match_dup 3))
18858         (const_int 0))
18859    (use (match_operand:DI 2 "register_operand" "a"))
18860    (use (match_dup 4))]
18861   "TARGET_64BIT"
18862   "rep stosq"
18863   [(set_attr "type" "str")
18864    (set_attr "prefix_rep" "1")
18865    (set_attr "memory" "store")
18866    (set_attr "mode" "DI")])
18868 (define_insn "*rep_stossi"
18869   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18870    (set (match_operand:SI 0 "register_operand" "=D")
18871         (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18872                             (const_int 2))
18873                  (match_operand:SI 3 "register_operand" "0")))
18874    (set (mem:BLK (match_dup 3))
18875         (const_int 0))
18876    (use (match_operand:SI 2 "register_operand" "a"))
18877    (use (match_dup 4))]
18878   "!TARGET_64BIT"
18879   "rep stos{l|d}"
18880   [(set_attr "type" "str")
18881    (set_attr "prefix_rep" "1")
18882    (set_attr "memory" "store")
18883    (set_attr "mode" "SI")])
18885 (define_insn "*rep_stossi_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 (ashift:DI (match_operand:DI 4 "register_operand" "1")
18889                             (const_int 2))
18890                  (match_operand:DI 3 "register_operand" "0")))
18891    (set (mem:BLK (match_dup 3))
18892         (const_int 0))
18893    (use (match_operand:SI 2 "register_operand" "a"))
18894    (use (match_dup 4))]
18895   "TARGET_64BIT"
18896   "rep stos{l|d}"
18897   [(set_attr "type" "str")
18898    (set_attr "prefix_rep" "1")
18899    (set_attr "memory" "store")
18900    (set_attr "mode" "SI")])
18902 (define_insn "*rep_stosqi"
18903   [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18904    (set (match_operand:SI 0 "register_operand" "=D")
18905         (plus:SI (match_operand:SI 3 "register_operand" "0")
18906                  (match_operand:SI 4 "register_operand" "1")))
18907    (set (mem:BLK (match_dup 3))
18908         (const_int 0))
18909    (use (match_operand:QI 2 "register_operand" "a"))
18910    (use (match_dup 4))]
18911   "!TARGET_64BIT"
18912   "rep stosb"
18913   [(set_attr "type" "str")
18914    (set_attr "prefix_rep" "1")
18915    (set_attr "memory" "store")
18916    (set_attr "mode" "QI")])
18918 (define_insn "*rep_stosqi_rex64"
18919   [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18920    (set (match_operand:DI 0 "register_operand" "=D")
18921         (plus:DI (match_operand:DI 3 "register_operand" "0")
18922                  (match_operand:DI 4 "register_operand" "1")))
18923    (set (mem:BLK (match_dup 3))
18924         (const_int 0))
18925    (use (match_operand:QI 2 "register_operand" "a"))
18926    (use (match_dup 4))]
18927   "TARGET_64BIT"
18928   "rep stosb"
18929   [(set_attr "type" "str")
18930    (set_attr "prefix_rep" "1")
18931    (set_attr "memory" "store")
18932    (set_attr "mode" "QI")])
18934 (define_expand "cmpstrnsi"
18935   [(set (match_operand:SI 0 "register_operand" "")
18936         (compare:SI (match_operand:BLK 1 "general_operand" "")
18937                     (match_operand:BLK 2 "general_operand" "")))
18938    (use (match_operand 3 "general_operand" ""))
18939    (use (match_operand 4 "immediate_operand" ""))]
18940   "! optimize_size || TARGET_INLINE_ALL_STRINGOPS"
18942   rtx addr1, addr2, out, outlow, count, countreg, align;
18944   /* Can't use this if the user has appropriated esi or edi.  */
18945   if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18946     FAIL;
18948   out = operands[0];
18949   if (!REG_P (out))
18950     out = gen_reg_rtx (SImode);
18952   addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18953   addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18954   if (addr1 != XEXP (operands[1], 0))
18955     operands[1] = replace_equiv_address_nv (operands[1], addr1);
18956   if (addr2 != XEXP (operands[2], 0))
18957     operands[2] = replace_equiv_address_nv (operands[2], addr2);
18959   count = operands[3];
18960   countreg = ix86_zero_extend_to_Pmode (count);
18962   /* %%% Iff we are testing strict equality, we can use known alignment
18963      to good advantage.  This may be possible with combine, particularly
18964      once cc0 is dead.  */
18965   align = operands[4];
18967   if (CONST_INT_P (count))
18968     {
18969       if (INTVAL (count) == 0)
18970         {
18971           emit_move_insn (operands[0], const0_rtx);
18972           DONE;
18973         }
18974       emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18975                                      operands[1], operands[2]));
18976     }
18977   else
18978     {
18979       if (TARGET_64BIT)
18980         emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
18981       else
18982         emit_insn (gen_cmpsi_1 (countreg, countreg));
18983       emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18984                                   operands[1], operands[2]));
18985     }
18987   outlow = gen_lowpart (QImode, out);
18988   emit_insn (gen_cmpintqi (outlow));
18989   emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18991   if (operands[0] != out)
18992     emit_move_insn (operands[0], out);
18994   DONE;
18997 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18999 (define_expand "cmpintqi"
19000   [(set (match_dup 1)
19001         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19002    (set (match_dup 2)
19003         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19004    (parallel [(set (match_operand:QI 0 "register_operand" "")
19005                    (minus:QI (match_dup 1)
19006                              (match_dup 2)))
19007               (clobber (reg:CC FLAGS_REG))])]
19008   ""
19009   "operands[1] = gen_reg_rtx (QImode);
19010    operands[2] = gen_reg_rtx (QImode);")
19012 ;; memcmp recognizers.  The `cmpsb' opcode does nothing if the count is
19013 ;; zero.  Emit extra code to make sure that a zero-length compare is EQ.
19015 (define_expand "cmpstrnqi_nz_1"
19016   [(parallel [(set (reg:CC FLAGS_REG)
19017                    (compare:CC (match_operand 4 "memory_operand" "")
19018                                (match_operand 5 "memory_operand" "")))
19019               (use (match_operand 2 "register_operand" ""))
19020               (use (match_operand:SI 3 "immediate_operand" ""))
19021               (clobber (match_operand 0 "register_operand" ""))
19022               (clobber (match_operand 1 "register_operand" ""))
19023               (clobber (match_dup 2))])]
19024   ""
19025   "ix86_current_function_needs_cld = 1;")
19027 (define_insn "*cmpstrnqi_nz_1"
19028   [(set (reg:CC FLAGS_REG)
19029         (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19030                     (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19031    (use (match_operand:SI 6 "register_operand" "2"))
19032    (use (match_operand:SI 3 "immediate_operand" "i"))
19033    (clobber (match_operand:SI 0 "register_operand" "=S"))
19034    (clobber (match_operand:SI 1 "register_operand" "=D"))
19035    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19036   "!TARGET_64BIT"
19037   "repz cmpsb"
19038   [(set_attr "type" "str")
19039    (set_attr "mode" "QI")
19040    (set_attr "prefix_rep" "1")])
19042 (define_insn "*cmpstrnqi_nz_rex_1"
19043   [(set (reg:CC FLAGS_REG)
19044         (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19045                     (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19046    (use (match_operand:DI 6 "register_operand" "2"))
19047    (use (match_operand:SI 3 "immediate_operand" "i"))
19048    (clobber (match_operand:DI 0 "register_operand" "=S"))
19049    (clobber (match_operand:DI 1 "register_operand" "=D"))
19050    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19051   "TARGET_64BIT"
19052   "repz cmpsb"
19053   [(set_attr "type" "str")
19054    (set_attr "mode" "QI")
19055    (set_attr "prefix_rep" "1")])
19057 ;; The same, but the count is not known to not be zero.
19059 (define_expand "cmpstrnqi_1"
19060   [(parallel [(set (reg:CC FLAGS_REG)
19061                 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19062                                      (const_int 0))
19063                   (compare:CC (match_operand 4 "memory_operand" "")
19064                               (match_operand 5 "memory_operand" ""))
19065                   (const_int 0)))
19066               (use (match_operand:SI 3 "immediate_operand" ""))
19067               (use (reg:CC FLAGS_REG))
19068               (clobber (match_operand 0 "register_operand" ""))
19069               (clobber (match_operand 1 "register_operand" ""))
19070               (clobber (match_dup 2))])]
19071   ""
19072   "ix86_current_function_needs_cld = 1;")
19074 (define_insn "*cmpstrnqi_1"
19075   [(set (reg:CC FLAGS_REG)
19076         (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19077                              (const_int 0))
19078           (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19079                       (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19080           (const_int 0)))
19081    (use (match_operand:SI 3 "immediate_operand" "i"))
19082    (use (reg:CC FLAGS_REG))
19083    (clobber (match_operand:SI 0 "register_operand" "=S"))
19084    (clobber (match_operand:SI 1 "register_operand" "=D"))
19085    (clobber (match_operand:SI 2 "register_operand" "=c"))]
19086   "!TARGET_64BIT"
19087   "repz cmpsb"
19088   [(set_attr "type" "str")
19089    (set_attr "mode" "QI")
19090    (set_attr "prefix_rep" "1")])
19092 (define_insn "*cmpstrnqi_rex_1"
19093   [(set (reg:CC FLAGS_REG)
19094         (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19095                              (const_int 0))
19096           (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19097                       (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19098           (const_int 0)))
19099    (use (match_operand:SI 3 "immediate_operand" "i"))
19100    (use (reg:CC FLAGS_REG))
19101    (clobber (match_operand:DI 0 "register_operand" "=S"))
19102    (clobber (match_operand:DI 1 "register_operand" "=D"))
19103    (clobber (match_operand:DI 2 "register_operand" "=c"))]
19104   "TARGET_64BIT"
19105   "repz cmpsb"
19106   [(set_attr "type" "str")
19107    (set_attr "mode" "QI")
19108    (set_attr "prefix_rep" "1")])
19110 (define_expand "strlensi"
19111   [(set (match_operand:SI 0 "register_operand" "")
19112         (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19113                     (match_operand:QI 2 "immediate_operand" "")
19114                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19115   ""
19117  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19118    DONE;
19119  else
19120    FAIL;
19123 (define_expand "strlendi"
19124   [(set (match_operand:DI 0 "register_operand" "")
19125         (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19126                     (match_operand:QI 2 "immediate_operand" "")
19127                     (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19128   ""
19130  if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19131    DONE;
19132  else
19133    FAIL;
19136 (define_expand "strlenqi_1"
19137   [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19138               (clobber (match_operand 1 "register_operand" ""))
19139               (clobber (reg:CC FLAGS_REG))])]
19140   ""
19141   "ix86_current_function_needs_cld = 1;")
19143 (define_insn "*strlenqi_1"
19144   [(set (match_operand:SI 0 "register_operand" "=&c")
19145         (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19146                     (match_operand:QI 2 "register_operand" "a")
19147                     (match_operand:SI 3 "immediate_operand" "i")
19148                     (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19149    (clobber (match_operand:SI 1 "register_operand" "=D"))
19150    (clobber (reg:CC FLAGS_REG))]
19151   "!TARGET_64BIT"
19152   "repnz scasb"
19153   [(set_attr "type" "str")
19154    (set_attr "mode" "QI")
19155    (set_attr "prefix_rep" "1")])
19157 (define_insn "*strlenqi_rex_1"
19158   [(set (match_operand:DI 0 "register_operand" "=&c")
19159         (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19160                     (match_operand:QI 2 "register_operand" "a")
19161                     (match_operand:DI 3 "immediate_operand" "i")
19162                     (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19163    (clobber (match_operand:DI 1 "register_operand" "=D"))
19164    (clobber (reg:CC FLAGS_REG))]
19165   "TARGET_64BIT"
19166   "repnz scasb"
19167   [(set_attr "type" "str")
19168    (set_attr "mode" "QI")
19169    (set_attr "prefix_rep" "1")])
19171 ;; Peephole optimizations to clean up after cmpstrn*.  This should be
19172 ;; handled in combine, but it is not currently up to the task.
19173 ;; When used for their truth value, the cmpstrn* expanders generate
19174 ;; code like this:
19176 ;;   repz cmpsb
19177 ;;   seta       %al
19178 ;;   setb       %dl
19179 ;;   cmpb       %al, %dl
19180 ;;   jcc        label
19182 ;; The intermediate three instructions are unnecessary.
19184 ;; This one handles cmpstrn*_nz_1...
19185 (define_peephole2
19186   [(parallel[
19187      (set (reg:CC FLAGS_REG)
19188           (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19189                       (mem:BLK (match_operand 5 "register_operand" ""))))
19190      (use (match_operand 6 "register_operand" ""))
19191      (use (match_operand:SI 3 "immediate_operand" ""))
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           (compare:CC (mem:BLK (match_dup 4))
19206                       (mem:BLK (match_dup 5))))
19207      (use (match_dup 6))
19208      (use (match_dup 3))
19209      (clobber (match_dup 0))
19210      (clobber (match_dup 1))
19211      (clobber (match_dup 2))])]
19212   "")
19214 ;; ...and this one handles cmpstrn*_1.
19215 (define_peephole2
19216   [(parallel[
19217      (set (reg:CC FLAGS_REG)
19218           (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19219                                (const_int 0))
19220             (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19221                         (mem:BLK (match_operand 5 "register_operand" "")))
19222             (const_int 0)))
19223      (use (match_operand:SI 3 "immediate_operand" ""))
19224      (use (reg:CC FLAGS_REG))
19225      (clobber (match_operand 0 "register_operand" ""))
19226      (clobber (match_operand 1 "register_operand" ""))
19227      (clobber (match_operand 2 "register_operand" ""))])
19228    (set (match_operand:QI 7 "register_operand" "")
19229         (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19230    (set (match_operand:QI 8 "register_operand" "")
19231         (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19232    (set (reg FLAGS_REG)
19233         (compare (match_dup 7) (match_dup 8)))
19234   ]
19235   "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19236   [(parallel[
19237      (set (reg:CC FLAGS_REG)
19238           (if_then_else:CC (ne (match_dup 6)
19239                                (const_int 0))
19240             (compare:CC (mem:BLK (match_dup 4))
19241                         (mem:BLK (match_dup 5)))
19242             (const_int 0)))
19243      (use (match_dup 3))
19244      (use (reg:CC FLAGS_REG))
19245      (clobber (match_dup 0))
19246      (clobber (match_dup 1))
19247      (clobber (match_dup 2))])]
19248   "")
19252 ;; Conditional move instructions.
19254 (define_expand "movdicc"
19255   [(set (match_operand:DI 0 "register_operand" "")
19256         (if_then_else:DI (match_operand 1 "comparison_operator" "")
19257                          (match_operand:DI 2 "general_operand" "")
19258                          (match_operand:DI 3 "general_operand" "")))]
19259   "TARGET_64BIT"
19260   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19262 (define_insn "x86_movdicc_0_m1_rex64"
19263   [(set (match_operand:DI 0 "register_operand" "=r")
19264         (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
19265           (const_int -1)
19266           (const_int 0)))
19267    (clobber (reg:CC FLAGS_REG))]
19268   "TARGET_64BIT"
19269   "sbb{q}\t%0, %0"
19270   ; Since we don't have the proper number of operands for an alu insn,
19271   ; fill in all the blanks.
19272   [(set_attr "type" "alu")
19273    (set_attr "pent_pair" "pu")
19274    (set_attr "memory" "none")
19275    (set_attr "imm_disp" "false")
19276    (set_attr "mode" "DI")
19277    (set_attr "length_immediate" "0")])
19279 (define_insn "*x86_movdicc_0_m1_se"
19280   [(set (match_operand:DI 0 "register_operand" "=r")
19281         (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
19282                          (const_int 1)
19283                          (const_int 0)))
19284    (clobber (reg:CC FLAGS_REG))]
19285   ""
19286   "sbb{q}\t%0, %0"
19287   [(set_attr "type" "alu")
19288    (set_attr "pent_pair" "pu")
19289    (set_attr "memory" "none")
19290    (set_attr "imm_disp" "false")
19291    (set_attr "mode" "DI")
19292    (set_attr "length_immediate" "0")])
19294 (define_insn "*movdicc_c_rex64"
19295   [(set (match_operand:DI 0 "register_operand" "=r,r")
19296         (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
19297                                 [(reg FLAGS_REG) (const_int 0)])
19298                       (match_operand:DI 2 "nonimmediate_operand" "rm,0")
19299                       (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
19300   "TARGET_64BIT && TARGET_CMOVE
19301    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19302   "@
19303    cmov%O2%C1\t{%2, %0|%0, %2}
19304    cmov%O2%c1\t{%3, %0|%0, %3}"
19305   [(set_attr "type" "icmov")
19306    (set_attr "mode" "DI")])
19308 (define_expand "movsicc"
19309   [(set (match_operand:SI 0 "register_operand" "")
19310         (if_then_else:SI (match_operand 1 "comparison_operator" "")
19311                          (match_operand:SI 2 "general_operand" "")
19312                          (match_operand:SI 3 "general_operand" "")))]
19313   ""
19314   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19316 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19317 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19318 ;; So just document what we're doing explicitly.
19320 (define_insn "x86_movsicc_0_m1"
19321   [(set (match_operand:SI 0 "register_operand" "=r")
19322         (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
19323           (const_int -1)
19324           (const_int 0)))
19325    (clobber (reg:CC FLAGS_REG))]
19326   ""
19327   "sbb{l}\t%0, %0"
19328   ; Since we don't have the proper number of operands for an alu insn,
19329   ; fill in all the blanks.
19330   [(set_attr "type" "alu")
19331    (set_attr "pent_pair" "pu")
19332    (set_attr "memory" "none")
19333    (set_attr "imm_disp" "false")
19334    (set_attr "mode" "SI")
19335    (set_attr "length_immediate" "0")])
19337 (define_insn "*x86_movsicc_0_m1_se"
19338   [(set (match_operand:SI 0 "register_operand" "=r")
19339         (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
19340                          (const_int 1)
19341                          (const_int 0)))
19342    (clobber (reg:CC FLAGS_REG))]
19343   ""
19344   "sbb{l}\t%0, %0"
19345   [(set_attr "type" "alu")
19346    (set_attr "pent_pair" "pu")
19347    (set_attr "memory" "none")
19348    (set_attr "imm_disp" "false")
19349    (set_attr "mode" "SI")
19350    (set_attr "length_immediate" "0")])
19352 (define_insn "*movsicc_noc"
19353   [(set (match_operand:SI 0 "register_operand" "=r,r")
19354         (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
19355                                 [(reg FLAGS_REG) (const_int 0)])
19356                       (match_operand:SI 2 "nonimmediate_operand" "rm,0")
19357                       (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
19358   "TARGET_CMOVE
19359    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19360   "@
19361    cmov%O2%C1\t{%2, %0|%0, %2}
19362    cmov%O2%c1\t{%3, %0|%0, %3}"
19363   [(set_attr "type" "icmov")
19364    (set_attr "mode" "SI")])
19366 (define_expand "movhicc"
19367   [(set (match_operand:HI 0 "register_operand" "")
19368         (if_then_else:HI (match_operand 1 "comparison_operator" "")
19369                          (match_operand:HI 2 "general_operand" "")
19370                          (match_operand:HI 3 "general_operand" "")))]
19371   "TARGET_HIMODE_MATH"
19372   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19374 (define_insn "*movhicc_noc"
19375   [(set (match_operand:HI 0 "register_operand" "=r,r")
19376         (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
19377                                 [(reg FLAGS_REG) (const_int 0)])
19378                       (match_operand:HI 2 "nonimmediate_operand" "rm,0")
19379                       (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
19380   "TARGET_CMOVE
19381    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19382   "@
19383    cmov%O2%C1\t{%2, %0|%0, %2}
19384    cmov%O2%c1\t{%3, %0|%0, %3}"
19385   [(set_attr "type" "icmov")
19386    (set_attr "mode" "HI")])
19388 (define_expand "movqicc"
19389   [(set (match_operand:QI 0 "register_operand" "")
19390         (if_then_else:QI (match_operand 1 "comparison_operator" "")
19391                          (match_operand:QI 2 "general_operand" "")
19392                          (match_operand:QI 3 "general_operand" "")))]
19393   "TARGET_QIMODE_MATH"
19394   "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19396 (define_insn_and_split "*movqicc_noc"
19397   [(set (match_operand:QI 0 "register_operand" "=r,r")
19398         (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19399                                 [(match_operand 4 "flags_reg_operand" "")
19400                                  (const_int 0)])
19401                       (match_operand:QI 2 "register_operand" "r,0")
19402                       (match_operand:QI 3 "register_operand" "0,r")))]
19403   "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19404   "#"
19405   "&& reload_completed"
19406   [(set (match_dup 0)
19407         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19408                       (match_dup 2)
19409                       (match_dup 3)))]
19410   "operands[0] = gen_lowpart (SImode, operands[0]);
19411    operands[2] = gen_lowpart (SImode, operands[2]);
19412    operands[3] = gen_lowpart (SImode, operands[3]);"
19413   [(set_attr "type" "icmov")
19414    (set_attr "mode" "SI")])
19416 (define_expand "mov<mode>cc"
19417   [(set (match_operand:X87MODEF 0 "register_operand" "")
19418         (if_then_else:X87MODEF
19419           (match_operand 1 "comparison_operator" "")
19420           (match_operand:X87MODEF 2 "register_operand" "")
19421           (match_operand:X87MODEF 3 "register_operand" "")))]
19422   "(TARGET_80387 && TARGET_CMOVE)
19423    || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19424   "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19426 (define_insn "*movsfcc_1_387"
19427   [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19428         (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19429                                 [(reg FLAGS_REG) (const_int 0)])
19430                       (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19431                       (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19432   "TARGET_80387 && TARGET_CMOVE
19433    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19434   "@
19435    fcmov%F1\t{%2, %0|%0, %2}
19436    fcmov%f1\t{%3, %0|%0, %3}
19437    cmov%O2%C1\t{%2, %0|%0, %2}
19438    cmov%O2%c1\t{%3, %0|%0, %3}"
19439   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19440    (set_attr "mode" "SF,SF,SI,SI")])
19442 (define_insn "*movdfcc_1"
19443   [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19444         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19445                                 [(reg FLAGS_REG) (const_int 0)])
19446                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19447                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19448   "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19449    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19450   "@
19451    fcmov%F1\t{%2, %0|%0, %2}
19452    fcmov%f1\t{%3, %0|%0, %3}
19453    #
19454    #"
19455   [(set_attr "type" "fcmov,fcmov,multi,multi")
19456    (set_attr "mode" "DF")])
19458 (define_insn "*movdfcc_1_rex64"
19459   [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19460         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19461                                 [(reg FLAGS_REG) (const_int 0)])
19462                       (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19463                       (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19464   "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19465    && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19466   "@
19467    fcmov%F1\t{%2, %0|%0, %2}
19468    fcmov%f1\t{%3, %0|%0, %3}
19469    cmov%O2%C1\t{%2, %0|%0, %2}
19470    cmov%O2%c1\t{%3, %0|%0, %3}"
19471   [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19472    (set_attr "mode" "DF")])
19474 (define_split
19475   [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19476         (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19477                                 [(match_operand 4 "flags_reg_operand" "")
19478                                  (const_int 0)])
19479                       (match_operand:DF 2 "nonimmediate_operand" "")
19480                       (match_operand:DF 3 "nonimmediate_operand" "")))]
19481   "!TARGET_64BIT && reload_completed"
19482   [(set (match_dup 2)
19483         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19484                       (match_dup 5)
19485                       (match_dup 6)))
19486    (set (match_dup 3)
19487         (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19488                       (match_dup 7)
19489                       (match_dup 8)))]
19490   "split_di (&operands[2], 2, &operands[5], &operands[7]);
19491    split_di (&operands[0], 1, &operands[2], &operands[3]);")
19493 (define_insn "*movxfcc_1"
19494   [(set (match_operand:XF 0 "register_operand" "=f,f")
19495         (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19496                                 [(reg FLAGS_REG) (const_int 0)])
19497                       (match_operand:XF 2 "register_operand" "f,0")
19498                       (match_operand:XF 3 "register_operand" "0,f")))]
19499   "TARGET_80387 && TARGET_CMOVE"
19500   "@
19501    fcmov%F1\t{%2, %0|%0, %2}
19502    fcmov%f1\t{%3, %0|%0, %3}"
19503   [(set_attr "type" "fcmov")
19504    (set_attr "mode" "XF")])
19506 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
19507 ;; the scalar versions to have only XMM registers as operands.
19509 ;; SSE5 conditional move
19510 (define_insn "*sse5_pcmov_<mode>"
19511   [(set (match_operand:MODEF 0 "register_operand" "=x,x")
19512         (if_then_else:MODEF
19513           (match_operand:MODEF 1 "register_operand" "x,0")
19514           (match_operand:MODEF 2 "register_operand" "0,x")
19515           (match_operand:MODEF 3 "register_operand" "x,x")))]
19516   "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1)"
19517   "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19518   [(set_attr "type" "sse4arg")])
19520 ;; These versions of the min/max patterns are intentionally ignorant of
19521 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19522 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19523 ;; are undefined in this condition, we're certain this is correct.
19525 (define_insn "<code><mode>3"
19526   [(set (match_operand:MODEF 0 "register_operand" "=x")
19527         (smaxmin:MODEF
19528           (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19529           (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19530   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19531   "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19532   [(set_attr "type" "sseadd")
19533    (set_attr "mode" "<MODE>")])
19535 ;; These versions of the min/max patterns implement exactly the operations
19536 ;;   min = (op1 < op2 ? op1 : op2)
19537 ;;   max = (!(op1 < op2) ? op1 : op2)
19538 ;; Their operands are not commutative, and thus they may be used in the
19539 ;; presence of -0.0 and NaN.
19541 (define_insn "*ieee_smin<mode>3"
19542   [(set (match_operand:MODEF 0 "register_operand" "=x")
19543         (unspec:MODEF
19544           [(match_operand:MODEF 1 "register_operand" "0")
19545            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19546          UNSPEC_IEEE_MIN))]
19547   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19548   "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19549   [(set_attr "type" "sseadd")
19550    (set_attr "mode" "<MODE>")])
19552 (define_insn "*ieee_smax<mode>3"
19553   [(set (match_operand:MODEF 0 "register_operand" "=x")
19554         (unspec:MODEF
19555           [(match_operand:MODEF 1 "register_operand" "0")
19556            (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19557          UNSPEC_IEEE_MAX))]
19558   "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19559   "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19560   [(set_attr "type" "sseadd")
19561    (set_attr "mode" "<MODE>")])
19563 ;; Make two stack loads independent:
19564 ;;   fld aa              fld aa
19565 ;;   fld %st(0)     ->   fld bb
19566 ;;   fmul bb             fmul %st(1), %st
19568 ;; Actually we only match the last two instructions for simplicity.
19569 (define_peephole2
19570   [(set (match_operand 0 "fp_register_operand" "")
19571         (match_operand 1 "fp_register_operand" ""))
19572    (set (match_dup 0)
19573         (match_operator 2 "binary_fp_operator"
19574            [(match_dup 0)
19575             (match_operand 3 "memory_operand" "")]))]
19576   "REGNO (operands[0]) != REGNO (operands[1])"
19577   [(set (match_dup 0) (match_dup 3))
19578    (set (match_dup 0) (match_dup 4))]
19580   ;; The % modifier is not operational anymore in peephole2's, so we have to
19581   ;; swap the operands manually in the case of addition and multiplication.
19582   "if (COMMUTATIVE_ARITH_P (operands[2]))
19583      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19584                                  operands[0], operands[1]);
19585    else
19586      operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19587                                  operands[1], operands[0]);")
19589 ;; Conditional addition patterns
19590 (define_expand "add<mode>cc"
19591   [(match_operand:SWI 0 "register_operand" "")
19592    (match_operand 1 "comparison_operator" "")
19593    (match_operand:SWI 2 "register_operand" "")
19594    (match_operand:SWI 3 "const_int_operand" "")]
19595   ""
19596   "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19599 ;; Misc patterns (?)
19601 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19602 ;; Otherwise there will be nothing to keep
19604 ;; [(set (reg ebp) (reg esp))]
19605 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19606 ;;  (clobber (eflags)]
19607 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19609 ;; in proper program order.
19610 (define_insn "pro_epilogue_adjust_stack_1"
19611   [(set (match_operand:SI 0 "register_operand" "=r,r")
19612         (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19613                  (match_operand:SI 2 "immediate_operand" "i,i")))
19614    (clobber (reg:CC FLAGS_REG))
19615    (clobber (mem:BLK (scratch)))]
19616   "!TARGET_64BIT"
19618   switch (get_attr_type (insn))
19619     {
19620     case TYPE_IMOV:
19621       return "mov{l}\t{%1, %0|%0, %1}";
19623     case TYPE_ALU:
19624       if (CONST_INT_P (operands[2])
19625           && (INTVAL (operands[2]) == 128
19626               || (INTVAL (operands[2]) < 0
19627                   && INTVAL (operands[2]) != -128)))
19628         {
19629           operands[2] = GEN_INT (-INTVAL (operands[2]));
19630           return "sub{l}\t{%2, %0|%0, %2}";
19631         }
19632       return "add{l}\t{%2, %0|%0, %2}";
19634     case TYPE_LEA:
19635       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19636       return "lea{l}\t{%a2, %0|%0, %a2}";
19638     default:
19639       gcc_unreachable ();
19640     }
19642   [(set (attr "type")
19643         (cond [(eq_attr "alternative" "0")
19644                  (const_string "alu")
19645                (match_operand:SI 2 "const0_operand" "")
19646                  (const_string "imov")
19647               ]
19648               (const_string "lea")))
19649    (set_attr "mode" "SI")])
19651 (define_insn "pro_epilogue_adjust_stack_rex64"
19652   [(set (match_operand:DI 0 "register_operand" "=r,r")
19653         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19654                  (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19655    (clobber (reg:CC FLAGS_REG))
19656    (clobber (mem:BLK (scratch)))]
19657   "TARGET_64BIT"
19659   switch (get_attr_type (insn))
19660     {
19661     case TYPE_IMOV:
19662       return "mov{q}\t{%1, %0|%0, %1}";
19664     case TYPE_ALU:
19665       if (CONST_INT_P (operands[2])
19666           /* Avoid overflows.  */
19667           && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19668           && (INTVAL (operands[2]) == 128
19669               || (INTVAL (operands[2]) < 0
19670                   && INTVAL (operands[2]) != -128)))
19671         {
19672           operands[2] = GEN_INT (-INTVAL (operands[2]));
19673           return "sub{q}\t{%2, %0|%0, %2}";
19674         }
19675       return "add{q}\t{%2, %0|%0, %2}";
19677     case TYPE_LEA:
19678       operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19679       return "lea{q}\t{%a2, %0|%0, %a2}";
19681     default:
19682       gcc_unreachable ();
19683     }
19685   [(set (attr "type")
19686         (cond [(eq_attr "alternative" "0")
19687                  (const_string "alu")
19688                (match_operand:DI 2 "const0_operand" "")
19689                  (const_string "imov")
19690               ]
19691               (const_string "lea")))
19692    (set_attr "mode" "DI")])
19694 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19695   [(set (match_operand:DI 0 "register_operand" "=r,r")
19696         (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19697                  (match_operand:DI 3 "immediate_operand" "i,i")))
19698    (use (match_operand:DI 2 "register_operand" "r,r"))
19699    (clobber (reg:CC FLAGS_REG))
19700    (clobber (mem:BLK (scratch)))]
19701   "TARGET_64BIT"
19703   switch (get_attr_type (insn))
19704     {
19705     case TYPE_ALU:
19706       return "add{q}\t{%2, %0|%0, %2}";
19708     case TYPE_LEA:
19709       operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19710       return "lea{q}\t{%a2, %0|%0, %a2}";
19712     default:
19713       gcc_unreachable ();
19714     }
19716   [(set_attr "type" "alu,lea")
19717    (set_attr "mode" "DI")])
19719 (define_insn "allocate_stack_worker_32"
19720   [(set (match_operand:SI 0 "register_operand" "+a")
19721         (unspec_volatile:SI [(match_dup 0)] UNSPECV_STACK_PROBE))
19722    (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 0)))
19723    (clobber (reg:CC FLAGS_REG))]
19724   "!TARGET_64BIT && TARGET_STACK_PROBE"
19725   "call\t___chkstk"
19726   [(set_attr "type" "multi")
19727    (set_attr "length" "5")])
19729 (define_insn "allocate_stack_worker_64"
19730   [(set (match_operand:DI 0 "register_operand" "+a")
19731         (unspec_volatile:DI [(match_dup 0)] UNSPECV_STACK_PROBE))
19732    (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 0)))
19733    (clobber (reg:DI R10_REG))
19734    (clobber (reg:DI R11_REG))
19735    (clobber (reg:CC FLAGS_REG))]
19736   "TARGET_64BIT && TARGET_STACK_PROBE"
19737   "call\t___chkstk"
19738   [(set_attr "type" "multi")
19739    (set_attr "length" "5")])
19741 (define_expand "allocate_stack"
19742   [(match_operand 0 "register_operand" "")
19743    (match_operand 1 "general_operand" "")]
19744   "TARGET_STACK_PROBE"
19746   rtx x;
19748 #ifndef CHECK_STACK_LIMIT
19749 #define CHECK_STACK_LIMIT 0
19750 #endif
19752   if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19753       && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19754     {
19755       x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19756                                stack_pointer_rtx, 0, OPTAB_DIRECT);
19757       if (x != stack_pointer_rtx)
19758         emit_move_insn (stack_pointer_rtx, x);
19759     }
19760   else
19761     {
19762       x = copy_to_mode_reg (Pmode, operands[1]);
19763       if (TARGET_64BIT)
19764         x = gen_allocate_stack_worker_64 (x);
19765       else
19766         x = gen_allocate_stack_worker_32 (x);
19767       emit_insn (x);
19768     }
19770   emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19771   DONE;
19774 (define_expand "builtin_setjmp_receiver"
19775   [(label_ref (match_operand 0 "" ""))]
19776   "!TARGET_64BIT && flag_pic"
19778   if (TARGET_MACHO)
19779     {
19780       rtx xops[3];
19781       rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19782       rtx label_rtx = gen_label_rtx ();
19783       emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19784       xops[0] = xops[1] = picreg;
19785       xops[2] = gen_rtx_CONST (SImode,
19786                   gen_rtx_MINUS (SImode,
19787                     gen_rtx_LABEL_REF (SImode, label_rtx),
19788                     gen_rtx_SYMBOL_REF (SImode, GOT_SYMBOL_NAME)));
19789       ix86_expand_binary_operator (MINUS, SImode, xops);
19790     }
19791   else
19792     emit_insn (gen_set_got (pic_offset_table_rtx));
19793   DONE;
19796 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19798 (define_split
19799   [(set (match_operand 0 "register_operand" "")
19800         (match_operator 3 "promotable_binary_operator"
19801            [(match_operand 1 "register_operand" "")
19802             (match_operand 2 "aligned_operand" "")]))
19803    (clobber (reg:CC FLAGS_REG))]
19804   "! TARGET_PARTIAL_REG_STALL && reload_completed
19805    && ((GET_MODE (operands[0]) == HImode
19806         && ((!optimize_size && !TARGET_FAST_PREFIX)
19807             /* ??? next two lines just !satisfies_constraint_K (...) */
19808             || !CONST_INT_P (operands[2])
19809             || satisfies_constraint_K (operands[2])))
19810        || (GET_MODE (operands[0]) == QImode
19811            && (TARGET_PROMOTE_QImode || optimize_size)))"
19812   [(parallel [(set (match_dup 0)
19813                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19814               (clobber (reg:CC FLAGS_REG))])]
19815   "operands[0] = gen_lowpart (SImode, operands[0]);
19816    operands[1] = gen_lowpart (SImode, operands[1]);
19817    if (GET_CODE (operands[3]) != ASHIFT)
19818      operands[2] = gen_lowpart (SImode, operands[2]);
19819    PUT_MODE (operands[3], SImode);")
19821 ; Promote the QImode tests, as i386 has encoding of the AND
19822 ; instruction with 32-bit sign-extended immediate and thus the
19823 ; instruction size is unchanged, except in the %eax case for
19824 ; which it is increased by one byte, hence the ! optimize_size.
19825 (define_split
19826   [(set (match_operand 0 "flags_reg_operand" "")
19827         (match_operator 2 "compare_operator"
19828           [(and (match_operand 3 "aligned_operand" "")
19829                 (match_operand 4 "const_int_operand" ""))
19830            (const_int 0)]))
19831    (set (match_operand 1 "register_operand" "")
19832         (and (match_dup 3) (match_dup 4)))]
19833   "! TARGET_PARTIAL_REG_STALL && reload_completed
19834    && ! optimize_size
19835    && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19836        || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19837    /* Ensure that the operand will remain sign-extended immediate.  */
19838    && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19839   [(parallel [(set (match_dup 0)
19840                    (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19841                                     (const_int 0)]))
19842               (set (match_dup 1)
19843                    (and:SI (match_dup 3) (match_dup 4)))])]
19845   operands[4]
19846     = gen_int_mode (INTVAL (operands[4])
19847                     & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19848   operands[1] = gen_lowpart (SImode, operands[1]);
19849   operands[3] = gen_lowpart (SImode, operands[3]);
19852 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19853 ; the TEST instruction with 32-bit sign-extended immediate and thus
19854 ; the instruction size would at least double, which is not what we
19855 ; want even with ! optimize_size.
19856 (define_split
19857   [(set (match_operand 0 "flags_reg_operand" "")
19858         (match_operator 1 "compare_operator"
19859           [(and (match_operand:HI 2 "aligned_operand" "")
19860                 (match_operand:HI 3 "const_int_operand" ""))
19861            (const_int 0)]))]
19862   "! TARGET_PARTIAL_REG_STALL && reload_completed
19863    && ! TARGET_FAST_PREFIX
19864    && ! optimize_size
19865    /* Ensure that the operand will remain sign-extended immediate.  */
19866    && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19867   [(set (match_dup 0)
19868         (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19869                          (const_int 0)]))]
19871   operands[3]
19872     = gen_int_mode (INTVAL (operands[3])
19873                     & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19874   operands[2] = gen_lowpart (SImode, operands[2]);
19877 (define_split
19878   [(set (match_operand 0 "register_operand" "")
19879         (neg (match_operand 1 "register_operand" "")))
19880    (clobber (reg:CC FLAGS_REG))]
19881   "! TARGET_PARTIAL_REG_STALL && reload_completed
19882    && (GET_MODE (operands[0]) == HImode
19883        || (GET_MODE (operands[0]) == QImode
19884            && (TARGET_PROMOTE_QImode || optimize_size)))"
19885   [(parallel [(set (match_dup 0)
19886                    (neg:SI (match_dup 1)))
19887               (clobber (reg:CC FLAGS_REG))])]
19888   "operands[0] = gen_lowpart (SImode, operands[0]);
19889    operands[1] = gen_lowpart (SImode, operands[1]);")
19891 (define_split
19892   [(set (match_operand 0 "register_operand" "")
19893         (not (match_operand 1 "register_operand" "")))]
19894   "! TARGET_PARTIAL_REG_STALL && reload_completed
19895    && (GET_MODE (operands[0]) == HImode
19896        || (GET_MODE (operands[0]) == QImode
19897            && (TARGET_PROMOTE_QImode || optimize_size)))"
19898   [(set (match_dup 0)
19899         (not:SI (match_dup 1)))]
19900   "operands[0] = gen_lowpart (SImode, operands[0]);
19901    operands[1] = gen_lowpart (SImode, operands[1]);")
19903 (define_split
19904   [(set (match_operand 0 "register_operand" "")
19905         (if_then_else (match_operator 1 "comparison_operator"
19906                                 [(reg FLAGS_REG) (const_int 0)])
19907                       (match_operand 2 "register_operand" "")
19908                       (match_operand 3 "register_operand" "")))]
19909   "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19910    && (GET_MODE (operands[0]) == HImode
19911        || (GET_MODE (operands[0]) == QImode
19912            && (TARGET_PROMOTE_QImode || optimize_size)))"
19913   [(set (match_dup 0)
19914         (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19915   "operands[0] = gen_lowpart (SImode, operands[0]);
19916    operands[2] = gen_lowpart (SImode, operands[2]);
19917    operands[3] = gen_lowpart (SImode, operands[3]);")
19920 ;; RTL Peephole optimizations, run before sched2.  These primarily look to
19921 ;; transform a complex memory operation into two memory to register operations.
19923 ;; Don't push memory operands
19924 (define_peephole2
19925   [(set (match_operand:SI 0 "push_operand" "")
19926         (match_operand:SI 1 "memory_operand" ""))
19927    (match_scratch:SI 2 "r")]
19928   "!optimize_size && !TARGET_PUSH_MEMORY
19929    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19930   [(set (match_dup 2) (match_dup 1))
19931    (set (match_dup 0) (match_dup 2))]
19932   "")
19934 (define_peephole2
19935   [(set (match_operand:DI 0 "push_operand" "")
19936         (match_operand:DI 1 "memory_operand" ""))
19937    (match_scratch:DI 2 "r")]
19938   "!optimize_size && !TARGET_PUSH_MEMORY
19939    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19940   [(set (match_dup 2) (match_dup 1))
19941    (set (match_dup 0) (match_dup 2))]
19942   "")
19944 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19945 ;; SImode pushes.
19946 (define_peephole2
19947   [(set (match_operand:SF 0 "push_operand" "")
19948         (match_operand:SF 1 "memory_operand" ""))
19949    (match_scratch:SF 2 "r")]
19950   "!optimize_size && !TARGET_PUSH_MEMORY
19951    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19952   [(set (match_dup 2) (match_dup 1))
19953    (set (match_dup 0) (match_dup 2))]
19954   "")
19956 (define_peephole2
19957   [(set (match_operand:HI 0 "push_operand" "")
19958         (match_operand:HI 1 "memory_operand" ""))
19959    (match_scratch:HI 2 "r")]
19960   "!optimize_size && !TARGET_PUSH_MEMORY
19961    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19962   [(set (match_dup 2) (match_dup 1))
19963    (set (match_dup 0) (match_dup 2))]
19964   "")
19966 (define_peephole2
19967   [(set (match_operand:QI 0 "push_operand" "")
19968         (match_operand:QI 1 "memory_operand" ""))
19969    (match_scratch:QI 2 "q")]
19970   "!optimize_size && !TARGET_PUSH_MEMORY
19971    && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19972   [(set (match_dup 2) (match_dup 1))
19973    (set (match_dup 0) (match_dup 2))]
19974   "")
19976 ;; Don't move an immediate directly to memory when the instruction
19977 ;; gets too big.
19978 (define_peephole2
19979   [(match_scratch:SI 1 "r")
19980    (set (match_operand:SI 0 "memory_operand" "")
19981         (const_int 0))]
19982   "! optimize_size
19983    && ! TARGET_USE_MOV0
19984    && TARGET_SPLIT_LONG_MOVES
19985    && get_attr_length (insn) >= ix86_cost->large_insn
19986    && peep2_regno_dead_p (0, FLAGS_REG)"
19987   [(parallel [(set (match_dup 1) (const_int 0))
19988               (clobber (reg:CC FLAGS_REG))])
19989    (set (match_dup 0) (match_dup 1))]
19990   "")
19992 (define_peephole2
19993   [(match_scratch:HI 1 "r")
19994    (set (match_operand:HI 0 "memory_operand" "")
19995         (const_int 0))]
19996   "! optimize_size
19997    && ! TARGET_USE_MOV0
19998    && TARGET_SPLIT_LONG_MOVES
19999    && get_attr_length (insn) >= ix86_cost->large_insn
20000    && peep2_regno_dead_p (0, FLAGS_REG)"
20001   [(parallel [(set (match_dup 2) (const_int 0))
20002               (clobber (reg:CC FLAGS_REG))])
20003    (set (match_dup 0) (match_dup 1))]
20004   "operands[2] = gen_lowpart (SImode, operands[1]);")
20006 (define_peephole2
20007   [(match_scratch:QI 1 "q")
20008    (set (match_operand:QI 0 "memory_operand" "")
20009         (const_int 0))]
20010   "! optimize_size
20011    && ! TARGET_USE_MOV0
20012    && TARGET_SPLIT_LONG_MOVES
20013    && get_attr_length (insn) >= ix86_cost->large_insn
20014    && peep2_regno_dead_p (0, FLAGS_REG)"
20015   [(parallel [(set (match_dup 2) (const_int 0))
20016               (clobber (reg:CC FLAGS_REG))])
20017    (set (match_dup 0) (match_dup 1))]
20018   "operands[2] = gen_lowpart (SImode, operands[1]);")
20020 (define_peephole2
20021   [(match_scratch:SI 2 "r")
20022    (set (match_operand:SI 0 "memory_operand" "")
20023         (match_operand:SI 1 "immediate_operand" ""))]
20024   "! optimize_size
20025    && TARGET_SPLIT_LONG_MOVES
20026    && get_attr_length (insn) >= ix86_cost->large_insn"
20027   [(set (match_dup 2) (match_dup 1))
20028    (set (match_dup 0) (match_dup 2))]
20029   "")
20031 (define_peephole2
20032   [(match_scratch:HI 2 "r")
20033    (set (match_operand:HI 0 "memory_operand" "")
20034         (match_operand:HI 1 "immediate_operand" ""))]
20035   "! optimize_size
20036    && TARGET_SPLIT_LONG_MOVES
20037    && get_attr_length (insn) >= ix86_cost->large_insn"
20038   [(set (match_dup 2) (match_dup 1))
20039    (set (match_dup 0) (match_dup 2))]
20040   "")
20042 (define_peephole2
20043   [(match_scratch:QI 2 "q")
20044    (set (match_operand:QI 0 "memory_operand" "")
20045         (match_operand:QI 1 "immediate_operand" ""))]
20046   "! optimize_size
20047    && TARGET_SPLIT_LONG_MOVES
20048    && get_attr_length (insn) >= ix86_cost->large_insn"
20049   [(set (match_dup 2) (match_dup 1))
20050    (set (match_dup 0) (match_dup 2))]
20051   "")
20053 ;; Don't compare memory with zero, load and use a test instead.
20054 (define_peephole2
20055   [(set (match_operand 0 "flags_reg_operand" "")
20056         (match_operator 1 "compare_operator"
20057           [(match_operand:SI 2 "memory_operand" "")
20058            (const_int 0)]))
20059    (match_scratch:SI 3 "r")]
20060   " ! optimize_size && ix86_match_ccmode (insn, CCNOmode)"
20061   [(set (match_dup 3) (match_dup 2))
20062    (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20063   "")
20065 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20066 ;; Don't split NOTs with a displacement operand, because resulting XOR
20067 ;; will not be pairable anyway.
20069 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20070 ;; represented using a modRM byte.  The XOR replacement is long decoded,
20071 ;; so this split helps here as well.
20073 ;; Note: Can't do this as a regular split because we can't get proper
20074 ;; lifetime information then.
20076 (define_peephole2
20077   [(set (match_operand:SI 0 "nonimmediate_operand" "")
20078         (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20079   "!optimize_size
20080    && ((TARGET_NOT_UNPAIRABLE
20081         && (!MEM_P (operands[0])
20082             || !memory_displacement_operand (operands[0], SImode)))
20083        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20084    && peep2_regno_dead_p (0, FLAGS_REG)"
20085   [(parallel [(set (match_dup 0)
20086                    (xor:SI (match_dup 1) (const_int -1)))
20087               (clobber (reg:CC FLAGS_REG))])]
20088   "")
20090 (define_peephole2
20091   [(set (match_operand:HI 0 "nonimmediate_operand" "")
20092         (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20093   "!optimize_size
20094    && ((TARGET_NOT_UNPAIRABLE
20095         && (!MEM_P (operands[0])
20096             || !memory_displacement_operand (operands[0], HImode)))
20097        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20098    && peep2_regno_dead_p (0, FLAGS_REG)"
20099   [(parallel [(set (match_dup 0)
20100                    (xor:HI (match_dup 1) (const_int -1)))
20101               (clobber (reg:CC FLAGS_REG))])]
20102   "")
20104 (define_peephole2
20105   [(set (match_operand:QI 0 "nonimmediate_operand" "")
20106         (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20107   "!optimize_size
20108    && ((TARGET_NOT_UNPAIRABLE
20109         && (!MEM_P (operands[0])
20110             || !memory_displacement_operand (operands[0], QImode)))
20111        || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20112    && peep2_regno_dead_p (0, FLAGS_REG)"
20113   [(parallel [(set (match_dup 0)
20114                    (xor:QI (match_dup 1) (const_int -1)))
20115               (clobber (reg:CC FLAGS_REG))])]
20116   "")
20118 ;; Non pairable "test imm, reg" instructions can be translated to
20119 ;; "and imm, reg" if reg dies.  The "and" form is also shorter (one
20120 ;; byte opcode instead of two, have a short form for byte operands),
20121 ;; so do it for other CPUs as well.  Given that the value was dead,
20122 ;; this should not create any new dependencies.  Pass on the sub-word
20123 ;; versions if we're concerned about partial register stalls.
20125 (define_peephole2
20126   [(set (match_operand 0 "flags_reg_operand" "")
20127         (match_operator 1 "compare_operator"
20128           [(and:SI (match_operand:SI 2 "register_operand" "")
20129                    (match_operand:SI 3 "immediate_operand" ""))
20130            (const_int 0)]))]
20131   "ix86_match_ccmode (insn, CCNOmode)
20132    && (true_regnum (operands[2]) != AX_REG
20133        || satisfies_constraint_K (operands[3]))
20134    && peep2_reg_dead_p (1, operands[2])"
20135   [(parallel
20136      [(set (match_dup 0)
20137            (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20138                             (const_int 0)]))
20139       (set (match_dup 2)
20140            (and:SI (match_dup 2) (match_dup 3)))])]
20141   "")
20143 ;; We don't need to handle HImode case, because it will be promoted to SImode
20144 ;; on ! TARGET_PARTIAL_REG_STALL
20146 (define_peephole2
20147   [(set (match_operand 0 "flags_reg_operand" "")
20148         (match_operator 1 "compare_operator"
20149           [(and:QI (match_operand:QI 2 "register_operand" "")
20150                    (match_operand:QI 3 "immediate_operand" ""))
20151            (const_int 0)]))]
20152   "! TARGET_PARTIAL_REG_STALL
20153    && ix86_match_ccmode (insn, CCNOmode)
20154    && true_regnum (operands[2]) != AX_REG
20155    && peep2_reg_dead_p (1, operands[2])"
20156   [(parallel
20157      [(set (match_dup 0)
20158            (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20159                             (const_int 0)]))
20160       (set (match_dup 2)
20161            (and:QI (match_dup 2) (match_dup 3)))])]
20162   "")
20164 (define_peephole2
20165   [(set (match_operand 0 "flags_reg_operand" "")
20166         (match_operator 1 "compare_operator"
20167           [(and:SI
20168              (zero_extract:SI
20169                (match_operand 2 "ext_register_operand" "")
20170                (const_int 8)
20171                (const_int 8))
20172              (match_operand 3 "const_int_operand" ""))
20173            (const_int 0)]))]
20174   "! TARGET_PARTIAL_REG_STALL
20175    && ix86_match_ccmode (insn, CCNOmode)
20176    && true_regnum (operands[2]) != AX_REG
20177    && peep2_reg_dead_p (1, operands[2])"
20178   [(parallel [(set (match_dup 0)
20179                    (match_op_dup 1
20180                      [(and:SI
20181                         (zero_extract:SI
20182                           (match_dup 2)
20183                           (const_int 8)
20184                           (const_int 8))
20185                         (match_dup 3))
20186                       (const_int 0)]))
20187               (set (zero_extract:SI (match_dup 2)
20188                                     (const_int 8)
20189                                     (const_int 8))
20190                    (and:SI
20191                      (zero_extract:SI
20192                        (match_dup 2)
20193                        (const_int 8)
20194                        (const_int 8))
20195                      (match_dup 3)))])]
20196   "")
20198 ;; Don't do logical operations with memory inputs.
20199 (define_peephole2
20200   [(match_scratch:SI 2 "r")
20201    (parallel [(set (match_operand:SI 0 "register_operand" "")
20202                    (match_operator:SI 3 "arith_or_logical_operator"
20203                      [(match_dup 0)
20204                       (match_operand:SI 1 "memory_operand" "")]))
20205               (clobber (reg:CC FLAGS_REG))])]
20206   "! optimize_size && ! TARGET_READ_MODIFY"
20207   [(set (match_dup 2) (match_dup 1))
20208    (parallel [(set (match_dup 0)
20209                    (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20210               (clobber (reg:CC FLAGS_REG))])]
20211   "")
20213 (define_peephole2
20214   [(match_scratch:SI 2 "r")
20215    (parallel [(set (match_operand:SI 0 "register_operand" "")
20216                    (match_operator:SI 3 "arith_or_logical_operator"
20217                      [(match_operand:SI 1 "memory_operand" "")
20218                       (match_dup 0)]))
20219               (clobber (reg:CC FLAGS_REG))])]
20220   "! optimize_size && ! TARGET_READ_MODIFY"
20221   [(set (match_dup 2) (match_dup 1))
20222    (parallel [(set (match_dup 0)
20223                    (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20224               (clobber (reg:CC FLAGS_REG))])]
20225   "")
20227 ; Don't do logical operations with memory outputs
20229 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20230 ; instruction into two 1-uop insns plus a 2-uop insn.  That last has
20231 ; the same decoder scheduling characteristics as the original.
20233 (define_peephole2
20234   [(match_scratch:SI 2 "r")
20235    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20236                    (match_operator:SI 3 "arith_or_logical_operator"
20237                      [(match_dup 0)
20238                       (match_operand:SI 1 "nonmemory_operand" "")]))
20239               (clobber (reg:CC FLAGS_REG))])]
20240   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20241   [(set (match_dup 2) (match_dup 0))
20242    (parallel [(set (match_dup 2)
20243                    (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20244               (clobber (reg:CC FLAGS_REG))])
20245    (set (match_dup 0) (match_dup 2))]
20246   "")
20248 (define_peephole2
20249   [(match_scratch:SI 2 "r")
20250    (parallel [(set (match_operand:SI 0 "memory_operand" "")
20251                    (match_operator:SI 3 "arith_or_logical_operator"
20252                      [(match_operand:SI 1 "nonmemory_operand" "")
20253                       (match_dup 0)]))
20254               (clobber (reg:CC FLAGS_REG))])]
20255   "! optimize_size && ! TARGET_READ_MODIFY_WRITE"
20256   [(set (match_dup 2) (match_dup 0))
20257    (parallel [(set (match_dup 2)
20258                    (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20259               (clobber (reg:CC FLAGS_REG))])
20260    (set (match_dup 0) (match_dup 2))]
20261   "")
20263 ;; Attempt to always use XOR for zeroing registers.
20264 (define_peephole2
20265   [(set (match_operand 0 "register_operand" "")
20266         (match_operand 1 "const0_operand" ""))]
20267   "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20268    && (! TARGET_USE_MOV0 || optimize_size)
20269    && GENERAL_REG_P (operands[0])
20270    && peep2_regno_dead_p (0, FLAGS_REG)"
20271   [(parallel [(set (match_dup 0) (const_int 0))
20272               (clobber (reg:CC FLAGS_REG))])]
20274   operands[0] = gen_lowpart (word_mode, operands[0]);
20277 (define_peephole2
20278   [(set (strict_low_part (match_operand 0 "register_operand" ""))
20279         (const_int 0))]
20280   "(GET_MODE (operands[0]) == QImode
20281     || GET_MODE (operands[0]) == HImode)
20282    && (! TARGET_USE_MOV0 || optimize_size)
20283    && peep2_regno_dead_p (0, FLAGS_REG)"
20284   [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20285               (clobber (reg:CC FLAGS_REG))])])
20287 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20288 (define_peephole2
20289   [(set (match_operand 0 "register_operand" "")
20290         (const_int -1))]
20291   "(GET_MODE (operands[0]) == HImode
20292     || GET_MODE (operands[0]) == SImode
20293     || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20294    && (optimize_size || TARGET_MOVE_M1_VIA_OR)
20295    && peep2_regno_dead_p (0, FLAGS_REG)"
20296   [(parallel [(set (match_dup 0) (const_int -1))
20297               (clobber (reg:CC FLAGS_REG))])]
20298   "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20299                               operands[0]);")
20301 ;; Attempt to convert simple leas to adds. These can be created by
20302 ;; move expanders.
20303 (define_peephole2
20304   [(set (match_operand:SI 0 "register_operand" "")
20305         (plus:SI (match_dup 0)
20306                  (match_operand:SI 1 "nonmemory_operand" "")))]
20307   "peep2_regno_dead_p (0, FLAGS_REG)"
20308   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20309               (clobber (reg:CC FLAGS_REG))])]
20310   "")
20312 (define_peephole2
20313   [(set (match_operand:SI 0 "register_operand" "")
20314         (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20315                             (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20316   "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20317   [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20318               (clobber (reg:CC FLAGS_REG))])]
20319   "operands[2] = gen_lowpart (SImode, operands[2]);")
20321 (define_peephole2
20322   [(set (match_operand:DI 0 "register_operand" "")
20323         (plus:DI (match_dup 0)
20324                  (match_operand:DI 1 "x86_64_general_operand" "")))]
20325   "peep2_regno_dead_p (0, FLAGS_REG)"
20326   [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20327               (clobber (reg:CC FLAGS_REG))])]
20328   "")
20330 (define_peephole2
20331   [(set (match_operand:SI 0 "register_operand" "")
20332         (mult:SI (match_dup 0)
20333                  (match_operand:SI 1 "const_int_operand" "")))]
20334   "exact_log2 (INTVAL (operands[1])) >= 0
20335    && peep2_regno_dead_p (0, FLAGS_REG)"
20336   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20337               (clobber (reg:CC FLAGS_REG))])]
20338   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20340 (define_peephole2
20341   [(set (match_operand:DI 0 "register_operand" "")
20342         (mult:DI (match_dup 0)
20343                  (match_operand:DI 1 "const_int_operand" "")))]
20344   "exact_log2 (INTVAL (operands[1])) >= 0
20345    && peep2_regno_dead_p (0, FLAGS_REG)"
20346   [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20347               (clobber (reg:CC FLAGS_REG))])]
20348   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20350 (define_peephole2
20351   [(set (match_operand:SI 0 "register_operand" "")
20352         (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20353                    (match_operand:DI 2 "const_int_operand" "")) 0))]
20354   "exact_log2 (INTVAL (operands[2])) >= 0
20355    && REGNO (operands[0]) == REGNO (operands[1])
20356    && peep2_regno_dead_p (0, FLAGS_REG)"
20357   [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20358               (clobber (reg:CC FLAGS_REG))])]
20359   "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20361 ;; The ESP adjustments can be done by the push and pop instructions.  Resulting
20362 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes.  On
20363 ;; many CPUs it is also faster, since special hardware to avoid esp
20364 ;; dependencies is present.
20366 ;; While some of these conversions may be done using splitters, we use peepholes
20367 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20369 ;; Convert prologue esp subtractions to push.
20370 ;; We need register to push.  In order to keep verify_flow_info happy we have
20371 ;; two choices
20372 ;; - use scratch and clobber it in order to avoid dependencies
20373 ;; - use already live register
20374 ;; We can't use the second way right now, since there is no reliable way how to
20375 ;; verify that given register is live.  First choice will also most likely in
20376 ;; fewer dependencies.  On the place of esp adjustments it is very likely that
20377 ;; call clobbered registers are dead.  We may want to use base pointer as an
20378 ;; alternative when no register is available later.
20380 (define_peephole2
20381   [(match_scratch:SI 0 "r")
20382    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20383               (clobber (reg:CC FLAGS_REG))
20384               (clobber (mem:BLK (scratch)))])]
20385   "optimize_size || !TARGET_SUB_ESP_4"
20386   [(clobber (match_dup 0))
20387    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20388               (clobber (mem:BLK (scratch)))])])
20390 (define_peephole2
20391   [(match_scratch:SI 0 "r")
20392    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20393               (clobber (reg:CC FLAGS_REG))
20394               (clobber (mem:BLK (scratch)))])]
20395   "optimize_size || !TARGET_SUB_ESP_8"
20396   [(clobber (match_dup 0))
20397    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20398    (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20399               (clobber (mem:BLK (scratch)))])])
20401 ;; Convert esp subtractions to push.
20402 (define_peephole2
20403   [(match_scratch:SI 0 "r")
20404    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20405               (clobber (reg:CC FLAGS_REG))])]
20406   "optimize_size || !TARGET_SUB_ESP_4"
20407   [(clobber (match_dup 0))
20408    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20410 (define_peephole2
20411   [(match_scratch:SI 0 "r")
20412    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20413               (clobber (reg:CC FLAGS_REG))])]
20414   "optimize_size || !TARGET_SUB_ESP_8"
20415   [(clobber (match_dup 0))
20416    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20417    (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20419 ;; Convert epilogue deallocator to pop.
20420 (define_peephole2
20421   [(match_scratch:SI 0 "r")
20422    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20423               (clobber (reg:CC FLAGS_REG))
20424               (clobber (mem:BLK (scratch)))])]
20425   "optimize_size || !TARGET_ADD_ESP_4"
20426   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20427               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20428               (clobber (mem:BLK (scratch)))])]
20429   "")
20431 ;; Two pops case is tricky, since pop causes dependency on destination register.
20432 ;; We use two registers if available.
20433 (define_peephole2
20434   [(match_scratch:SI 0 "r")
20435    (match_scratch:SI 1 "r")
20436    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20437               (clobber (reg:CC FLAGS_REG))
20438               (clobber (mem:BLK (scratch)))])]
20439   "optimize_size || !TARGET_ADD_ESP_8"
20440   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20441               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20442               (clobber (mem:BLK (scratch)))])
20443    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20444               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20445   "")
20447 (define_peephole2
20448   [(match_scratch:SI 0 "r")
20449    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20450               (clobber (reg:CC FLAGS_REG))
20451               (clobber (mem:BLK (scratch)))])]
20452   "optimize_size"
20453   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20454               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20455               (clobber (mem:BLK (scratch)))])
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   "")
20460 ;; Convert esp additions to pop.
20461 (define_peephole2
20462   [(match_scratch:SI 0 "r")
20463    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20464               (clobber (reg:CC FLAGS_REG))])]
20465   ""
20466   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20467               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20468   "")
20470 ;; Two pops case is tricky, since pop causes dependency on destination register.
20471 ;; We use two registers if available.
20472 (define_peephole2
20473   [(match_scratch:SI 0 "r")
20474    (match_scratch:SI 1 "r")
20475    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20476               (clobber (reg:CC FLAGS_REG))])]
20477   ""
20478   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20479               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20480    (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20481               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20482   "")
20484 (define_peephole2
20485   [(match_scratch:SI 0 "r")
20486    (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20487               (clobber (reg:CC FLAGS_REG))])]
20488   "optimize_size"
20489   [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20490               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20491    (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20492               (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20493   "")
20495 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20496 ;; required and register dies.  Similarly for 128 to plus -128.
20497 (define_peephole2
20498   [(set (match_operand 0 "flags_reg_operand" "")
20499         (match_operator 1 "compare_operator"
20500           [(match_operand 2 "register_operand" "")
20501            (match_operand 3 "const_int_operand" "")]))]
20502   "(INTVAL (operands[3]) == -1
20503     || INTVAL (operands[3]) == 1
20504     || INTVAL (operands[3]) == 128)
20505    && ix86_match_ccmode (insn, CCGCmode)
20506    && peep2_reg_dead_p (1, operands[2])"
20507   [(parallel [(set (match_dup 0)
20508                    (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20509               (clobber (match_dup 2))])]
20510   "")
20512 (define_peephole2
20513   [(match_scratch:DI 0 "r")
20514    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20515               (clobber (reg:CC FLAGS_REG))
20516               (clobber (mem:BLK (scratch)))])]
20517   "optimize_size || !TARGET_SUB_ESP_4"
20518   [(clobber (match_dup 0))
20519    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20520               (clobber (mem:BLK (scratch)))])])
20522 (define_peephole2
20523   [(match_scratch:DI 0 "r")
20524    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20525               (clobber (reg:CC FLAGS_REG))
20526               (clobber (mem:BLK (scratch)))])]
20527   "optimize_size || !TARGET_SUB_ESP_8"
20528   [(clobber (match_dup 0))
20529    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20530    (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20531               (clobber (mem:BLK (scratch)))])])
20533 ;; Convert esp subtractions to push.
20534 (define_peephole2
20535   [(match_scratch:DI 0 "r")
20536    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20537               (clobber (reg:CC FLAGS_REG))])]
20538   "optimize_size || !TARGET_SUB_ESP_4"
20539   [(clobber (match_dup 0))
20540    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20542 (define_peephole2
20543   [(match_scratch:DI 0 "r")
20544    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20545               (clobber (reg:CC FLAGS_REG))])]
20546   "optimize_size || !TARGET_SUB_ESP_8"
20547   [(clobber (match_dup 0))
20548    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20549    (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20551 ;; Convert epilogue deallocator to pop.
20552 (define_peephole2
20553   [(match_scratch:DI 0 "r")
20554    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20555               (clobber (reg:CC FLAGS_REG))
20556               (clobber (mem:BLK (scratch)))])]
20557   "optimize_size || !TARGET_ADD_ESP_4"
20558   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20559               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20560               (clobber (mem:BLK (scratch)))])]
20561   "")
20563 ;; Two pops case is tricky, since pop causes dependency on destination register.
20564 ;; We use two registers if available.
20565 (define_peephole2
20566   [(match_scratch:DI 0 "r")
20567    (match_scratch:DI 1 "r")
20568    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20569               (clobber (reg:CC FLAGS_REG))
20570               (clobber (mem:BLK (scratch)))])]
20571   "optimize_size || !TARGET_ADD_ESP_8"
20572   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20573               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20574               (clobber (mem:BLK (scratch)))])
20575    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20576               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20577   "")
20579 (define_peephole2
20580   [(match_scratch:DI 0 "r")
20581    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20582               (clobber (reg:CC FLAGS_REG))
20583               (clobber (mem:BLK (scratch)))])]
20584   "optimize_size"
20585   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20586               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20587               (clobber (mem:BLK (scratch)))])
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   "")
20592 ;; Convert esp additions to pop.
20593 (define_peephole2
20594   [(match_scratch:DI 0 "r")
20595    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20596               (clobber (reg:CC FLAGS_REG))])]
20597   ""
20598   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20599               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20600   "")
20602 ;; Two pops case is tricky, since pop causes dependency on destination register.
20603 ;; We use two registers if available.
20604 (define_peephole2
20605   [(match_scratch:DI 0 "r")
20606    (match_scratch:DI 1 "r")
20607    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20608               (clobber (reg:CC FLAGS_REG))])]
20609   ""
20610   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20611               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20612    (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20613               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20614   "")
20616 (define_peephole2
20617   [(match_scratch:DI 0 "r")
20618    (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20619               (clobber (reg:CC FLAGS_REG))])]
20620   "optimize_size"
20621   [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20622               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20623    (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20624               (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20625   "")
20627 ;; Convert imul by three, five and nine into lea
20628 (define_peephole2
20629   [(parallel
20630     [(set (match_operand:SI 0 "register_operand" "")
20631           (mult:SI (match_operand:SI 1 "register_operand" "")
20632                    (match_operand:SI 2 "const_int_operand" "")))
20633      (clobber (reg:CC FLAGS_REG))])]
20634   "INTVAL (operands[2]) == 3
20635    || INTVAL (operands[2]) == 5
20636    || INTVAL (operands[2]) == 9"
20637   [(set (match_dup 0)
20638         (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20639                  (match_dup 1)))]
20640   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20642 (define_peephole2
20643   [(parallel
20644     [(set (match_operand:SI 0 "register_operand" "")
20645           (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20646                    (match_operand:SI 2 "const_int_operand" "")))
20647      (clobber (reg:CC FLAGS_REG))])]
20648   "!optimize_size
20649    && (INTVAL (operands[2]) == 3
20650        || INTVAL (operands[2]) == 5
20651        || INTVAL (operands[2]) == 9)"
20652   [(set (match_dup 0) (match_dup 1))
20653    (set (match_dup 0)
20654         (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20655                  (match_dup 0)))]
20656   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20658 (define_peephole2
20659   [(parallel
20660     [(set (match_operand:DI 0 "register_operand" "")
20661           (mult:DI (match_operand:DI 1 "register_operand" "")
20662                    (match_operand:DI 2 "const_int_operand" "")))
20663      (clobber (reg:CC FLAGS_REG))])]
20664   "TARGET_64BIT
20665    && (INTVAL (operands[2]) == 3
20666        || INTVAL (operands[2]) == 5
20667        || INTVAL (operands[2]) == 9)"
20668   [(set (match_dup 0)
20669         (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20670                  (match_dup 1)))]
20671   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20673 (define_peephole2
20674   [(parallel
20675     [(set (match_operand:DI 0 "register_operand" "")
20676           (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20677                    (match_operand:DI 2 "const_int_operand" "")))
20678      (clobber (reg:CC FLAGS_REG))])]
20679   "TARGET_64BIT
20680    && !optimize_size
20681    && (INTVAL (operands[2]) == 3
20682        || INTVAL (operands[2]) == 5
20683        || INTVAL (operands[2]) == 9)"
20684   [(set (match_dup 0) (match_dup 1))
20685    (set (match_dup 0)
20686         (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20687                  (match_dup 0)))]
20688   { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20690 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20691 ;; imul $32bit_imm, reg, reg is direct decoded.
20692 (define_peephole2
20693   [(match_scratch:DI 3 "r")
20694    (parallel [(set (match_operand:DI 0 "register_operand" "")
20695                    (mult:DI (match_operand:DI 1 "memory_operand" "")
20696                             (match_operand:DI 2 "immediate_operand" "")))
20697               (clobber (reg:CC FLAGS_REG))])]
20698   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20699    && !satisfies_constraint_K (operands[2])"
20700   [(set (match_dup 3) (match_dup 1))
20701    (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20702               (clobber (reg:CC FLAGS_REG))])]
20705 (define_peephole2
20706   [(match_scratch:SI 3 "r")
20707    (parallel [(set (match_operand:SI 0 "register_operand" "")
20708                    (mult:SI (match_operand:SI 1 "memory_operand" "")
20709                             (match_operand:SI 2 "immediate_operand" "")))
20710               (clobber (reg:CC FLAGS_REG))])]
20711   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20712    && !satisfies_constraint_K (operands[2])"
20713   [(set (match_dup 3) (match_dup 1))
20714    (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20715               (clobber (reg:CC FLAGS_REG))])]
20718 (define_peephole2
20719   [(match_scratch:SI 3 "r")
20720    (parallel [(set (match_operand:DI 0 "register_operand" "")
20721                    (zero_extend:DI
20722                      (mult:SI (match_operand:SI 1 "memory_operand" "")
20723                               (match_operand:SI 2 "immediate_operand" ""))))
20724               (clobber (reg:CC FLAGS_REG))])]
20725   "TARGET_SLOW_IMUL_IMM32_MEM && !optimize_size
20726    && !satisfies_constraint_K (operands[2])"
20727   [(set (match_dup 3) (match_dup 1))
20728    (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20729               (clobber (reg:CC FLAGS_REG))])]
20732 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20733 ;; Convert it into imul reg, reg
20734 ;; It would be better to force assembler to encode instruction using long
20735 ;; immediate, but there is apparently no way to do so.
20736 (define_peephole2
20737   [(parallel [(set (match_operand:DI 0 "register_operand" "")
20738                    (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20739                             (match_operand:DI 2 "const_int_operand" "")))
20740               (clobber (reg:CC FLAGS_REG))])
20741    (match_scratch:DI 3 "r")]
20742   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20743    && satisfies_constraint_K (operands[2])"
20744   [(set (match_dup 3) (match_dup 2))
20745    (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20746               (clobber (reg:CC FLAGS_REG))])]
20748   if (!rtx_equal_p (operands[0], operands[1]))
20749     emit_move_insn (operands[0], operands[1]);
20752 (define_peephole2
20753   [(parallel [(set (match_operand:SI 0 "register_operand" "")
20754                    (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20755                             (match_operand:SI 2 "const_int_operand" "")))
20756               (clobber (reg:CC FLAGS_REG))])
20757    (match_scratch:SI 3 "r")]
20758   "TARGET_SLOW_IMUL_IMM8 && !optimize_size
20759    && satisfies_constraint_K (operands[2])"
20760   [(set (match_dup 3) (match_dup 2))
20761    (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20762               (clobber (reg:CC FLAGS_REG))])]
20764   if (!rtx_equal_p (operands[0], operands[1]))
20765     emit_move_insn (operands[0], operands[1]);
20768 (define_peephole2
20769   [(parallel [(set (match_operand:HI 0 "register_operand" "")
20770                    (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20771                             (match_operand:HI 2 "immediate_operand" "")))
20772               (clobber (reg:CC FLAGS_REG))])
20773    (match_scratch:HI 3 "r")]
20774   "TARGET_SLOW_IMUL_IMM8 && !optimize_size"
20775   [(set (match_dup 3) (match_dup 2))
20776    (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20777               (clobber (reg:CC FLAGS_REG))])]
20779   if (!rtx_equal_p (operands[0], operands[1]))
20780     emit_move_insn (operands[0], operands[1]);
20783 ;; After splitting up read-modify operations, array accesses with memory
20784 ;; operands might end up in form:
20785 ;;  sall    $2, %eax
20786 ;;  movl    4(%esp), %edx
20787 ;;  addl    %edx, %eax
20788 ;; instead of pre-splitting:
20789 ;;  sall    $2, %eax
20790 ;;  addl    4(%esp), %eax
20791 ;; Turn it into:
20792 ;;  movl    4(%esp), %edx
20793 ;;  leal    (%edx,%eax,4), %eax
20795 (define_peephole2
20796   [(parallel [(set (match_operand 0 "register_operand" "")
20797                    (ashift (match_operand 1 "register_operand" "")
20798                            (match_operand 2 "const_int_operand" "")))
20799                (clobber (reg:CC FLAGS_REG))])
20800    (set (match_operand 3 "register_operand")
20801         (match_operand 4 "x86_64_general_operand" ""))
20802    (parallel [(set (match_operand 5 "register_operand" "")
20803                    (plus (match_operand 6 "register_operand" "")
20804                          (match_operand 7 "register_operand" "")))
20805                    (clobber (reg:CC FLAGS_REG))])]
20806   "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20807    /* Validate MODE for lea.  */
20808    && ((!TARGET_PARTIAL_REG_STALL
20809         && (GET_MODE (operands[0]) == QImode
20810             || GET_MODE (operands[0]) == HImode))
20811        || GET_MODE (operands[0]) == SImode
20812        || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20813    /* We reorder load and the shift.  */
20814    && !rtx_equal_p (operands[1], operands[3])
20815    && !reg_overlap_mentioned_p (operands[0], operands[4])
20816    /* Last PLUS must consist of operand 0 and 3.  */
20817    && !rtx_equal_p (operands[0], operands[3])
20818    && (rtx_equal_p (operands[3], operands[6])
20819        || rtx_equal_p (operands[3], operands[7]))
20820    && (rtx_equal_p (operands[0], operands[6])
20821        || rtx_equal_p (operands[0], operands[7]))
20822    /* The intermediate operand 0 must die or be same as output.  */
20823    && (rtx_equal_p (operands[0], operands[5])
20824        || peep2_reg_dead_p (3, operands[0]))"
20825   [(set (match_dup 3) (match_dup 4))
20826    (set (match_dup 0) (match_dup 1))]
20828   enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20829   int scale = 1 << INTVAL (operands[2]);
20830   rtx index = gen_lowpart (Pmode, operands[1]);
20831   rtx base = gen_lowpart (Pmode, operands[3]);
20832   rtx dest = gen_lowpart (mode, operands[5]);
20834   operands[1] = gen_rtx_PLUS (Pmode, base,
20835                               gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20836   if (mode != Pmode)
20837     operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20838   operands[0] = dest;
20841 ;; Call-value patterns last so that the wildcard operand does not
20842 ;; disrupt insn-recog's switch tables.
20844 (define_insn "*call_value_pop_0"
20845   [(set (match_operand 0 "" "")
20846         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20847               (match_operand:SI 2 "" "")))
20848    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20849                             (match_operand:SI 3 "immediate_operand" "")))]
20850   "!TARGET_64BIT"
20852   if (SIBLING_CALL_P (insn))
20853     return "jmp\t%P1";
20854   else
20855     return "call\t%P1";
20857   [(set_attr "type" "callv")])
20859 (define_insn "*call_value_pop_1"
20860   [(set (match_operand 0 "" "")
20861         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20862               (match_operand:SI 2 "" "")))
20863    (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
20864                             (match_operand:SI 3 "immediate_operand" "i")))]
20865   "!TARGET_64BIT"
20867   if (constant_call_address_operand (operands[1], Pmode))
20868     {
20869       if (SIBLING_CALL_P (insn))
20870         return "jmp\t%P1";
20871       else
20872         return "call\t%P1";
20873     }
20874   if (SIBLING_CALL_P (insn))
20875     return "jmp\t%A1";
20876   else
20877     return "call\t%A1";
20879   [(set_attr "type" "callv")])
20881 (define_insn "*call_value_0"
20882   [(set (match_operand 0 "" "")
20883         (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20884               (match_operand:SI 2 "" "")))]
20885   "!TARGET_64BIT"
20887   if (SIBLING_CALL_P (insn))
20888     return "jmp\t%P1";
20889   else
20890     return "call\t%P1";
20892   [(set_attr "type" "callv")])
20894 (define_insn "*call_value_0_rex64"
20895   [(set (match_operand 0 "" "")
20896         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20897               (match_operand:DI 2 "const_int_operand" "")))]
20898   "TARGET_64BIT"
20900   if (SIBLING_CALL_P (insn))
20901     return "jmp\t%P1";
20902   else
20903     return "call\t%P1";
20905   [(set_attr "type" "callv")])
20907 (define_insn "*call_value_1"
20908   [(set (match_operand 0 "" "")
20909         (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
20910               (match_operand:SI 2 "" "")))]
20911   "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
20913   if (constant_call_address_operand (operands[1], Pmode))
20914     return "call\t%P1";
20915   return "call\t%A1";
20917   [(set_attr "type" "callv")])
20919 (define_insn "*sibcall_value_1"
20920   [(set (match_operand 0 "" "")
20921         (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
20922               (match_operand:SI 2 "" "")))]
20923   "SIBLING_CALL_P (insn) && !TARGET_64BIT"
20925   if (constant_call_address_operand (operands[1], Pmode))
20926     return "jmp\t%P1";
20927   return "jmp\t%A1";
20929   [(set_attr "type" "callv")])
20931 (define_insn "*call_value_1_rex64"
20932   [(set (match_operand 0 "" "")
20933         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20934               (match_operand:DI 2 "" "")))]
20935   "!SIBLING_CALL_P (insn) && TARGET_64BIT
20936    && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20938   if (constant_call_address_operand (operands[1], Pmode))
20939     return "call\t%P1";
20940   return "call\t%A1";
20942   [(set_attr "type" "callv")])
20944 (define_insn "*call_value_1_rex64_large"
20945   [(set (match_operand 0 "" "")
20946         (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20947               (match_operand:DI 2 "" "")))]
20948   "!SIBLING_CALL_P (insn) && TARGET_64BIT"
20949   "call\t%A1"
20950   [(set_attr "type" "callv")])
20952 (define_insn "*sibcall_value_1_rex64"
20953   [(set (match_operand 0 "" "")
20954         (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20955               (match_operand:DI 2 "" "")))]
20956   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20957   "jmp\t%P1"
20958   [(set_attr "type" "callv")])
20960 (define_insn "*sibcall_value_1_rex64_v"
20961   [(set (match_operand 0 "" "")
20962         (call (mem:QI (reg:DI R11_REG))
20963               (match_operand:DI 1 "" "")))]
20964   "SIBLING_CALL_P (insn) && TARGET_64BIT"
20965   "jmp\t{*%%}r11"
20966   [(set_attr "type" "callv")])
20968 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20969 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20970 ;; caught for use by garbage collectors and the like.  Using an insn that
20971 ;; maps to SIGILL makes it more likely the program will rightfully die.
20972 ;; Keeping with tradition, "6" is in honor of #UD.
20973 (define_insn "trap"
20974   [(trap_if (const_int 1) (const_int 6))]
20975   ""
20976   { return ASM_SHORT "0x0b0f"; }
20977   [(set_attr "length" "2")])
20979 (define_expand "sse_prologue_save"
20980   [(parallel [(set (match_operand:BLK 0 "" "")
20981                    (unspec:BLK [(reg:DI 21)
20982                                 (reg:DI 22)
20983                                 (reg:DI 23)
20984                                 (reg:DI 24)
20985                                 (reg:DI 25)
20986                                 (reg:DI 26)
20987                                 (reg:DI 27)
20988                                 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
20989               (use (match_operand:DI 1 "register_operand" ""))
20990               (use (match_operand:DI 2 "immediate_operand" ""))
20991               (use (label_ref:DI (match_operand 3 "" "")))])]
20992   "TARGET_64BIT"
20993   "")
20995 (define_insn "*sse_prologue_save_insn"
20996   [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20997                           (match_operand:DI 4 "const_int_operand" "n")))
20998         (unspec:BLK [(reg:DI 21)
20999                      (reg:DI 22)
21000                      (reg:DI 23)
21001                      (reg:DI 24)
21002                      (reg:DI 25)
21003                      (reg:DI 26)
21004                      (reg:DI 27)
21005                      (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
21006    (use (match_operand:DI 1 "register_operand" "r"))
21007    (use (match_operand:DI 2 "const_int_operand" "i"))
21008    (use (label_ref:DI (match_operand 3 "" "X")))]
21009   "TARGET_64BIT
21010    && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21011    && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21013   int i;
21014   operands[0] = gen_rtx_MEM (Pmode,
21015                              gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21016   output_asm_insn ("jmp\t%A1", operands);
21017   for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21018     {
21019       operands[4] = adjust_address (operands[0], DImode, i*16);
21020       operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21021       PUT_MODE (operands[4], TImode);
21022       if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21023         output_asm_insn ("rex", operands);
21024       output_asm_insn ("movaps\t{%5, %4|%4, %5}", operands);
21025     }
21026   (*targetm.asm_out.internal_label) (asm_out_file, "L",
21027                                      CODE_LABEL_NUMBER (operands[3]));
21028   return "";
21030   [(set_attr "type" "other")
21031    (set_attr "length_immediate" "0")
21032    (set_attr "length_address" "0")
21033    (set_attr "length" "34")
21034    (set_attr "memory" "store")
21035    (set_attr "modrm" "0")
21036    (set_attr "mode" "DI")])
21038 (define_expand "prefetch"
21039   [(prefetch (match_operand 0 "address_operand" "")
21040              (match_operand:SI 1 "const_int_operand" "")
21041              (match_operand:SI 2 "const_int_operand" ""))]
21042   "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21044   int rw = INTVAL (operands[1]);
21045   int locality = INTVAL (operands[2]);
21047   gcc_assert (rw == 0 || rw == 1);
21048   gcc_assert (locality >= 0 && locality <= 3);
21049   gcc_assert (GET_MODE (operands[0]) == Pmode
21050               || GET_MODE (operands[0]) == VOIDmode);
21052   /* Use 3dNOW prefetch in case we are asking for write prefetch not
21053      supported by SSE counterpart or the SSE prefetch is not available
21054      (K6 machines).  Otherwise use SSE prefetch as it allows specifying
21055      of locality.  */
21056   if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21057     operands[2] = GEN_INT (3);
21058   else
21059     operands[1] = const0_rtx;
21062 (define_insn "*prefetch_sse"
21063   [(prefetch (match_operand:SI 0 "address_operand" "p")
21064              (const_int 0)
21065              (match_operand:SI 1 "const_int_operand" ""))]
21066   "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21068   static const char * const patterns[4] = {
21069    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21070   };
21072   int locality = INTVAL (operands[1]);
21073   gcc_assert (locality >= 0 && locality <= 3);
21075   return patterns[locality];
21077   [(set_attr "type" "sse")
21078    (set_attr "memory" "none")])
21080 (define_insn "*prefetch_sse_rex"
21081   [(prefetch (match_operand:DI 0 "address_operand" "p")
21082              (const_int 0)
21083              (match_operand:SI 1 "const_int_operand" ""))]
21084   "TARGET_PREFETCH_SSE && TARGET_64BIT"
21086   static const char * const patterns[4] = {
21087    "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21088   };
21090   int locality = INTVAL (operands[1]);
21091   gcc_assert (locality >= 0 && locality <= 3);
21093   return patterns[locality];
21095   [(set_attr "type" "sse")
21096    (set_attr "memory" "none")])
21098 (define_insn "*prefetch_3dnow"
21099   [(prefetch (match_operand:SI 0 "address_operand" "p")
21100              (match_operand:SI 1 "const_int_operand" "n")
21101              (const_int 3))]
21102   "TARGET_3DNOW && !TARGET_64BIT"
21104   if (INTVAL (operands[1]) == 0)
21105     return "prefetch\t%a0";
21106   else
21107     return "prefetchw\t%a0";
21109   [(set_attr "type" "mmx")
21110    (set_attr "memory" "none")])
21112 (define_insn "*prefetch_3dnow_rex"
21113   [(prefetch (match_operand:DI 0 "address_operand" "p")
21114              (match_operand:SI 1 "const_int_operand" "n")
21115              (const_int 3))]
21116   "TARGET_3DNOW && TARGET_64BIT"
21118   if (INTVAL (operands[1]) == 0)
21119     return "prefetch\t%a0";
21120   else
21121     return "prefetchw\t%a0";
21123   [(set_attr "type" "mmx")
21124    (set_attr "memory" "none")])
21126 (define_expand "stack_protect_set"
21127   [(match_operand 0 "memory_operand" "")
21128    (match_operand 1 "memory_operand" "")]
21129   ""
21131 #ifdef TARGET_THREAD_SSP_OFFSET
21132   if (TARGET_64BIT)
21133     emit_insn (gen_stack_tls_protect_set_di (operands[0],
21134                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21135   else
21136     emit_insn (gen_stack_tls_protect_set_si (operands[0],
21137                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21138 #else
21139   if (TARGET_64BIT)
21140     emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21141   else
21142     emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21143 #endif
21144   DONE;
21147 (define_insn "stack_protect_set_si"
21148   [(set (match_operand:SI 0 "memory_operand" "=m")
21149         (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21150    (set (match_scratch:SI 2 "=&r") (const_int 0))
21151    (clobber (reg:CC FLAGS_REG))]
21152   ""
21153   "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21154   [(set_attr "type" "multi")])
21156 (define_insn "stack_protect_set_di"
21157   [(set (match_operand:DI 0 "memory_operand" "=m")
21158         (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21159    (set (match_scratch:DI 2 "=&r") (const_int 0))
21160    (clobber (reg:CC FLAGS_REG))]
21161   "TARGET_64BIT"
21162   "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21163   [(set_attr "type" "multi")])
21165 (define_insn "stack_tls_protect_set_si"
21166   [(set (match_operand:SI 0 "memory_operand" "=m")
21167         (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21168    (set (match_scratch:SI 2 "=&r") (const_int 0))
21169    (clobber (reg:CC FLAGS_REG))]
21170   ""
21171   "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21172   [(set_attr "type" "multi")])
21174 (define_insn "stack_tls_protect_set_di"
21175   [(set (match_operand:DI 0 "memory_operand" "=m")
21176         (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21177    (set (match_scratch:DI 2 "=&r") (const_int 0))
21178    (clobber (reg:CC FLAGS_REG))]
21179   "TARGET_64BIT"
21180   {
21181      /* The kernel uses a different segment register for performance reasons; a
21182         system call would not have to trash the userspace segment register,
21183         which would be expensive */
21184      if (ix86_cmodel != CM_KERNEL)
21185         return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21186      else
21187         return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21188   }
21189   [(set_attr "type" "multi")])
21191 (define_expand "stack_protect_test"
21192   [(match_operand 0 "memory_operand" "")
21193    (match_operand 1 "memory_operand" "")
21194    (match_operand 2 "" "")]
21195   ""
21197   rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21198   ix86_compare_op0 = operands[0];
21199   ix86_compare_op1 = operands[1];
21200   ix86_compare_emitted = flags;
21202 #ifdef TARGET_THREAD_SSP_OFFSET
21203   if (TARGET_64BIT)
21204     emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21205                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21206   else
21207     emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21208                                         GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21209 #else
21210   if (TARGET_64BIT)
21211     emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21212   else
21213     emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21214 #endif
21215   emit_jump_insn (gen_beq (operands[2]));
21216   DONE;
21219 (define_insn "stack_protect_test_si"
21220   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21221         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21222                      (match_operand:SI 2 "memory_operand" "m")]
21223                     UNSPEC_SP_TEST))
21224    (clobber (match_scratch:SI 3 "=&r"))]
21225   ""
21226   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21227   [(set_attr "type" "multi")])
21229 (define_insn "stack_protect_test_di"
21230   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21231         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21232                      (match_operand:DI 2 "memory_operand" "m")]
21233                     UNSPEC_SP_TEST))
21234    (clobber (match_scratch:DI 3 "=&r"))]
21235   "TARGET_64BIT"
21236   "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21237   [(set_attr "type" "multi")])
21239 (define_insn "stack_tls_protect_test_si"
21240   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21241         (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21242                      (match_operand:SI 2 "const_int_operand" "i")]
21243                     UNSPEC_SP_TLS_TEST))
21244    (clobber (match_scratch:SI 3 "=r"))]
21245   ""
21246   "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21247   [(set_attr "type" "multi")])
21249 (define_insn "stack_tls_protect_test_di"
21250   [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21251         (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21252                      (match_operand:DI 2 "const_int_operand" "i")]
21253                     UNSPEC_SP_TLS_TEST))
21254    (clobber (match_scratch:DI 3 "=r"))]
21255   "TARGET_64BIT"
21256   {
21257      /* The kernel uses a different segment register for performance reasons; a
21258         system call would not have to trash the userspace segment register,
21259         which would be expensive */
21260      if (ix86_cmodel != CM_KERNEL)
21261         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21262      else
21263         return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21264   }
21265   [(set_attr "type" "multi")])
21267 (define_mode_iterator CRC32MODE [QI HI SI])
21268 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21269 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21271 (define_insn "sse4_2_crc32<mode>"
21272   [(set (match_operand:SI 0 "register_operand" "=r")
21273         (unspec:SI
21274           [(match_operand:SI 1 "register_operand" "0")
21275            (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21276           UNSPEC_CRC32))]
21277   "TARGET_SSE4_2"
21278   "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21279   [(set_attr "type" "sselog1")
21280    (set_attr "prefix_rep" "1")
21281    (set_attr "prefix_extra" "1")
21282    (set_attr "mode" "SI")])
21284 (define_insn "sse4_2_crc32di"
21285   [(set (match_operand:DI 0 "register_operand" "=r")
21286         (unspec:DI
21287           [(match_operand:DI 1 "register_operand" "0")
21288            (match_operand:DI 2 "nonimmediate_operand" "rm")]
21289           UNSPEC_CRC32))]
21290   "TARGET_SSE4_2 && TARGET_64BIT"
21291   "crc32q\t{%2, %0|%0, %2}"
21292   [(set_attr "type" "sselog1")
21293    (set_attr "prefix_rep" "1")
21294    (set_attr "prefix_extra" "1")
21295    (set_attr "mode" "DI")])
21297 (include "mmx.md")
21298 (include "sse.md")
21299 (include "sync.md")